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 5564 var counter = 0, 5565 $headCache = $('head'), 5566 oldBigText = window.BigText, 5567 oldjQueryMethod = $.fn.bigtext, 5568 BigText = { 5569 DEBUG_MODE: false, 5570 DEFAULT_MIN_FONT_SIZE_PX: null, 5571 DEFAULT_MAX_FONT_SIZE_PX: 528, 5572 GLOBAL_STYLE_ID: 'bigtext-style', 5573 STYLE_ID: 'bigtext-id', 5574 LINE_CLASS_PREFIX: 'bigtext-line', 5575 EXEMPT_CLASS: 'bigtext-exempt', 5576 noConflict: function(restore) 5577 { 5578 if(restore) { 5579 $.fn.bigtext = oldjQueryMethod; 5580 window.BigText = oldBigText; 5581 } 5582 return BigText; 5583 }, 5584 supports: { 5585 wholeNumberFontSizeOnly: (function() { 5586 if( !( 'getComputedStyle' in window ) ) { 5587 return true; 5588 } 5589 var test = $('<div/>').css({ 5590 position: 'absolute', 5591 'font-size': '14.1px' 5592 }).insertBefore( $('script').eq(0) ), 5593 computedStyle = window.getComputedStyle( test[0], null ); 5594 5595 var ret = computedStyle && computedStyle.getPropertyValue( 'font-size' ) === '14px'; 5596 test.remove(); 5597 return ret; 5598 })() 5599 }, 5600 init: function() { 5601 if(!$('#'+BigText.GLOBAL_STYLE_ID).length) { 5602 $headCache.append(BigText.generateStyleTag(BigText.GLOBAL_STYLE_ID, ['.bigtext * { white-space: nowrap; } .bigtext > * { display: block; }', 5603 '.bigtext .' + BigText.EXEMPT_CLASS + ', .bigtext .' + BigText.EXEMPT_CLASS + ' * { white-space: normal; }'])); 5604 } 5605 }, 5606 bindResize: function(eventName, resizeFunction) { 5607 var timeoutId; 5608 $(window).off(eventName).on(eventName, function() { 5609 if( timeoutId ) { 5610 clearTimeout( timeoutId ); 5611 } 5612 timeoutId = setTimeout( resizeFunction, 100 ); 5613 }); 5614 }, 5615 getStyleId: function(id) 5616 { 5617 return BigText.STYLE_ID + '-' + id; 5618 }, 5619 generateStyleTag: function(id, css) 5620 { 5621 return $('<style>' + css.join('\n') + '</style>').attr('id', id); 5622 }, 5623 clearCss: function(id) 5624 { 5625 var styleId = BigText.getStyleId(id); 5626 $('#' + styleId).remove(); 5627 }, 5628 generateCss: function(id, linesFontSizes, lineWordSpacings, minFontSizes) 5629 { 5630 var css = []; 5631 5632 BigText.clearCss(id); 5633 5634 for(var j=0, k=linesFontSizes.length; j<k; j++) { 5635 css.push('#' + id + ' .' + BigText.LINE_CLASS_PREFIX + j + ' {' + 5636 (minFontSizes[j] ? ' white-space: normal;' : '') + 5637 (linesFontSizes[j] ? ' font-size: ' + linesFontSizes[j] + 'px;' : '') + 5638 (lineWordSpacings[j] ? ' word-spacing: ' + lineWordSpacings[j] + 'px;' : '') + 5639 '}'); 5640 } 5641 5642 return BigText.generateStyleTag(BigText.getStyleId(id), css); 5643 }, 5644 jQueryMethod: function(options) 5645 {
5646 BigText.init(); 5647 5648 options = $.extend({ 5649 minfontsize: BigText.DEFAULT_MIN_FONT_SIZE_PX, 5650 maxfontsize: BigText.DEFAULT_MAX_FONT_SIZE_PX, 5651 childSelector: '', 5652 resize: true 5653 }, options || {}); 5654 5655 this.each(function() 5656 { 5657 var $t = $(this).addClass('bigtext'), 5658 maxWidth = $t.width(), 5659 id = $t.attr('id'), 5660 $children = options.childSelector ? $t.find( options.childSelector ) : $t.children(); 5661 5662 if(!id) { 5663 id = 'bigtext-id' + (counter++); 5664 $t.attr('id', id); 5665 } 5666 5667 if(options.resize) { 5668 BigText.bindResize('resize.bigtext-event-' + id, function() 5669 { 5670 // TODO only call this if the width has changed. 5671 BigText.jQueryMethod.call($('#' + id), options); 5672 }); 5673 } 5674 5675 BigText.clearCss(id); 5676 5677 $children.addClass(function(lineNumber, className) 5678 { 5679 // remove existing line classes. 5680 return [className.replace(new RegExp('\\b' + BigText.LINE_CLASS_PREFIX + '\\d+\\b'), ''), 5681 BigText.LINE_CLASS_PREFIX + lineNumber].join(' '); 5682 }); 5683 5684 var sizes = BigText.calculateSizes($t, $children, maxWidth, options.maxfontsize, options.minfontsize); 5685 $headCache.append(BigText.generateCss(id, sizes.fontSizes, sizes.wordSpacings, sizes.minFontSizes)); 5686 }); 5687 5688 return this.trigger('bigtext:complete'); 5689 }, 5690 testLineDimensions: function($line, maxWidth, property, size, interval, units, previousWidth) 5691 { 5692 var width; 5693 previousWidth = typeof previousWidth === 'number' ? previousWidth : 0; 5694 $line.css(property, size + units); 5695 5696 width = $line.width(); 5697 5698 if(width >= maxWidth) { 5699 // console.log(width, ' previous: ' + previousWidth, property + ' at ' + interval, 'prior: ' + (parseFloat(size) - interval), 'new:' + parseFloat(size)); 5700 $line.css(property, ''); 5701 5702 if(width === maxWidth) { 5703 return { 5704 match: 'exact', 5705 size: parseFloat((parseFloat(size) - 0.1).toFixed(3)) 5706 }; 5707 } 5708 5709 // Since this is an estimate, we calculate how far over the width we went with the new value. 5710 // If this is word-spacing (our last resort guess) and the over is less than the under, we keep the higher value. 5711 // Otherwise, we revert to the underestimate. 5712 var under = maxWidth - previousWidth, 5713 over = width - maxWidth; 5714 5715 return { 5716 match: 'estimate', 5717 size: parseFloat((parseFloat(size) - (property === 'word-spacing' && previousWidth && ( over < under ) ? 0 : interval)).toFixed(3)) 5718 }; 5719 } 5720 5721 return width; 5722 }, 5723 calculateSizes: function($t, $children, maxWidth, maxFontSize, minFontSize) 5724 { 5725 var $c = $t.clone(true) 5726 .addClass('bigtext-cloned') 5727 .css({ 5728 fontFamily: $t.css('font-family'), 5729 textTransform: $t.css('text-transform'), 5730 wordSpacing: $t.css('word-spacing'), 5731 letterSpacing: $t.css('letter-spacing'), 5732 position: 'absolute', 5733 left: BigText.DEBUG_MODE ? 0 : -9999, 5734 top: BigText.DEBUG_MODE ? 0 : -9999 5735 }) 5736 .appendTo(document.body); 5737 5738 // font-size isn't the only thing we can modify, we can also mess with: 5739 // word-spacing and letter-spacing. WebKit does not respect subpixel 5740 // letter-spacing, word-spacing, or font-size. 5741 // TODO try -webkit-transform: scale() as a workaround. 5742 var fontSizes = [], 5743 wordSpacings = [], 5744 minFontSizes = [], 5745 ratios = []; 5746 5747 $children.css('float', 'left').each(function() { 5748 var $line = $(this), 5749 // TODO replace 8, 4 with a proportional size to the calculated font-size. 5750 intervals = BigText.supports.wholeNumberFontSizeOnly ? [8, 4, 1] : [8, 4, 1, 0.1], 5751 lineMax, 5752 newFontSize; 5753 5754 if($line.hasClass(BigText.EXEMPT_CLASS)) { 5755 fontSizes.push(null); 5756 ratios.push(null); 5757 minFontSizes.push(false); 5758 return; 5759 } 5760 5761 // TODO we can cache this ratio? 5762 var autoGuessSubtraction = 32, // font size in px 5763 currentFontSize = parseFloat($line.css('font-size')), 5764 ratio = ( $line.width() / currentFontSize ).toFixed(6); 5765 5766 newFontSize = parseInt( maxWidth / ratio, 10 ) - autoGuessSubtraction; 5767 5768 outer: for(var m=0, n=intervals.length; m<n; m++) { 5769 inner: for(var j=1, k=10; j<=k; j++) { 5770 if(newFontSize + j*intervals[m] > maxFontSize) { 5771 newFontSize = maxFontSize; 5772 break outer; 5773 } 5774 5775 lineMax = BigText.testLineDimensions($line, maxWidth, 'font-size', newFontSize + j*intervals[m], intervals[m], 'px', lineMax); 5776 if(typeof lineMax !== 'number') { 5777 newFontSize = lineMax.size; 5778 5779 if(lineMax.match === 'exact') { 5780 break outer; 5781 } 5782 break inner; 5783 } 5784 } 5785 } 5786 5787 ratios.push(maxWidth / newFontSize); 5788 5789 if(newFontSize > maxFontSize) { 5790 fontSizes.push(maxFontSize); 5791 minFontSizes.push(false); 5792 } else if(!!minFontSize && newFontSize < minFontSize) { 5793 fontSizes.push(minFontSize); 5794 minFontSizes.push(true); 5795 } else { 5796 fontSizes.push(newFontSize); 5797 minFontSizes.push(false); 5798 } 5799 }).each(function(lineNumber) { 5800 var $line = $(this), 5801 wordSpacing = 0, 5802 interval = 1, 5803 maxWordSpacing; 5804 5805 if($line.hasClass(BigText.EXEMPT_CLASS)) { 5806 wordSpacings.push(null); 5807 return; 5808 } 5809 5810 // must re-use font-size, even though it was removed above. 5811 $line.css('font-size', fontSizes[lineNumber] + 'px'); 5812 5813 for(var m=1, n=3; m<n; m+=interval) { 5814 maxWordSpacing = BigText.testLineDimensions($line, maxWidth, 'word-spacing', m, interval, 'px', maxWordSpacing); 5815 if(typeof maxWordSpacing !== 'number') { 5816 wordSpacing = maxWordSpacing.size; 5817 break; 5818 } 5819 } 5820 5821 $line.css('font-size', ''); 5822 wordSpacings.push(wordSpacing); 5823 }).removeAttr('style'); 5824 5825 if( !BigText.DEBUG_MODE ) { 5826 $c.remove(); 5827 } else { 5828 $c.css({ 5829 'background-color': 'rgba(255,255,255,.4)' 5830 }); 5831 } 5832 5833 return { 5834 fontSizes: fontSizes, 5835 wordSpacings: wordSpacings, 5836 ratios: ratios, 5837 minFontSizes: minFontSizes 5838 }; 5839 } 5840 }; 5841 5842 $.fn.bigtext = BigText.jQueryMethod; 5843 window.BigText = BigText; 5844 5845})(this, jQuery); 5846/*! 5847 * Isotope PACKAGED v3.0.6 5848 * 5849 * Licensed GPLv3 for open source use 5850 * or Isotope Commercial License for commercial use 5851 * 5852 * https://isotope.metafizzy.co 5853 * Copyright 2010-2018 Metafizzy
vendor: 15,902 bytes, lines 5853-6503
5853 5854 */ 5855 5856/** 5857 * Bridget makes jQuery widgets 5858 * v2.0.1 5859 * MIT license 5860 */ 5861 5862/* jshint browser: true, strict: true, undef: true, unused: true */ 5863 5864( function( window, factory ) { 5865 // universal module definition 5866 /*jshint strict: false */ /* globals define, module, require */ 5867 if ( typeof define == 'function' && define.amd ) { 5868 // AMD 5869 define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) { 5870 return factory( window, jQuery ); 5871 }); 5872 } else if ( typeof module == 'object' && module.exports ) { 5873 // CommonJS 5874 module.exports = factory( 5875 window, 5876 require('jquery') 5877 ); 5878 } else { 5879 // browser global 5880 window.jQueryBridget = factory( 5881 window, 5882 window.jQuery 5883 ); 5884 } 5885 5886}( window, function factory( window, jQuery ) { 5887'use strict'; 5888 5889// ----- utils ----- // 5890 5891var arraySlice = Array.prototype.slice; 5892 5893// helper function for logging errors 5894// $.error breaks jQuery chaining 5895var console = window.console; 5896var logError = typeof console == 'undefined' ? function() {} : 5897 function( message ) { 5898 console.error( message ); 5899 }; 5900 5901// ----- jQueryBridget ----- // 5902 5903function jQueryBridget( namespace, PluginClass, $ ) { 5904 $ = $ || jQuery || window.jQuery; 5905 if ( !$ ) { 5906 return; 5907 } 5908 5909 // add option method -> $().plugin('option', {...}) 5910 if ( !PluginClass.prototype.option ) { 5911 // option setter 5912 PluginClass.prototype.option = function( opts ) { 5913 // bail out if not an object 5914 if ( !$.isPlainObject( opts ) ){ 5915 return; 5916 } 5917 this.options = $.extend( true, this.options, opts ); 5918 }; 5919 } 5920 5921 // make jQuery plugin 5922 $.fn[ namespace ] = function( arg0 /*, arg1 */ ) { 5923 if ( typeof arg0 == 'string' ) { 5924 // method call $().plugin( 'methodName', { options } ) 5925 // shift arguments by 1 5926 var args = arraySlice.call( arguments, 1 ); 5927 return methodCall( this, arg0, args ); 5928 } 5929 // just $().plugin({ options }) 5930 plainCall( this, arg0 ); 5931 return this; 5932 }; 5933 5934 // $().plugin('methodName') 5935 function methodCall( $elems, methodName, args ) { 5936 var returnValue; 5937 var pluginMethodStr = '$().' + namespace + '("' + methodName + '")'; 5938 5939 $elems.each( function( i, elem ) { 5940 // get instance 5941 var instance = $.data( elem, namespace ); 5942 if ( !instance ) { 5943 logError( namespace + ' not initialized. Cannot call methods, i.e. ' + 5944 pluginMethodStr ); 5945 return; 5946 } 5947 5948 var method = instance[ methodName ]; 5949 if ( !method || methodName.charAt(0) == '_' ) { 5950 logError( pluginMethodStr + ' is not a valid method' ); 5951 return; 5952 } 5953 5954 // apply method, get return value 5955 var value = method.apply( instance, args ); 5956 // set return value if value is returned, use only first value 5957 returnValue = returnValue === undefined ? value : returnValue; 5958 }); 5959 5960 return returnValue !== undefined ? returnValue : $elems; 5961 } 5962 5963 function plainCall( $elems, options ) { 5964 $elems.each( function( i, elem ) { 5965 var instance = $.data( elem, namespace ); 5966 if ( instance ) { 5967 // set options & init 5968 instance.option( options ); 5969 instance._init(); 5970 } else { 5971 // initialize new instance 5972 instance = new PluginClass( elem, options ); 5973 $.data( elem, namespace, instance ); 5974 } 5975 }); 5976 } 5977 5978 updateJQuery( $ ); 5979 5980} 5981 5982// ----- updateJQuery ----- // 5983 5984// set $.bridget for v1 backwards compatibility 5985function updateJQuery( $ ) { 5986 if ( !$ || ( $ && $.bridget ) ) { 5987 return; 5988 } 5989 $.bridget = jQueryBridget; 5990} 5991 5992updateJQuery( jQuery || window.jQuery ); 5993 5994// ----- ----- // 5995 5996return jQueryBridget; 5997 5998})); 5999 6000/** 6001 * EvEmitter v1.1.0 6002 * Lil' event emitter 6003 * MIT License 6004 */ 6005 6006/* jshint unused: true, undef: true, strict: true */ 6007 6008( function( global, factory ) { 6009 // universal module definition 6010 /* jshint strict: false */ /* globals define, module, window */ 6011 if ( typeof define == 'function' && define.amd ) { 6012 // AMD - RequireJS 6013 define( 'ev-emitter/ev-emitter',factory ); 6014 } else if ( typeof module == 'object' && module.exports ) { 6015 // CommonJS - Browserify, Webpack 6016 module.exports = factory(); 6017 } else { 6018 // Browser globals 6019 global.EvEmitter = factory(); 6020 } 6021 6022}( typeof window != 'undefined' ? window : this, function() { 6023 6024 6025 6026function EvEmitter() {} 6027 6028var proto = EvEmitter.prototype; 6029 6030proto.on = function( eventName, listener ) { 6031 if ( !eventName || !listener ) { 6032 return; 6033 } 6034 // set events hash 6035 var events = this._events = this._events || {}; 6036 // set listeners array 6037 var listeners = events[ eventName ] = events[ eventName ] || []; 6038 // only add once 6039 if ( listeners.indexOf( listener ) == -1 ) { 6040 listeners.push( listener ); 6041 } 6042 6043 return this; 6044}; 6045 6046proto.once = function( eventName, listener ) { 6047 if ( !eventName || !listener ) { 6048 return; 6049 } 6050 // add event 6051 this.on( eventName, listener ); 6052 // set once flag 6053 // set onceEvents hash 6054 var onceEvents = this._onceEvents = this._onceEvents || {}; 6055 // set onceListeners object 6056 var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 6057 // set flag 6058 onceListeners[ listener ] = true; 6059 6060 return this; 6061}; 6062 6063proto.off = function( eventName, listener ) { 6064 var listeners = this._events && this._events[ eventName ]; 6065 if ( !listeners || !listeners.length ) { 6066 return; 6067 } 6068 var index = listeners.indexOf( listener ); 6069 if ( index != -1 ) { 6070 listeners.splice( index, 1 ); 6071 } 6072 6073 return this; 6074}; 6075 6076proto.emitEvent = function( eventName, args ) { 6077 var listeners = this._events && this._events[ eventName ]; 6078 if ( !listeners || !listeners.length ) { 6079 return; 6080 } 6081 // copy over to avoid interference if .off() in listener 6082 listeners = listeners.slice(0); 6083 args = args || []; 6084 // once stuff 6085 var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 6086 6087 for ( var i=0; i < listeners.length; i++ ) { 6088 var listener = listeners[i] 6089 var isOnce = onceListeners && onceListeners[ listener ]; 6090 if ( isOnce ) { 6091 // remove listener 6092 // remove before trigger to prevent recursion 6093 this.off( eventName, listener ); 6094 // unset once flag 6095 delete onceListeners[ listener ]; 6096 } 6097 // trigger listener 6098 listener.apply( this, args ); 6099 } 6100 6101 return this; 6102}; 6103 6104proto.allOff = function() { 6105 delete this._events; 6106 delete this._onceEvents; 6107}; 6108 6109return EvEmitter; 6110 6111})); 6112 6113/*! 6114 * getSize v2.0.3 6115 * measure size of elements 6116 * MIT license 6117 */ 6118 6119/* jshint browser: true, strict: true, undef: true, unused: true */ 6120/* globals console: false */ 6121 6122( function( window, factory ) { 6123 /* jshint strict: false */ /* globals define, module */ 6124 if ( typeof define == 'function' && define.amd ) { 6125 // AMD 6126 define( 'get-size/get-size',factory ); 6127 } else if ( typeof module == 'object' && module.exports ) { 6128 // CommonJS 6129 module.exports = factory(); 6130 } else { 6131 // browser global 6132 window.getSize = factory(); 6133 } 6134 6135})( window, function factory() { 6136'use strict'; 6137 6138// -------------------------- helpers -------------------------- // 6139 6140// get a number from a string, not a percentage 6141function getStyleSize( value ) { 6142 var num = parseFloat( value ); 6143 // not a percent like '100%', and a number 6144 var isValid = value.indexOf('%') == -1 && !isNaN( num ); 6145 return isValid && num; 6146} 6147 6148function noop() {} 6149 6150var logError = typeof console == 'undefined' ? noop : 6151 function( message ) { 6152 console.error( message ); 6153 }; 6154 6155// -------------------------- measurements -------------------------- // 6156 6157var measurements = [ 6158 'paddingLeft', 6159 'paddingRight', 6160 'paddingTop', 6161 'paddingBottom', 6162 'marginLeft', 6163 'marginRight', 6164 'marginTop', 6165 'marginBottom', 6166 'borderLeftWidth', 6167 'borderRightWidth', 6168 'borderTopWidth', 6169 'borderBottomWidth' 6170]; 6171 6172var measurementsLength = measurements.length; 6173 6174function getZeroSize() { 6175 var size = { 6176 width: 0, 6177 height: 0, 6178 innerWidth: 0, 6179 innerHeight: 0, 6180 outerWidth: 0, 6181 outerHeight: 0 6182 }; 6183 for ( var i=0; i < measurementsLength; i++ ) { 6184 var measurement = measurements[i]; 6185 size[ measurement ] = 0; 6186 } 6187 return size; 6188} 6189 6190// -------------------------- getStyle -------------------------- // 6191 6192/** 6193 * getStyle, get style of element, check for Firefox bug 6194 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397 6195 */ 6196function getStyle( elem ) { 6197 var style = getComputedStyle( elem ); 6198 if ( !style ) { 6199 logError( 'Style returned ' + style + 6200 '. Are you running this code in a hidden iframe on Firefox? ' + 6201 'See https://bit.ly/getsizebug1' ); 6202 } 6203 return style; 6204} 6205 6206// -------------------------- setup -------------------------- // 6207 6208var isSetup = false; 6209 6210var isBoxSizeOuter; 6211 6212/** 6213 * setup 6214 * check isBoxSizerOuter 6215 * do on first getSize() rather than on page load for Firefox bug 6216 */ 6217function setup() { 6218 // setup once 6219 if ( isSetup ) { 6220 return; 6221 } 6222 isSetup = true; 6223 6224 // -------------------------- box sizing -------------------------- // 6225 6226 /** 6227 * Chrome & Safari measure the outer-width on style.width on border-box elems 6228 * IE11 & Firefox<29 measures the inner-width 6229 */ 6230 var div = document.createElement('div'); 6231 div.style.width = '200px'; 6232 div.style.padding = '1px 2px 3px 4px'; 6233 div.style.borderStyle = 'solid'; 6234 div.style.borderWidth = '1px 2px 3px 4px'; 6235 div.style.boxSizing = 'border-box'; 6236 6237 var body = document.body || document.documentElement; 6238 body.appendChild( div ); 6239 var style = getStyle( div ); 6240 // round value for browser zoom. desandro/masonry#928 6241 isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200; 6242 getSize.isBoxSizeOuter = isBoxSizeOuter; 6243 6244 body.removeChild( div ); 6245} 6246 6247// -------------------------- getSize -------------------------- // 6248 6249function getSize( elem ) { 6250 setup(); 6251 6252 // use querySeletor if elem is string 6253 if ( typeof elem == 'string' ) { 6254 elem = document.querySelector( elem ); 6255 } 6256 6257 // do not proceed on non-objects 6258 if ( !elem || typeof elem != 'object' || !elem.nodeType ) { 6259 return; 6260 } 6261 6262 var style = getStyle( elem ); 6263 6264 // if hidden, everything is 0 6265 if ( style.display == 'none' ) { 6266 return getZeroSize(); 6267 } 6268 6269 var size = {}; 6270 size.width = elem.offsetWidth; 6271 size.height = elem.offsetHeight; 6272 6273 var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; 6274 6275 // get all measurements 6276 for ( var i=0; i < measurementsLength; i++ ) { 6277 var measurement = measurements[i]; 6278 var value = style[ measurement ]; 6279 var num = parseFloat( value ); 6280 // any 'auto', 'medium' value will be 0 6281 size[ measurement ] = !isNaN( num ) ? num : 0; 6282 } 6283 6284 var paddingWidth = size.paddingLeft + size.paddingRight; 6285 var paddingHeight = size.paddingTop + size.paddingBottom; 6286 var marginWidth = size.marginLeft + size.marginRight; 6287 var marginHeight = size.marginTop + size.marginBottom; 6288 var borderWidth = size.borderLeftWidth + size.borderRightWidth; 6289 var borderHeight = size.borderTopWidth + size.borderBottomWidth; 6290 6291 var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; 6292 6293 // overwrite width and height if we can get it from style 6294 var styleWidth = getStyleSize( style.width ); 6295 if ( styleWidth !== false ) { 6296 size.width = styleWidth + 6297 // add padding and border unless it's already including it 6298 ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); 6299 } 6300 6301 var styleHeight = getStyleSize( style.height ); 6302 if ( styleHeight !== false ) { 6303 size.height = styleHeight + 6304 // add padding and border unless it's already including it 6305 ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); 6306 } 6307 6308 size.innerWidth = size.width - ( paddingWidth + borderWidth ); 6309 size.innerHeight = size.height - ( paddingHeight + borderHeight ); 6310 6311 size.outerWidth = size.width + marginWidth; 6312 size.outerHeight = size.height + marginHeight; 6313 6314 return size; 6315} 6316 6317return getSize; 6318 6319}); 6320 6321/** 6322 * matchesSelector v2.0.2 6323 * matchesSelector( element, '.selector' ) 6324 * MIT license 6325 */ 6326 6327/*jshint browser: true, strict: true, undef: true, unused: true */ 6328 6329( function( window, factory ) { 6330 /*global define: false, module: false */ 6331 'use strict'; 6332 // universal module definition 6333 if ( typeof define == 'function' && define.amd ) { 6334 // AMD 6335 define( 'desandro-matches-selector/matches-selector',factory ); 6336 } else if ( typeof module == 'object' && module.exports ) { 6337 // CommonJS 6338 module.exports = factory(); 6339 } else { 6340 // browser global 6341 window.matchesSelector = factory(); 6342 } 6343 6344}( window, function factory() { 6345 'use strict'; 6346 6347 var matchesMethod = ( function() { 6348 var ElemProto = window.Element.prototype; 6349 // check for the standard method name first 6350 if ( ElemProto.matches ) { 6351 return 'matches'; 6352 } 6353 // check un-prefixed 6354 if ( ElemProto.matchesSelector ) { 6355 return 'matchesSelector'; 6356 } 6357 // check vendor prefixes 6358 var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; 6359 6360 for ( var i=0; i < prefixes.length; i++ ) { 6361 var prefix = prefixes[i]; 6362 var method = prefix + 'MatchesSelector'; 6363 if ( ElemProto[ method ] ) { 6364 return method; 6365 } 6366 } 6367 })(); 6368 6369 return function matchesSelector( elem, selector ) { 6370 return elem[ matchesMethod ]( selector ); 6371 }; 6372 6373})); 6374 6375/** 6376 * Fizzy UI utils v2.0.7 6377 * MIT license 6378 */ 6379 6380/*jshint browser: true, undef: true, unused: true, strict: true */ 6381 6382( function( window, factory ) { 6383 // universal module definition 6384 /*jshint strict: false */ /*globals define, module, require */ 6385 6386 if ( typeof define == 'function' && define.amd ) { 6387 // AMD 6388 define( 'fizzy-ui-utils/utils',[ 6389 'desandro-matches-selector/matches-selector' 6390 ], function( matchesSelector ) { 6391 return factory( window, matchesSelector ); 6392 }); 6393 } else if ( typeof module == 'object' && module.exports ) { 6394 // CommonJS 6395 module.exports = factory( 6396 window, 6397 require('desandro-matches-selector') 6398 ); 6399 } else { 6400 // browser global 6401 window.fizzyUIUtils = factory( 6402 window, 6403 window.matchesSelector 6404 ); 6405 } 6406 6407}( window, function factory( window, matchesSelector ) { 6408 6409 6410 6411var utils = {}; 6412 6413// ----- extend ----- // 6414 6415// extends objects 6416utils.extend = function( a, b ) { 6417 for ( var prop in b ) { 6418 a[ prop ] = b[ prop ]; 6419 } 6420 return a; 6421}; 6422 6423// ----- modulo ----- // 6424 6425utils.modulo = function( num, div ) { 6426 return ( ( num % div ) + div ) % div; 6427}; 6428 6429// ----- makeArray ----- // 6430 6431var arraySlice = Array.prototype.slice; 6432 6433// turn element or nodeList into an array 6434utils.makeArray = function( obj ) { 6435 if ( Array.isArray( obj ) ) { 6436 // use object if already an array 6437 return obj; 6438 } 6439 // return empty array if undefined or null. #6 6440 if ( obj === null || obj === undefined ) { 6441 return []; 6442 } 6443 6444 var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; 6445 if ( isArrayLike ) { 6446 // convert nodeList to array 6447 return arraySlice.call( obj ); 6448 } 6449 6450 // array of single index 6451 return [ obj ]; 6452}; 6453 6454// ----- removeFrom ----- // 6455 6456utils.removeFrom = function( ary, obj ) { 6457 var index = ary.indexOf( obj ); 6458 if ( index != -1 ) { 6459 ary.splice( index, 1 ); 6460 } 6461}; 6462 6463// ----- getParent ----- // 6464 6465utils.getParent = function( elem, selector ) { 6466 while ( elem.parentNode && elem != document.body ) { 6467 elem = elem.parentNode; 6468 if ( matchesSelector( elem, selector ) ) { 6469 return elem; 6470 } 6471 } 6472}; 6473 6474// ----- getQueryElement ----- // 6475 6476// use element as selector string 6477utils.getQueryElement = function( elem ) { 6478 if ( typeof elem == 'string' ) { 6479 return document.querySelector( elem ); 6480 } 6481 return elem; 6482}; 6483 6484// ----- handleEvent ----- // 6485 6486// enable .ontype to trigger from .addEventListener( elem, 'type' ) 6487utils.handleEvent = function( event ) { 6488 var method = 'on' + event.type; 6489 if ( this[ method ] ) { 6490 this[ method ]( event ); 6491 } 6492}; 6493 6494// ----- filterFindElements ----- // 6495 6496utils.filterFindElements = function( elems, selector ) { 6497 // make array of elems 6498 elems = utils.makeArray( elems ); 6499 var ffElems = []; 6500 6501 elems.forEach( function( elem ) { 6502 // check that elem is an actual element 6503
6503// START UNCODE EDIT 6504 // if ( !( elem instanceof HTMLElement ) ) { 6505 if ( !( elem instanceof HTMLElement ) && !SiteParameters.is_frontend_editor ) { 6506 // END UNCODE EDIT
vendor: 23,480 bytes, lines 6506-7418
6506 6507 return; 6508 } 6509 // add elem if no selector 6510 if ( !selector ) { 6511 ffElems.push( elem ); 6512 return; 6513 } 6514 // filter & find items if we have a selector 6515 // filter 6516 if ( matchesSelector( elem, selector ) ) { 6517 ffElems.push( elem ); 6518 } 6519 // find children 6520 var childElems = elem.querySelectorAll( selector ); 6521 // concat childElems to filterFound array 6522 for ( var i=0; i < childElems.length; i++ ) { 6523 ffElems.push( childElems[i] ); 6524 } 6525 }); 6526 6527 return ffElems; 6528}; 6529 6530// ----- debounceMethod ----- // 6531 6532utils.debounceMethod = function( _class, methodName, threshold ) { 6533 threshold = threshold || 100; 6534 // original method 6535 var method = _class.prototype[ methodName ]; 6536 var timeoutName = methodName + 'Timeout'; 6537 6538 _class.prototype[ methodName ] = function() { 6539 var timeout = this[ timeoutName ]; 6540 clearTimeout( timeout ); 6541 6542 var args = arguments; 6543 var _this = this; 6544 this[ timeoutName ] = setTimeout( function() { 6545 method.apply( _this, args ); 6546 delete _this[ timeoutName ]; 6547 }, threshold ); 6548 }; 6549}; 6550 6551// ----- docReady ----- // 6552 6553utils.docReady = function( callback ) { 6554 var readyState = document.readyState; 6555 if ( readyState == 'complete' || readyState == 'interactive' ) { 6556 // do async to allow for other scripts to run. metafizzy/flickity#441 6557 setTimeout( callback ); 6558 } else { 6559 document.addEventListener( 'DOMContentLoaded', callback ); 6560 } 6561}; 6562 6563// ----- htmlInit ----- // 6564 6565// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ 6566utils.toDashed = function( str ) { 6567 return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { 6568 return $1 + '-' + $2; 6569 }).toLowerCase(); 6570}; 6571 6572var console = window.console; 6573/** 6574 * allow user to initialize classes via [data-namespace] or .js-namespace class 6575 * htmlInit( Widget, 'widgetName' ) 6576 * options are parsed from data-namespace-options 6577 */ 6578utils.htmlInit = function( WidgetClass, namespace ) { 6579 utils.docReady( function() { 6580 var dashedNamespace = utils.toDashed( namespace ); 6581 var dataAttr = 'data-' + dashedNamespace; 6582 var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' ); 6583 var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace ); 6584 var elems = utils.makeArray( dataAttrElems ) 6585 .concat( utils.makeArray( jsDashElems ) ); 6586 var dataOptionsAttr = dataAttr + '-options'; 6587 var jQuery = window.jQuery; 6588 6589 elems.forEach( function( elem ) { 6590 var attr = elem.getAttribute( dataAttr ) || 6591 elem.getAttribute( dataOptionsAttr ); 6592 var options; 6593 try { 6594 options = attr && JSON.parse( attr ); 6595 } catch ( error ) { 6596 // log error, do not initialize 6597 if ( console ) { 6598 console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className + 6599 ': ' + error ); 6600 } 6601 return; 6602 } 6603 // initialize 6604 var instance = new WidgetClass( elem, options ); 6605 // make available via $().data('namespace') 6606 if ( jQuery ) { 6607 jQuery.data( elem, namespace, instance ); 6608 } 6609 }); 6610 6611 }); 6612}; 6613 6614// ----- ----- // 6615 6616return utils; 6617 6618})); 6619 6620/** 6621 * Outlayer Item 6622 */ 6623 6624( function( window, factory ) { 6625 // universal module definition 6626 /* jshint strict: false */ /* globals define, module, require */ 6627 if ( typeof define == 'function' && define.amd ) { 6628 // AMD - RequireJS 6629 define( 'outlayer/item',[ 6630 'ev-emitter/ev-emitter', 6631 'get-size/get-size' 6632 ], 6633 factory 6634 ); 6635 } else if ( typeof module == 'object' && module.exports ) { 6636 // CommonJS - Browserify, Webpack 6637 module.exports = factory( 6638 require('ev-emitter'), 6639 require('get-size') 6640 ); 6641 } else { 6642 // browser global 6643 window.Outlayer = {}; 6644 window.Outlayer.Item = factory( 6645 window.EvEmitter, 6646 window.getSize 6647 ); 6648 } 6649 6650}( window, function factory( EvEmitter, getSize ) { 6651'use strict'; 6652 6653// ----- helpers ----- // 6654 6655function isEmptyObj( obj ) { 6656 for ( var prop in obj ) { 6657 return false; 6658 } 6659 prop = null; 6660 return true; 6661} 6662 6663// -------------------------- CSS3 support -------------------------- // 6664 6665 6666var docElemStyle = document.documentElement.style; 6667 6668var transitionProperty = typeof docElemStyle.transition == 'string' ? 6669 'transition' : 'WebkitTransition'; 6670var transformProperty = typeof docElemStyle.transform == 'string' ? 6671 'transform' : 'WebkitTransform'; 6672 6673var transitionEndEvent = { 6674 WebkitTransition: 'webkitTransitionEnd', 6675 transition: 'transitionend' 6676}[ transitionProperty ]; 6677 6678// cache all vendor properties that could have vendor prefix 6679var vendorProperties = { 6680 transform: transformProperty, 6681 transition: transitionProperty, 6682 transitionDuration: transitionProperty + 'Duration', 6683 transitionProperty: transitionProperty + 'Property', 6684 transitionDelay: transitionProperty + 'Delay' 6685}; 6686 6687// -------------------------- Item -------------------------- // 6688 6689function Item( element, layout ) { 6690 if ( !element ) { 6691 return; 6692 } 6693 6694 this.element = element; 6695 // parent layout class, i.e. Masonry, Isotope, or Packery 6696 this.layout = layout; 6697 this.position = { 6698 x: 0, 6699 y: 0 6700 }; 6701 6702 this._create(); 6703} 6704 6705// inherit EvEmitter 6706var proto = Item.prototype = Object.create( EvEmitter.prototype ); 6707proto.constructor = Item; 6708 6709proto._create = function() { 6710 // transition objects 6711 this._transn = { 6712 ingProperties: {}, 6713 clean: {}, 6714 onEnd: {} 6715 }; 6716 6717 this.css({ 6718 position: 'absolute' 6719 }); 6720}; 6721 6722// trigger specified handler for event type 6723proto.handleEvent = function( event ) { 6724 var method = 'on' + event.type; 6725 if ( this[ method ] ) { 6726 this[ method ]( event ); 6727 } 6728}; 6729 6730proto.getSize = function() { 6731 this.size = getSize( this.element ); 6732}; 6733 6734/** 6735 * apply CSS styles to element 6736 * @param {Object} style 6737 */ 6738proto.css = function( style ) { 6739 var elemStyle = this.element.style; 6740 6741 for ( var prop in style ) { 6742 // use vendor property if available 6743 var supportedProp = vendorProperties[ prop ] || prop; 6744 elemStyle[ supportedProp ] = style[ prop ]; 6745 } 6746}; 6747 6748 // measure position, and sets it 6749proto.getPosition = function() { 6750 var style = getComputedStyle( this.element ); 6751 var isOriginLeft = this.layout._getOption('originLeft'); 6752 var isOriginTop = this.layout._getOption('originTop'); 6753 var xValue = style[ isOriginLeft ? 'left' : 'right' ]; 6754 var yValue = style[ isOriginTop ? 'top' : 'bottom' ]; 6755 var x = parseFloat( xValue ); 6756 var y = parseFloat( yValue ); 6757 // convert percent to pixels 6758 var layoutSize = this.layout.size; 6759 if ( xValue.indexOf('%') != -1 ) { 6760 x = ( x / 100 ) * layoutSize.width; 6761 } 6762 if ( yValue.indexOf('%') != -1 ) { 6763 y = ( y / 100 ) * layoutSize.height; 6764 } 6765 // clean up 'auto' or other non-integer values 6766 x = isNaN( x ) ? 0 : x; 6767 y = isNaN( y ) ? 0 : y; 6768 // remove padding from measurement 6769 x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight; 6770 y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom; 6771 6772 this.position.x = x; 6773 this.position.y = y; 6774}; 6775 6776// set settled position, apply padding 6777proto.layoutPosition = function() { 6778 var layoutSize = this.layout.size; 6779 var style = {}; 6780 var isOriginLeft = this.layout._getOption('originLeft'); 6781 var isOriginTop = this.layout._getOption('originTop'); 6782 6783 // x 6784 var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight'; 6785 var xProperty = isOriginLeft ? 'left' : 'right'; 6786 var xResetProperty = isOriginLeft ? 'right' : 'left'; 6787 6788 var x = this.position.x + layoutSize[ xPadding ]; 6789 // set in percentage or pixels 6790 style[ xProperty ] = this.getXValue( x ); 6791 // reset other property 6792 style[ xResetProperty ] = ''; 6793 6794 // y 6795 var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom'; 6796 var yProperty = isOriginTop ? 'top' : 'bottom'; 6797 var yResetProperty = isOriginTop ? 'bottom' : 'top'; 6798 6799 var y = this.position.y + layoutSize[ yPadding ]; 6800 // set in percentage or pixels 6801 style[ yProperty ] = this.getYValue( y ); 6802 // reset other property 6803 style[ yResetProperty ] = ''; 6804 6805 this.css( style ); 6806 this.emitEvent( 'layout', [ this ] ); 6807}; 6808 6809proto.getXValue = function( x ) { 6810 var isHorizontal = this.layout._getOption('horizontal'); 6811 return this.layout.options.percentPosition && !isHorizontal ? 6812 ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px'; 6813}; 6814 6815proto.getYValue = function( y ) { 6816 var isHorizontal = this.layout._getOption('horizontal'); 6817 return this.layout.options.percentPosition && isHorizontal ? 6818 ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px'; 6819}; 6820 6821proto._transitionTo = function( x, y ) { 6822 this.getPosition(); 6823 // get current x & y from top/left 6824 var curX = this.position.x; 6825 var curY = this.position.y; 6826 6827 var didNotMove = x == this.position.x && y == this.position.y; 6828 6829 // save end position 6830 this.setPosition( x, y ); 6831 6832 // if did not move and not transitioning, just go to layout 6833 if ( didNotMove && !this.isTransitioning ) { 6834 this.layoutPosition(); 6835 return; 6836 } 6837 6838 var transX = x - curX; 6839 var transY = y - curY; 6840 var transitionStyle = {}; 6841 transitionStyle.transform = this.getTranslate( transX, transY ); 6842 6843 this.transition({ 6844 to: transitionStyle, 6845 onTransitionEnd: { 6846 transform: this.layoutPosition 6847 }, 6848 isCleaning: true 6849 }); 6850}; 6851 6852proto.getTranslate = function( x, y ) { 6853 // flip cooridinates if origin on right or bottom 6854 var isOriginLeft = this.layout._getOption('originLeft'); 6855 var isOriginTop = this.layout._getOption('originTop'); 6856 x = isOriginLeft ? x : -x; 6857 y = isOriginTop ? y : -y; 6858 return 'translate3d(' + x + 'px, ' + y + 'px, 0)'; 6859}; 6860 6861// non transition + transform support 6862proto.goTo = function( x, y ) { 6863 this.setPosition( x, y ); 6864 this.layoutPosition(); 6865}; 6866 6867proto.moveTo = proto._transitionTo; 6868 6869proto.setPosition = function( x, y ) { 6870 this.position.x = parseFloat( x ); 6871 this.position.y = parseFloat( y ); 6872}; 6873 6874// ----- transition ----- // 6875 6876/** 6877 * @param {Object} style - CSS 6878 * @param {Function} onTransitionEnd 6879 */ 6880 6881// non transition, just trigger callback 6882proto._nonTransition = function( args ) { 6883 this.css( args.to ); 6884 if ( args.isCleaning ) { 6885 this._removeStyles( args.to ); 6886 } 6887 for ( var prop in args.onTransitionEnd ) { 6888 args.onTransitionEnd[ prop ].call( this ); 6889 } 6890}; 6891 6892/** 6893 * proper transition 6894 * @param {Object} args - arguments 6895 * @param {Object} to - style to transition to 6896 * @param {Object} from - style to start transition from 6897 * @param {Boolean} isCleaning - removes transition styles after transition 6898 * @param {Function} onTransitionEnd - callback 6899 */ 6900proto.transition = function( args ) { 6901 // redirect to nonTransition if no transition duration 6902 if ( !parseFloat( this.layout.options.transitionDuration ) ) { 6903 this._nonTransition( args ); 6904 return; 6905 } 6906 6907 var _transition = this._transn; 6908 // keep track of onTransitionEnd callback by css property 6909 for ( var prop in args.onTransitionEnd ) { 6910 _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ]; 6911 } 6912 // keep track of properties that are transitioning 6913 for ( prop in args.to ) { 6914 _transition.ingProperties[ prop ] = true; 6915 // keep track of properties to clean up when transition is done 6916 if ( args.isCleaning ) { 6917 _transition.clean[ prop ] = true; 6918 } 6919 } 6920 6921 // set from styles 6922 if ( args.from ) { 6923 this.css( args.from ); 6924 // force redraw. http://blog.alexmaccaw.com/css-transitions 6925 var h = this.element.offsetHeight; 6926 // hack for JSHint to hush about unused var 6927 h = null; 6928 } 6929 // enable transition 6930 this.enableTransition( args.to ); 6931 // set styles that are transitioning 6932 this.css( args.to ); 6933 6934 this.isTransitioning = true; 6935 6936}; 6937 6938// dash before all cap letters, including first for 6939// WebkitTransform => -webkit-transform 6940function toDashedAll( str ) { 6941 return str.replace( /([A-Z])/g, function( $1 ) { 6942 return '-' + $1.toLowerCase(); 6943 }); 6944} 6945 6946var transitionProps = 'opacity,' + toDashedAll( transformProperty ); 6947 6948proto.enableTransition = function(/* style */) { 6949 // HACK changing transitionProperty during a transition 6950 // will cause transition to jump 6951 if ( this.isTransitioning ) { 6952 return; 6953 } 6954 6955 // make `transition: foo, bar, baz` from style object 6956 // HACK un-comment this when enableTransition can work 6957 // while a transition is happening 6958 // var transitionValues = []; 6959 // for ( var prop in style ) { 6960 // // dash-ify camelCased properties like WebkitTransition 6961 // prop = vendorProperties[ prop ] || prop; 6962 // transitionValues.push( toDashedAll( prop ) ); 6963 // } 6964 // munge number to millisecond, to match stagger 6965 var duration = this.layout.options.transitionDuration; 6966 duration = typeof duration == 'number' ? duration + 'ms' : duration; 6967 // enable transition styles 6968 this.css({ 6969 transitionProperty: transitionProps, 6970 transitionDuration: duration, 6971 transitionDelay: this.staggerDelay || 0 6972 }); 6973 // listen for transition end event 6974 this.element.addEventListener( transitionEndEvent, this, false ); 6975}; 6976 6977// ----- events ----- // 6978 6979proto.onwebkitTransitionEnd = function( event ) { 6980 this.ontransitionend( event ); 6981}; 6982 6983proto.onotransitionend = function( event ) { 6984 this.ontransitionend( event ); 6985}; 6986 6987// properties that I munge to make my life easier 6988var dashedVendorProperties = { 6989 '-webkit-transform': 'transform' 6990}; 6991 6992proto.ontransitionend = function( event ) { 6993 // disregard bubbled events from children 6994 if ( event.target !== this.element ) { 6995 return; 6996 } 6997 var _transition = this._transn; 6998 // get property name of transitioned property, convert to prefix-free 6999 var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName; 7000 7001 // remove property that has completed transitioning 7002 delete _transition.ingProperties[ propertyName ]; 7003 // check if any properties are still transitioning 7004 if ( isEmptyObj( _transition.ingProperties ) ) { 7005 // all properties have completed transitioning 7006 this.disableTransition(); 7007 } 7008 // clean style 7009 if ( propertyName in _transition.clean ) { 7010 // clean up style 7011 this.element.style[ event.propertyName ] = ''; 7012 delete _transition.clean[ propertyName ]; 7013 } 7014 // trigger onTransitionEnd callback 7015 if ( propertyName in _transition.onEnd ) { 7016 var onTransitionEnd = _transition.onEnd[ propertyName ]; 7017 onTransitionEnd.call( this ); 7018 delete _transition.onEnd[ propertyName ]; 7019 } 7020 7021 this.emitEvent( 'transitionEnd', [ this ] ); 7022}; 7023 7024proto.disableTransition = function() { 7025 this.removeTransitionStyles(); 7026 this.element.removeEventListener( transitionEndEvent, this, false ); 7027 this.isTransitioning = false; 7028}; 7029 7030/** 7031 * removes style property from element 7032 * @param {Object} style 7033**/ 7034proto._removeStyles = function( style ) { 7035 // clean up transition styles 7036 var cleanStyle = {}; 7037 for ( var prop in style ) { 7038 cleanStyle[ prop ] = ''; 7039 } 7040 this.css( cleanStyle ); 7041}; 7042 7043var cleanTransitionStyle = { 7044 transitionProperty: '', 7045 transitionDuration: '', 7046 transitionDelay: '' 7047}; 7048 7049proto.removeTransitionStyles = function() { 7050 // remove transition 7051 this.css( cleanTransitionStyle ); 7052}; 7053 7054// ----- stagger ----- // 7055 7056proto.stagger = function( delay ) { 7057 delay = isNaN( delay ) ? 0 : delay; 7058 this.staggerDelay = delay + 'ms'; 7059}; 7060 7061// ----- show/hide/remove ----- // 7062 7063// remove element from DOM 7064proto.removeElem = function() { 7065 this.element.parentNode.removeChild( this.element ); 7066 // remove display: none 7067 this.css({ display: '' }); 7068 this.emitEvent( 'remove', [ this ] ); 7069}; 7070 7071proto.remove = function() { 7072 // just remove element if no transition support or no transition 7073 if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) { 7074 this.removeElem(); 7075 return; 7076 } 7077 7078 // start transition 7079 this.once( 'transitionEnd', function() { 7080 this.removeElem(); 7081 }); 7082 this.hide(); 7083}; 7084 7085proto.reveal = function() { 7086 delete this.isHidden; 7087 // remove display: none 7088 this.css({ display: '' }); 7089 7090 var options = this.layout.options; 7091 7092 var onTransitionEnd = {}; 7093 var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle'); 7094 onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd; 7095 7096 this.transition({ 7097 from: options.hiddenStyle, 7098 to: options.visibleStyle, 7099 isCleaning: true, 7100 onTransitionEnd: onTransitionEnd 7101 }); 7102}; 7103 7104proto.onRevealTransitionEnd = function() { 7105 // check if still visible 7106 // during transition, item may have been hidden 7107 if ( !this.isHidden ) { 7108 this.emitEvent('reveal'); 7109 } 7110}; 7111 7112/** 7113 * get style property use for hide/reveal transition end 7114 * @param {String} styleProperty - hiddenStyle/visibleStyle 7115 * @returns {String} 7116 */ 7117proto.getHideRevealTransitionEndProperty = function( styleProperty ) { 7118 var optionStyle = this.layout.options[ styleProperty ]; 7119 // use opacity 7120 if ( optionStyle.opacity ) { 7121 return 'opacity'; 7122 } 7123 // get first property 7124 for ( var prop in optionStyle ) { 7125 return prop; 7126 } 7127}; 7128 7129proto.hide = function() { 7130 // set flag 7131 this.isHidden = true; 7132 // remove display: none 7133 this.css({ display: '' }); 7134 7135 var options = this.layout.options; 7136 7137 var onTransitionEnd = {}; 7138 var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle'); 7139 onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd; 7140 7141 this.transition({ 7142 from: options.visibleStyle, 7143 to: options.hiddenStyle, 7144 // keep hidden stuff hidden 7145 isCleaning: true, 7146 onTransitionEnd: onTransitionEnd 7147 }); 7148}; 7149 7150proto.onHideTransitionEnd = function() { 7151 // check if still hidden 7152 // during transition, item may have been un-hidden 7153 if ( this.isHidden ) { 7154 this.css({ display: 'none' }); 7155 this.emitEvent('hide'); 7156 } 7157}; 7158 7159proto.destroy = function() { 7160 this.css({ 7161 position: '', 7162 left: '', 7163 right: '', 7164 top: '', 7165 bottom: '', 7166 transition: '', 7167 transform: '' 7168 }); 7169}; 7170 7171return Item; 7172 7173})); 7174 7175/*! 7176 * Outlayer v2.1.1 7177 * the brains and guts of a layout library 7178 * MIT license 7179 */ 7180 7181( function( window, factory ) { 7182 'use strict'; 7183 // universal module definition 7184 /* jshint strict: false */ /* globals define, module, require */ 7185 if ( typeof define == 'function' && define.amd ) { 7186 // AMD - RequireJS 7187 define( 'outlayer/outlayer',[ 7188 'ev-emitter/ev-emitter', 7189 'get-size/get-size', 7190 'fizzy-ui-utils/utils', 7191 './item' 7192 ], 7193 function( EvEmitter, getSize, utils, Item ) { 7194 return factory( window, EvEmitter, getSize, utils, Item); 7195 } 7196 ); 7197 } else if ( typeof module == 'object' && module.exports ) { 7198 // CommonJS - Browserify, Webpack 7199 module.exports = factory( 7200 window, 7201 require('ev-emitter'), 7202 require('get-size'), 7203 require('fizzy-ui-utils'), 7204 require('./item') 7205 ); 7206 } else { 7207 // browser global 7208 window.Outlayer = factory( 7209 window, 7210 window.EvEmitter, 7211 window.getSize, 7212 window.fizzyUIUtils, 7213 window.Outlayer.Item 7214 ); 7215 } 7216 7217}( window, function factory( window, EvEmitter, getSize, utils, Item ) { 7218'use strict'; 7219 7220// ----- vars ----- // 7221 7222var console = window.console; 7223var jQuery = window.jQuery; 7224var noop = function() {}; 7225 7226// -------------------------- Outlayer -------------------------- // 7227 7228// globally unique identifiers 7229var GUID = 0; 7230// internal store of all Outlayer intances 7231var instances = {}; 7232 7233 7234/** 7235 * @param {Element, String} element 7236 * @param {Object} options 7237 * @constructor 7238 */ 7239function Outlayer( element, options ) { 7240 var queryElement = utils.getQueryElement( element ); 7241 if ( !queryElement ) { 7242 if ( console ) { 7243 console.error( 'Bad element for ' + this.constructor.namespace + 7244 ': ' + ( queryElement || element ) ); 7245 } 7246 return; 7247 } 7248 this.element = queryElement; 7249 // add jQuery 7250 if ( jQuery ) { 7251 this.$element = jQuery( this.element ); 7252 } 7253 7254 // options 7255 this.options = utils.extend( {}, this.constructor.defaults ); 7256 this.option( options ); 7257 7258 // add id for Outlayer.getFromElement 7259 var id = ++GUID; 7260 this.element.outlayerGUID = id; // expando 7261 instances[ id ] = this; // associate via id 7262 7263 // kick it off 7264 this._create(); 7265 7266 var isInitLayout = this._getOption('initLayout'); 7267 if ( isInitLayout ) { 7268 this.layout(); 7269 } 7270} 7271 7272// settings are for internal use only 7273Outlayer.namespace = 'outlayer'; 7274Outlayer.Item = Item; 7275 7276// default options 7277Outlayer.defaults = { 7278 containerStyle: { 7279 position: 'relative' 7280 }, 7281 initLayout: true, 7282 originLeft: true, 7283 originTop: true, 7284 resize: true, 7285 resizeContainer: true, 7286 // item options 7287 transitionDuration: '0.4s', 7288 hiddenStyle: { 7289 opacity: 0, 7290 transform: 'scale(0.001)' 7291 }, 7292 visibleStyle: { 7293 opacity: 1, 7294 transform: 'scale(1)' 7295 } 7296}; 7297 7298var proto = Outlayer.prototype; 7299// inherit EvEmitter 7300utils.extend( proto, EvEmitter.prototype ); 7301 7302/** 7303 * set options 7304 * @param {Object} opts 7305 */ 7306proto.option = function( opts ) { 7307 utils.extend( this.options, opts ); 7308}; 7309 7310/** 7311 * get backwards compatible option value, check old name 7312 */ 7313proto._getOption = function( option ) { 7314 var oldOption = this.constructor.compatOptions[ option ]; 7315 return oldOption && this.options[ oldOption ] !== undefined ? 7316 this.options[ oldOption ] : this.options[ option ]; 7317}; 7318 7319Outlayer.compatOptions = { 7320 // currentName: oldName 7321 initLayout: 'isInitLayout', 7322 horizontal: 'isHorizontal', 7323 layoutInstant: 'isLayoutInstant', 7324 originLeft: 'isOriginLeft', 7325 originTop: 'isOriginTop', 7326 resize: 'isResizeBound', 7327 resizeContainer: 'isResizingContainer' 7328}; 7329 7330proto._create = function() { 7331 // get items from children 7332 this.reloadItems(); 7333 // elements that affect layout, but are not laid out 7334 this.stamps = []; 7335 this.stamp( this.options.stamp ); 7336 // set container style 7337 utils.extend( this.element.style, this.options.containerStyle ); 7338 7339 // bind resize method 7340 var canBindResize = this._getOption('resize'); 7341 if ( canBindResize ) { 7342 this.bindResize(); 7343 } 7344}; 7345 7346// goes through all children again and gets bricks in proper order 7347proto.reloadItems = function() { 7348 // collection of item elements 7349 this.items = this._itemize( this.element.children ); 7350}; 7351 7352 7353/** 7354 * turn elements into Outlayer.Items to be used in layout 7355 * @param {Array or NodeList or HTMLElement} elems 7356 * @returns {Array} items - collection of new Outlayer Items 7357 */ 7358proto._itemize = function( elems ) { 7359 7360 var itemElems = this._filterFindItemElements( elems ); 7361 var Item = this.constructor.Item; 7362 7363 // create new Outlayer Items for collection 7364 var items = []; 7365 for ( var i=0; i < itemElems.length; i++ ) { 7366 var elem = itemElems[i]; 7367 var item = new Item( elem, this ); 7368 items.push( item ); 7369 } 7370 7371 return items; 7372}; 7373 7374/** 7375 * get item elements to be used in layout 7376 * @param {Array or NodeList or HTMLElement} elems 7377 * @returns {Array} items - item elements 7378 */ 7379proto._filterFindItemElements = function( elems ) { 7380 return utils.filterFindElements( elems, this.options.itemSelector ); 7381}; 7382 7383/** 7384 * getter method for getting item elements 7385 * @returns {Array} elems - collection of item elements 7386 */ 7387proto.getItemElements = function() { 7388 return this.items.map( function( item ) { 7389 return item.element; 7390 }); 7391}; 7392 7393// ----- init & layout ----- // 7394 7395/** 7396 * lays out all items 7397 */ 7398proto.layout = function() { 7399 this._resetLayout(); 7400 this._manageStamps(); 7401 7402 // don't animate first layout 7403 var layoutInstant = this._getOption('layoutInstant'); 7404 var isInstant = layoutInstant !== undefined ? 7405 layoutInstant : !this._isLayoutInited; 7406 this.layoutItems( this.items, isInstant ); 7407 7408 // flag for initalized 7409 this._isLayoutInited = true; 7410}; 7411 7412// _init is alias for layout 7413proto._init = proto.layout; 7414 7415/** 7416 * logic before any new layout 7417 */ 7418proto._resetLayout = function() {
vendor: 13,499 bytes, lines 7419-7987
7419 this.getSize(); 7420}; 7421 7422 7423proto.getSize = function() { 7424 this.size = getSize( this.element ); 7425}; 7426 7427/** 7428 * get measurement from option, for columnWidth, rowHeight, gutter 7429 * if option is String -> get element from selector string, & get size of element 7430 * if option is Element -> get size of element 7431 * else use option as a number 7432 * 7433 * @param {String} measurement 7434 * @param {String} size - width or height 7435 * @private 7436 */ 7437proto._getMeasurement = function( measurement, size ) { 7438 var option = this.options[ measurement ]; 7439 var elem; 7440 if ( !option ) { 7441 // default to 0 7442 this[ measurement ] = 0; 7443 } else { 7444 // use option as an element 7445 if ( typeof option == 'string' ) { 7446 elem = this.element.querySelector( option ); 7447 } else if ( option instanceof HTMLElement ) { 7448 elem = option; 7449 } 7450 // use size of element, if element 7451 this[ measurement ] = elem ? getSize( elem )[ size ] : option; 7452 } 7453}; 7454 7455/** 7456 * layout a collection of item elements 7457 * @api public 7458 */ 7459proto.layoutItems = function( items, isInstant ) { 7460 items = this._getItemsForLayout( items ); 7461 7462 this._layoutItems( items, isInstant ); 7463 7464 this._postLayout(); 7465}; 7466 7467/** 7468 * get the items to be laid out 7469 * you may want to skip over some items 7470 * @param {Array} items 7471 * @returns {Array} items 7472 */ 7473proto._getItemsForLayout = function( items ) { 7474 return items.filter( function( item ) { 7475 return !item.isIgnored; 7476 }); 7477}; 7478 7479/** 7480 * layout items 7481 * @param {Array} items 7482 * @param {Boolean} isInstant 7483 */ 7484proto._layoutItems = function( items, isInstant ) { 7485 this._emitCompleteOnItems( 'layout', items ); 7486 7487 if ( !items || !items.length ) { 7488 // no items, emit event with empty array 7489 return; 7490 } 7491 7492 var queue = []; 7493 7494 items.forEach( function( item ) { 7495 // get x/y object from method 7496 var position = this._getItemLayoutPosition( item ); 7497 // enqueue 7498 position.item = item; 7499 position.isInstant = isInstant || item.isLayoutInstant; 7500 queue.push( position ); 7501 }, this ); 7502 7503 this._processLayoutQueue( queue ); 7504}; 7505 7506/** 7507 * get item layout position 7508 * @param {Outlayer.Item} item 7509 * @returns {Object} x and y position 7510 */ 7511proto._getItemLayoutPosition = function( /* item */ ) { 7512 return { 7513 x: 0, 7514 y: 0 7515 }; 7516}; 7517 7518/** 7519 * iterate over array and position each item 7520 * Reason being - separating this logic prevents 'layout invalidation' 7521 * thx @paul_irish 7522 * @param {Array} queue 7523 */ 7524proto._processLayoutQueue = function( queue ) { 7525 this.updateStagger(); 7526 queue.forEach( function( obj, i ) { 7527 this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i ); 7528 }, this ); 7529}; 7530 7531// set stagger from option in milliseconds number 7532proto.updateStagger = function() { 7533 var stagger = this.options.stagger; 7534 if ( stagger === null || stagger === undefined ) { 7535 this.stagger = 0; 7536 return; 7537 } 7538 this.stagger = getMilliseconds( stagger ); 7539 return this.stagger; 7540}; 7541 7542/** 7543 * Sets position of item in DOM 7544 * @param {Outlayer.Item} item 7545 * @param {Number} x - horizontal position 7546 * @param {Number} y - vertical position 7547 * @param {Boolean} isInstant - disables transitions 7548 */ 7549proto._positionItem = function( item, x, y, isInstant, i ) { 7550 if ( isInstant ) { 7551 // if not transition, just set CSS 7552 item.goTo( x, y ); 7553 } else { 7554 item.stagger( i * this.stagger ); 7555 item.moveTo( x, y ); 7556 } 7557}; 7558 7559/** 7560 * Any logic you want to do after each layout, 7561 * i.e. size the container 7562 */ 7563proto._postLayout = function() { 7564 this.resizeContainer(); 7565}; 7566 7567proto.resizeContainer = function() { 7568 var isResizingContainer = this._getOption('resizeContainer'); 7569 if ( !isResizingContainer ) { 7570 return; 7571 } 7572 var size = this._getContainerSize(); 7573 if ( size ) { 7574 this._setContainerMeasure( size.width, true ); 7575 this._setContainerMeasure( size.height, false ); 7576 } 7577}; 7578 7579/** 7580 * Sets width or height of container if returned 7581 * @returns {Object} size 7582 * @param {Number} width 7583 * @param {Number} height 7584 */ 7585proto._getContainerSize = noop; 7586 7587/** 7588 * @param {Number} measure - size of width or height 7589 * @param {Boolean} isWidth 7590 */ 7591proto._setContainerMeasure = function( measure, isWidth ) { 7592 if ( measure === undefined ) { 7593 return; 7594 } 7595 7596 var elemSize = this.size; 7597 // add padding and border width if border box 7598 if ( elemSize.isBorderBox ) { 7599 measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + 7600 elemSize.borderLeftWidth + elemSize.borderRightWidth : 7601 elemSize.paddingBottom + elemSize.paddingTop + 7602 elemSize.borderTopWidth + elemSize.borderBottomWidth; 7603 } 7604 7605 measure = Math.max( measure, 0 ); 7606 this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px'; 7607}; 7608 7609/** 7610 * emit eventComplete on a collection of items events 7611 * @param {String} eventName 7612 * @param {Array} items - Outlayer.Items 7613 */ 7614proto._emitCompleteOnItems = function( eventName, items ) { 7615 var _this = this; 7616 function onComplete() { 7617 _this.dispatchEvent( eventName + 'Complete', null, [ items ] ); 7618 } 7619 7620 var count = items.length; 7621 if ( !items || !count ) { 7622 onComplete(); 7623 return; 7624 } 7625 7626 var doneCount = 0; 7627 function tick() { 7628 doneCount++; 7629 if ( doneCount == count ) { 7630 onComplete(); 7631 } 7632 } 7633 7634 // bind callback 7635 items.forEach( function( item ) { 7636 item.once( eventName, tick ); 7637 }); 7638}; 7639 7640/** 7641 * emits events via EvEmitter and jQuery events 7642 * @param {String} type - name of event 7643 * @param {Event} event - original event 7644 * @param {Array} args - extra arguments 7645 */ 7646proto.dispatchEvent = function( type, event, args ) { 7647 // add original event to arguments 7648 var emitArgs = event ? [ event ].concat( args ) : args; 7649 this.emitEvent( type, emitArgs ); 7650 7651 if ( jQuery ) { 7652 // set this.$element 7653 this.$element = this.$element || jQuery( this.element ); 7654 if ( event ) { 7655 // create jQuery event 7656 var $event = jQuery.Event( event ); 7657 $event.type = type; 7658 this.$element.trigger( $event, args ); 7659 } else { 7660 // just trigger with type if no event available 7661 this.$element.trigger( type, args ); 7662 } 7663 } 7664}; 7665 7666// -------------------------- ignore & stamps -------------------------- // 7667 7668 7669/** 7670 * keep item in collection, but do not lay it out 7671 * ignored items do not get skipped in layout 7672 * @param {Element} elem 7673 */ 7674proto.ignore = function( elem ) { 7675 var item = this.getItem( elem ); 7676 if ( item ) { 7677 item.isIgnored = true; 7678 } 7679}; 7680 7681/** 7682 * return item to layout collection 7683 * @param {Element} elem 7684 */ 7685proto.unignore = function( elem ) { 7686 var item = this.getItem( elem ); 7687 if ( item ) { 7688 delete item.isIgnored; 7689 } 7690}; 7691 7692/** 7693 * adds elements to stamps 7694 * @param {NodeList, Array, Element, or String} elems 7695 */ 7696proto.stamp = function( elems ) { 7697 elems = this._find( elems ); 7698 if ( !elems ) { 7699 return; 7700 } 7701 7702 this.stamps = this.stamps.concat( elems ); 7703 // ignore 7704 elems.forEach( this.ignore, this ); 7705}; 7706 7707/** 7708 * removes elements to stamps 7709 * @param {NodeList, Array, or Element} elems 7710 */ 7711proto.unstamp = function( elems ) { 7712 elems = this._find( elems ); 7713 if ( !elems ){ 7714 return; 7715 } 7716 7717 elems.forEach( function( elem ) { 7718 // filter out removed stamp elements 7719 utils.removeFrom( this.stamps, elem ); 7720 this.unignore( elem ); 7721 }, this ); 7722}; 7723 7724/** 7725 * finds child elements 7726 * @param {NodeList, Array, Element, or String} elems 7727 * @returns {Array} elems 7728 */ 7729proto._find = function( elems ) { 7730 if ( !elems ) { 7731 return; 7732 } 7733 // if string, use argument as selector string 7734 if ( typeof elems == 'string' ) { 7735 elems = this.element.querySelectorAll( elems ); 7736 } 7737 elems = utils.makeArray( elems ); 7738 return elems; 7739}; 7740 7741proto._manageStamps = function() { 7742 if ( !this.stamps || !this.stamps.length ) { 7743 return; 7744 } 7745 7746 this._getBoundingRect(); 7747 7748 this.stamps.forEach( this._manageStamp, this ); 7749}; 7750 7751// update boundingLeft / Top 7752proto._getBoundingRect = function() { 7753 // get bounding rect for container element 7754 var boundingRect = this.element.getBoundingClientRect(); 7755 var size = this.size; 7756 this._boundingRect = { 7757 left: boundingRect.left + size.paddingLeft + size.borderLeftWidth, 7758 top: boundingRect.top + size.paddingTop + size.borderTopWidth, 7759 right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ), 7760 bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth ) 7761 }; 7762}; 7763 7764/** 7765 * @param {Element} stamp 7766**/ 7767proto._manageStamp = noop; 7768 7769/** 7770 * get x/y position of element relative to container element 7771 * @param {Element} elem 7772 * @returns {Object} offset - has left, top, right, bottom 7773 */ 7774proto._getElementOffset = function( elem ) { 7775 var boundingRect = elem.getBoundingClientRect(); 7776 var thisRect = this._boundingRect; 7777 var size = getSize( elem ); 7778 var offset = { 7779 left: boundingRect.left - thisRect.left - size.marginLeft, 7780 top: boundingRect.top - thisRect.top - size.marginTop, 7781 right: thisRect.right - boundingRect.right - size.marginRight, 7782 bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom 7783 }; 7784 return offset; 7785}; 7786 7787// -------------------------- resize -------------------------- // 7788 7789// enable event handlers for listeners 7790// i.e. resize -> onresize 7791proto.handleEvent = utils.handleEvent; 7792 7793/** 7794 * Bind layout to window resizing 7795 */ 7796proto.bindResize = function() { 7797 window.addEventListener( 'resize', this ); 7798 this.isResizeBound = true; 7799}; 7800 7801/** 7802 * Unbind layout to window resizing 7803 */ 7804proto.unbindResize = function() { 7805 window.removeEventListener( 'resize', this ); 7806 this.isResizeBound = false; 7807}; 7808 7809proto.onresize = function() { 7810 this.resize(); 7811}; 7812 7813utils.debounceMethod( Outlayer, 'onresize', 100 ); 7814 7815proto.resize = function() { 7816 // don't trigger if size did not change 7817 // or if resize was unbound. See #9 7818 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 7819 return; 7820 } 7821 7822 this.layout(); 7823}; 7824 7825/** 7826 * check if layout is needed post layout 7827 * @returns Boolean 7828 */ 7829proto.needsResizeLayout = function() { 7830 var size = getSize( this.element ); 7831 // check that this.size and size are there 7832 // IE8 triggers resize on body size change, so they might not be 7833 var hasSizes = this.size && size; 7834 return hasSizes && size.innerWidth !== this.size.innerWidth; 7835}; 7836 7837// -------------------------- methods -------------------------- // 7838 7839/** 7840 * add items to Outlayer instance 7841 * @param {Array or NodeList or Element} elems 7842 * @returns {Array} items - Outlayer.Items 7843**/ 7844proto.addItems = function( elems ) { 7845 var items = this._itemize( elems ); 7846 // add items to collection 7847 if ( items.length ) { 7848 this.items = this.items.concat( items ); 7849 } 7850 return items; 7851}; 7852 7853/** 7854 * Layout newly-appended item elements 7855 * @param {Array or NodeList or Element} elems 7856 */ 7857proto.appended = function( elems ) { 7858 var items = this.addItems( elems ); 7859 if ( !items.length ) { 7860 return; 7861 } 7862 // layout and reveal just the new items 7863 this.layoutItems( items, true ); 7864 this.reveal( items ); 7865}; 7866 7867/** 7868 * Layout prepended elements 7869 * @param {Array or NodeList or Element} elems 7870 */ 7871proto.prepended = function( elems ) { 7872 var items = this._itemize( elems ); 7873 if ( !items.length ) { 7874 return; 7875 } 7876 // add items to beginning of collection 7877 var previousItems = this.items.slice(0); 7878 this.items = items.concat( previousItems ); 7879 // start new layout 7880 this._resetLayout(); 7881 this._manageStamps(); 7882 // layout new stuff without transition 7883 this.layoutItems( items, true ); 7884 this.reveal( items ); 7885 // layout previous items 7886 this.layoutItems( previousItems ); 7887}; 7888 7889/** 7890 * reveal a collection of items 7891 * @param {Array of Outlayer.Items} items 7892 */ 7893proto.reveal = function( items ) { 7894 this._emitCompleteOnItems( 'reveal', items ); 7895 if ( !items || !items.length ) { 7896 return; 7897 } 7898 var stagger = this.updateStagger(); 7899 items.forEach( function( item, i ) { 7900 item.stagger( i * stagger ); 7901 item.reveal(); 7902 }); 7903}; 7904 7905/** 7906 * hide a collection of items 7907 * @param {Array of Outlayer.Items} items 7908 */ 7909proto.hide = function( items ) { 7910 this._emitCompleteOnItems( 'hide', items ); 7911 if ( !items || !items.length ) { 7912 return; 7913 } 7914 var stagger = this.updateStagger(); 7915 items.forEach( function( item, i ) { 7916 item.stagger( i * stagger ); 7917 item.hide(); 7918 }); 7919}; 7920 7921/** 7922 * reveal item elements 7923 * @param {Array}, {Element}, {NodeList} items 7924 */ 7925proto.revealItemElements = function( elems ) { 7926 var items = this.getItems( elems ); 7927 this.reveal( items ); 7928}; 7929 7930/** 7931 * hide item elements 7932 * @param {Array}, {Element}, {NodeList} items 7933 */ 7934proto.hideItemElements = function( elems ) { 7935 var items = this.getItems( elems ); 7936 this.hide( items ); 7937}; 7938 7939/** 7940 * get Outlayer.Item, given an Element 7941 * @param {Element} elem 7942 * @param {Function} callback 7943 * @returns {Outlayer.Item} item 7944 */ 7945proto.getItem = function( elem ) { 7946 // loop through items to get the one that matches 7947 for ( var i=0; i < this.items.length; i++ ) { 7948 var item = this.items[i]; 7949 if ( item.element == elem ) { 7950 // return item 7951 return item; 7952 } 7953 } 7954}; 7955 7956/** 7957 * get collection of Outlayer.Items, given Elements 7958 * @param {Array} elems 7959 * @returns {Array} items - Outlayer.Items 7960 */ 7961proto.getItems = function( elems ) { 7962 elems = utils.makeArray( elems ); 7963 var items = []; 7964 elems.forEach( function( elem ) { 7965 var item = this.getItem( elem ); 7966 if ( item ) { 7967 items.push( item ); 7968 } 7969 }, this ); 7970 7971 return items; 7972}; 7973 7974/** 7975 * remove element(s) from instance and DOM 7976 * @param {Array or NodeList or Element} elems 7977 */ 7978proto.remove = function( elems ) { 7979 var removeItems = this.getItems( elems ); 7980 7981 this._emitCompleteOnItems( 'remove', removeItems ); 7982 7983 // bail if no items to remove 7984 if ( !removeItems || !removeItems.length ) { 7985 return; 7986 } 7987
vendor: 38,285 bytes, lines 7988-9411
7988 removeItems.forEach( function( item ) { 7989 item.remove(); 7990 // remove item from collection 7991 utils.removeFrom( this.items, item ); 7992 }, this ); 7993}; 7994 7995// ----- destroy ----- // 7996 7997// remove and disable Outlayer instance 7998proto.destroy = function() { 7999 // clean up dynamic styles 8000 var style = this.element.style; 8001 style.height = ''; 8002 style.position = ''; 8003 style.width = ''; 8004 // destroy items 8005 this.items.forEach( function( item ) { 8006 item.destroy(); 8007 }); 8008 8009 this.unbindResize(); 8010 8011 var id = this.element.outlayerGUID; 8012 delete instances[ id ]; // remove reference to instance by id 8013 delete this.element.outlayerGUID; 8014 // remove data for jQuery 8015 if ( jQuery ) { 8016 jQuery.removeData( this.element, this.constructor.namespace ); 8017 } 8018 8019}; 8020 8021// -------------------------- data -------------------------- // 8022 8023/** 8024 * get Outlayer instance from element 8025 * @param {Element} elem 8026 * @returns {Outlayer} 8027 */ 8028Outlayer.data = function( elem ) { 8029 elem = utils.getQueryElement( elem ); 8030 var id = elem && elem.outlayerGUID; 8031 return id && instances[ id ]; 8032}; 8033 8034 8035// -------------------------- create Outlayer class -------------------------- // 8036 8037/** 8038 * create a layout class 8039 * @param {String} namespace 8040 */ 8041Outlayer.create = function( namespace, options ) { 8042 // sub-class Outlayer 8043 var Layout = subclass( Outlayer ); 8044 // apply new options and compatOptions 8045 Layout.defaults = utils.extend( {}, Outlayer.defaults ); 8046 utils.extend( Layout.defaults, options ); 8047 Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions ); 8048 8049 Layout.namespace = namespace; 8050 8051 Layout.data = Outlayer.data; 8052 8053 // sub-class Item 8054 Layout.Item = subclass( Item ); 8055 8056 // -------------------------- declarative -------------------------- // 8057 8058 utils.htmlInit( Layout, namespace ); 8059 8060 // -------------------------- jQuery bridge -------------------------- // 8061 8062 // make into jQuery plugin 8063 if ( jQuery && jQuery.bridget ) { 8064 jQuery.bridget( namespace, Layout ); 8065 } 8066 8067 return Layout; 8068}; 8069 8070function subclass( Parent ) { 8071 function SubClass() { 8072 Parent.apply( this, arguments ); 8073 } 8074 8075 SubClass.prototype = Object.create( Parent.prototype ); 8076 SubClass.prototype.constructor = SubClass; 8077 8078 return SubClass; 8079} 8080 8081// ----- helpers ----- // 8082 8083// how many milliseconds are in each unit 8084var msUnits = { 8085 ms: 1, 8086 s: 1000 8087}; 8088 8089// munge time-like parameter into millisecond number 8090// '0.4s' -> 40 8091function getMilliseconds( time ) { 8092 if ( typeof time == 'number' ) { 8093 return time; 8094 } 8095 var matches = time.match( /(^\d*\.?\d*)(\w*)/ ); 8096 var num = matches && matches[1]; 8097 var unit = matches && matches[2]; 8098 if ( !num.length ) { 8099 return 0; 8100 } 8101 num = parseFloat( num ); 8102 var mult = msUnits[ unit ] || 1; 8103 return num * mult; 8104} 8105 8106// ----- fin ----- // 8107 8108// back in global 8109Outlayer.Item = Item; 8110 8111return Outlayer; 8112 8113})); 8114 8115/** 8116 * Isotope Item 8117**/ 8118 8119( function( window, factory ) { 8120 // universal module definition 8121 /* jshint strict: false */ /*globals define, module, require */ 8122 if ( typeof define == 'function' && define.amd ) { 8123 // AMD 8124 define( 'isotope-layout/js/item',[ 8125 'outlayer/outlayer' 8126 ], 8127 factory ); 8128 } else if ( typeof module == 'object' && module.exports ) { 8129 // CommonJS 8130 module.exports = factory( 8131 require('outlayer') 8132 ); 8133 } else { 8134 // browser global 8135 window.Isotope = window.Isotope || {}; 8136 window.Isotope.Item = factory( 8137 window.Outlayer 8138 ); 8139 } 8140 8141}( window, function factory( Outlayer ) { 8142'use strict'; 8143 8144// -------------------------- Item -------------------------- // 8145 8146// sub-class Outlayer Item 8147function Item() { 8148 Outlayer.Item.apply( this, arguments ); 8149} 8150 8151var proto = Item.prototype = Object.create( Outlayer.Item.prototype ); 8152 8153var _create = proto._create; 8154proto._create = function() { 8155 // assign id, used for original-order sorting 8156 this.id = this.layout.itemGUID++; 8157 _create.call( this ); 8158 this.sortData = {}; 8159}; 8160 8161proto.updateSortData = function() { 8162 if ( this.isIgnored ) { 8163 return; 8164 } 8165 // default sorters 8166 this.sortData.id = this.id; 8167 // for backward compatibility 8168 this.sortData['original-order'] = this.id; 8169 this.sortData.random = Math.random(); 8170 // go thru getSortData obj and apply the sorters 8171 var getSortData = this.layout.options.getSortData; 8172 var sorters = this.layout._sorters; 8173 for ( var key in getSortData ) { 8174 var sorter = sorters[ key ]; 8175 this.sortData[ key ] = sorter( this.element, this ); 8176 } 8177}; 8178 8179var _destroy = proto.destroy; 8180proto.destroy = function() { 8181 // call super 8182 _destroy.apply( this, arguments ); 8183 // reset display, #741 8184 this.css({ 8185 display: '' 8186 }); 8187}; 8188 8189return Item; 8190 8191})); 8192 8193/** 8194 * Isotope LayoutMode 8195 */ 8196 8197( function( window, factory ) { 8198 // universal module definition 8199 /* jshint strict: false */ /*globals define, module, require */ 8200 if ( typeof define == 'function' && define.amd ) { 8201 // AMD 8202 define( 'isotope-layout/js/layout-mode',[ 8203 'get-size/get-size', 8204 'outlayer/outlayer' 8205 ], 8206 factory ); 8207 } else if ( typeof module == 'object' && module.exports ) { 8208 // CommonJS 8209 module.exports = factory( 8210 require('get-size'), 8211 require('outlayer') 8212 ); 8213 } else { 8214 // browser global 8215 window.Isotope = window.Isotope || {}; 8216 window.Isotope.LayoutMode = factory( 8217 window.getSize, 8218 window.Outlayer 8219 ); 8220 } 8221 8222}( window, function factory( getSize, Outlayer ) { 8223 'use strict'; 8224 8225 // layout mode class 8226 function LayoutMode( isotope ) { 8227 this.isotope = isotope; 8228 // link properties 8229 if ( isotope ) { 8230 this.options = isotope.options[ this.namespace ]; 8231 this.element = isotope.element; 8232 this.items = isotope.filteredItems; 8233 this.size = isotope.size; 8234 } 8235 } 8236 8237 var proto = LayoutMode.prototype; 8238 8239 /** 8240 * some methods should just defer to default Outlayer method 8241 * and reference the Isotope instance as `this` 8242 **/ 8243 var facadeMethods = [ 8244 '_resetLayout', 8245 '_getItemLayoutPosition', 8246 '_manageStamp', 8247 '_getContainerSize', 8248 '_getElementOffset', 8249 'needsResizeLayout', 8250 '_getOption' 8251 ]; 8252 8253 facadeMethods.forEach( function( methodName ) { 8254 proto[ methodName ] = function() { 8255 return Outlayer.prototype[ methodName ].apply( this.isotope, arguments ); 8256 }; 8257 }); 8258 8259 // ----- ----- // 8260 8261 // for horizontal layout modes, check vertical size 8262 proto.needsVerticalResizeLayout = function() { 8263 // don't trigger if size did not change 8264 var size = getSize( this.isotope.element ); 8265 // check that this.size and size are there 8266 // IE8 triggers resize on body size change, so they might not be 8267 var hasSizes = this.isotope.size && size; 8268 return hasSizes && size.innerHeight != this.isotope.size.innerHeight; 8269 }; 8270 8271 // ----- measurements ----- // 8272 8273 proto._getMeasurement = function() { 8274 this.isotope._getMeasurement.apply( this, arguments ); 8275 }; 8276 8277 proto.getColumnWidth = function() { 8278 this.getSegmentSize( 'column', 'Width' ); 8279 }; 8280 8281 proto.getRowHeight = function() { 8282 this.getSegmentSize( 'row', 'Height' ); 8283 }; 8284 8285 /** 8286 * get columnWidth or rowHeight 8287 * segment: 'column' or 'row' 8288 * size 'Width' or 'Height' 8289 **/ 8290 proto.getSegmentSize = function( segment, size ) { 8291 var segmentName = segment + size; 8292 var outerSize = 'outer' + size; 8293 // columnWidth / outerWidth // rowHeight / outerHeight 8294 this._getMeasurement( segmentName, outerSize ); 8295 // got rowHeight or columnWidth, we can chill 8296 if ( this[ segmentName ] ) { 8297 return; 8298 } 8299 // fall back to item of first element 8300 var firstItemSize = this.getFirstItemSize(); 8301 this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] || 8302 // or size of container 8303 this.isotope.size[ 'inner' + size ]; 8304 }; 8305 8306 proto.getFirstItemSize = function() { 8307 var firstItem = this.isotope.filteredItems[0]; 8308 return firstItem && firstItem.element && getSize( firstItem.element ); 8309 }; 8310 8311 // ----- methods that should reference isotope ----- // 8312 8313 proto.layout = function() { 8314 this.isotope.layout.apply( this.isotope, arguments ); 8315 }; 8316 8317 proto.getSize = function() { 8318 this.isotope.getSize(); 8319 this.size = this.isotope.size; 8320 }; 8321 8322 // -------------------------- create -------------------------- // 8323 8324 LayoutMode.modes = {}; 8325 8326 LayoutMode.create = function( namespace, options ) { 8327 8328 function Mode() { 8329 LayoutMode.apply( this, arguments ); 8330 } 8331 8332 Mode.prototype = Object.create( proto ); 8333 Mode.prototype.constructor = Mode; 8334 8335 // default options 8336 if ( options ) { 8337 Mode.options = options; 8338 } 8339 8340 Mode.prototype.namespace = namespace; 8341 // register in Isotope 8342 LayoutMode.modes[ namespace ] = Mode; 8343 8344 return Mode; 8345 }; 8346 8347 return LayoutMode; 8348 8349})); 8350 8351/*! 8352 * Masonry v4.2.1 8353 * Cascading grid layout library 8354 * https://masonry.desandro.com 8355 * MIT License 8356 * by David DeSandro 8357 */ 8358 8359( function( window, factory ) { 8360 // universal module definition 8361 /* jshint strict: false */ /*globals define, module, require */ 8362 if ( typeof define == 'function' && define.amd ) { 8363 // AMD 8364 define( 'masonry-layout/masonry',[ 8365 'outlayer/outlayer', 8366 'get-size/get-size' 8367 ], 8368 factory ); 8369 } else if ( typeof module == 'object' && module.exports ) { 8370 // CommonJS 8371 module.exports = factory( 8372 require('outlayer'), 8373 require('get-size') 8374 ); 8375 } else { 8376 // browser global 8377 window.Masonry = factory( 8378 window.Outlayer, 8379 window.getSize 8380 ); 8381 } 8382 8383}( window, function factory( Outlayer, getSize ) { 8384 8385 8386 8387// -------------------------- masonryDefinition -------------------------- // 8388 8389 // create an Outlayer layout class 8390 var Masonry = Outlayer.create('masonry'); 8391 // isFitWidth -> fitWidth 8392 Masonry.compatOptions.fitWidth = 'isFitWidth'; 8393 8394 var proto = Masonry.prototype; 8395 8396 proto._resetLayout = function() { 8397 this.getSize(); 8398 this._getMeasurement( 'columnWidth', 'outerWidth' ); 8399 this._getMeasurement( 'gutter', 'outerWidth' ); 8400 this.measureColumns(); 8401 8402 // reset column Y 8403 this.colYs = []; 8404 for ( var i=0; i < this.cols; i++ ) { 8405 this.colYs.push( 0 ); 8406 } 8407 8408 this.maxY = 0; 8409 this.horizontalColIndex = 0; 8410 }; 8411 8412 proto.measureColumns = function() { 8413 this.getContainerWidth(); 8414 // if columnWidth is 0, default to outerWidth of first item 8415 if ( !this.columnWidth ) { 8416 var firstItem = this.items[0]; 8417 var firstItemElem = firstItem && firstItem.element; 8418 // columnWidth fall back to item of first element 8419 this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth || 8420 // if first elem has no width, default to size of container 8421 this.containerWidth; 8422 } 8423 8424 var columnWidth = this.columnWidth += this.gutter; 8425 8426 // calculate columns 8427 var containerWidth = this.containerWidth + this.gutter; 8428 var cols = containerWidth / columnWidth; 8429 // fix rounding errors, typically with gutters 8430 var excess = columnWidth - containerWidth % columnWidth; 8431 // if overshoot is less than a pixel, round up, otherwise floor it 8432 var mathMethod = excess && excess < 1 ? 'round' : 'floor'; 8433 cols = Math[ mathMethod ]( cols ); 8434 this.cols = Math.max( cols, 1 ); 8435 }; 8436 8437 proto.getContainerWidth = function() { 8438 // container is parent if fit width 8439 var isFitWidth = this._getOption('fitWidth'); 8440 var container = isFitWidth ? this.element.parentNode : this.element; 8441 // check that this.size and size are there 8442 // IE8 triggers resize on body size change, so they might not be 8443 var size = getSize( container ); 8444 this.containerWidth = size && size.innerWidth; 8445 }; 8446 8447 proto._getItemLayoutPosition = function( item ) { 8448 item.getSize(); 8449 // how many columns does this brick span 8450 var remainder = item.size.outerWidth % this.columnWidth; 8451 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 8452 // round if off by 1 pixel, otherwise use ceil 8453 var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth ); 8454 colSpan = Math.min( colSpan, this.cols ); 8455 // use horizontal or top column position 8456 var colPosMethod = this.options.horizontalOrder ? 8457 '_getHorizontalColPosition' : '_getTopColPosition'; 8458 var colPosition = this[ colPosMethod ]( colSpan, item ); 8459 // position the brick 8460 var position = { 8461 x: this.columnWidth * colPosition.col, 8462 y: colPosition.y 8463 }; 8464 // apply setHeight to necessary columns 8465 var setHeight = colPosition.y + item.size.outerHeight; 8466 var setMax = colSpan + colPosition.col; 8467 for ( var i = colPosition.col; i < setMax; i++ ) { 8468 this.colYs[i] = setHeight; 8469 } 8470 8471 return position; 8472 }; 8473 8474 proto._getTopColPosition = function( colSpan ) { 8475 var colGroup = this._getTopColGroup( colSpan ); 8476 // get the minimum Y value from the columns 8477 var minimumY = Math.min.apply( Math, colGroup ); 8478 8479 return { 8480 col: colGroup.indexOf( minimumY ), 8481 y: minimumY, 8482 }; 8483 }; 8484 8485 /** 8486 * @param {Number} colSpan - number of columns the element spans 8487 * @returns {Array} colGroup 8488 */ 8489 proto._getTopColGroup = function( colSpan ) { 8490 if ( colSpan < 2 ) { 8491 // if brick spans only one column, use all the column Ys 8492 return this.colYs; 8493 } 8494 8495 var colGroup = []; 8496 // how many different places could this brick fit horizontally 8497 var groupCount = this.cols + 1 - colSpan; 8498 // for each group potential horizontal position 8499 for ( var i = 0; i < groupCount; i++ ) { 8500 colGroup[i] = this._getColGroupY( i, colSpan ); 8501 } 8502 return colGroup; 8503 }; 8504 8505 proto._getColGroupY = function( col, colSpan ) { 8506 if ( colSpan < 2 ) { 8507 return this.colYs[ col ]; 8508 } 8509 // make an array of colY values for that one group 8510 var groupColYs = this.colYs.slice( col, col + colSpan ); 8511 // and get the max value of the array 8512 return Math.max.apply( Math, groupColYs ); 8513 }; 8514 8515 // get column position based on horizontal index. #873 8516 proto._getHorizontalColPosition = function( colSpan, item ) { 8517 var col = this.horizontalColIndex % this.cols; 8518 var isOver = colSpan > 1 && col + colSpan > this.cols; 8519 // shift to next row if item can't fit on current row 8520 col = isOver ? 0 : col; 8521 // don't let zero-size items take up space 8522 var hasSize = item.size.outerWidth && item.size.outerHeight; 8523 this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex; 8524 8525 return { 8526 col: col, 8527 y: this._getColGroupY( col, colSpan ), 8528 }; 8529 }; 8530 8531 proto._manageStamp = function( stamp ) { 8532 var stampSize = getSize( stamp ); 8533 var offset = this._getElementOffset( stamp ); 8534 // get the columns that this stamp affects 8535 var isOriginLeft = this._getOption('originLeft'); 8536 var firstX = isOriginLeft ? offset.left : offset.right; 8537 var lastX = firstX + stampSize.outerWidth; 8538 var firstCol = Math.floor( firstX / this.columnWidth ); 8539 firstCol = Math.max( 0, firstCol ); 8540 var lastCol = Math.floor( lastX / this.columnWidth ); 8541 // lastCol should not go over if multiple of columnWidth #425 8542 lastCol -= lastX % this.columnWidth ? 0 : 1; 8543 lastCol = Math.min( this.cols - 1, lastCol ); 8544 // set colYs to bottom of the stamp 8545 8546 var isOriginTop = this._getOption('originTop'); 8547 var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) + 8548 stampSize.outerHeight; 8549 for ( var i = firstCol; i <= lastCol; i++ ) { 8550 this.colYs[i] = Math.max( stampMaxY, this.colYs[i] ); 8551 } 8552 }; 8553 8554 proto._getContainerSize = function() { 8555 this.maxY = Math.max.apply( Math, this.colYs ); 8556 var size = { 8557 height: this.maxY 8558 }; 8559 8560 if ( this._getOption('fitWidth') ) { 8561 size.width = this._getContainerFitWidth(); 8562 } 8563 8564 return size; 8565 }; 8566 8567 proto._getContainerFitWidth = function() { 8568 var unusedCols = 0; 8569 // count unused columns 8570 var i = this.cols; 8571 while ( --i ) { 8572 if ( this.colYs[i] !== 0 ) { 8573 break; 8574 } 8575 unusedCols++; 8576 } 8577 // fit container to columns that have been used 8578 return ( this.cols - unusedCols ) * this.columnWidth - this.gutter; 8579 }; 8580 8581 proto.needsResizeLayout = function() { 8582 var previousWidth = this.containerWidth; 8583 this.getContainerWidth(); 8584 return previousWidth != this.containerWidth; 8585 }; 8586 8587 return Masonry; 8588 8589})); 8590 8591/*! 8592 * Masonry layout mode 8593 * sub-classes Masonry 8594 * https://masonry.desandro.com 8595 */ 8596 8597( function( window, factory ) { 8598 // universal module definition 8599 /* jshint strict: false */ /*globals define, module, require */ 8600 if ( typeof define == 'function' && define.amd ) { 8601 // AMD 8602 define( 'isotope-layout/js/layout-modes/masonry',[ 8603 '../layout-mode', 8604 'masonry-layout/masonry' 8605 ], 8606 factory ); 8607 } else if ( typeof module == 'object' && module.exports ) { 8608 // CommonJS 8609 module.exports = factory( 8610 require('../layout-mode'), 8611 require('masonry-layout') 8612 ); 8613 } else { 8614 // browser global 8615 factory( 8616 window.Isotope.LayoutMode, 8617 window.Masonry 8618 ); 8619 } 8620 8621}( window, function factory( LayoutMode, Masonry ) { 8622'use strict'; 8623 8624// -------------------------- masonryDefinition -------------------------- // 8625 8626 // create an Outlayer layout class 8627 var MasonryMode = LayoutMode.create('masonry'); 8628 8629 var proto = MasonryMode.prototype; 8630 8631 var keepModeMethods = { 8632 _getElementOffset: true, 8633 layout: true, 8634 _getMeasurement: true 8635 }; 8636 8637 // inherit Masonry prototype 8638 for ( var method in Masonry.prototype ) { 8639 // do not inherit mode methods 8640 if ( !keepModeMethods[ method ] ) { 8641 proto[ method ] = Masonry.prototype[ method ]; 8642 } 8643 } 8644 8645 var measureColumns = proto.measureColumns; 8646 proto.measureColumns = function() { 8647 // set items, used if measuring first item 8648 this.items = this.isotope.filteredItems; 8649 measureColumns.call( this ); 8650 }; 8651 8652 // point to mode options for fitWidth 8653 var _getOption = proto._getOption; 8654 proto._getOption = function( option ) { 8655 if ( option == 'fitWidth' ) { 8656 return this.options.isFitWidth !== undefined ? 8657 this.options.isFitWidth : this.options.fitWidth; 8658 } 8659 return _getOption.apply( this.isotope, arguments ); 8660 }; 8661 8662 return MasonryMode; 8663 8664})); 8665 8666/** 8667 * fitRows layout mode 8668 */ 8669 8670( function( window, factory ) { 8671 // universal module definition 8672 /* jshint strict: false */ /*globals define, module, require */ 8673 if ( typeof define == 'function' && define.amd ) { 8674 // AMD 8675 define( 'isotope-layout/js/layout-modes/fit-rows',[ 8676 '../layout-mode' 8677 ], 8678 factory ); 8679 } else if ( typeof exports == 'object' ) { 8680 // CommonJS 8681 module.exports = factory( 8682 require('../layout-mode') 8683 ); 8684 } else { 8685 // browser global 8686 factory( 8687 window.Isotope.LayoutMode 8688 ); 8689 } 8690 8691}( window, function factory( LayoutMode ) { 8692'use strict'; 8693 8694var FitRows = LayoutMode.create('fitRows'); 8695 8696var proto = FitRows.prototype; 8697 8698proto._resetLayout = function() { 8699 this.x = 0; 8700 this.y = 0; 8701 this.maxY = 0; 8702 this._getMeasurement( 'gutter', 'outerWidth' ); 8703}; 8704 8705proto._getItemLayoutPosition = function( item ) { 8706 item.getSize(); 8707 8708 var itemWidth = item.size.outerWidth + this.gutter; 8709 // if this element cannot fit in the current row 8710 var containerWidth = this.isotope.size.innerWidth + this.gutter; 8711 if ( this.x !== 0 && itemWidth + this.x > containerWidth ) { 8712 this.x = 0; 8713 this.y = this.maxY; 8714 } 8715 8716 var position = { 8717 x: this.x, 8718 y: this.y 8719 }; 8720 8721 this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight ); 8722 this.x += itemWidth; 8723 8724 return position; 8725}; 8726 8727proto._getContainerSize = function() { 8728 return { height: this.maxY }; 8729}; 8730 8731return FitRows; 8732 8733})); 8734 8735/** 8736 * vertical layout mode 8737 */ 8738 8739( function( window, factory ) { 8740 // universal module definition 8741 /* jshint strict: false */ /*globals define, module, require */ 8742 if ( typeof define == 'function' && define.amd ) { 8743 // AMD 8744 define( 'isotope-layout/js/layout-modes/vertical',[ 8745 '../layout-mode' 8746 ], 8747 factory ); 8748 } else if ( typeof module == 'object' && module.exports ) { 8749 // CommonJS 8750 module.exports = factory( 8751 require('../layout-mode') 8752 ); 8753 } else { 8754 // browser global 8755 factory( 8756 window.Isotope.LayoutMode 8757 ); 8758 } 8759 8760}( window, function factory( LayoutMode ) { 8761'use strict'; 8762 8763var Vertical = LayoutMode.create( 'vertical', { 8764 horizontalAlignment: 0 8765}); 8766 8767var proto = Vertical.prototype; 8768 8769proto._resetLayout = function() { 8770 this.y = 0; 8771}; 8772 8773proto._getItemLayoutPosition = function( item ) { 8774 item.getSize(); 8775 var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) * 8776 this.options.horizontalAlignment; 8777 var y = this.y; 8778 this.y += item.size.outerHeight; 8779 return { x: x, y: y }; 8780}; 8781 8782proto._getContainerSize = function() { 8783 return { height: this.y }; 8784}; 8785 8786return Vertical; 8787 8788})); 8789 8790/*! 8791 * Isotope v3.0.6 8792 * 8793 * Licensed GPLv3 for open source use 8794 * or Isotope Commercial License for commercial use 8795 * 8796 * https://isotope.metafizzy.co 8797 * Copyright 2010-2018 Metafizzy 8798 */ 8799 8800( function( window, factory ) { 8801 // universal module definition 8802 /* jshint strict: false */ /*globals define, module, require */ 8803 if ( typeof define == 'function' && define.amd ) { 8804 // AMD 8805 define( [ 8806 'outlayer/outlayer', 8807 'get-size/get-size', 8808 'desandro-matches-selector/matches-selector', 8809 'fizzy-ui-utils/utils', 8810 'isotope-layout/js/item', 8811 'isotope-layout/js/layout-mode', 8812 // include default layout modes 8813 'isotope-layout/js/layout-modes/masonry', 8814 'isotope-layout/js/layout-modes/fit-rows', 8815 'isotope-layout/js/layout-modes/vertical' 8816 ], 8817 function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) { 8818 return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ); 8819 }); 8820 } else if ( typeof module == 'object' && module.exports ) { 8821 // CommonJS 8822 module.exports = factory( 8823 window, 8824 require('outlayer'), 8825 require('get-size'), 8826 require('desandro-matches-selector'), 8827 require('fizzy-ui-utils'), 8828 require('isotope-layout/js/item'), 8829 require('isotope-layout/js/layout-mode'), 8830 // include default layout modes 8831 require('isotope-layout/js/layout-modes/masonry'), 8832 require('isotope-layout/js/layout-modes/fit-rows'), 8833 require('isotope-layout/js/layout-modes/vertical') 8834 ); 8835 } else { 8836 // browser global 8837 window.Isotope = factory( 8838 window, 8839 window.Outlayer, 8840 window.getSize, 8841 window.matchesSelector, 8842 window.fizzyUIUtils, 8843 window.Isotope.Item, 8844 window.Isotope.LayoutMode 8845 ); 8846 } 8847 8848}( window, function factory( window, Outlayer, getSize, matchesSelector, utils, 8849 Item, LayoutMode ) { 8850 8851 8852 8853// -------------------------- vars -------------------------- // 8854 8855var jQuery = window.jQuery; 8856 8857// -------------------------- helpers -------------------------- // 8858 8859var trim = String.prototype.trim ? 8860 function( str ) { 8861 return str.trim(); 8862 } : 8863 function( str ) { 8864 return str.replace( /^\s+|\s+$/g, '' ); 8865 }; 8866 8867// -------------------------- isotopeDefinition -------------------------- // 8868 8869 // create an Outlayer layout class 8870 var Isotope = Outlayer.create( 'isotope', { 8871 layoutMode: 'masonry', 8872 isJQueryFiltering: true, 8873 sortAscending: true 8874 }); 8875 8876 Isotope.Item = Item; 8877 Isotope.LayoutMode = LayoutMode; 8878 8879 var proto = Isotope.prototype; 8880 8881 proto._create = function() { 8882 this.itemGUID = 0; 8883 // functions that sort items 8884 this._sorters = {}; 8885 this._getSorters(); 8886 // call super 8887 Outlayer.prototype._create.call( this ); 8888 8889 // create layout modes 8890 this.modes = {}; 8891 // start filteredItems with all items 8892 this.filteredItems = this.items; 8893 // keep of track of sortBys 8894 this.sortHistory = [ 'original-order' ]; 8895 // create from registered layout modes 8896 for ( var name in LayoutMode.modes ) { 8897 this._initLayoutMode( name ); 8898 } 8899 }; 8900 8901 proto.reloadItems = function() { 8902 // reset item ID counter 8903 this.itemGUID = 0; 8904 // call super 8905 Outlayer.prototype.reloadItems.call( this ); 8906 }; 8907 8908 proto._itemize = function() { 8909 var items = Outlayer.prototype._itemize.apply( this, arguments ); 8910 // assign ID for original-order 8911 for ( var i=0; i < items.length; i++ ) { 8912 var item = items[i]; 8913 item.id = this.itemGUID++; 8914 } 8915 this._updateItemsSortData( items ); 8916 return items; 8917 }; 8918 8919 8920 // -------------------------- layout -------------------------- // 8921 8922 proto._initLayoutMode = function( name ) { 8923 var Mode = LayoutMode.modes[ name ]; 8924 // set mode options 8925 // HACK extend initial options, back-fill in default options 8926 var initialOpts = this.options[ name ] || {}; 8927 this.options[ name ] = Mode.options ? 8928 utils.extend( Mode.options, initialOpts ) : initialOpts; 8929 // init layout mode instance 8930 this.modes[ name ] = new Mode( this ); 8931 }; 8932 8933 8934 proto.layout = function() { 8935 // if first time doing layout, do all magic 8936 if ( !this._isLayoutInited && this._getOption('initLayout') ) { 8937 this.arrange(); 8938 return; 8939 } 8940 this._layout(); 8941 }; 8942 8943 // private method to be used in layout() & magic() 8944 proto._layout = function() { 8945 // don't animate first layout 8946 var isInstant = this._getIsInstant(); 8947 // layout flow 8948 this._resetLayout(); 8949 this._manageStamps(); 8950 this.layoutItems( this.filteredItems, isInstant ); 8951 8952 // flag for initalized 8953 this._isLayoutInited = true; 8954 }; 8955 8956 // filter + sort + layout 8957 proto.arrange = function( opts ) { 8958 // set any options pass 8959 this.option( opts ); 8960 this._getIsInstant(); 8961 // filter, sort, and layout 8962 8963 // filter 8964 var filtered = this._filter( this.items ); 8965 this.filteredItems = filtered.matches; 8966 8967 this._bindArrangeComplete(); 8968 8969 if ( this._isInstant ) { 8970 this._noTransition( this._hideReveal, [ filtered ] ); 8971 } else { 8972 this._hideReveal( filtered ); 8973 } 8974 8975 this._sort(); 8976 this._layout(); 8977 }; 8978 // alias to _init for main plugin method 8979 proto._init = proto.arrange; 8980 8981 proto._hideReveal = function( filtered ) { 8982 this.reveal( filtered.needReveal ); 8983 this.hide( filtered.needHide ); 8984 }; 8985 8986 // HACK 8987 // Don't animate/transition first layout 8988 // Or don't animate/transition other layouts 8989 proto._getIsInstant = function() { 8990 var isLayoutInstant = this._getOption('layoutInstant'); 8991 var isInstant = isLayoutInstant !== undefined ? isLayoutInstant : 8992 !this._isLayoutInited; 8993 this._isInstant = isInstant; 8994 return isInstant; 8995 }; 8996 8997 // listen for layoutComplete, hideComplete and revealComplete 8998 // to trigger arrangeComplete 8999 proto._bindArrangeComplete = function() { 9000 // listen for 3 events to trigger arrangeComplete 9001 var isLayoutComplete, isHideComplete, isRevealComplete; 9002 var _this = this; 9003 function arrangeParallelCallback() { 9004 if ( isLayoutComplete && isHideComplete && isRevealComplete ) { 9005 _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] ); 9006 } 9007 } 9008 this.once( 'layoutComplete', function() { 9009 isLayoutComplete = true; 9010 arrangeParallelCallback(); 9011 }); 9012 this.once( 'hideComplete', function() { 9013 isHideComplete = true; 9014 arrangeParallelCallback(); 9015 }); 9016 this.once( 'revealComplete', function() { 9017 isRevealComplete = true; 9018 arrangeParallelCallback(); 9019 }); 9020 }; 9021 9022 // -------------------------- filter -------------------------- // 9023 9024 proto._filter = function( items ) { 9025 var filter = this.options.filter; 9026 filter = filter || '*'; 9027 var matches = []; 9028 var hiddenMatched = []; 9029 var visibleUnmatched = []; 9030 9031 var test = this._getFilterTest( filter ); 9032 9033 // test each item 9034 for ( var i=0; i < items.length; i++ ) { 9035 var item = items[i]; 9036 if ( item.isIgnored ) { 9037 continue; 9038 } 9039 // add item to either matched or unmatched group 9040 var isMatched = test( item ); 9041 // item.isFilterMatched = isMatched; 9042 // add to matches if its a match 9043 if ( isMatched ) { 9044 matches.push( item ); 9045 } 9046 // add to additional group if item needs to be hidden or revealed 9047 if ( isMatched && item.isHidden ) { 9048 hiddenMatched.push( item ); 9049 } else if ( !isMatched && !item.isHidden ) { 9050 visibleUnmatched.push( item ); 9051 } 9052 } 9053 9054 // return collections of items to be manipulated 9055 return { 9056 matches: matches, 9057 needReveal: hiddenMatched, 9058 needHide: visibleUnmatched 9059 }; 9060 }; 9061 9062 // get a jQuery, function, or a matchesSelector test given the filter 9063 proto._getFilterTest = function( filter ) { 9064 if ( jQuery && this.options.isJQueryFiltering ) { 9065 // use jQuery 9066 return function( item ) { 9067 return jQuery( item.element ).is( filter ); 9068 }; 9069 } 9070 if ( typeof filter == 'function' ) { 9071 // use filter as function 9072 return function( item ) { 9073 return filter( item.element ); 9074 }; 9075 } 9076 // default, use filter as selector string 9077 return function( item ) { 9078 return matchesSelector( item.element, filter ); 9079 }; 9080 }; 9081 9082 // -------------------------- sorting -------------------------- // 9083 9084 /** 9085 * @params {Array} elems 9086 * @public 9087 */ 9088 proto.updateSortData = function( elems ) { 9089 // get items 9090 var items; 9091 if ( elems ) { 9092 elems = utils.makeArray( elems ); 9093 items = this.getItems( elems ); 9094 } else { 9095 // update all items if no elems provided 9096 items = this.items; 9097 } 9098 9099 this._getSorters(); 9100 this._updateItemsSortData( items ); 9101 }; 9102 9103 proto._getSorters = function() { 9104 var getSortData = this.options.getSortData; 9105 for ( var key in getSortData ) { 9106 var sorter = getSortData[ key ]; 9107 this._sorters[ key ] = mungeSorter( sorter ); 9108 } 9109 }; 9110 9111 /** 9112 * @params {Array} items - of Isotope.Items 9113 * @private 9114 */ 9115 proto._updateItemsSortData = function( items ) { 9116 // do not update if no items 9117 var len = items && items.length; 9118 9119 for ( var i=0; len && i < len; i++ ) { 9120 var item = items[i]; 9121 item.updateSortData(); 9122 } 9123 }; 9124 9125 // ----- munge sorter ----- // 9126 9127 // encapsulate this, as we just need mungeSorter 9128 // other functions in here are just for munging 9129 var mungeSorter = ( function() { 9130 // add a magic layer to sorters for convienent shorthands 9131 // `.foo-bar` will use the text of .foo-bar querySelector 9132 // `[foo-bar]` will use attribute 9133 // you can also add parser 9134 // `.foo-bar parseInt` will parse that as a number 9135 function mungeSorter( sorter ) { 9136 // if not a string, return function or whatever it is 9137 if ( typeof sorter != 'string' ) { 9138 return sorter; 9139 } 9140 // parse the sorter string 9141 var args = trim( sorter ).split(' '); 9142 var query = args[0]; 9143 // check if query looks like [an-attribute] 9144 var attrMatch = query.match( /^\[(.+)\]$/ ); 9145 var attr = attrMatch && attrMatch[1]; 9146 var getValue = getValueGetter( attr, query ); 9147 // use second argument as a parser 9148 var parser = Isotope.sortDataParsers[ args[1] ]; 9149 // parse the value, if there was a parser 9150 sorter = parser ? function( elem ) { 9151 return elem && parser( getValue( elem ) ); 9152 } : 9153 // otherwise just return value 9154 function( elem ) { 9155 return elem && getValue( elem ); 9156 }; 9157 9158 return sorter; 9159 } 9160 9161 // get an attribute getter, or get text of the querySelector 9162 function getValueGetter( attr, query ) { 9163 // if query looks like [foo-bar], get attribute 9164 if ( attr ) { 9165 return function getAttribute( elem ) { 9166 return elem.getAttribute( attr ); 9167 }; 9168 } 9169 9170 // otherwise, assume its a querySelector, and get its text 9171 return function getChildText( elem ) { 9172 var child = elem.querySelector( query ); 9173 return child && child.textContent; 9174 }; 9175 } 9176 9177 return mungeSorter; 9178 })(); 9179 9180 // parsers used in getSortData shortcut strings 9181 Isotope.sortDataParsers = { 9182 'parseInt': function( val ) { 9183 return parseInt( val, 10 ); 9184 }, 9185 'parseFloat': function( val ) { 9186 return parseFloat( val ); 9187 } 9188 }; 9189 9190 // ----- sort method ----- // 9191 9192 // sort filteredItem order 9193 proto._sort = function() { 9194 if ( !this.options.sortBy ) { 9195 return; 9196 } 9197 // keep track of sortBy History 9198 var sortBys = utils.makeArray( this.options.sortBy ); 9199 if ( !this._getIsSameSortBy( sortBys ) ) { 9200 // concat all sortBy and sortHistory, add to front, oldest goes in last 9201 this.sortHistory = sortBys.concat( this.sortHistory ); 9202 } 9203 // sort magic 9204 var itemSorter = getItemSorter( this.sortHistory, this.options.sortAscending ); 9205 this.filteredItems.sort( itemSorter ); 9206 }; 9207 9208 // check if sortBys is same as start of sortHistory 9209 proto._getIsSameSortBy = function( sortBys ) { 9210 for ( var i=0; i < sortBys.length; i++ ) { 9211 if ( sortBys[i] != this.sortHistory[i] ) { 9212 return false; 9213 } 9214 } 9215 return true; 9216 }; 9217 9218 // returns a function used for sorting 9219 function getItemSorter( sortBys, sortAsc ) { 9220 return function sorter( itemA, itemB ) { 9221 // cycle through all sortKeys 9222 for ( var i = 0; i < sortBys.length; i++ ) { 9223 var sortBy = sortBys[i]; 9224 var a = itemA.sortData[ sortBy ]; 9225 var b = itemB.sortData[ sortBy ]; 9226 if ( a > b || a < b ) { 9227 // if sortAsc is an object, use the value given the sortBy key 9228 var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc; 9229 var direction = isAscending ? 1 : -1; 9230 return ( a > b ? 1 : -1 ) * direction; 9231 } 9232 } 9233 return 0; 9234 }; 9235 } 9236 9237 // -------------------------- methods -------------------------- // 9238 9239 // get layout mode 9240 proto._mode = function() { 9241 var layoutMode = this.options.layoutMode; 9242 var mode = this.modes[ layoutMode ]; 9243 if ( !mode ) { 9244 // TODO console.error 9245 throw new Error( 'No layout mode: ' + layoutMode ); 9246 } 9247 // HACK sync mode's options 9248 // any options set after init for layout mode need to be synced 9249 mode.options = this.options[ layoutMode ]; 9250 return mode; 9251 }; 9252 9253 proto._resetLayout = function() { 9254 // trigger original reset layout 9255 Outlayer.prototype._resetLayout.call( this ); 9256 this._mode()._resetLayout(); 9257 }; 9258 9259 proto._getItemLayoutPosition = function( item ) { 9260 return this._mode()._getItemLayoutPosition( item ); 9261 }; 9262 9263 proto._manageStamp = function( stamp ) { 9264 this._mode()._manageStamp( stamp ); 9265 }; 9266 9267 proto._getContainerSize = function() { 9268 return this._mode()._getContainerSize(); 9269 }; 9270 9271 proto.needsResizeLayout = function() { 9272 return this._mode().needsResizeLayout(); 9273 }; 9274 9275 // -------------------------- adding & removing -------------------------- // 9276 9277 // HEADS UP overwrites default Outlayer appended 9278 proto.appended = function( elems ) { 9279 var items = this.addItems( elems ); 9280 if ( !items.length ) { 9281 return; 9282 } 9283 // filter, layout, reveal new items 9284 var filteredItems = this._filterRevealAdded( items ); 9285 // add to filteredItems 9286 this.filteredItems = this.filteredItems.concat( filteredItems ); 9287 }; 9288 9289 // HEADS UP overwrites default Outlayer prepended 9290 proto.prepended = function( elems ) { 9291 var items = this._itemize( elems ); 9292 if ( !items.length ) { 9293 return; 9294 } 9295 // start new layout 9296 this._resetLayout(); 9297 this._manageStamps(); 9298 // filter, layout, reveal new items 9299 var filteredItems = this._filterRevealAdded( items ); 9300 // layout previous items 9301 this.layoutItems( this.filteredItems ); 9302 // add to items and filteredItems 9303 this.filteredItems = filteredItems.concat( this.filteredItems ); 9304 this.items = items.concat( this.items ); 9305 }; 9306 9307 proto._filterRevealAdded = function( items ) { 9308 var filtered = this._filter( items ); 9309 this.hide( filtered.needHide ); 9310 // reveal all new items 9311 this.reveal( filtered.matches ); 9312 // layout new items, no transition 9313 this.layoutItems( filtered.matches, true ); 9314 return filtered.matches; 9315 }; 9316 9317 /** 9318 * Filter, sort, and layout newly-appended item elements 9319 * @param {Array or NodeList or Element} elems 9320 */ 9321 proto.insert = function( elems ) { 9322 var items = this.addItems( elems ); 9323 if ( !items.length ) { 9324 return; 9325 } 9326 // append item elements 9327 var i, item; 9328 var len = items.length; 9329 for ( i=0; i < len; i++ ) { 9330 item = items[i]; 9331 this.element.appendChild( item.element ); 9332 } 9333 // filter new stuff 9334 var filteredInsertItems = this._filter( items ).matches; 9335 // set flag 9336 for ( i=0; i < len; i++ ) { 9337 items[i].isLayoutInstant = true; 9338 } 9339 this.arrange(); 9340 // reset flag 9341 for ( i=0; i < len; i++ ) { 9342 delete items[i].isLayoutInstant; 9343 } 9344 this.reveal( filteredInsertItems ); 9345 }; 9346 9347 var _remove = proto.remove; 9348 proto.remove = function( elems ) { 9349 elems = utils.makeArray( elems ); 9350 var removeItems = this.getItems( elems ); 9351 // do regular thing 9352 _remove.call( this, elems ); 9353 // bail if no items to remove 9354 var len = removeItems && removeItems.length; 9355 // remove elems from filteredItems 9356 for ( var i=0; len && i < len; i++ ) { 9357 var item = removeItems[i]; 9358 // remove item from collection 9359 utils.removeFrom( this.filteredItems, item ); 9360 } 9361 }; 9362 9363 proto.shuffle = function() { 9364 // update random sortData 9365 for ( var i=0; i < this.items.length; i++ ) { 9366 var item = this.items[i]; 9367 item.sortData.random = Math.random(); 9368 } 9369 this.options.sortBy = 'random'; 9370 this._sort(); 9371 this._layout(); 9372 }; 9373 9374 /** 9375 * trigger fn without transition 9376 * kind of hacky to have this in the first place 9377 * @param {Function} fn 9378 * @param {Array} args 9379 * @returns ret 9380 * @private 9381 */ 9382 proto._noTransition = function( fn, args ) { 9383 // save transitionDuration before disabling 9384 var transitionDuration = this.options.transitionDuration; 9385 // disable transition 9386 this.options.transitionDuration = 0; 9387 // do it 9388 var returnValue = fn.apply( this, args ); 9389 // re-enable transition for reveal 9390 this.options.transitionDuration = transitionDuration; 9391 return returnValue; 9392 }; 9393 9394 // ----- helper methods ----- // 9395 9396 /** 9397 * getter method for getting filtered item elements 9398 * @returns {Array} elems - collection of item elements 9399 */ 9400 proto.getFilteredItemElements = function() { 9401 return this.filteredItems.map( function( item ) { 9402 return item.element; 9403 }); 9404 }; 9405 9406 // ----- ----- // 9407 9408 return Isotope; 9409 9410})); 9411
vendor: 29,252 bytes, lines 9412-10568
9412/*! 9413 * Packery layout mode PACKAGED v2.0.1 9414 * sub-classes Packery 9415 */ 9416 9417/** 9418 * Rect 9419 * low-level utility class for basic geometry 9420 */ 9421 9422( function( window, factory ) { 9423 // universal module definition 9424 /* jshint strict: false */ /* globals define, module */ 9425 if ( typeof define == 'function' && define.amd ) { 9426 // AMD 9427 define( 'packery/js/rect',factory ); 9428 } else if ( typeof module == 'object' && module.exports ) { 9429 // CommonJS 9430 module.exports = factory(); 9431 } else { 9432 // browser global 9433 window.Packery = window.Packery || {}; 9434 window.Packery.Rect = factory(); 9435 } 9436 9437}( window, function factory() { 9438 9439 9440// -------------------------- Rect -------------------------- // 9441 9442function Rect( props ) { 9443 // extend properties from defaults 9444 for ( var prop in Rect.defaults ) { 9445 this[ prop ] = Rect.defaults[ prop ]; 9446 } 9447 9448 for ( prop in props ) { 9449 this[ prop ] = props[ prop ]; 9450 } 9451 9452} 9453 9454Rect.defaults = { 9455 x: 0, 9456 y: 0, 9457 width: 0, 9458 height: 0 9459}; 9460 9461var proto = Rect.prototype; 9462 9463/** 9464 * Determines whether or not this rectangle wholly encloses another rectangle or point. 9465 * @param {Rect} rect 9466 * @returns {Boolean} 9467**/ 9468proto.contains = function( rect ) { 9469 // points don't have width or height 9470 var otherWidth = rect.width || 0; 9471 var otherHeight = rect.height || 0; 9472 return this.x <= rect.x && 9473 this.y <= rect.y && 9474 this.x + this.width >= rect.x + otherWidth && 9475 this.y + this.height >= rect.y + otherHeight; 9476}; 9477 9478/** 9479 * Determines whether or not the rectangle intersects with another. 9480 * @param {Rect} rect 9481 * @returns {Boolean} 9482**/ 9483proto.overlaps = function( rect ) { 9484 var thisRight = this.x + this.width; 9485 var thisBottom = this.y + this.height; 9486 var rectRight = rect.x + rect.width; 9487 var rectBottom = rect.y + rect.height; 9488 9489 // http://stackoverflow.com/a/306332 9490 return this.x < rectRight && 9491 thisRight > rect.x && 9492 this.y < rectBottom && 9493 thisBottom > rect.y; 9494}; 9495 9496/** 9497 * @param {Rect} rect - the overlapping rect 9498 * @returns {Array} freeRects - rects representing the area around the rect 9499**/ 9500proto.getMaximalFreeRects = function( rect ) { 9501 9502 // if no intersection, return false 9503 if ( !this.overlaps( rect ) ) { 9504 return false; 9505 } 9506 9507 var freeRects = []; 9508 var freeRect; 9509 9510 var thisRight = this.x + this.width; 9511 var thisBottom = this.y + this.height; 9512 var rectRight = rect.x + rect.width; 9513 var rectBottom = rect.y + rect.height; 9514 9515 // top 9516 if ( this.y < rect.y ) { 9517 freeRect = new Rect({ 9518 x: this.x, 9519 y: this.y, 9520 width: this.width, 9521 height: rect.y - this.y 9522 }); 9523 freeRects.push( freeRect ); 9524 } 9525 9526 // right 9527 if ( thisRight > rectRight ) { 9528 freeRect = new Rect({ 9529 x: rectRight, 9530 y: this.y, 9531 width: thisRight - rectRight, 9532 height: this.height 9533 }); 9534 freeRects.push( freeRect ); 9535 } 9536 9537 // bottom 9538 if ( thisBottom > rectBottom ) { 9539 freeRect = new Rect({ 9540 x: this.x, 9541 y: rectBottom, 9542 width: this.width, 9543 height: thisBottom - rectBottom 9544 }); 9545 freeRects.push( freeRect ); 9546 } 9547 9548 // left 9549 if ( this.x < rect.x ) { 9550 freeRect = new Rect({ 9551 x: this.x, 9552 y: this.y, 9553 width: rect.x - this.x, 9554 height: this.height 9555 }); 9556 freeRects.push( freeRect ); 9557 } 9558 9559 return freeRects; 9560}; 9561 9562proto.canFit = function( rect ) { 9563 return this.width >= rect.width && this.height >= rect.height; 9564}; 9565 9566return Rect; 9567 9568})); 9569 9570/** 9571 * Packer 9572 * bin-packing algorithm 9573 */ 9574 9575( function( window, factory ) { 9576 // universal module definition 9577 /* jshint strict: false */ /* globals define, module, require */ 9578 if ( typeof define == 'function' && define.amd ) { 9579 // AMD 9580 define( 'packery/js/packer',[ './rect' ], factory ); 9581 } else if ( typeof module == 'object' && module.exports ) { 9582 // CommonJS 9583 module.exports = factory( 9584 require('./rect') 9585 ); 9586 } else { 9587 // browser global 9588 var Packery = window.Packery = window.Packery || {}; 9589 Packery.Packer = factory( Packery.Rect ); 9590 } 9591 9592}( window, function factory( Rect ) { 9593 9594 9595// -------------------------- Packer -------------------------- // 9596 9597/** 9598 * @param {Number} width 9599 * @param {Number} height 9600 * @param {String} sortDirection 9601 * topLeft for vertical, leftTop for horizontal 9602 */ 9603function Packer( width, height, sortDirection ) { 9604 this.width = width || 0; 9605 this.height = height || 0; 9606 this.sortDirection = sortDirection || 'downwardLeftToRight'; 9607 9608 this.reset(); 9609} 9610 9611var proto = Packer.prototype; 9612 9613proto.reset = function() { 9614 this.spaces = []; 9615 9616 var initialSpace = new Rect({ 9617 x: 0, 9618 y: 0, 9619 width: this.width, 9620 height: this.height 9621 }); 9622 9623 this.spaces.push( initialSpace ); 9624 // set sorter 9625 this.sorter = sorters[ this.sortDirection ] || sorters.downwardLeftToRight; 9626}; 9627 9628// change x and y of rect to fit with in Packer's available spaces 9629proto.pack = function( rect ) { 9630 for ( var i=0; i < this.spaces.length; i++ ) { 9631 var space = this.spaces[i]; 9632 if ( space.canFit( rect ) ) { 9633 this.placeInSpace( rect, space ); 9634 break; 9635 } 9636 } 9637}; 9638 9639proto.columnPack = function( rect ) { 9640 for ( var i=0; i < this.spaces.length; i++ ) { 9641 var space = this.spaces[i]; 9642 var canFitInSpaceColumn = space.x <= rect.x && 9643 space.x + space.width >= rect.x + rect.width && 9644 space.height >= rect.height - 0.01; // fudge number for rounding error 9645 if ( canFitInSpaceColumn ) { 9646 rect.y = space.y; 9647 this.placed( rect ); 9648 break; 9649 } 9650 } 9651}; 9652 9653proto.rowPack = function( rect ) { 9654 for ( var i=0; i < this.spaces.length; i++ ) { 9655 var space = this.spaces[i]; 9656 var canFitInSpaceRow = space.y <= rect.y && 9657 space.y + space.height >= rect.y + rect.height && 9658 space.width >= rect.width - 0.01; // fudge number for rounding error 9659 if ( canFitInSpaceRow ) { 9660 rect.x = space.x; 9661 this.placed( rect ); 9662 break; 9663 } 9664 } 9665}; 9666 9667proto.placeInSpace = function( rect, space ) { 9668 // place rect in space 9669 rect.x = space.x; 9670 rect.y = space.y; 9671 9672 this.placed( rect ); 9673}; 9674 9675// update spaces with placed rect 9676proto.placed = function( rect ) { 9677 // update spaces 9678 var revisedSpaces = []; 9679 for ( var i=0; i < this.spaces.length; i++ ) { 9680 var space = this.spaces[i]; 9681 var newSpaces = space.getMaximalFreeRects( rect ); 9682 // add either the original space or the new spaces to the revised spaces 9683 if ( newSpaces ) { 9684 revisedSpaces.push.apply( revisedSpaces, newSpaces ); 9685 } else { 9686 revisedSpaces.push( space ); 9687 } 9688 } 9689 9690 this.spaces = revisedSpaces; 9691 9692 this.mergeSortSpaces(); 9693}; 9694 9695proto.mergeSortSpaces = function() { 9696 // remove redundant spaces 9697 Packer.mergeRects( this.spaces ); 9698 this.spaces.sort( this.sorter ); 9699}; 9700 9701// add a space back 9702proto.addSpace = function( rect ) { 9703 this.spaces.push( rect ); 9704 this.mergeSortSpaces(); 9705}; 9706 9707// -------------------------- utility functions -------------------------- // 9708 9709/** 9710 * Remove redundant rectangle from array of rectangles 9711 * @param {Array} rects: an array of Rects 9712 * @returns {Array} rects: an array of Rects 9713**/ 9714Packer.mergeRects = function( rects ) { 9715 var i = 0; 9716 var rect = rects[i]; 9717 9718 rectLoop: 9719 while ( rect ) { 9720 var j = 0; 9721 var compareRect = rects[ i + j ]; 9722 9723 while ( compareRect ) { 9724 if ( compareRect == rect ) { 9725 j++; // next 9726 } else if ( compareRect.contains( rect ) ) { 9727 // remove rect 9728 rects.splice( i, 1 ); 9729 rect = rects[i]; // set next rect 9730 continue rectLoop; // bail on compareLoop 9731 } else if ( rect.contains( compareRect ) ) { 9732 // remove compareRect 9733 rects.splice( i + j, 1 ); 9734 } else { 9735 j++; 9736 } 9737 compareRect = rects[ i + j ]; // set next compareRect 9738 } 9739 i++; 9740 rect = rects[i]; 9741 } 9742 9743 return rects; 9744}; 9745 9746 9747// -------------------------- sorters -------------------------- // 9748 9749// functions for sorting rects in order 9750var sorters = { 9751 // top down, then left to right 9752 downwardLeftToRight: function( a, b ) { 9753 return a.y - b.y || a.x - b.x; 9754 }, 9755 // left to right, then top down 9756 rightwardTopToBottom: function( a, b ) { 9757 return a.x - b.x || a.y - b.y; 9758 } 9759}; 9760 9761 9762// -------------------------- -------------------------- // 9763 9764return Packer; 9765 9766})); 9767 9768/** 9769 * Packery Item Element 9770**/ 9771 9772( function( window, factory ) { 9773 // universal module definition 9774 /* jshint strict: false */ /* globals define, module, require */ 9775 if ( typeof define == 'function' && define.amd ) { 9776 // AMD 9777 define( 'packery/js/item',[ 9778 'outlayer/outlayer', 9779 './rect' 9780 ], 9781 factory ); 9782 } else if ( typeof module == 'object' && module.exports ) { 9783 // CommonJS 9784 module.exports = factory( 9785 require('outlayer'), 9786 require('./rect') 9787 ); 9788 } else { 9789 // browser global 9790 window.Packery.Item = factory( 9791 window.Outlayer, 9792 window.Packery.Rect 9793 ); 9794 } 9795 9796}( window, function factory( Outlayer, Rect ) { 9797 9798 9799// -------------------------- Item -------------------------- // 9800 9801var docElemStyle = document.documentElement.style; 9802 9803var transformProperty = typeof docElemStyle.transform == 'string' ? 9804 'transform' : 'WebkitTransform'; 9805 9806// sub-class Item 9807var Item = function PackeryItem() { 9808 Outlayer.Item.apply( this, arguments ); 9809}; 9810 9811var proto = Item.prototype = Object.create( Outlayer.Item.prototype ); 9812 9813var __create = proto._create; 9814proto._create = function() { 9815 // call default _create logic 9816 __create.call( this ); 9817 this.rect = new Rect(); 9818}; 9819 9820var _moveTo = proto.moveTo; 9821proto.moveTo = function( x, y ) { 9822 // don't shift 1px while dragging 9823 var dx = Math.abs( this.position.x - x ); 9824 var dy = Math.abs( this.position.y - y ); 9825 9826 var canHackGoTo = this.layout.dragItemCount && !this.isPlacing && 9827 !this.isTransitioning && dx < 1 && dy < 1; 9828 if ( canHackGoTo ) { 9829 this.goTo( x, y ); 9830 return; 9831 } 9832 _moveTo.apply( this, arguments ); 9833}; 9834 9835// -------------------------- placing -------------------------- // 9836 9837proto.enablePlacing = function() { 9838 this.removeTransitionStyles(); 9839 // remove transform property from transition 9840 if ( this.isTransitioning && transformProperty ) { 9841 this.element.style[ transformProperty ] = 'none'; 9842 } 9843 this.isTransitioning = false; 9844 this.getSize(); 9845 this.layout._setRectSize( this.element, this.rect ); 9846 this.isPlacing = true; 9847}; 9848 9849proto.disablePlacing = function() { 9850 this.isPlacing = false; 9851}; 9852 9853// ----- ----- // 9854 9855// remove element from DOM 9856proto.removeElem = function() { 9857 this.element.parentNode.removeChild( this.element ); 9858 // add space back to packer 9859 this.layout.packer.addSpace( this.rect ); 9860 this.emitEvent( 'remove', [ this ] ); 9861}; 9862 9863// ----- dropPlaceholder ----- // 9864 9865proto.showDropPlaceholder = function() { 9866 var dropPlaceholder = this.dropPlaceholder; 9867 if ( !dropPlaceholder ) { 9868 // create dropPlaceholder 9869 dropPlaceholder = this.dropPlaceholder = document.createElement('div'); 9870 dropPlaceholder.className = 'packery-drop-placeholder'; 9871 dropPlaceholder.style.position = 'absolute'; 9872 } 9873 9874 dropPlaceholder.style.width = this.size.width + 'px'; 9875 dropPlaceholder.style.height = this.size.height + 'px'; 9876 this.positionDropPlaceholder(); 9877 this.layout.element.appendChild( dropPlaceholder ); 9878}; 9879 9880proto.positionDropPlaceholder = function() { 9881 this.dropPlaceholder.style[ transformProperty ] = 'translate(' + 9882 this.rect.x + 'px, ' + this.rect.y + 'px)'; 9883}; 9884 9885proto.hideDropPlaceholder = function() { 9886 this.layout.element.removeChild( this.dropPlaceholder ); 9887}; 9888 9889// ----- ----- // 9890 9891return Item; 9892 9893})); 9894 9895/*! 9896 * Packery v2.0.0 9897 * Gapless, draggable grid layouts 9898 * 9899 * Licensed GPLv3 for open source use 9900 * or Packery Commercial License for commercial use 9901 * 9902 * http://packery.metafizzy.co 9903 * Copyright 2016 Metafizzy 9904 */ 9905 9906( function( window, factory ) { 9907 // universal module definition 9908 /* jshint strict: false */ /* globals define, module, require */ 9909 if ( typeof define == 'function' && define.amd ) { 9910 // AMD 9911 define( 'packery/js/packery',[ 9912 'get-size/get-size', 9913 'outlayer/outlayer', 9914 './rect', 9915 './packer', 9916 './item' 9917 ], 9918 factory ); 9919 } else if ( typeof module == 'object' && module.exports ) { 9920 // CommonJS 9921 module.exports = factory( 9922 require('get-size'), 9923 require('outlayer'), 9924 require('./rect'), 9925 require('./packer'), 9926 require('./item') 9927 ); 9928 } else { 9929 // browser global 9930 window.Packery = factory( 9931 window.getSize, 9932 window.Outlayer, 9933 window.Packery.Rect, 9934 window.Packery.Packer, 9935 window.Packery.Item 9936 ); 9937 } 9938 9939}( window, function factory( getSize, Outlayer, Rect, Packer, Item ) { 9940 9941 9942// ----- Rect ----- // 9943 9944// allow for pixel rounding errors IE8-IE11 & Firefox; #227 9945Rect.prototype.canFit = function( rect ) { 9946 return this.width >= rect.width - 1 && this.height >= rect.height - 1; 9947}; 9948 9949// -------------------------- Packery -------------------------- // 9950 9951// create an Outlayer layout class 9952var Packery = Outlayer.create('packery'); 9953Packery.Item = Item; 9954 9955var proto = Packery.prototype; 9956 9957proto._create = function() { 9958 // call super 9959 Outlayer.prototype._create.call( this ); 9960 9961 // initial properties 9962 this.packer = new Packer(); 9963 // packer for drop targets 9964 this.shiftPacker = new Packer(); 9965 this.isEnabled = true; 9966 9967 this.dragItemCount = 0; 9968 9969 // create drag handlers 9970 var _this = this; 9971 this.handleDraggabilly = { 9972 dragStart: function() { 9973 _this.itemDragStart( this.element ); 9974 }, 9975 dragMove: function() { 9976 _this.itemDragMove( this.element, this.position.x, this.position.y ); 9977 }, 9978 dragEnd: function() { 9979 _this.itemDragEnd( this.element ); 9980 } 9981 }; 9982 9983 this.handleUIDraggable = { 9984 start: function handleUIDraggableStart( event, ui ) { 9985 // HTML5 may trigger dragstart, dismiss HTML5 dragging 9986 if ( !ui ) { 9987 return; 9988 } 9989 _this.itemDragStart( event.currentTarget ); 9990 }, 9991 drag: function handleUIDraggableDrag( event, ui ) { 9992 if ( !ui ) { 9993 return; 9994 } 9995 _this.itemDragMove( event.currentTarget, ui.position.left, ui.position.top ); 9996 }, 9997 stop: function handleUIDraggableStop( event, ui ) { 9998 if ( !ui ) { 9999 return; 10000 } 10001 _this.itemDragEnd( event.currentTarget ); 10002 } 10003 }; 10004 10005}; 10006 10007 10008// ----- init & layout ----- // 10009 10010/** 10011 * logic before any new layout 10012 */ 10013proto._resetLayout = function() { 10014 this.getSize(); 10015 10016 this._getMeasurements(); 10017 10018 // reset packer 10019 var width, height, sortDirection; 10020 // packer settings, if horizontal or vertical 10021 if ( this._getOption('horizontal') ) { 10022 width = Infinity; 10023 height = this.size.innerHeight + this.gutter; 10024 sortDirection = 'rightwardTopToBottom'; 10025 } else { 10026 width = this.size.innerWidth + this.gutter; 10027 height = Infinity; 10028 sortDirection = 'downwardLeftToRight'; 10029 } 10030 10031 this.packer.width = this.shiftPacker.width = width; 10032 this.packer.height = this.shiftPacker.height = height; 10033 this.packer.sortDirection = this.shiftPacker.sortDirection = sortDirection; 10034 10035 this.packer.reset(); 10036 10037 // layout 10038 this.maxY = 0; 10039 this.maxX = 0; 10040}; 10041 10042/** 10043 * update columnWidth, rowHeight, & gutter 10044 * @private 10045 */ 10046proto._getMeasurements = function() { 10047 this._getMeasurement( 'columnWidth', 'width' ); 10048 this._getMeasurement( 'rowHeight', 'height' ); 10049 this._getMeasurement( 'gutter', 'width' ); 10050}; 10051 10052proto._getItemLayoutPosition = function( item ) { 10053 this._setRectSize( item.element, item.rect ); 10054 if ( this.isShifting || this.dragItemCount > 0 ) { 10055 var packMethod = this._getPackMethod(); 10056 this.packer[ packMethod ]( item.rect ); 10057 } else { 10058 this.packer.pack( item.rect ); 10059 } 10060 10061 this._setMaxXY( item.rect ); 10062 return item.rect; 10063}; 10064 10065proto.shiftLayout = function() { 10066 this.isShifting = true; 10067 this.layout(); 10068 delete this.isShifting; 10069}; 10070 10071proto._getPackMethod = function() { 10072 return this._getOption('horizontal') ? 'rowPack' : 'columnPack'; 10073}; 10074 10075 10076/** 10077 * set max X and Y value, for size of container 10078 * @param {Packery.Rect} rect 10079 * @private 10080 */ 10081proto._setMaxXY = function( rect ) { 10082 this.maxX = Math.max( rect.x + rect.width, this.maxX ); 10083 this.maxY = Math.max( rect.y + rect.height, this.maxY ); 10084}; 10085 10086/** 10087 * set the width and height of a rect, applying columnWidth and rowHeight 10088 * @param {Element} elem 10089 * @param {Packery.Rect} rect 10090 */ 10091proto._setRectSize = function( elem, rect ) { 10092 var size = getSize( elem ); 10093 var w = size.outerWidth; 10094 var h = size.outerHeight; 10095 // size for columnWidth and rowHeight, if available 10096 // only check if size is non-zero, #177 10097 if ( w || h ) { 10098 w = this._applyGridGutter( w, this.columnWidth ); 10099 h = this._applyGridGutter( h, this.rowHeight ); 10100 } 10101 // rect must fit in packer 10102 rect.width = Math.min( w, this.packer.width ); 10103 rect.height = Math.min( h, this.packer.height ); 10104}; 10105 10106/** 10107 * fits item to columnWidth/rowHeight and adds gutter 10108 * @param {Number} measurement - item width or height 10109 * @param {Number} gridSize - columnWidth or rowHeight 10110 * @returns measurement 10111 */ 10112proto._applyGridGutter = function( measurement, gridSize ) { 10113 // just add gutter if no gridSize 10114 if ( !gridSize ) { 10115 return measurement + this.gutter; 10116 } 10117 gridSize += this.gutter; 10118 // fit item to columnWidth/rowHeight 10119 var remainder = measurement % gridSize; 10120 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 10121 measurement = Math[ mathMethod ]( measurement / gridSize ) * gridSize; 10122 return measurement; 10123}; 10124 10125proto._getContainerSize = function() { 10126 if ( this._getOption('horizontal') ) { 10127 return { 10128 width: this.maxX - this.gutter 10129 }; 10130 } else { 10131 return { 10132 height: this.maxY - this.gutter 10133 }; 10134 } 10135}; 10136 10137 10138// -------------------------- stamp -------------------------- // 10139 10140/** 10141 * makes space for element 10142 * @param {Element} elem 10143 */ 10144proto._manageStamp = function( elem ) { 10145 10146 var item = this.getItem( elem ); 10147 var rect; 10148 if ( item && item.isPlacing ) { 10149 rect = item.rect; 10150 } else { 10151 var offset = this._getElementOffset( elem ); 10152 rect = new Rect({ 10153 x: this._getOption('originLeft') ? offset.left : offset.right, 10154 y: this._getOption('originTop') ? offset.top : offset.bottom 10155 }); 10156 } 10157 10158 this._setRectSize( elem, rect ); 10159 // save its space in the packer 10160 this.packer.placed( rect ); 10161 this._setMaxXY( rect ); 10162}; 10163 10164// -------------------------- methods -------------------------- // 10165 10166function verticalSorter( a, b ) { 10167 return a.position.y - b.position.y || a.position.x - b.position.x; 10168} 10169 10170function horizontalSorter( a, b ) { 10171 return a.position.x - b.position.x || a.position.y - b.position.y; 10172} 10173 10174proto.sortItemsByPosition = function() { 10175 var sorter = this._getOption('horizontal') ? horizontalSorter : verticalSorter; 10176 this.items.sort( sorter ); 10177}; 10178 10179/** 10180 * Fit item element in its current position 10181 * Packery will position elements around it 10182 * useful for expanding elements 10183 * 10184 * @param {Element} elem 10185 * @param {Number} x - horizontal destination position, optional 10186 * @param {Number} y - vertical destination position, optional 10187 */ 10188proto.fit = function( elem, x, y ) { 10189 var item = this.getItem( elem ); 10190 if ( !item ) { 10191 return; 10192 } 10193 10194 // stamp item to get it out of layout 10195 this.stamp( item.element ); 10196 // set placing flag 10197 item.enablePlacing(); 10198 this.updateShiftTargets( item ); 10199 // fall back to current position for fitting 10200 x = x === undefined ? item.rect.x: x; 10201 y = y === undefined ? item.rect.y: y; 10202 // position it best at its destination 10203 this.shift( item, x, y ); 10204 this._bindFitEvents( item ); 10205 item.moveTo( item.rect.x, item.rect.y ); 10206 // layout everything else 10207 this.shiftLayout(); 10208 // return back to regularly scheduled programming 10209 this.unstamp( item.element ); 10210 this.sortItemsByPosition(); 10211 item.disablePlacing(); 10212}; 10213 10214/** 10215 * emit event when item is fit and other items are laid out 10216 * @param {Packery.Item} item 10217 * @private 10218 */ 10219proto._bindFitEvents = function( item ) { 10220 var _this = this; 10221 var ticks = 0; 10222 function onLayout() { 10223 ticks++; 10224 if ( ticks != 2 ) { 10225 return; 10226 } 10227 _this.dispatchEvent( 'fitComplete', null, [ item ] ); 10228 } 10229 // when item is laid out 10230 item.once( 'layout', onLayout ); 10231 // when all items are laid out 10232 this.once( 'layoutComplete', onLayout ); 10233}; 10234 10235// -------------------------- resize -------------------------- // 10236 10237// debounced, layout on resize 10238proto.resize = function() { 10239 // don't trigger if size did not change 10240 // or if resize was unbound. See #285, outlayer#9 10241 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 10242 return; 10243 } 10244 10245 if ( this.options.shiftPercentResize ) { 10246 this.resizeShiftPercentLayout(); 10247 } else { 10248 this.layout(); 10249 } 10250}; 10251 10252/** 10253 * check if layout is needed post layout 10254 * @returns Boolean 10255 */ 10256proto.needsResizeLayout = function() { 10257 var size = getSize( this.element ); 10258 var innerSize = this._getOption('horizontal') ? 'innerHeight' : 'innerWidth'; 10259 return size[ innerSize ] != this.size[ innerSize ]; 10260}; 10261 10262proto.resizeShiftPercentLayout = function() { 10263 var items = this._getItemsForLayout( this.items ); 10264 10265 var isHorizontal = this._getOption('horizontal'); 10266 var coord = isHorizontal ? 'y' : 'x'; 10267 var measure = isHorizontal ? 'height' : 'width'; 10268 var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth'; 10269 var innerSize = isHorizontal ? 'innerHeight' : 'innerWidth'; 10270 10271 // proportional re-align items 10272 var previousSegment = this[ segmentName ]; 10273 previousSegment = previousSegment && previousSegment + this.gutter; 10274 10275 if ( previousSegment ) { 10276 this._getMeasurements(); 10277 var currentSegment = this[ segmentName ] + this.gutter; 10278 items.forEach( function( item ) { 10279 var seg = Math.round( item.rect[ coord ] / previousSegment ); 10280 item.rect[ coord ] = seg * currentSegment; 10281 }); 10282 } else { 10283 var currentSize = getSize( this.element )[ innerSize ] + this.gutter; 10284 var previousSize = this.packer[ measure ]; 10285 items.forEach( function( item ) { 10286 item.rect[ coord ] = ( item.rect[ coord ] / previousSize ) * currentSize; 10287 }); 10288 } 10289 10290 this.shiftLayout(); 10291}; 10292 10293// -------------------------- drag -------------------------- // 10294 10295/** 10296 * handle an item drag start event 10297 * @param {Element} elem 10298 */ 10299proto.itemDragStart = function( elem ) { 10300 if ( !this.isEnabled ) { 10301 return; 10302 } 10303 this.stamp( elem ); 10304 // this.ignore( elem ); 10305 var item = this.getItem( elem ); 10306 if ( !item ) { 10307 return; 10308 } 10309 10310 item.enablePlacing(); 10311 item.showDropPlaceholder(); 10312 this.dragItemCount++; 10313 this.updateShiftTargets( item ); 10314}; 10315 10316proto.updateShiftTargets = function( dropItem ) { 10317 this.shiftPacker.reset(); 10318 10319 // pack stamps 10320 this._getBoundingRect(); 10321 var isOriginLeft = this._getOption('originLeft'); 10322 var isOriginTop = this._getOption('originTop'); 10323 this.stamps.forEach( function( stamp ) { 10324 // ignore dragged item 10325 var item = this.getItem( stamp ); 10326 if ( item && item.isPlacing ) { 10327 return; 10328 } 10329 var offset = this._getElementOffset( stamp ); 10330 var rect = new Rect({ 10331 x: isOriginLeft ? offset.left : offset.right, 10332 y: isOriginTop ? offset.top : offset.bottom 10333 }); 10334 this._setRectSize( stamp, rect ); 10335 // save its space in the packer 10336 this.shiftPacker.placed( rect ); 10337 }, this ); 10338 10339 // reset shiftTargets 10340 var isHorizontal = this._getOption('horizontal'); 10341 var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth'; 10342 var measure = isHorizontal ? 'height' : 'width'; 10343 10344 this.shiftTargetKeys = []; 10345 this.shiftTargets = []; 10346 var boundsSize; 10347 var segment = this[ segmentName ]; 10348 segment = segment && segment + this.gutter; 10349 10350 if ( segment ) { 10351 var segmentSpan = Math.ceil( dropItem.rect[ measure ] / segment ); 10352 var segs = Math.floor( ( this.shiftPacker[ measure ] + this.gutter ) / segment ); 10353 boundsSize = ( segs - segmentSpan ) * segment; 10354 // add targets on top 10355 for ( var i=0; i < segs; i++ ) { 10356 this._addShiftTarget( i * segment, 0, boundsSize ); 10357 } 10358 } else { 10359 boundsSize = ( this.shiftPacker[ measure ] + this.gutter ) - dropItem.rect[ measure ]; 10360 this._addShiftTarget( 0, 0, boundsSize ); 10361 } 10362 10363 // pack each item to measure where shiftTargets are 10364 var items = this._getItemsForLayout( this.items ); 10365 var packMethod = this._getPackMethod(); 10366 items.forEach( function( item ) { 10367 var rect = item.rect; 10368 this._setRectSize( item.element, rect ); 10369 this.shiftPacker[ packMethod ]( rect ); 10370 10371 // add top left corner 10372 this._addShiftTarget( rect.x, rect.y, boundsSize ); 10373 // add bottom left / top right corner 10374 var cornerX = isHorizontal ? rect.x + rect.width : rect.x; 10375 var cornerY = isHorizontal ? rect.y : rect.y + rect.height; 10376 this._addShiftTarget( cornerX, cornerY, boundsSize ); 10377 10378 if ( segment ) { 10379 // add targets for each column on bottom / row on right 10380 var segSpan = Math.round( rect[ measure ] / segment ); 10381 for ( var i=1; i < segSpan; i++ ) { 10382 var segX = isHorizontal ? cornerX : rect.x + segment * i; 10383 var segY = isHorizontal ? rect.y + segment * i : cornerY; 10384 this._addShiftTarget( segX, segY, boundsSize ); 10385 } 10386 } 10387 }, this ); 10388 10389}; 10390 10391proto._addShiftTarget = function( x, y, boundsSize ) { 10392 var checkCoord = this._getOption('horizontal') ? y : x; 10393 if ( checkCoord !== 0 && checkCoord > boundsSize ) { 10394 return; 10395 } 10396 // create string for a key, easier to keep track of what targets 10397 var key = x + ',' + y; 10398 var hasKey = this.shiftTargetKeys.indexOf( key ) != -1; 10399 if ( hasKey ) { 10400 return; 10401 } 10402 this.shiftTargetKeys.push( key ); 10403 this.shiftTargets.push({ x: x, y: y }); 10404}; 10405 10406// -------------------------- drop -------------------------- // 10407 10408proto.shift = function( item, x, y ) { 10409 var shiftPosition; 10410 var minDistance = Infinity; 10411 var position = { x: x, y: y }; 10412 this.shiftTargets.forEach( function( target ) { 10413 var distance = getDistance( target, position ); 10414 if ( distance < minDistance ) { 10415 shiftPosition = target; 10416 minDistance = distance; 10417 } 10418 }); 10419 item.rect.x = shiftPosition.x; 10420 item.rect.y = shiftPosition.y; 10421}; 10422 10423function getDistance( a, b ) { 10424 var dx = b.x - a.x; 10425 var dy = b.y - a.y; 10426 return Math.sqrt( dx * dx + dy * dy ); 10427} 10428 10429// -------------------------- drag move -------------------------- // 10430 10431var DRAG_THROTTLE_TIME = 120; 10432 10433/** 10434 * handle an item drag move event 10435 * @param {Element} elem 10436 * @param {Number} x - horizontal change in position 10437 * @param {Number} y - vertical change in position 10438 */ 10439proto.itemDragMove = function( elem, x, y ) { 10440 var item = this.isEnabled && this.getItem( elem ); 10441 if ( !item ) { 10442 return; 10443 } 10444 10445 x -= this.size.paddingLeft; 10446 y -= this.size.paddingTop; 10447 10448 var _this = this; 10449 function onDrag() { 10450 _this.shift( item, x, y ); 10451 item.positionDropPlaceholder(); 10452 _this.layout(); 10453 } 10454 10455 // throttle 10456 var now = new Date(); 10457 if ( this._itemDragTime && now - this._itemDragTime < DRAG_THROTTLE_TIME ) { 10458 clearTimeout( this.dragTimeout ); 10459 this.dragTimeout = setTimeout( onDrag, DRAG_THROTTLE_TIME ); 10460 } else { 10461 onDrag(); 10462 this._itemDragTime = now; 10463 } 10464}; 10465 10466// -------------------------- drag end -------------------------- // 10467 10468/** 10469 * handle an item drag end event 10470 * @param {Element} elem 10471 */ 10472proto.itemDragEnd = function( elem ) { 10473 var item = this.isEnabled && this.getItem( elem ); 10474 if ( !item ) { 10475 return; 10476 } 10477 10478 clearTimeout( this.dragTimeout ); 10479 item.element.classList.add('is-positioning-post-drag'); 10480 10481 var completeCount = 0; 10482 var _this = this; 10483 function onDragEndLayoutComplete() { 10484 completeCount++; 10485 if ( completeCount != 2 ) { 10486 return; 10487 } 10488 // reset drag item 10489 item.element.classList.remove('is-positioning-post-drag'); 10490 item.hideDropPlaceholder(); 10491 _this.dispatchEvent( 'dragItemPositioned', null, [ item ] ); 10492 } 10493 10494 item.once( 'layout', onDragEndLayoutComplete ); 10495 this.once( 'layoutComplete', onDragEndLayoutComplete ); 10496 item.moveTo( item.rect.x, item.rect.y ); 10497 this.layout(); 10498 this.dragItemCount = Math.max( 0, this.dragItemCount - 1 ); 10499 this.sortItemsByPosition(); 10500 item.disablePlacing(); 10501 this.unstamp( item.element ); 10502}; 10503 10504/** 10505 * binds Draggabilly events 10506 * @param {Draggabilly} draggie 10507 */ 10508proto.bindDraggabillyEvents = function( draggie ) { 10509 this._bindDraggabillyEvents( draggie, 'on' ); 10510}; 10511 10512proto.unbindDraggabillyEvents = function( draggie ) { 10513 this._bindDraggabillyEvents( draggie, 'off' ); 10514}; 10515 10516proto._bindDraggabillyEvents = function( draggie, method ) { 10517 var handlers = this.handleDraggabilly; 10518 draggie[ method ]( 'dragStart', handlers.dragStart ); 10519 draggie[ method ]( 'dragMove', handlers.dragMove ); 10520 draggie[ method ]( 'dragEnd', handlers.dragEnd ); 10521}; 10522 10523/** 10524 * binds jQuery UI Draggable events 10525 * @param {jQuery} $elems 10526 */ 10527proto.bindUIDraggableEvents = function( $elems ) { 10528 this._bindUIDraggableEvents( $elems, 'on' ); 10529}; 10530 10531proto.unbindUIDraggableEvents = function( $elems ) { 10532 this._bindUIDraggableEvents( $elems, 'off' ); 10533}; 10534 10535proto._bindUIDraggableEvents = function( $elems, method ) { 10536 var handlers = this.handleUIDraggable; 10537 $elems 10538 [ method ]( 'dragstart', handlers.start ) 10539 [ method ]( 'drag', handlers.drag ) 10540 [ method ]( 'dragstop', handlers.stop ); 10541}; 10542 10543// ----- destroy ----- // 10544 10545var _destroy = proto.destroy; 10546proto.destroy = function() { 10547 _destroy.apply( this, arguments ); 10548 // disable flag; prevent drag events from triggering. #72 10549 this.isEnabled = false; 10550}; 10551 10552// ----- ----- // 10553 10554Packery.Rect = Rect; 10555Packery.Packer = Packer; 10556 10557return Packery; 10558 10559})); 10560 10561/*! 10562 * Packery layout mode v2.0.1 10563 * sub-classes Packery 10564 */ 10565 10566/*jshint browser: true, strict: true, undef: true, unused: true */ 10567 10568( function( window, factory ) {
10569 10570 // universal module definition 10571 if ( typeof define == 'function' && define.amd ) { 10572 // AMD 10573 define( [ 10574 'isotope-layout/js/layout-mode', 10575 'packery/js/packery' 10576 ], 10577 factory ); 10578 } else if ( typeof module == 'object' && module.exports ) { 10579 // CommonJS 10580 module.exports = factory( 10581 require('isotope-layout/js/layout-mode'), 10582 require('packery') 10583 ); 10584 } else { 10585 // browser global 10586 factory( 10587 window.Isotope.LayoutMode, 10588 window.Packery 10589 ); 10590 } 10591 10592}( window, function factor( LayoutMode, Packery ) { 10593 10594 10595 // create an Outlayer layout class 10596 var PackeryMode = LayoutMode.create('packery'); 10597 var proto = PackeryMode.prototype; 10598 10599 var keepModeMethods = { 10600 _getElementOffset: true, 10601 _getMeasurement: true 10602 }; 10603 10604 // inherit Packery prototype 10605 for ( var method in Packery.prototype ) { 10606 // do not inherit mode methods 10607 if ( !keepModeMethods[ method ] ) { 10608 proto[ method ] = Packery.prototype[ method ]; 10609 } 10610 } 10611 10612 // set packer in _resetLayout 10613 var _resetLayout = proto._resetLayout; 10614 proto._resetLayout = function() { 10615 this.packer = this.packer || new Packery.Packer(); 10616 this.shiftPacker = this.shiftPacker || new Packery.Packer(); 10617 _resetLayout.apply( this, arguments ); 10618 }; 10619 10620 var _getItemLayoutPosition = proto._getItemLayoutPosition; 10621 proto._getItemLayoutPosition = function( item ) { 10622 // set packery rect 10623 item.rect = item.rect || new Packery.Rect(); 10624 return _getItemLayoutPosition.call( this, item ); 10625 }; 10626 10627 // needsResizeLayout for vertical or horizontal 10628 var _needsResizeLayout = proto.needsResizeLayout; 10629 proto.needsResizeLayout = function() { 10630 if ( this._getOption('horizontal') ) { 10631 return this.needsVerticalResizeLayout(); 10632 } else { 10633 return _needsResizeLayout.call( this ); 10634 } 10635 }; 10636 10637 // point to mode options for horizontal 10638 var _getOption = proto._getOption; 10639 proto._getOption = function( option ) { 10640 if ( option == 'horizontal' ) { 10641 return this.options.isHorizontal !== undefined ? 10642 this.options.isHorizontal : this.options.horizontal; 10643 } 10644 return _getOption.apply( this.isotope, arguments ); 10645 }; 10646 10647 return PackeryMode; 10648 10649})); 10650 10651/*! 10652 * cellsByRows layout mode for Isotope 10653 * v1.1.3 10654 * http://isotope.metafizzy.co/layout-modes/cellsbyrow.html 10655 */ 10656 10657/*jshint browser: true, devel: false, strict: true, undef: true, unused: true */ 10658 10659( function( window, factory ) { 10660 // universal module definition 10661 /* jshint strict: false */ /*globals define, module, require */ 10662 if ( typeof define === 'function' && define.amd ) { 10663 // AMD 10664 define( [ 10665 'isotope/js/layout-mode' 10666 ], 10667 factory ); 10668 } else if ( typeof exports === 'object' ) { 10669 // CommonJS 10670 module.exports = factory( 10671 require('isotope-layout/js/layout-mode') 10672 ); 10673 } else { 10674 // browser global 10675 factory( 10676 window.Isotope.LayoutMode 10677 ); 10678 } 10679 10680}( window, function factory( LayoutMode ) { 10681 'use strict'; 10682 10683 var CellsByRow = LayoutMode.create( 'cellsByRow' ); 10684 var proto = CellsByRow.prototype; 10685 10686 proto._resetLayout = function() { 10687 // reset properties 10688 this.itemIndex = 0; 10689 // measurements 10690 this.getColumnWidth(); 10691 this.getRowHeight(); 10692 // set cols 10693 this.cols = Math.floor( this.isotope.size.innerWidth / this.columnWidth ); 10694 this.cols = Math.max( this.cols, 1 ); 10695 }; 10696 10697 proto._getItemLayoutPosition = function( item ) { 10698 item.getSize(); 10699 var col = this.itemIndex % this.cols; 10700 var row = Math.floor( this.itemIndex / this.cols ); 10701 // center item within cell 10702 var x = ( col + 0.5 ) * this.columnWidth - item.size.outerWidth / 2; 10703 var y = ( row + 0.5 ) * this.rowHeight - item.size.outerHeight / 2; 10704 this.itemIndex++; 10705 return { x: x, y: y }; 10706 }; 10707 10708 proto._getContainerSize = function() { 10709 return { 10710 height: Math.ceil( this.itemIndex / this.cols ) * this.rowHeight 10711 }; 10712 }; 10713 10714 return CellsByRow; 10715 10716})); 10717/*global jQuery: true */ 10718 10719/*! 10720 -------------------------------- 10721 Infinite Scroll 10722 -------------------------------- 10723 + https://github.com/paulirish/infinite-scroll 10724 + version 2.1.0 10725 + Copyright 2011/12 Paul Irish & Luke Shumard 10726 + Licensed under the MIT license 10727 10728 + Documentation: http://infinite-scroll.com/ 10729*/ 10730 10731// Uses AMD or browser globals to create a jQuery plugin. 10732(function (factory) { 10733 if (typeof define === 'function' && define.amd) { 10734 // AMD. Register as an anonymous module. 10735 define(['jquery'], factory); 10736 } else { 10737 // Browser globals 10738 factory(jQuery); 10739 } 10740}(function ($, undefined) { 10741 'use strict'; 10742
10743 $.infinitescroll = function infscr(options, callback, element) { 10744 this.element = $(element); 10745 10746 // Flag the object in the event of a failed creation 10747 if (!this._create(options, callback)) { 10748 this.failed = true; 10749 } 10750 }; 10751 10752 $.infinitescroll.defaults = { 10753 loading: { 10754 finished: undefined, 10755 finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>", 10756 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
10756MzExnbRvQ2Sy7vN0zvVtNfU2tLY3rPgLdnDvca4VQS/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
10756iqpQpZ4apwSwRtjqrB3muoF9BboaXKmshlqWqsWiGt2wphJkQbAU5hoCACH5BAUKABsALAcABADOAAsAAAX/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', 10757 msg: null, 10758 msgText: '<em>Loading the next set of posts...</em>', 10759 selector: null, 10760 speed: 'fast', 10761 start: undefined 10762 }, 10763 state: { 10764 isDuringAjax: false, 10765 isInvalidPage: false,
10766 isDestroyed: false, 10767 isDone: false, // For when it goes all the way through the archive. 10768 isPaused: false, 10769 isBeyondMaxPage: false, 10770 currPage: 1 10771 }, 10772 debug: false, 10773 behavior: undefined, 10774 binder: $(window), // used to cache the selector 10775 nextSelector: 'div.navigation a:first', 10776 navSelector: 'div.navigation', 10777 contentSelector: null, // rename to pageFragment 10778 extraScrollPx: 150, 10779 itemSelector: 'div.post', 10780 animate: false, 10781 pathParse: undefined, 10782 dataType: 'html', 10783 appendCallback: true, 10784 bufferPx: 40, 10785 errorCallback: function () { }, 10786 infid: 0, //Instance ID 10787 pixelsFromNavToBottom: undefined, 10788 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 10789 prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted 10790 maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work) 10791 }; 10792 10793 $.infinitescroll.prototype = { 10794 10795 /* 10796 ---------------------------- 10797 Private methods 10798 ---------------------------- 10799 */ 10800 10801 // Bind or unbind from scroll 10802 _binding: function infscr_binding(binding) { 10803 10804 var instance = this, 10805 opts = instance.options; 10806 10807 opts.v = '2.0b2.120520'; 10808 10809 // if behavior is defined and this function is extended, call that instead of default 10810 if (!!opts.behavior && this['_binding_' + opts.behavior] !== undefined) { 10811 this['_binding_' + opts.behavior].call(this); 10812 return; 10813 } 10814 10815 if (binding !== 'bind' && binding !== 'unbind') { 10816 this._debug('Binding value ' + binding + ' not valid'); 10817 return false; 10818 } 10819 10820 if (binding === 'unbind') { 10821 (this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid); 10822 } else { 10823 (this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () { 10824 instance.scroll(); 10825 }); 10826 } 10827 10828 this._debug('Binding', binding); 10829 }, 10830 10831 // Fundamental aspects of the plugin are initialized 10832 _create: function infscr_create(options, callback) { 10833 10834 // Add custom options to defaults 10835 var opts = $.extend(true, {}, $.infinitescroll.defaults, options); 10836 this.options = opts; 10837 var $window = $(window); 10838 var instance = this; 10839 10840 // Validate selectors 10841 if (!instance._validate(options)) { 10842 return false; 10843 } 10844 10845 // Validate page fragment path 10846 var path = $(opts.nextSelector).attr('href'); 10847 if (!path) { 10848 this._debug('Navigation selector not found'); 10849 return false; 10850 } 10851 10852 // Set the path to be a relative URL from root. 10853 opts.path = opts.path || this._determinepath(path); 10854 10855 // contentSelector is 'page fragment' option for .load() / .ajax() calls 10856 opts.contentSelector = opts.contentSelector || this.element; 10857 10858 // loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector 10859 opts.loading.selector = opts.loading.selector || opts.contentSelector; 10860 10861 // Define loading.msg 10862 opts.loading.msg = opts.loading.msg || $('<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>'); 10863 10864 // Preload loading.img 10865 (new Image()).src = opts.loading.img; 10866 10867 // distance from nav links to bottom 10868 // computed as: height of the document + top offset of container - top offset of nav link 10869 if (opts.pixelsFromNavToBottom === undefined) { 10870 opts.pixelsFromNavToBottom = $(document).height() - $(opts.navSelector).offset().top; 10871 this._debug('pixelsFromNavToBottom: ' + opts.pixelsFromNavToBottom); 10872 } 10873 10874 var self = this; 10875 10876 // determine loading.start actions 10877 opts.loading.start = opts.loading.start || function () { 10878 $(opts.navSelector).hide(); 10879 opts.loading.msg 10880 .appendTo(opts.loading.selector) 10881 .show(opts.loading.speed, $.proxy(function () { 10882 this.beginAjax(opts); 10883 }, self)); 10884 }; 10885 10886 // determine loading.finished actions 10887 opts.loading.finished = opts.loading.finished || function () { 10888 if (!opts.state.isBeyondMaxPage) 10889 opts.loading.msg.fadeOut(opts.loading.speed); 10890 }; 10891 10892 // callback loading 10893 opts.callback = function (instance, data, url) { 10894 if (!!opts.behavior && instance['_callback_' + opts.behavior] !== undefined) { 10895 instance['_callback_' + opts.behavior].call($(opts.contentSelector)[0], data, url); 10896 } 10897 10898 if (callback) { 10899 callback.call($(opts.contentSelector)[0], data, opts, url); 10900 } 10901 10902 if (opts.prefill) { 10903 $window.bind('resize.infinite-scroll', instance._prefill); 10904 } 10905 }; 10906 10907 if (options.debug) { 10908 // Tell IE9 to use its built-in console 10909 if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log === 'object') { 10910 ['log', 'info', 'warn', 'error', 'assert', 'dir', 'clear', 'profile', 'profileEnd'] 10911 .forEach(function (method) { 10912 console[method] = this.call(console[method], console); 10913 }, Function.prototype.bind); 10914 } 10915 } 10916 10917 this._setup(); 10918 10919 // Setups the prefill method for use 10920 if (opts.prefill) { 10921 this._prefill(); 10922 } 10923 10924 // Return true to indicate successful creation 10925 return true; 10926 }, 10927 10928 _prefill: function infscr_prefill() { 10929 var instance = this; 10930 var $window = $(window); 10931 10932 function needsPrefill() { 10933 return ($(instance.options.contentSelector).height() <= $window.height()); 10934 } 10935 10936 this._prefill = function () { 10937 if (needsPrefill()) { 10938 instance.scroll(); 10939 } 10940 10941 $window.bind('resize.infinite-scroll', function () { 10942 if (needsPrefill()) { 10943 $window.unbind('resize.infinite-scroll'); 10944 instance.scroll(); 10945 } 10946 }); 10947 }; 10948 10949 // Call self after setting up the new function 10950 this._prefill(); 10951 }, 10952 10953 // Console log wrapper 10954 _debug: function infscr_debug() { 10955 if (true !== this.options.debug) { 10956 return; 10957 } 10958 10959 if (typeof console !== 'undefined' && typeof console.log === 'function') { 10960 // Modern browsers 10961 // Single argument, which is a string 10962 if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') { 10963 console.log((Array.prototype.slice.call(arguments)).toString()); 10964 } else { 10965 console.log(Array.prototype.slice.call(arguments)); 10966 } 10967 } else if (!Function.prototype.bind && typeof console !== 'undefined' && typeof console.log === 'object') { 10968 // IE8 10969 Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments)); 10970 } 10971 }, 10972 10973 // find the number to increment in the path.
10974 _determinepath: function infscr_determinepath(path) { 10975 10976 var opts = this.options; 10977 10978 // if behavior is defined and this function is extended, call that instead of default 10979 if (!!opts.behavior && this['_determinepath_' + opts.behavior] !== undefined) { 10980 return this['_determinepath_' + opts.behavior].call(this, path); 10981 } 10982 10983 var url = new URL(path); 10984 var pathname = url.pathname; 10985 var hasNumber = /\d/.test(pathname); 10986 10987 if (!!opts.pathParse) { 10988 this._debug('pathParse manual'); 10989 return opts.pathParse(path, this.options.state.currPage + 1); 10990 } else if (hasNumber && path.match(/(\?|\&)(upage=)(\d+)/)) { 10991 var parts = path.split(/(\?|\&)(upage=)(\d+)/); 10992 return [parts[0] + parts[1] + parts[2], parts[4]]; 10993 } else if (path.match(/^(.*?)\b2\b(.*?$)/)) { 10994 path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1); 10995 10996 // if there is any 2 in the url at all. 10997 } else if (path.match(/^(.*?)2(.*?$)/)) { 10998 // page= is used in django: 10999 // http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127 11000 if (path.match(/^(.*?page=)2(\/.*|$)/)) { 11001 path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1); 11002 return path; 11003 } 11004 11005 path = path.match(/^(.*?)2(.*?$)/).slice(1); 11006 11007 } else { 11008 // page= is used in drupal too but second page is page=1 not page=2: 11009 // thx Jerod Fritz, vladikoff 11010 if (path.match(/^(.*?page=)1(\/.*|$)/)) { 11011 path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1); 11012 return path; 11013 } else { 11014 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."); 11015 // Get rid of isInvalidPage to allow permalink to state 11016 opts.state.isInvalidPage = true; //prevent it from running on this page. 11017 } 11018 } 11019 this._debug('determinePath', path); 11020 return path; 11021 11022 }, 11023 11024 // Custom error 11025 _error: function infscr_error(xhr) { 11026 11027 var opts = this.options; 11028 11029 // if behavior is defined and this function is extended, call that instead of default 11030 if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) { 11031 this['_error_'+opts.behavior].call(this,xhr); 11032 return; 11033 } 11034 11035 if (xhr !== 'destroy' && xhr !== 'end') { 11036 xhr = 'unknown'; 11037 } 11038 11039 this._debug('Error', xhr); 11040 11041 if (xhr === 'end' || opts.state.isBeyondMaxPage) { 11042 this._showdonemsg(); 11043 } 11044 11045 opts.state.isDone = true; 11046 opts.state.currPage = 1; // if you need to go back to this instance 11047 opts.state.isPaused = false; 11048 opts.state.isBeyondMaxPage = false; 11049 this._binding('unbind'); 11050 11051 }, 11052 11053 // Load Callback 11054 _loadcallback: function infscr_loadcallback(box, data, url) { 11055 var opts = this.options, 11056 callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK 11057 result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append', 11058 frag; 11059 11060 // if behavior is defined and this function is extended, call that instead of default 11061 if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) { 11062 this['_loadcallback_'+opts.behavior].call(this,box,data); 11063 return; 11064 } 11065 11066 switch (result) { 11067 case 'done': 11068 this._showdonemsg(); 11069 return false; 11070 11071 case 'no-append': 11072 if (opts.dataType === 'html') { 11073 data = '<div>' + data + '</div>'; 11074 data = $(data).find(opts.itemSelector); 11075 } 11076 11077 // if it didn't return anything 11078 if (data.length === 0) { 11079 return this._error('end'); 11080 } 11081 11082 break; 11083 11084 case 'append': 11085 var children = box.children(); 11086 // if it didn't return anything 11087 if (children.length === 0) { 11088 return this._error('end'); 11089 } 11090 11091 // use a documentFragment because it works when content is going into a table or UL 11092 frag = document.createDocumentFragment(); 11093 while (box[0].firstChild) { 11094 frag.appendChild(box[0].firstChild); 11095 } 11096 11097 this._debug('contentSelector', $(opts.contentSelector)[0]); 11098 $(opts.contentSelector)[0].appendChild(frag); 11099 // previously, we would pass in the new DOM element as context for the callback 11100 // however we're now using a documentfragment, which doesn't have parents or children, 11101 // so the context is the contentContainer guy, and we pass in an array 11102 // of the elements collected as the first argument. 11103 11104 data = children.get(); 11105 break; 11106 } 11107 11108 // loadingEnd function 11109 opts.loading.finished.call($(opts.contentSelector)[0],opts); 11110 11111 // smooth scroll to ease in the new content 11112 if (opts.animate) { 11113 var scrollTo = $(window).scrollTop() + $(opts.loading.msg).height() + opts.extraScrollPx + 'px'; 11114 $('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; }); 11115 } 11116 11117 if (!opts.animate) { 11118 // once the call is done, we can allow it again. 11119 opts.state.isDuringAjax = false;
11120 } 11121 11122 callback(this, data, url); 11123 11124 if (opts.prefill) { 11125 this._prefill(); 11126 } 11127 }, 11128 11129 _nearbottom: function infscr_nearbottom() { 11130 11131 var opts = this.options, 11132 pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height(); 11133 11134 // if behavior is defined and this function is extended, call that instead of default 11135 if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) { 11136 return this['_nearbottom_'+opts.behavior].call(this); 11137 } 11138 11139 this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom); 11140 11141 // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom.... 11142 return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom); 11143 11144 }, 11145 11146 // Pause / temporarily disable plugin from firing 11147 _pausing: function infscr_pausing(pause) { 11148 11149 var opts = this.options; 11150 11151 // if behavior is defined and this function is extended, call that instead of default 11152 if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) { 11153 this['_pausing_'+opts.behavior].call(this,pause); 11154 return; 11155 } 11156 11157 // If pause is not 'pause' or 'resume', toggle it's value 11158 if (pause !== 'pause' && pause !== 'resume' && pause !== null) { 11159 this._debug('Invalid argument. Toggling pause value instead'); 11160 } 11161 11162 pause = (pause && (pause === 'pause' || pause === 'resume')) ? pause : 'toggle'; 11163 11164 switch (pause) { 11165 case 'pause': 11166 opts.state.isPaused = true; 11167 break; 11168 11169 case 'resume': 11170 opts.state.isPaused = false; 11171 break; 11172 11173 case 'toggle': 11174 opts.state.isPaused = !opts.state.isPaused; 11175 break; 11176 } 11177 11178 this._debug('Paused', opts.state.isPaused); 11179 return false; 11180 11181 }, 11182 11183 // Behavior is determined 11184 // If the behavior option is undefined, it will set to default and bind to scroll 11185 _setup: function infscr_setup() { 11186 11187 var opts = this.options; 11188 11189 // if behavior is defined and this function is extended, call that instead of default 11190 if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) { 11191 this['_setup_'+opts.behavior].call(this); 11192 return; 11193 } 11194 11195 this._binding('bind'); 11196 11197 return false; 11198 11199 }, 11200 11201 // Show done message 11202 _showdonemsg: function infscr_showdonemsg() { 11203 11204 var opts = this.options; 11205 11206 // if behavior is defined and this function is extended, call that instead of default 11207 if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) { 11208 this['_showdonemsg_'+opts.behavior].call(this); 11209 return; 11210 } 11211 11212 opts.loading.msg 11213 .find('img') 11214 .hide() 11215 .parent() 11216 .find('div').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () { 11217 $(this).parent().fadeOut(opts.loading.speed); 11218 }); 11219 11220 // user provided callback when done 11221 opts.errorCallback.call($(opts.contentSelector)[0],'done'); 11222 }, 11223 11224 // grab each selector option and see if any fail 11225 _validate: function infscr_validate(opts) { 11226 for (var key in opts) { 11227 if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) { 11228 this._debug('Your ' + key + ' found no elements.'); 11229 return false; 11230 } 11231 } 11232 11233 return true; 11234 }, 11235 11236 /* 11237 ---------------------------- 11238 Public methods 11239 ---------------------------- 11240 */ 11241 11242 // Bind to scroll 11243 bind: function infscr_bind() { 11244 this._binding('bind'); 11245 }, 11246 11247 // Destroy current instance of plugin 11248 destroy: function infscr_destroy() { 11249 this.options.state.isDestroyed = true; 11250 this.options.loading.finished(); 11251 return this._error('destroy'); 11252 }, 11253 11254 // Set pause value to false 11255 pause: function infscr_pause() { 11256 this._pausing('pause'); 11257 }, 11258 11259 // Set pause value to false 11260 resume: function infscr_resume() { 11261 this._pausing('resume'); 11262 }, 11263 11264 beginAjax: function infscr_ajax(opts) { 11265 var instance = this, 11266 path = opts.path, 11267 box, desturl, method, condition; 11268 11269 // increment the URL bit. e.g. /page/3/ 11270 opts.state.currPage++; 11271 11272 // Manually control maximum page 11273 if ( opts.maxPage !== undefined && opts.state.currPage > opts.maxPage ){ 11274 opts.state.isBeyondMaxPage = true; 11275 this.destroy(); 11276 return; 11277 } 11278 11279 // if we're dealing with a table we can't use DIVs 11280 box = $(opts.contentSelector).is('table, tbody') ? $('<tbody/>') : $('<div/>'); 11281 11282 desturl = (typeof path === 'function') ? path(opts.state.currPage) : path.join(opts.state.currPage); 11283 11284 instance._debug('heading into ajax', desturl); 11285 11286 method = (opts.dataType === 'html' || opts.dataType === 'json' ) ? opts.dataType : 'html+callback'; 11287 if (opts.appendCallback && opts.dataType === 'html') { 11288 method += '+callback'; 11289 } 11290 11291 switch (method) { 11292 case 'html+callback': 11293 instance._debug('Using HTML via .load() method'); 11294 box.load(desturl + ' ' + opts.itemSelector, undefined, function infscr_ajax_callback(responseText) { 11295 instance._loadcallback(box, responseText, desturl); 11296 }); 11297 11298 break; 11299 11300 case 'html': 11301 instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); 11302 $.ajax({ 11303 // params 11304 url: desturl, 11305 dataType: opts.dataType, 11306 complete: function infscr_ajax_callback(jqXHR, textStatus) { 11307 condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified'); 11308 if (condition) { 11309 instance._loadcallback(box, jqXHR.responseText, desturl); 11310 } else { 11311 instance._error('end'); 11312 } 11313 } 11314 }); 11315 11316 break; 11317 case 'json': 11318 instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); 11319 $.ajax({ 11320 dataType: 'json', 11321 type: 'GET', 11322 url: desturl, 11323 success: function (data, textStatus, jqXHR) { 11324 condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified'); 11325 if (opts.appendCallback) { 11326 // if appendCallback is true, you must defined template in options. 11327 // note that data passed into _loadcallback is already an html (after processed in opts.template(data)). 11328 if (opts.template !== undefined) { 11329 var theData = opts.template(data); 11330 box.append(theData); 11331 if (condition) { 11332 instance._loadcallback(box, theData); 11333 } else { 11334 instance._error('end'); 11335 } 11336 } else { 11337 instance._debug('template must be defined.'); 11338 instance._error('end'); 11339 } 11340 } else { 11341 // if appendCallback is false, we will pass in the JSON object. you should handle it yourself in your callback. 11342 if (condition) { 11343 instance._loadcallback(box, data, desturl); 11344 } else { 11345 instance._error('end'); 11346 } 11347 } 11348 }, 11349 error: function() { 11350 instance._debug('JSON ajax request failed.'); 11351 instance._error('end'); 11352 } 11353 }); 11354 11355 break; 11356 } 11357 }, 11358 11359 // Retrieve next set of content items 11360 retrieve: function infscr_retrieve(pageNum) { 11361 pageNum = pageNum || null; 11362 11363 var instance = this, 11364 opts = instance.options; 11365 11366 // if behavior is defined and this function is extended, call that instead of default 11367 if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) { 11368 this['retrieve_'+opts.behavior].call(this,pageNum); 11369 return; 11370 } 11371 11372 // for manual triggers, if destroyed, get out of here 11373 if (opts.state.isDestroyed) { 11374 this._debug('Instance is destroyed'); 11375 return false;
11376 } 11377 11378 // we dont want to fire the ajax multiple times 11379 opts.state.isDuringAjax = true; 11380 11381 opts.loading.start.call($(opts.contentSelector)[0],opts); 11382 }, 11383 11384 // Check to see next page is needed 11385 scroll: function infscr_scroll() { 11386 11387 var opts = this.options, 11388 state = opts.state; 11389 11390 // if behavior is defined and this function is extended, call that instead of default 11391 if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) { 11392 this['scroll_'+opts.behavior].call(this); 11393 return; 11394 } 11395 11396 if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) { 11397 return; 11398 } 11399 11400 if (!this._nearbottom()) { 11401 return; 11402 } 11403 11404 this.retrieve(); 11405 11406 }, 11407 11408 // Toggle pause value 11409 toggle: function infscr_toggle() { 11410 this._pausing(); 11411 }, 11412 11413 // Unbind from scroll 11414 unbind: function infscr_unbind() { 11415 this._binding('unbind'); 11416 }, 11417 11418 // update options 11419 update: function infscr_options(key) { 11420 if ($.isPlainObject(key)) { 11421 this.options = $.extend(true,this.options,key); 11422 } 11423 } 11424 }; 11425 11426 11427 /* 11428 ---------------------------- 11429 Infinite Scroll function 11430 ---------------------------- 11431 11432 Borrowed logic from the following... 11433 11434 jQuery UI 11435 - https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js 11436 11437 jCarousel 11438 - https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js 11439 11440 Masonry 11441 - https://github.com/desandro/masonry/blob/master/jquery.masonry.js 11442 11443*/ 11444 11445 $.fn.infinitescroll = function infscr_init(options, callback) { 11446 11447 11448 var thisCall = typeof options; 11449 11450 switch (thisCall) { 11451 11452 // method 11453 case 'string': 11454 var args = Array.prototype.slice.call(arguments, 1); 11455 11456 this.each(function () { 11457 var instance = $.data(this, 'infinitescroll'); 11458 11459 if (!instance) { 11460 // not setup yet 11461 // return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup'); 11462 return false; 11463 } 11464 11465 if (!$.isFunction(instance[options]) || options.charAt(0) === '_') { 11466 // return $.error('No such method ' + options + ' for Infinite Scroll'); 11467 return false; 11468 } 11469 11470 // no errors! 11471 instance[options].apply(instance, args); 11472 }); 11473 11474 break; 11475 11476 // creation 11477 case 'object': 11478 11479 this.each(function () { 11480 11481 var instance = $.data(this, 'infinitescroll'); 11482 11483 if (instance) { 11484 11485 // update options of current instance 11486 instance.update(options); 11487 11488 } else { 11489 11490 // initialize new instance 11491 instance = new $.infinitescroll(options, callback, this); 11492 11493 // don't attach if instantiation failed 11494 if (!instance.failed) { 11495 $.data(this, 'infinitescroll', instance); 11496 } 11497 11498 } 11499 11500 }); 11501 11502 break; 11503 11504 } 11505 11506 return this; 11507 }; 11508 11509 11510 11511 /* 11512 * smartscroll: debounced scroll event for jQuery * 11513 * https://github.com/lukeshumard/smartscroll 11514 * Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js * 11515 * Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. * 11516 */ 11517 11518 var event = $.event, 11519 scrollTimeout; 11520 11521 event.special.smartscroll = { 11522 setup: function () { 11523 $(this).bind('scroll', event.special.smartscroll.handler); 11524 }, 11525 teardown: function () { 11526 $(this).unbind('scroll', event.special.smartscroll.handler); 11527 }, 11528 handler: function (event, execAsap) { 11529 // Save the context 11530 var context = this, 11531 args = arguments; 11532 11533 // set correct event type 11534 event.type = 'smartscroll'; 11535 11536 if (scrollTimeout) { clearTimeout(scrollTimeout); } 11537 scrollTimeout = setTimeout(function () { 11538 $(context).trigger('smartscroll', args); 11539 }, execAsap === 'execAsap' ? 0 : 100); 11540 } 11541 }; 11542 11543 $.fn.smartscroll = function (fn) {
11544 return fn ? this.bind('smartscroll', fn) : this.trigger('smartscroll', ['execAsap']); 11545 }; 11546 11547})); 11548 11549/*! 11550Waypoints - 4.0.1 11551Copyright © 2011-2016 Caleb Troughton 11552Licensed under the MIT license. 11553https://github.com/imakewebthings/waypoints/blob/master/licenses.txt 11554*/ 11555(function() { 11556 'use strict' 11557 11558 var keyCounter = 0 11559 var allWaypoints = {} 11560 11561 /* http://imakewebthings.com/waypoints/api/waypoint */ 11562 function Waypoint(options) { 11563 if (!options) { 11564 throw new Error('No options passed to Waypoint constructor') 11565 } 11566 if (!options.element) { 11567 throw new Error('No element option passed to Waypoint constructor') 11568 } 11569 if (!options.handler) { 11570 throw new Error('No handler option passed to Waypoint constructor') 11571 } 11572 11573 this.key = 'waypoint-' + keyCounter 11574 this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options) 11575 this.element = this.options.element 11576 this.adapter = new Waypoint.Adapter(this.element) 11577 this.callback = options.handler 11578 this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 11579 this.enabled = this.options.enabled 11580 this.triggerPoint = null 11581 this.group = Waypoint.Group.findOrCreate({ 11582 name: this.options.group, 11583 axis: this.axis 11584 }) 11585 this.context = Waypoint.Context.findOrCreateByElement(this.options.context) 11586 11587 if (Waypoint.offsetAliases[this.options.offset]) { 11588 this.options.offset = Waypoint.offsetAliases[this.options.offset] 11589 } 11590 this.group.add(this) 11591 this.context.add(this) 11592 allWaypoints[this.key] = this 11593 keyCounter += 1 11594 } 11595 11596 /* Private */ 11597 Waypoint.prototype.queueTrigger = function(direction) { 11598 this.group.queueTrigger(this, direction) 11599 } 11600 11601 /* Private */ 11602 Waypoint.prototype.trigger = function(args) { 11603 if (!this.enabled) { 11604 return 11605 } 11606 if (this.callback) { 11607 this.callback.apply(this, args) 11608 } 11609 } 11610 11611 /* Public */ 11612 /* http://imakewebthings.com/waypoints/api/destroy */ 11613 Waypoint.prototype.destroy = function() { 11614 this.context.remove(this) 11615 this.group.remove(this) 11616 delete allWaypoints[this.key] 11617 } 11618 11619 /* Public */ 11620 /* http://imakewebthings.com/waypoints/api/disable */ 11621 Waypoint.prototype.disable = function() { 11622 this.enabled = false 11623 return this 11624 } 11625 11626 /* Public */ 11627 /* http://imakewebthings.com/waypoints/api/enable */ 11628 Waypoint.prototype.enable = function() { 11629 this.context.refresh() 11630 this.enabled = true 11631 return this 11632 } 11633 11634 /* Public */ 11635 /* http://imakewebthings.com/waypoints/api/next */ 11636 Waypoint.prototype.next = function() { 11637 return this.group.next(this) 11638 } 11639 11640 /* Public */ 11641 /* http://imakewebthings.com/waypoints/api/previous */ 11642 Waypoint.prototype.previous = function() { 11643 return this.group.previous(this) 11644 } 11645 11646 /* Private */ 11647 Waypoint.invokeAll = function(method) { 11648 var allWaypointsArray = []
11649 for (var waypointKey in allWaypoints) { 11650 allWaypointsArray.push(allWaypoints[waypointKey]) 11651 } 11652 for (var i = 0, end = allWaypointsArray.length; i < end; i++) { 11653 allWaypointsArray[i][method]() 11654 } 11655 } 11656 11657 /* Public */ 11658 /* http://imakewebthings.com/waypoints/api/destroy-all */ 11659 Waypoint.destroyAll = function() { 11660 Waypoint.invokeAll('destroy') 11661 } 11662 11663 /* Public */ 11664 /* http://imakewebthings.com/waypoints/api/disable-all */ 11665 Waypoint.disableAll = function() { 11666 Waypoint.invokeAll('disable') 11667 } 11668 11669 /* Public */ 11670 /* http://imakewebthings.com/waypoints/api/enable-all */ 11671 Waypoint.enableAll = function() { 11672 Waypoint.Context.refreshAll() 11673 for (var waypointKey in allWaypoints) { 11674 allWaypoints[waypointKey].enabled = true 11675 } 11676 return this 11677 } 11678 11679 /* Public */ 11680 /* http://imakewebthings.com/waypoints/api/refresh-all */ 11681 Waypoint.refreshAll = function() { 11682 Waypoint.Context.refreshAll() 11683 } 11684 11685 /* Public */ 11686 /* http://imakewebthings.com/waypoints/api/viewport-height */ 11687 Waypoint.viewportHeight = function() { 11688 return window.innerHeight || document.documentElement.clientHeight 11689 } 11690 11691 /* Public */ 11692 /* http://imakewebthings.com/waypoints/api/viewport-width */ 11693 Waypoint.viewportWidth = function() { 11694 return document.documentElement.clientWidth 11695 } 11696 11697 Waypoint.adapters = [] 11698 11699 Waypoint.defaults = { 11700 context: window, 11701 continuous: true, 11702 enabled: true, 11703 group: 'default', 11704 horizontal: false, 11705 offset: 0 11706 } 11707 11708 Waypoint.offsetAliases = { 11709 'bottom-in-view': function() { 11710 return this.context.innerHeight() - this.adapter.outerHeight() 11711 }, 11712 'right-in-view': function() { 11713 return this.context.innerWidth() - this.adapter.outerWidth() 11714 } 11715 } 11716 11717 window.Waypoint = Waypoint 11718}()) 11719;(function() { 11720 'use strict' 11721 11722 function requestAnimationFrameShim(callback) { 11723 window.setTimeout(callback, 1000 / 60) 11724 } 11725 11726 var keyCounter = 0 11727 var contexts = {} 11728 var Waypoint = window.Waypoint 11729 var oldWindowLoad = window.onload 11730 11731 /* http://imakewebthings.com/waypoints/api/context */ 11732 function Context(element) { 11733 this.element = element 11734 this.Adapter = Waypoint.Adapter 11735 this.adapter = new this.Adapter(element) 11736 this.key = 'waypoint-context-' + keyCounter 11737 this.didScroll = false 11738 this.didResize = false 11739 this.oldScroll = { 11740 x: this.adapter.scrollLeft(), 11741 y: this.adapter.scrollTop() 11742 } 11743 this.waypoints = { 11744 vertical: {}, 11745 horizontal: {} 11746 } 11747 11748 element.waypointContextKey = this.key 11749 contexts[element.waypointContextKey] = this 11750 keyCounter += 1 11751 if (!Waypoint.windowContext) { 11752 Waypoint.windowContext = true 11753 Waypoint.windowContext = new Context(window) 11754 } 11755 11756 this.createThrottledScrollHandler() 11757 this.createThrottledResizeHandler() 11758 } 11759 11760 /* Private */ 11761 Context.prototype.add = function(waypoint) { 11762 var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical' 11763 this.waypoints[axis][waypoint.key] = waypoint 11764 this.refresh() 11765 } 11766 11767 /* Private */ 11768 Context.prototype.checkEmpty = function() { 11769 var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal) 11770 var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical) 11771 var isWindow = this.element == this.element.window 11772 if (horizontalEmpty && verticalEmpty && !isWindow) { 11773 this.adapter.off('.waypoints') 11774 delete contexts[this.key] 11775 } 11776 } 11777 11778 /* Private */ 11779 Context.prototype.createThrottledResizeHandler = function() { 11780 var self = this 11781 11782 function resizeHandler() { 11783 self.handleResize() 11784 self.didResize = false 11785 } 11786 11787 this.adapter.on('resize.waypoints', function() { 11788 if (!self.didResize) { 11789 self.didResize = true 11790 Waypoint.requestAnimationFrame(resizeHandler) 11791 } 11792 }) 11793 } 11794 11795 /* Private */ 11796 Context.prototype.createThrottledScrollHandler = function() { 11797 var self = this 11798 function scrollHandler() { 11799 self.handleScroll() 11800 self.didScroll = false 11801 } 11802 11803 this.adapter.on('scroll.waypoints', function() { 11804 if (!self.didScroll || Waypoint.isTouch) { 11805 self.didScroll = true 11806 Waypoint.requestAnimationFrame(scrollHandler) 11807 } 11808 }) 11809 } 11810 11811 /* Private */ 11812 Context.prototype.handleResize = function() { 11813 Waypoint.Context.refreshAll() 11814 } 11815 11816 /* Private */ 11817 Context.prototype.handleScroll = function() { 11818 var triggeredGroups = {} 11819 var axes = { 11820 horizontal: { 11821 newScroll: this.adapter.scrollLeft(), 11822 oldScroll: this.oldScroll.x, 11823 forward: 'right', 11824 backward: 'left' 11825 }, 11826 vertical: { 11827 newScroll: this.adapter.scrollTop(), 11828 oldScroll: this.oldScroll.y, 11829 forward: 'down', 11830 backward: 'up' 11831 } 11832 } 11833 11834 for (var axisKey in axes) { 11835 var axis = axes[axisKey] 11836 var isForward = axis.newScroll > axis.oldScroll 11837 var direction = isForward ? axis.forward : axis.backward 11838
11839 for (var waypointKey in this.waypoints[axisKey]) { 11840 var waypoint = this.waypoints[axisKey][waypointKey] 11841 if (waypoint.triggerPoint === null) { 11842 continue 11843 } 11844 var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint 11845 var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint 11846 var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint 11847 var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint 11848 if (crossedForward || crossedBackward) { 11849 waypoint.queueTrigger(direction) 11850 triggeredGroups[waypoint.group.id] = waypoint.group 11851 } 11852 } 11853 } 11854 11855 for (var groupKey in triggeredGroups) { 11856 triggeredGroups[groupKey].flushTriggers() 11857 } 11858 11859 this.oldScroll = { 11860 x: axes.horizontal.newScroll, 11861 y: axes.vertical.newScroll 11862 } 11863 } 11864 11865 /* Private */ 11866 Context.prototype.innerHeight = function() { 11867 /*eslint-disable eqeqeq */ 11868 if (this.element == this.element.window) { 11869 return Waypoint.viewportHeight() 11870 } 11871 /*eslint-enable eqeqeq */ 11872 return this.adapter.innerHeight() 11873 } 11874 11875 /* Private */ 11876 Context.prototype.remove = function(waypoint) { 11877 delete this.waypoints[waypoint.axis][waypoint.key] 11878 this.checkEmpty() 11879 } 11880 11881 /* Private */ 11882 Context.prototype.innerWidth = function() { 11883 /*eslint-disable eqeqeq */ 11884 if (this.element == this.element.window) { 11885 return Waypoint.viewportWidth() 11886 } 11887 /*eslint-enable eqeqeq */ 11888 return this.adapter.innerWidth() 11889 } 11890 11891 /* Public */ 11892 /* http://imakewebthings.com/waypoints/api/context-destroy */ 11893 Context.prototype.destroy = function() { 11894 var allWaypoints = [] 11895 for (var axis in this.waypoints) {
11896 for (var waypointKey in this.waypoints[axis]) { 11897 allWaypoints.push(this.waypoints[axis][waypointKey]) 11898 } 11899 } 11900 for (var i = 0, end = allWaypoints.length; i < end; i++) { 11901 allWaypoints[i].destroy() 11902 } 11903 } 11904 11905 /* Public */ 11906 /* http://imakewebthings.com/waypoints/api/context-refresh */ 11907 Context.prototype.refresh = function() { 11908 /*eslint-disable eqeqeq */ 11909 var isWindow = this.element == this.element.window 11910 /*eslint-enable eqeqeq */ 11911 var contextOffset = isWindow ? undefined : this.adapter.offset() 11912 var triggeredGroups = {} 11913 var axes 11914 11915 this.handleScroll() 11916 axes = { 11917 horizontal: { 11918 contextOffset: isWindow ? 0 : contextOffset.left, 11919 contextScroll: isWindow ? 0 : this.oldScroll.x, 11920 contextDimension: this.innerWidth(), 11921 oldScroll: this.oldScroll.x, 11922 forward: 'right', 11923 backward: 'left', 11924 offsetProp: 'left' 11925 }, 11926 vertical: { 11927 contextOffset: isWindow ? 0 : contextOffset.top, 11928 contextScroll: isWindow ? 0 : this.oldScroll.y, 11929 contextDimension: this.innerHeight(), 11930 oldScroll: this.oldScroll.y, 11931 forward: 'down', 11932 backward: 'up', 11933 offsetProp: 'top' 11934 } 11935 } 11936 11937 for (var axisKey in axes) { 11938 var axis = axes[axisKey]
11939 for (var waypointKey in this.waypoints[axisKey]) { 11940 var waypoint = this.waypoints[axisKey][waypointKey] 11941 var adjustment = waypoint.options.offset 11942 var oldTriggerPoint = waypoint.triggerPoint 11943 var elementOffset = 0 11944 var freshWaypoint = oldTriggerPoint == null 11945 var contextModifier, wasBeforeScroll, nowAfterScroll 11946 var triggeredBackward, triggeredForward 11947 11948 if (waypoint.element !== waypoint.element.window) { 11949 elementOffset = waypoint.adapter.offset()[axis.offsetProp] 11950 } 11951 11952 if (typeof adjustment === 'function') { 11953 adjustment = adjustment.apply(waypoint) 11954 } 11955 else if (typeof adjustment === 'string') { 11956 adjustment = parseFloat(adjustment) 11957 if (waypoint.options.offset.indexOf('%') > - 1) { 11958 adjustment = Math.ceil(axis.contextDimension * adjustment / 100) 11959 } 11960 } 11961 11962 contextModifier = axis.contextScroll - axis.contextOffset 11963 waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment) 11964 wasBeforeScroll = oldTriggerPoint < axis.oldScroll 11965 nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll 11966 triggeredBackward = wasBeforeScroll && nowAfterScroll 11967 triggeredForward = !wasBeforeScroll && !nowAfterScroll 11968 11969 if (!freshWaypoint && triggeredBackward) { 11970 waypoint.queueTrigger(axis.backward) 11971 triggeredGroups[waypoint.group.id] = waypoint.group 11972 } 11973 else if (!freshWaypoint && triggeredForward) { 11974 waypoint.queueTrigger(axis.forward) 11975 triggeredGroups[waypoint.group.id] = waypoint.group 11976 } 11977 else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) { 11978 waypoint.queueTrigger(axis.forward) 11979 triggeredGroups[waypoint.group.id] = waypoint.group 11980 } 11981 } 11982 } 11983 11984 Waypoint.requestAnimationFrame(function() { 11985 for (var groupKey in triggeredGroups) { 11986 triggeredGroups[groupKey].flushTriggers() 11987 } 11988 }) 11989 11990 return this 11991 } 11992 11993 /* Private */ 11994 Context.findOrCreateByElement = function(element) { 11995 return Context.findByElement(element) || new Context(element) 11996 } 11997 11998 /* Private */ 11999 Context.refreshAll = function() { 12000 for (var contextId in contexts) { 12001 contexts[contextId].refresh() 12002 } 12003 } 12004 12005 /* Public */ 12006 /* http://imakewebthings.com/waypoints/api/context-find-by-element */ 12007 Context.findByElement = function(element) { 12008 return contexts[element.waypointContextKey] 12009 } 12010 12011 window.onload = function() { 12012 if (oldWindowLoad) { 12013 oldWindowLoad() 12014 } 12015 Context.refreshAll() 12016 } 12017 12018 12019 Waypoint.requestAnimationFrame = function(callback) { 12020 var requestFn = window.requestAnimationFrame || 12021 window.mozRequestAnimationFrame || 12022 window.webkitRequestAnimationFrame || 12023 requestAnimationFrameShim 12024 requestFn.call(window, callback) 12025 } 12026 Waypoint.Context = Context 12027}()) 12028;(function() { 12029 'use strict' 12030 12031 function byTriggerPoint(a, b) { 12032 return a.triggerPoint - b.triggerPoint 12033 } 12034 12035 function byReverseTriggerPoint(a, b) { 12036 return b.triggerPoint - a.triggerPoint 12037 } 12038 12039 var groups = { 12040 vertical: {}, 12041 horizontal: {} 12042 } 12043 var Waypoint = window.Waypoint 12044 12045 /* http://imakewebthings.com/waypoints/api/group */ 12046 function Group(options) { 12047 this.name = options.name 12048 this.axis = options.axis 12049 this.id = this.name + '-' + this.axis 12050 this.waypoints = [] 12051 this.clearTriggerQueues() 12052 groups[this.axis][this.name] = this 12053 } 12054 12055 /* Private */ 12056 Group.prototype.add = function(waypoint) { 12057 this.waypoints.push(waypoint) 12058 } 12059 12060 /* Private */ 12061 Group.prototype.clearTriggerQueues = function() { 12062 this.triggerQueues = { 12063 up: [], 12064 down: [], 12065 left: [], 12066 right: [] 12067 } 12068 } 12069 12070 /* Private */ 12071 Group.prototype.flushTriggers = function() { 12072 for (var direction in this.triggerQueues) { 12073 var waypoints = this.triggerQueues[direction] 12074 var reverse = direction === 'up' || direction === 'left' 12075 waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint) 12076 for (var i = 0, end = waypoints.length; i < end; i += 1) { 12077 var waypoint = waypoints[i] 12078 if (waypoint.options.continuous || i === waypoints.length - 1) { 12079 waypoint.trigger([direction]) 12080 } 12081 } 12082 } 12083 this.clearTriggerQueues() 12084 } 12085 12086 /* Private */ 12087 Group.prototype.next = function(waypoint) { 12088 this.waypoints.sort(byTriggerPoint) 12089 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 12090 var isLast = index === this.waypoints.length - 1 12091 return isLast ? null : this.waypoints[index + 1] 12092 } 12093 12094 /* Private */ 12095 Group.prototype.previous = function(waypoint) { 12096 this.waypoints.sort(byTriggerPoint) 12097 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 12098 return index ? this.waypoints[index - 1] : null 12099 } 12100 12101 /* Private */ 12102 Group.prototype.queueTrigger = function(waypoint, direction) { 12103 this.triggerQueues[direction].push(waypoint) 12104 } 12105 12106 /* Private */ 12107 Group.prototype.remove = function(waypoint) { 12108 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 12109 if (index > -1) { 12110 this.waypoints.splice(index, 1) 12111 } 12112 } 12113 12114 /* Public */ 12115 /* http://imakewebthings.com/waypoints/api/first */ 12116 Group.prototype.first = function() { 12117 return this.waypoints[0] 12118 } 12119 12120 /* Public */ 12121 /* http://imakewebthings.com/waypoints/api/last */ 12122 Group.prototype.last = function() { 12123 return this.waypoints[this.waypoints.length - 1] 12124 } 12125 12126 /* Private */ 12127 Group.findOrCreate = function(options) { 12128 return groups[options.axis][options.name] || new Group(options) 12129 } 12130 12131 Waypoint.Group = Group 12132}()) 12133;(function() { 12134 'use strict' 12135 12136 var $ = window.jQuery 12137 var Waypoint = window.Waypoint 12138 12139 function JQueryAdapter(element) { 12140 this.$element = $(element) 12141 } 12142 12143 $.each([
12144 'innerHeight', 12145 'innerWidth', 12146 'off', 12147 'offset', 12148 'on', 12149 'outerHeight', 12150 'outerWidth', 12151 'scrollLeft', 12152 'scrollTop' 12153 ], function(i, method) { 12154 JQueryAdapter.prototype[method] = function() { 12155 var args = Array.prototype.slice.call(arguments) 12156 return this.$element[method].apply(this.$element, args) 12157 } 12158 }) 12159 12160 $.each([ 12161 'extend', 12162 'inArray', 12163 'isEmptyObject' 12164 ], function(i, method) { 12165 JQueryAdapter[method] = $[method] 12166 }) 12167 12168 Waypoint.adapters.push({ 12169 name: 'jquery', 12170 Adapter: JQueryAdapter 12171 }) 12172 Waypoint.Adapter = JQueryAdapter 12173}()) 12174;(function() { 12175 'use strict' 12176 12177 var Waypoint = window.Waypoint 12178 12179 function createExtension(framework) { 12180 return function() { 12181 var waypoints = [] 12182 var overrides = arguments[0] 12183 12184 if (framework.isFunction(arguments[0])) { 12185 overrides = framework.extend({}, arguments[1]) 12186 overrides.handler = arguments[0] 12187 } 12188 12189 this.each(function() { 12190 var options = framework.extend({}, overrides, { 12191 element: this 12192 }) 12193 if (typeof options.context === 'string') { 12194 options.context = framework(this).closest(options.context)[0] 12195 } 12196 waypoints.push(new Waypoint(options)) 12197 }) 12198 12199 return waypoints 12200 } 12201 } 12202 12203 if (window.jQuery) { 12204 window.jQuery.fn.waypoint = createExtension(window.jQuery) 12205 } 12206 if (window.Zepto) { 12207 window.Zepto.fn.waypoint = createExtension(window.Zepto) 12208 } 12209}()) 12210; 12211/*! 12212Waypoints Inview Shortcut - 4.0.1 12213Copyright © 2011-2016 Caleb Troughton 12214Licensed under the MIT license. 12215https://github.com/imakewebthings/waypoints/blob/master/licenses.txt 12216*/ 12217(function() { 12218 'use strict' 12219 12220 function noop() {} 12221 12222 var Waypoint = window.Waypoint 12223 12224 /* http://imakewebthings.com/waypoints/shortcuts/inview */ 12225 function Inview(options) { 12226 this.options = Waypoint.Adapter.extend({}, Inview.defaults, options) 12227 this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 12228 this.waypoints = [] 12229 this.element = this.options.element 12230 this.createWaypoints() 12231 } 12232 12233 /* Private */ 12234 Inview.prototype.createWaypoints = function() { 12235 var configs = { 12236 vertical: [{ 12237 down: 'enter', 12238 up: 'exited', 12239 offset: '100%' 12240 }, { 12241 down: 'entered', 12242 up: 'exit', 12243 offset: 'bottom-in-view' 12244 }, { 12245 down: 'exit', 12246 up: 'entered', 12247 offset: 0 12248 }, { 12249 down: 'exited', 12250 up: 'enter', 12251 offset: function() { 12252 return -this.adapter.outerHeight() 12253 } 12254 }], 12255 horizontal: [{ 12256 right: 'enter', 12257 left: 'exited', 12258 offset: '100%' 12259 }, { 12260 right: 'entered', 12261 left: 'exit', 12262 offset: 'right-in-view' 12263 }, { 12264 right: 'exit', 12265 left: 'entered', 12266 offset: 0 12267 }, { 12268 right: 'exited', 12269 left: 'enter', 12270 offset: function() { 12271 return -this.adapter.outerWidth() 12272 } 12273 }] 12274 } 12275 12276 for (var i = 0, end = configs[this.axis].length; i < end; i++) { 12277 var config = configs[this.axis][i] 12278 this.createWaypoint(config) 12279 } 12280 } 12281 12282 /* Private */ 12283 Inview.prototype.createWaypoint = function(config) { 12284 var self = this 12285 this.waypoints.push(new Waypoint({ 12286 context: this.options.context, 12287 element: this.options.element, 12288 enabled: this.options.enabled, 12289 handler: (function(config) { 12290 return function(direction) { 12291 self.options[config[direction]].call(self, direction) 12292 } 12293 }(config)), 12294 offset: config.offset, 12295 horizontal: this.options.horizontal 12296 })) 12297 } 12298 12299 /* Public */ 12300 Inview.prototype.destroy = function() { 12301 for (var i = 0, end = this.waypoints.length; i < end; i++) { 12302 this.waypoints[i].destroy() 12303 } 12304 this.waypoints = [] 12305 } 12306 12307 Inview.prototype.disable = function() { 12308 for (var i = 0, end = this.waypoints.length; i < end; i++) { 12309 this.waypoints[i].disable() 12310 } 12311 } 12312 12313 Inview.prototype.enable = function() { 12314 for (var i = 0, end = this.waypoints.length; i < end; i++) { 12315 this.waypoints[i].enable() 12316 } 12317 } 12318 12319 Inview.defaults = { 12320 context: window, 12321 enabled: true, 12322 enter: noop, 12323 entered: noop,
12324 exit: noop, 12325 exited: noop 12326 } 12327 12328 Waypoint.Inview = Inview 12329}()) 12330; 12331 12332/* 12333 * SmartMenus jQuery v0.9.6 12334 * http://www.smartmenus.org/ 12335 * 12336 * Copyright 2014 Vasil Dinkov, Vadikom Web Ltd. 12337 * http://vadikom.com/ 12338 * 12339 * Released under the MIT license: 12340 * http://www.opensource.org/licenses/MIT 12341 */ 12342 12343(function($) { 12344 12345 var menuTrees = [], 12346 IE = !!window.createPopup, // we need to detect it, unfortunately 12347 IElt9 = IE && !document.defaultView, 12348 IElt8 = IE && !document.querySelector, 12349 IE6 = IE && typeof document.documentElement.currentStyle.minWidth == 'undefined', 12350 mouse = false, // optimize for touch by default - we will detect for mouse input 12351 mouseDetectionEnabled = false; 12352 12353 // Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.) 12354 function initMouseDetection(disable) { 12355 if (!mouseDetectionEnabled && !disable) { 12356 // if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present 12357 // 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) 12358 var firstTime = true, 12359 lastMove = null; 12360 $(document).bind({ 12361 'mousemove.smartmenus_mouse': function(e) { 12362 var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() }; 12363 if (lastMove) { 12364 var deltaX = Math.abs(lastMove.x - thisMove.x), 12365 deltaY = Math.abs(lastMove.y - thisMove.y); 12366 if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) { 12367 mouse = true; 12368 // 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 12369 if (firstTime) { 12370 var $a = $(e.target).closest('a'); 12371 if ($a.is('a')) { 12372 $.each(menuTrees, function() { 12373 if ($.contains(this.$root[0], $a[0])) { 12374 this.itemEnter({ currentTarget: $a[0] }); 12375 return false; 12376 } 12377 }); 12378 } 12379 firstTime = false; 12380 } 12381 } 12382 } 12383 lastMove = thisMove; 12384 }, 12385 'touchstart.smartmenus_mouse pointerover.smartmenus_mouse MSPointerOver.smartmenus_mouse': function(e) { 12386 if (!/^(4|mouse|pen)$/.test(e.originalEvent.pointerType)) { 12387 mouse = false; 12388 } 12389 } 12390 }); 12391 mouseDetectionEnabled = true; 12392 } else if (mouseDetectionEnabled && disable) { 12393 $(document).unbind('.smartmenus_mouse'); 12394 mouseDetectionEnabled = false; 12395 } 12396 }; 12397 12398 $.SmartMenus = function(elm, options) { 12399 this.$root = $(elm); 12400 this.opts = options; 12401 this.rootId = ''; // internal 12402 this.$subArrow = null; 12403 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) 12404 this.activatedItems = []; // stores last activated A's for each level 12405 this.visibleSubMenus = []; // stores visible sub menus UL's 12406 this.showTimeout = 0; 12407 this.hideTimeout = 0; 12408 this.scrollTimeout = 0; 12409 this.clickActivated = false; 12410 this.zIndexInc = 0; 12411 this.$firstLink = null; // we'll use these for some tests 12412 this.$firstSub = null; // at runtime so we'll cache them 12413 this.disabled = false; 12414 this.$disableOverlay = null; 12415 this.init(); 12416 }; 12417 12418 $.extend($.SmartMenus, { 12419 hideAll: function() { 12420 $.each(menuTrees, function() { 12421 this.menuHideAll(); 12422 }); 12423 }, 12424 destroy: function() { 12425 while (menuTrees.length) { 12426 menuTrees[0].destroy(); 12427 } 12428 initMouseDetection(true); 12429 }, 12430 prototype: { 12431 init: function(refresh) { 12432 var self = this; 12433 12434 if (!refresh) { 12435 menuTrees.push(this); 12436 12437 this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, ''); 12438 12439 if (this.$root.hasClass('sm-rtl')) { 12440 this.opts.rightToLeftSubMenus = true; 12441 } 12442 12443 // init root (main menu) 12444 this.$root 12445 .data('smartmenus', this) 12446 .attr('data-smartmenus-id', this.rootId) 12447 .dataSM('level', 1) 12448 .bind({ 12449 'mouseover.smartmenus focusin.smartmenus': $.proxy(this.rootOver, this),
12450 'mouseout.smartmenus focusout.smartmenus': $.proxy(this.rootOut, this) 12451 }) 12452 .delegate('a, div.logo-container', { 12453 'mouseenter.smartmenus': $.proxy(this.itemEnter, this), 12454 'mouseleave.smartmenus': $.proxy(this.itemLeave, this), 12455 'mousedown.smartmenus': $.proxy(this.itemDown, this), 12456 'focus.smartmenus': $.proxy(this.itemFocus, this), 12457 'blur.smartmenus': $.proxy(this.itemBlur, this), 12458 'click.smartmenus': $.proxy(this.itemClick, this), 12459 'touchend.smartmenus': $.proxy(this.itemTouchEnd, this) 12460 }); 12461 12462 var eNamespace = '.smartmenus' + this.rootId; 12463 // hide menus on tap or click outside the root UL 12464 if (this.opts.hideOnClick) { 12465 $(document).on('touchstart' + eNamespace, $.proxy(this.docTouchStart, this)) 12466 .on('touchmove' + eNamespace, $.proxy(this.docTouchMove, this)) 12467 .on('touchend' + eNamespace, $.proxy(this.docTouchEnd, this)) 12468 // for Opera Mobile < 11.5, webOS browser, etc. we'll check click too 12469 .on('click' + eNamespace, $.proxy(this.docClick, this)); 12470 } 12471 // hide sub menus on resize 12472 $(window).on('resize' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this)); 12473 var $vmenu = $('body.vmenu .vmenu-container'); 12474 if ( ! $vmenu.length && UNCODE.wwidth > UNCODE.mediaQuery ) { 12475 $(window).on('scroll' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this)); 12476 } 12477 12478 if (this.opts.subIndicators) { 12479 this.$subArrow = $('<span/>').addClass('sub-arrow'); 12480 if (this.opts.subIndicatorsText) { 12481 this.$subArrow.html(this.opts.subIndicatorsText); 12482 } 12483 } 12484 12485 // make sure mouse detection is enabled 12486 initMouseDetection(); 12487 } 12488 12489 // init sub menus 12490 this.$firstSub = this.$root.find('ul').each(function() { self.menuInit($(this)); }).eq(0); 12491 12492 this.$firstLink = this.$root.find('a').eq(0); 12493 12494 // find current item 12495 if (this.opts.markCurrentItem) { 12496 var reDefaultDoc = /(index|default)\.[^#\?\/]*/i, 12497 reHash = /#.*/, 12498 locHref = window.location.href.replace(reDefaultDoc, ''), 12499 locHrefNoHash = locHref.replace(reHash, ''); 12500 this.$root.find('a').each(function() { 12501 var href = this.href.replace(reDefaultDoc, ''), 12502 $this = $(this); 12503 if (href == locHref || href == locHrefNoHash) { 12504 $this.addClass('current'); 12505 if (self.opts.markCurrentTree) { 12506 $this.parents('li').each(function() { 12507 var $this = $(this); 12508 if ($this.dataSM('sub')) { 12509 $this.children('a').addClass('current'); 12510 } 12511 }); 12512 } 12513 } 12514 }); 12515 } 12516 }, 12517 destroy: function() { 12518 this.menuHideAll(); 12519 this.$root 12520 .removeData('smartmenus') 12521 .removeAttr('data-smartmenus-id') 12522 .removeDataSM('level') 12523 .unbind('.smartmenus') 12524 .undelegate('.smartmenus'); 12525 var eNamespace = '.smartmenus' + this.rootId; 12526 $(document).unbind(eNamespace); 12527 $(window).unbind(eNamespace); 12528 if (this.opts.subIndicators) { 12529 this.$subArrow = null; 12530 } 12531 var self = this; 12532 $.each(this.subMenus, function() { 12533 if (this.hasClass('mega-menu')) { 12534 this.find('ul').removeDataSM('in-mega'); 12535 } 12536 if (this.dataSM('shown-before')) { 12537 if (IElt8) { 12538 this.children().css({ styleFloat: '', width: '' }); 12539 } 12540 if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) { 12541 if (!IE6) { 12542 this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap'); 12543 } else { 12544 this.css({ width: '', overflowX: '', overflowY: '' }).children().children('a').css('white-space', ''); 12545 } 12546 } 12547 if (this.dataSM('scroll-arrows')) { 12548 this.dataSM('scroll-arrows').remove(); 12549 } 12550 this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' }); 12551 } 12552 if (self.opts.subIndicators) { 12553 this.dataSM('parent-a').removeClass('has-submenu').children('span.sub-arrow').remove(); 12554 } 12555 this.removeDataSM('shown-before') 12556 .removeDataSM('ie-shim') 12557 .removeDataSM('scroll-arrows') 12558 .removeDataSM('parent-a') 12559 .removeDataSM('level') 12560 .removeDataSM('beforefirstshowfired') 12561 .parent().removeDataSM('sub'); 12562 }); 12563 if (this.opts.markCurrentItem) { 12564 this.$root.find('a.current').removeClass('current'); 12565 } 12566 this.$root = null; 12567 this.$firstLink = null; 12568 this.$firstSub = null; 12569 if (this.$disableOverlay) { 12570 this.$disableOverlay.remove(); 12571 this.$disableOverlay = null; 12572 } 12573 menuTrees.splice($.inArray(this, menuTrees), 1); 12574 }, 12575 disable: function(noOverlay) { 12576 if (!this.disabled) { 12577 this.menuHideAll(); 12578 // display overlay over the menu to prevent interaction 12579 if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) { 12580 var pos = this.$root.offset(); 12581 this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({ 12582 position: 'absolute', 12583 top: pos.top, 12584 left: pos.left, 12585 width: this.$root.outerWidth(), 12586 height: this.$root.outerHeight(),
12587 zIndex: this.getStartZIndex() + 1, 12588 opacity: 0 12589 }).appendTo(document.body); 12590 } 12591 this.disabled = true; 12592 } 12593 }, 12594 docClick: function(e) { 12595 // hide on any click outside the menu or on a menu link 12596 if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).is('a')) { 12597 this.menuHideAll($(e.target)); 12598 } 12599 }, 12600 docTouchEnd: function(e) { 12601 if (!this.lastTouch) { 12602 return; 12603 } 12604 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))) { 12605 if (this.hideTimeout) { 12606 clearTimeout(this.hideTimeout); 12607 this.hideTimeout = 0; 12608 } 12609 // hide with a delay to prevent triggering accidental unwanted click on some page element 12610 var self = this; 12611 this.hideTimeout = setTimeout(function() { self.menuHideAll($(e.target)); }, 350); 12612 } 12613 this.lastTouch = null; 12614 }, 12615 docTouchMove: function(e) { 12616 if (!this.lastTouch) { 12617 return; 12618 } 12619 var touchPoint = e.originalEvent.touches[0]; 12620 this.lastTouch.x2 = touchPoint.pageX; 12621 this.lastTouch.y2 = touchPoint.pageY; 12622 }, 12623 docTouchStart: function(e) { 12624 var touchPoint = e.originalEvent.touches[0]; 12625 this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target }; 12626 }, 12627 enable: function() { 12628 if (this.disabled) { 12629 if (this.$disableOverlay) { 12630 this.$disableOverlay.remove(); 12631 this.$disableOverlay = null; 12632 } 12633 this.disabled = false; 12634 } 12635 }, 12636 getHeight: function($elm) { 12637 return this.getOffset($elm, true); 12638 }, 12639 // returns precise width/height float values in IE9+, FF4+, recent WebKit 12640 // http://vadikom.com/dailies/offsetwidth-offsetheight-useless-in-ie9-firefox4/ 12641 getOffset: function($elm, height) { 12642 var old, 12643 $win = $(window), 12644 winW = $win.width(); 12645 if ($elm.css('display') == 'none') { 12646 old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility }; 12647 $elm.css({ position: 'absolute', visibility: 'hidden' }).show(); 12648 if ( 12649 ($('body').hasClass('menu-mobile-off-canvas') && winW < 960 && $elm.closest('.main-menu-container').length) 12650 || 12651 (( $('body').hasClass('vmenu-offcanvas-overlay') || $('body').hasClass('vmenu') ) && winW >= 960 && $elm.closest('.main-menu-container').length && !$elm.closest('.menu-horizontal-inner').length) 12652 ) { 12653 $elm.closest('li').addClass('smartmenu-open-item'); 12654 } 12655 } 12656 var defaultView = $elm[0].ownerDocument.defaultView, 12657 compStyle = defaultView && defaultView.getComputedStyle && defaultView.getComputedStyle($elm[0], null), 12658 val = compStyle && parseFloat(compStyle[height ? 'height' : 'width']); 12659 if (val) { 12660 val += parseFloat(compStyle[height ? 'paddingTop' : 'paddingLeft']) 12661 + parseFloat(compStyle[height ? 'paddingBottom' : 'paddingRight']) 12662 + parseInt(compStyle[height ? 'borderTopWidth' : 'borderLeftWidth']) 12663 + parseInt(compStyle[height ? 'borderBottomWidth' : 'borderRightWidth']); 12664 } else { 12665 val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth; 12666 } 12667 if (old) { 12668 $elm.hide().css(old); 12669 } 12670 return val; 12671 }, 12672 getWidth: function($elm) { 12673 return this.getOffset($elm); 12674 }, 12675 getStartZIndex: function() { 12676 var zIndex = parseInt(this.$root.css('z-index')); 12677 return !isNaN(zIndex) ? zIndex : 1; 12678 }, 12679 handleEvents: function() { 12680 return !this.disabled && this.isCSSOn(); 12681 }, 12682 handleItemEvents: function($a) { 12683 return this.handleEvents() && !this.isLinkInMegaMenu($a); 12684 }, 12685 isCollapsible: function() { 12686 return this.$firstSub.css('position') == 'static'; 12687 }, 12688 isCSSOn: function() { 12689 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'; 12690 }, 12691 isFixed: function() { 12692 return this.$root.css('position') == 'fixed'; 12693 }, 12694 isLinkInMegaMenu: function($a) { 12695 return !$a.parent().parent().dataSM('level'); 12696 }, 12697 isTouchMode: function() { 12698 return !mouse || this.isCollapsible(); 12699 }, 12700 itemActivate: function($a) { 12701 var $li = $a.parent(), 12702 $ul = $li.parent(), 12703 level = $ul.dataSM('level'); 12704 // 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 12705 if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) { 12706 var self = this; 12707 $($ul.parentsUntil('[data-smartmenus-id]', 'ul').get().reverse()).add($ul).each(function() { 12708 self.itemActivate($(this).dataSM('parent-a')); 12709 }); 12710 } 12711 // hide any visible deeper level sub menus 12712 if (this.visibleSubMenus.length > level) { 12713 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--) { 12714 //if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) { 12715 this.menuHide(this.visibleSubMenus[i]); 12716 //} 12717 } 12718 } 12719 // save new active item and sub menu for this level 12720 this.activatedItems[level - 1] = $a; 12721 this.visibleSubMenus[level - 1] = $ul; 12722 if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) { 12723 return; 12724 } 12725 // show the sub menu if this item has one 12726 var $sub = $li.dataSM('sub'); 12727 if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) { 12728 this.menuShow($sub); 12729 } 12730 }, 12731 itemBlur: function(e) { 12732 var $a = $(e.currentTarget); 12733 if (!this.handleItemEvents($a)) { 12734 return; 12735 } 12736 this.$root.triggerHandler('blur.smapi', $a[0]); 12737 }, 12738 itemClick: function(e) { 12739 var $a = $(e.currentTarget); 12740 12741 if (!this.handleItemEvents($a)) { 12742 return; 12743 } 12744 $a.removeDataSM('mousedown'); 12745 if (this.$root.triggerHandler('click.smapi', $a[0]) === false) { 12746 return false;
12747 } 12748 var $sub = $a.parent().dataSM('sub'); 12749 if (this.isTouchMode()) { 12750 // undo fix: prevent the address bar on iPhone from sliding down when expanding a sub menu 12751 if ($a.dataSM('href')) { 12752 $a.attr('href', $a.dataSM('href')).removeDataSM('href'); 12753 } 12754 // if the sub is not visible 12755 if ($sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) { 12756 // try to activate the item and show the sub 12757 this.itemActivate($a); 12758 // if "itemActivate" showed the sub, prevent the click so that the link is not loaded 12759 // 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 12760 if ($sub.is(':visible')) { 12761 return false; 12762 } 12763 } 12764 } else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub) { 12765 this.clickActivated = true; 12766 this.menuShow($sub); 12767 return false; 12768 } 12769 if ($a.hasClass('disabled')) { 12770 return false; 12771 } 12772 if (this.$root.triggerHandler('select.smapi', $a[0]) === false) { 12773 return false; 12774 } 12775 }, 12776 itemDown: function(e) { 12777 var $a = $(e.currentTarget); 12778 if (!this.handleItemEvents($a)) { 12779 return; 12780 } 12781 $a.dataSM('mousedown', true); 12782 }, 12783 itemEnter: function(e) { 12784 var $a = $(e.currentTarget); 12785 if (!this.handleItemEvents($a)) { 12786 return; 12787 } 12788 if (!this.isTouchMode()) { 12789 if (this.showTimeout) { 12790 clearTimeout(this.showTimeout); 12791 this.showTimeout = 0; 12792 } 12793 var self = this; 12794 this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 ? 1 : this.opts.showTimeout); 12795 } 12796 this.$root.triggerHandler('mouseenter.smapi', $a[0]); 12797 }, 12798 itemFocus: function(e) { 12799 var $a = $(e.currentTarget); 12800 if (!this.handleItemEvents($a)) { 12801 return; 12802 } 12803 // 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 12804 if ((!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) { 12805 this.itemActivate($a); 12806 } 12807 this.$root.triggerHandler('focus.smapi', $a[0]); 12808 }, 12809 itemLeave: function(e) { 12810 var $a = $(e.currentTarget); 12811 if (!this.handleItemEvents($a)) { 12812 return; 12813 } 12814 if (!this.isTouchMode()) { 12815 if ($a[0].blur) { 12816 $a[0].blur(); 12817 } 12818 if (this.showTimeout) { 12819 clearTimeout(this.showTimeout); 12820 this.showTimeout = 0; 12821 } 12822 } 12823 $a.removeDataSM('mousedown'); 12824 this.$root.triggerHandler('mouseleave.smapi', $a[0]); 12825 }, 12826 itemTouchEnd: function(e) { 12827 var $a = $(e.currentTarget); 12828 if (!this.handleItemEvents($a)) { 12829 return; 12830 } 12831 // prevent the address bar on iPhone from sliding down when expanding a sub menu 12832 var $sub = $a.parent().dataSM('sub'); 12833 if ($a.attr('href').charAt(0) !== '#' && $sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) { 12834 $a.dataSM('href', $a.attr('href')); 12835 $a.attr('href', '#'); 12836 } 12837 }, 12838 menuFixLayout: function($ul) { 12839 // fixes a menu that is being shown for the first time 12840 if (!$ul.dataSM('shown-before')) { 12841 $ul.hide().dataSM('shown-before', true); 12842 // fix the layout of the items in IE<8 12843 if (IElt8) { 12844 $ul.children().css({ styleFloat: 'left', width: '100%' }); 12845 } 12846 } 12847 }, 12848 menuHide: function($sub) { 12849 if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) { 12850 return; 12851 } 12852 $sub.stop(true, true); 12853 if ($sub.is(':visible')) { 12854 var complete = function() { 12855 // unset z-index 12856 if (IElt9) { 12857 $sub.parent().css('z-index', ''); 12858 } else { 12859 $sub.css('z-index', ''); 12860 } 12861 }; 12862 // if sub is collapsible (mobile view) 12863 if (this.isCollapsible()) { 12864 if (this.opts.collapsibleHideFunction) { 12865 this.opts.collapsibleHideFunction.call(this, $sub, complete); 12866 } else { 12867 $sub.hide(this.opts.collapsibleHideDuration, complete); 12868 } 12869 } else { 12870 if (this.opts.hideFunction) { 12871 this.opts.hideFunction.call(this, $sub, complete); 12872 } else { 12873 $sub.hide(this.opts.hideDuration, complete); 12874 } 12875 } 12876 // remove IE iframe shim 12877 if ($sub.dataSM('ie-shim')) { 12878 $sub.dataSM('ie-shim').remove(); 12879 } 12880 // deactivate scrolling if it is activated for this sub 12881 if ($sub.dataSM('scroll')) { 12882 $sub.unbind('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide(); 12883 } 12884 // unhighlight parent item 12885 $sub.dataSM('parent-a').removeClass('highlighted'); 12886 var level = $sub.dataSM('level'); 12887 this.activatedItems.splice(level - 1, 1); 12888 this.visibleSubMenus.splice(level - 1, 1); 12889 this.$root.triggerHandler('hide.smapi', $sub[0]); 12890 } 12891 }, 12892 menuHideAll: function($item) { 12893 if ($item != undefined && $item.parent().hasClass('menu-item') && !$item.parent().hasClass('menu-item-has-children')) return; 12894 var $win = $(window), 12895 winW = $win.width(); 12896 if (this.showTimeout) { 12897 clearTimeout(this.showTimeout); 12898 this.showTimeout = 0; 12899 } 12900 // hide all subs 12901 for (var i = this.visibleSubMenus.length - 1; i > 0; i--) { 12902 if ( this.visibleSubMenus[i].closest('.smartmenu-open-item').length ) { 12903 if ( $item != undefined && $item.closest('.smartmenu-open-item').length ) { 12904 this.menuHide(this.visibleSubMenus[i]); 12905 $(this.visibleSubMenus[i]).closest('.smartmenu-open-item').removeClass('smartmenu-open-item'); 12906 } else { 12907 return; 12908 } 12909 } else { 12910 //if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) { 12911 this.menuHide(this.visibleSubMenus[i]); 12912 //} 12913 } 12914 } 12915 // hide root if it's popup 12916 if (this.opts.isPopup) { 12917 this.$root.stop(true, true); 12918 if (this.$root.is(':visible')) { 12919 if (this.opts.hideFunction) { 12920 this.opts.hideFunction.call(this, this.$root); 12921 } else { 12922 this.$root.hide(this.opts.hideDuration); 12923 } 12924 // remove IE iframe shim 12925 if (this.$root.dataSM('ie-shim')) { 12926 this.$root.dataSM('ie-shim').remove(); 12927 } 12928 } 12929 } 12930 this.activatedItems = []; 12931 this.visibleSubMenus = []; 12932 this.clickActivated = false;
12933 // reset z-index increment 12934 this.zIndexInc = 0; 12935 }, 12936 menuIframeShim: function($ul) { 12937 // create iframe shim for the menu 12938 if (IE && this.opts.overlapControlsInIE && !$ul.dataSM('ie-shim')) { 12939 $ul.dataSM('ie-shim', $('<iframe/>').attr({ src: 'javascript:0', tabindex: -9 }) 12940 .css({ position: 'absolute', top: 'auto', left: '0', opacity: 0, border: '0' }) 12941 ); 12942 } 12943 }, 12944 menuInit: function($ul) { 12945 if (!$ul.dataSM('in-mega')) { 12946 this.subMenus.push($ul); 12947 // mark UL's in mega drop downs (if any) so we can neglect them 12948 if ($ul.hasClass('mega-menu')) { 12949 $ul.find('ul').dataSM('in-mega', true); 12950 } 12951 // get level (much faster than, for example, using parentsUntil) 12952 var level = 2, 12953 par = $ul[0]; 12954 while (par != null && par.parentNode != null && ( par = par.parentNode.parentNode) != this.$root[0]) { 12955 level++; 12956 } 12957 // cache stuff 12958 $ul.dataSM('parent-a', $ul.prevAll('a').eq(-1)) 12959 .dataSM('level', level) 12960 .parent().dataSM('sub', $ul); 12961 // add sub indicator to parent item 12962 if (this.opts.subIndicators) { 12963 $ul.dataSM('parent-a').addClass('has-submenu')[this.opts.subIndicatorsPos](this.$subArrow.clone()); 12964 } 12965 } 12966 }, 12967 menuPosition: function($sub) { 12968 var fixIE = $('html.ie').length; 12969 // if (fixIE) { 12970 // var $rowParent = $($sub).closest('.main-menu-container'); 12971 // $rowParent.height($rowParent.height()); 12972 // } 12973 var $a = $sub.dataSM('parent-a'), 12974 $li = $sub.parent(), 12975 $ul = $sub.parent().parent(), 12976 // $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'), 12977 $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'), 12978 level = $sub.dataSM('level'), 12979 subW = this.getWidth($sub), 12980 subH = this.getHeight($sub), 12981 itemOffset = $a.offset(), 12982 itemX = itemOffset.left, 12983 itemY = itemOffset.top, 12984 itemW = this.getWidth($a), 12985 itemH = this.getHeight($a), 12986 $win = $(window), 12987 winX = $win.scrollLeft(), 12988 winY = $win.scrollTop(), 12989 winW = $win.width(), 12990 winH = $win.height(), 12991 containerW = $container.width(), 12992 containerOffsetX = containerW + ((winW - containerW) / 2), 12993 horizontalParent = $ul.hasClass('sm') && !$ul.hasClass('sm-vertical'), 12994 subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX, 12995 subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY, 12996 x, y, leftPos; 12997 12998 if (horizontalParent) { 12999 x = this.opts.rightToLeftSubMenus ? itemW - subW - subOffsetX : subOffsetX; 13000 y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY; 13001 } else { 13002 x = this.opts.rightToLeftSubMenus ? subOffsetX - subW : subW - subOffsetX; 13003 y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY; 13004 } 13005 if (this.opts.keepInViewport && !this.isCollapsible()) { 13006 if (this.isFixed()) { 13007 itemX -= winX; 13008 itemY -= winY; 13009 winX = winY = 0; 13010 } 13011 var absX = itemX + x, 13012 absY = itemY + y; 13013 if (this.opts.rightToLeftSubMenus && absX < winX) { 13014 x = horizontalParent ? winX - absX + x : itemW - subOffsetX; 13015 } else if (!this.opts.rightToLeftSubMenus && absX + subW > winX + containerOffsetX ) { 13016 x = horizontalParent ? winX + containerOffsetX - subW - absX + x : subOffsetX - subW; 13017 } 13018 if (!horizontalParent) { 13019 if (subH < winH && absY + subH > winY + winH) { 13020 y += winY + winH - subH - absY; 13021 } else if (subH >= winH || absY < winY) { 13022 y += winY - absY; 13023 } 13024 } 13025 // do we need scrolling? 13026 // 0.49 added for the sake of IE9/FF4+ where we might be dealing with float numbers for "subH" 13027 if (mouse && (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49)) { 13028 var self = this; 13029 if (!$sub.dataSM('scroll-arrows')) { 13030 $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]]) 13031 .bind({ 13032 mouseenter: function() { self.menuScroll($sub, $(this).hasClass('scroll-up')); }, 13033 mouseleave: function(e) { 13034 self.menuScrollStop($sub); 13035 self.menuScrollOut($sub, e); 13036 }, 13037 'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); } 13038 }) 13039 .insertAfter($sub) 13040 ); 13041 } 13042 // bind events to show/hide arrows on hover and save scrolling data for this sub 13043 var vportY = winY - (itemY + itemH); 13044 $sub.dataSM('scroll', { 13045 vportY: vportY, 13046 subH: subH, 13047 winH: winH, 13048 step: 1 13049 }) 13050 .bind({ 13051 'mouseover.smartmenus_scroll': function(e) { self.menuScrollOver($sub, e); }, 13052 'mouseout.smartmenus_scroll': function(e) { self.menuScrollOut($sub, e); }, 13053 'mousewheel.smartmenus_scroll DOMMouseScroll.smartmenus_scroll': function(e) { self.menuScrollMousewheel($sub, e); } 13054 }) 13055 .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
13055StartZIndex() + this.zIndexInc }) 13056 .eq(0).css('margin-top', vportY).end() 13057 .eq(1).css('margin-top', vportY + winH - this.getHeight($sub.dataSM('scroll-arrows').eq(1))).end() 13058 .eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show(); 13059 } 13060 } 13061 if ( !$sub.closest('.menu-accordion').length ) { 13062 var rightPos = 'auto'; 13063 if ( $sub.closest('.grid-filters').length ) { 13064 if ( $sub.closest('.text-right').length ) { 13065 leftPos = '0px'; 13066 rightPos = 'auto'; 13067 } else { 13068 leftPos = 'auto'; 13069 rightPos = '0px'; 13070 } 13071 x = 0; 13072 } else { 13073 if ( $sub.hasClass('mega-menu-inner') ) { 13074 $sub.css({ width: containerW}); 13075 leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.row-menu').offset().left)); 13076 if ( ! $('body').hasClass('megamenu-side-to-side') ) { 13077 leftPos += parseFloat($sub.closest('.row-menu-inner').css('paddingLeft')); 13078 } 13079 x = 0; 13080 } else { 13081 leftPos = (level > 2 ? $li.position().left - parseFloat($li.closest('ul').css('paddingLeft')) : $li.position().left ) + 'px'; 13082 x = (level > 2 && x >= 0) ? x + 1 : x - 1; 13083 } 13084 } 13085 } 13086 13087 // $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) }); 13088 $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) }); 13089 // IE iframe shim 13090 this.menuIframeShim($sub); 13091 if ($sub.dataSM('ie-shim')) { 13092 $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) }); 13093 } 13094 }, 13095 menuScroll: function($sub, up, wheel) { 13096 var y = parseFloat($sub.css('margin-top')), 13097 scroll = $sub.dataSM('scroll'), 13098 navH = $('.navbar-main').outerHeight(), 13099 end = scroll.vportY + (up ? navH + 54 : scroll.winH - scroll.subH), 13100 step = wheel || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor($sub.dataSM('scroll').step); 13101 $sub.add($sub.dataSM('ie-shim')).css('margin-top', Math.abs(end - y) > step ? y + (up ? step : -step) : end); 13102 y = parseFloat($sub.css('margin-top')); 13103 // show opposite arrow if appropriate 13104 if (up && y + scroll.subH > scroll.vportY + scroll.winH || !up && y < scroll.vportY) { 13105 $sub.dataSM('scroll-arrows').eq(up ? 1 : 0).show(); 13106 } 13107 // accelerate when not using mousewheel to scroll 13108 if (!wheel && this.opts.scrollAccelerate && $sub.dataSM('scroll').step < this.opts.scrollStep) { 13109 $sub.dataSM('scroll').step += 0.5; 13110 } 13111 // "y" and "end" might be float numbers in IE9/FF4+ so this weird way to check is used 13112 if (Math.abs(y - end) < 1) { 13113 $sub.dataSM('scroll-arrows').eq(up ? 0 : 1).hide(); 13114 $sub.dataSM('scroll').step = 1; 13115 } else if (!wheel) { 13116 var self = this; 13117 this.scrollTimeout = setTimeout(function() { self.menuScroll($sub, up); }, this.opts.scrollInterval); 13118 } 13119 }, 13120 menuScrollMousewheel: function($sub, e) { 13121 var $closestSub = $(e.target).closest('ul'); 13122 while ($closestSub.dataSM('in-mega')) { 13123 $closestSub = $closestSub.parent().closest('ul'); 13124 } 13125 if ($closestSub[0] == $sub[0]) { 13126 var up = (e.originalEvent.wheelDelta || -e.originalEvent.detail) > 0; 13127 if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) { 13128 this.menuScroll($sub, up, true); 13129 } 13130 } 13131 if ( ! $sub.hasClass('mega-menu-inner') ) { 13132 e.preventDefault(); 13133 } 13134 }, 13135 menuScrollOut: function($sub, e) { 13136 var reClass = /^scroll-(up|down)/, 13137 $closestSub = $(e.relatedTarget).closest('ul'); 13138 while ($closestSub.dataSM('in-mega')) { 13139 $closestSub = $closestSub.parent().closest('ul'); 13140 } 13141 if (!reClass.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || $closestSub[0] != $sub[0])) { 13142 $sub.dataSM('scroll-arrows').css('visibility', 'hidden'); 13143 } 13144 }, 13145 menuScrollOver: function($sub, e) { 13146 var reClass = /^scroll-(up|down)/, 13147 $closestSub = $(e.target).closest('ul'); 13148 while ($closestSub.dataSM('in-mega')) { 13149 $closestSub = $closestSub.parent().closest('ul'); 13150 } 13151 if (!reClass.test(e.target.className) && $closestSub[0] == $sub[0]) { 13152 $sub.dataSM('scroll-arrows').css('visibility', 'visible'); 13153 } 13154 }, 13155 menuScrollStop: function($sub) { 13156 if (this.scrollTimeout) { 13157 clearTimeout(this.scrollTimeout); 13158 this.scrollTimeout = 0; 13159 $sub.dataSM('scroll').step = 1; 13160 } 13161 }, 13162 menuShow: function($sub) { 13163 if (!$sub.dataSM('beforefirstshowfired')) { 13164 $sub.dataSM('beforefirstshowfired', true); 13165 if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) { 13166 return; 13167 } 13168 } 13169 if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) { 13170 return; 13171 } 13172 this.menuFixLayout($sub); 13173 $sub.stop(true, true); 13174 if (!$sub.is(':visible')) { 13175 $sub.css({ 13176 'visibility': 'visible', 13177 'pointer-events': 'auto', 13178 }); 13179 // set z-index - for IE < 9 set it to the parent LI
13180 var zIndex = this.getStartZIndex() + (++this.zIndexInc); 13181 if (IElt9) { 13182 $sub.parent().css('z-index', zIndex); 13183 } else { 13184 $sub.css('z-index', zIndex); 13185 } 13186 // highlight parent item 13187 if (this.opts.keepHighlighted || this.isCollapsible()) { 13188 if ($sub.dataSM('parent-a').attr('data-type') != 'title') 13189 $sub.dataSM('parent-a').addClass('highlighted'); 13190 } 13191 // min/max-width fix - no way to rely purely on CSS as all UL's are nested 13192 if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) { 13193 if (!IElt8) { 13194 $sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 13195 if (this.opts.subMenusMinWidth) { 13196 $sub.css('min-width', this.opts.subMenusMinWidth); 13197 } 13198 if (this.opts.subMenusMaxWidth) { 13199 var noMaxWidth = this.getWidth($sub); 13200 if ( ! $sub.hasClass('mega-menu-inner') ) { 13201 $sub.css('max-width', this.opts.subMenusMaxWidth); 13202 } 13203 if (noMaxWidth > this.getWidth($sub)) { 13204 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 13205 } 13206 } 13207 // IE6,7 13208 } else { 13209 $sub.children().css('styleFloat', 'none'); 13210 if (IE6) { 13211 $sub.width(this.opts.subMenusMinWidth ? this.opts.subMenusMinWidth : 1) 13212 .children().children('a').css('white-space', 'nowrap'); 13213 } else { // IE7 13214 $sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 13215 if (this.opts.subMenusMinWidth) { 13216 $sub.css('min-width', this.opts.subMenusMinWidth); 13217 } 13218 } 13219 if (this.opts.subMenusMaxWidth) { 13220 var noMaxWidth = $sub.width(); 13221 if (IE6) { 13222 var maxWidth = $sub.css({ width: this.opts.subMenusMaxWidth, overflowX: 'hidden', overflowY: 'hidden' }).width(); 13223 if (noMaxWidth > maxWidth) { 13224 $sub.css({ width: maxWidth, overflowX: 'visible', overflowY: 'visible' }).children().children('a').css('white-space', ''); 13225 } else { 13226 $sub.css({ width: noMaxWidth, overflowX: 'visible', overflowY: 'visible' }); 13227 } 13228 } else { // IE7 13229 if ( ! $sub.hasClass('mega-menu-inner') ) { 13230 $sub.css('max-width', this.opts.subMenusMaxWidth); 13231 } 13232 if (noMaxWidth > $sub.width()) { 13233 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 13234 } else { 13235 $sub.width(noMaxWidth); 13236 } 13237 } 13238 } else { 13239 $sub.width($sub.width()); 13240 } 13241 $sub.children().css('styleFloat', 'left'); 13242 } 13243 } 13244 if ( $sub.hasClass('mega-menu-inner') && $('body').hasClass('scrollable-megamenu') && UNCODE.wwidth > UNCODE.mediaQuery ) { 13245 var $nav = $('.navbar-main'), 13246 navH = 0, 13247 navTop = 0, 13248 $vmenu = $('body.vmenu .vmenu-container, body.menu-overlay .vmenu-container, body.menu-offcanvas .vmenu-container'); 13249 if ( $nav.length && typeof $nav[0] !== 'undefined' ) { 13250 var navRect = $nav[0].getBoundingClientRect(); 13251 navH = navRect.height; 13252 navTop = navRect.top; 13253 } 13254 if ( ! $vmenu.length ) { 13255 $sub.css({ maxHeight: UNCODE.wheight - navH }); 13256 } 13257 } 13258 this.menuPosition($sub); 13259 // insert IE iframe shim 13260 if ($sub.dataSM('ie-shim')) { 13261 $sub.dataSM('ie-shim').insertBefore($sub); 13262 } 13263 var complete = function() { 13264 // fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used 13265 $sub.css('overflow', ''); 13266 }; 13267 // if sub is collapsible (mobile view) 13268 if (this.isCollapsible()) { 13269 if (this.opts.collapsibleShowFunction) { 13270 this.opts.collapsibleShowFunction.call(this, $sub, complete); 13271 } else { 13272 $sub.show(this.opts.collapsibleShowDuration, complete); 13273 } 13274 } else { 13275 if (this.opts.showFunction) { 13276 this.opts.showFunction.call(this, $sub, complete); 13277 } else { 13278 $sub.show(this.opts.showDuration, complete); 13279 } 13280 } 13281 // save new sub menu for this level 13282 this.visibleSubMenus[$sub.dataSM('level') - 1] = $sub; 13283 this.$root.triggerHandler('show.smapi', $sub[0]); 13284 } 13285 }, 13286 popupHide: function(noHideTimeout) { 13287 if (this.hideTimeout) { 13288 clearTimeout(this.hideTimeout); 13289 this.hideTimeout = 0; 13290 } 13291 var self = this; 13292 this.hideTimeout = setTimeout(function() { 13293 self.menuHideAll(); 13294 }, noHideTimeout ? 1 : this.opts.hideTimeout); 13295 }, 13296 popupShow: function(left, top) { 13297 if (!this.opts.isPopup) { 13298 alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'); 13299 return; 13300 } 13301 if (this.hideTimeout) { 13302 clearTimeout(this.hideTimeout); 13303 this.hideTimeout = 0; 13304 } 13305 this.menuFixLayout(this.$root); 13306 this.$root.stop(true, true); 13307 if (!this.$root.is(':visible')) { 13308 this.$root.css({ left: left, top: top }); 13309 // IE iframe shim 13310 this.menuIframeShim(this.$root); 13311 if (this.$root.dataSM('ie-shim')) { 13312 this.$root.dataSM('ie-shim').css({ zIndex: this.$root.css('z-index'), width: this.getWidth(this.$root), height: this.getHeight(this.$root), left
13312: left, top: top }).insertBefore(this.$root); 13313 } 13314 // show menu 13315 if (this.opts.showFunction) { 13316 this.opts.showFunction.call(this, this.$root); 13317 } else { 13318 this.$root.show(this.opts.showDuration); 13319 } 13320 this.visibleSubMenus[0] = this.$root; 13321 } 13322 }, 13323 refresh: function() { 13324 this.menuHideAll(); 13325 this.$root.find('ul').each(function() { 13326 var $this = $(this); 13327 if ($this.dataSM('scroll-arrows')) { 13328 $this.dataSM('scroll-arrows').remove(); 13329 } 13330 }) 13331 .removeDataSM('in-mega') 13332 .removeDataSM('shown-before') 13333 .removeDataSM('ie-shim') 13334 .removeDataSM('scroll-arrows') 13335 .removeDataSM('parent-a') 13336 .removeDataSM('level') 13337 .removeDataSM('beforefirstshowfired'); 13338 this.$root.find('a.has-submenu').removeClass('has-submenu') 13339 .parent().removeDataSM('sub'); 13340 if (this.opts.subIndicators) { 13341 this.$root.find('span.sub-arrow').remove(); 13342 } 13343 if (this.opts.markCurrentItem) { 13344 this.$root.find('a.current').removeClass('current'); 13345 } 13346 this.subMenus = []; 13347 this.init(true); 13348 }, 13349 rootOut: function(e) { 13350 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 13351 return; 13352 } 13353 if (this.hideTimeout) { 13354 clearTimeout(this.hideTimeout); 13355 this.hideTimeout = 0; 13356 } 13357 if (!this.opts.showOnClick || !this.opts.hideOnClick) { 13358 var self = this; 13359 this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout); 13360 } 13361 }, 13362 rootOver: function(e) { 13363 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 13364 return; 13365 } 13366 if (this.hideTimeout) { 13367 clearTimeout(this.hideTimeout); 13368 this.hideTimeout = 0; 13369 } 13370 }, 13371 winResize: function(e) { 13372 if (!this.handleEvents()) { 13373 // we still need to resize the disable overlay if it's visible 13374 if (this.$disableOverlay) { 13375 var pos = this.$root.offset(); 13376 this.$disableOverlay.css({ 13377 top: pos.top, 13378 left: pos.left, 13379 width: this.$root.outerWidth(), 13380 height: this.$root.outerHeight() 13381 }); 13382 } 13383 return; 13384 } 13385 // hide sub menus on resize - on mobile do it only on orientation change 13386 if (!this.isCollapsible() && (!('onorientationchange' in window) || e.type == 'orientationchange')) { 13387 if (this.activatedItems.length) { 13388 this.activatedItems[this.activatedItems.length - 1][0].blur(); 13389 } 13390 this.menuHideAll(); 13391 } 13392 } 13393 } 13394 }); 13395 13396 $.fn.dataSM = function(key, val) { 13397 if (val) { 13398 return this.data(key + '_smartmenus', val); 13399 } 13400 return this.data(key + '_smartmenus'); 13401 } 13402 13403 $.fn.removeDataSM = function(key) { 13404 return this.removeData(key + '_smartmenus'); 13405 } 13406 13407 $.fn.smartmenus = function(options) { 13408 if (typeof options == 'string') { 13409 var args = arguments, 13410 method = options; 13411 Array.prototype.shift.call(args); 13412 return this.each(function() { 13413 var smartmenus = $(this).data('smartmenus'); 13414 if (smartmenus && smartmenus[method]) { 13415 smartmenus[method].apply(smartmenus, args); 13416 } 13417 }); 13418 } 13419 var opts = $.extend({}, $.fn.smartmenus.defaults, options); 13420 return this.each(function() { 13421 new $.SmartMenus(this, opts); 13422 }); 13423 } 13424 13425 // default settings 13426 $.fn.smartmenus.defaults = { 13427 isPopup: false, // is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar 13428 mainMenuSubOffsetX: 0, // pixels offset from default position
13429 mainMenuSubOffsetY: 0, // pixels offset from default position 13430 subMenusSubOffsetX: 0, // pixels offset from default position 13431 subMenusSubOffsetY: 0, // pixels offset from default position 13432 subMenusMinWidth: false, //'10em', // min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 13433 subMenusMaxWidth: false, //'20em', // max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 13434 subIndicators: true, // create sub menu indicators - creates a SPAN and inserts it in the A 13435 subIndicatorsPos: 'prepend', // position of the SPAN relative to the menu item content ('prepend', 'append') 13436 subIndicatorsText: '+', // [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too) 13437 scrollStep: 30, // pixels step when scrolling long sub menus that do not fit in the viewport height 13438 scrollInterval: 30, // interval between each scrolling step 13439 scrollAccelerate: true, // accelerate scrolling or use a fixed step 13440 showTimeout: 250, // timeout before showing the sub menus 13441 hideTimeout: 500, // timeout before hiding the sub menus 13442 showDuration: 0, // duration for show animation - set to 0 for no animation - matters only if showFunction:null 13443 showFunction: null, // custom function to use when showing a sub menu (the default is the jQuery 'show') 13444 // don't forget to call complete() at the end of whatever you do 13445 // e.g.: function($ul, complete) { $ul.fadeIn(250, complete); } 13446 hideDuration: 0, // duration for hide animation - set to 0 for no animation - matters only if hideFunction:null 13447 hideFunction: function($ul, complete) { $ul.fadeOut(200, complete); }, // custom function to use when hiding a sub menu (the default is the jQuery 'hide') 13448 // don't forget to call complete() at the end of whatever you do 13449 // e.g.: function($ul, complete) { $ul.fadeOut(250, complete); } 13450 collapsibleShowDuration:0, // duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null 13451 collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); }, // custom function to use when showing a collapsible sub menu 13452 // (i.e. when mobile styles are used to make the sub menus collapsible) 13453 collapsibleHideDuration:0, // duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null 13454 collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); }, // custom function to use when hiding a collapsible sub menu 13455 // (i.e. when mobile styles are used to make the sub menus collapsible) 13456 showOnClick: false, // show the first-level sub menus onclick instead of onmouseover (matters only for mouse input) 13457 hideOnClick: true, // hide the sub menus on click/tap anywhere on the page 13458 keepInViewport: true, // reposition the sub menus if needed to make sure they always appear inside the viewport 13459 keepHighlighted: true, // keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's) 13460 markCurrentItem: false, // automatically add the 'current' class to the A element of the item linking to the current URL 13461 markCurrentTree: true, // add the 'current' class also to the A elements of all ancestor items of the current item 13462 rightToLeftSubMenus: false, // right to left display of the sub menus (check the CSS for the sub indicators' position) 13463 bottomToTopSubMenus: false, // bottom to top display of the sub menus 13464 overlapControlsInIE: true // make sure sub menus appear on top of special OS controls in IE (i.e. SELECT, OBJECT, EMBED, etc.) 13465 }; 13466 13467})(jQuery); 13468/* 13469 * jQuery Easing v1.4.1 - http://gsgd.co.uk/sandbox/jquery/easing/ 13470 * Open source under the BSD License. 13471 * Copyright © 2008 George McGinley Smith 13472 * All rights reserved. 13473 * https://raw.github.com/gdsmith/jquery.easing/master/LICENSE 13474*/ 13475 13476/* globals jQuery, define, module, require */ 13477(function (factory) { 13478 if (typeof define === "function" && define.amd) { 13479 define(['jquery'], function ($) { 13480 return factory($); 13481 }); 13482 } else if (typeof module === "object" && typeof module.exports === "object") { 13483 module.exports = factory(require('jquery')); 13484 } else { 13485 factory(jQuery); 13486 } 13487})(function($){ 13488 13489 // Preserve the original jQuery "swing" easing as "jswing" 13490 if (typeof $.easing !== 'undefined') { 13491 $.easing['jswing'] = $.easing['swing']; 13492 } 13493 13494 var pow = Math.pow, 13495 sqrt = Math.sqrt, 13496 sin = Math.sin, 13497 cos = Math.cos, 13498 PI = Math.PI,
13499 c1 = 1.70158, 13500 c2 = c1 * 1.525, 13501 c3 = c1 + 1, 13502 c4 = ( 2 * PI ) / 3, 13503 c5 = ( 2 * PI ) / 4.5; 13504 13505 // x is the fraction of animation progress, in the range 0..1 13506 function bounceOut(x) { 13507 var n1 = 7.5625, 13508 d1 = 2.75; 13509 if ( x < 1/d1 ) { 13510 return n1*x*x; 13511 } else if ( x < 2/d1 ) { 13512 return n1*(x-=(1.5/d1))*x + .75; 13513 } else if ( x < 2.5/d1 ) { 13514 return n1*(x-=(2.25/d1))*x + .9375; 13515 } else { 13516 return n1*(x-=(2.625/d1))*x + .984375; 13517 } 13518 } 13519 13520 $.extend( $.easing, { 13521 def: 'easeOutQuad', 13522 swing: function (x) { 13523 return $.easing[$.easing.def](x); 13524 }, 13525 easeInQuad: function (x) { 13526 return x * x; 13527 }, 13528 easeOutQuad: function (x) { 13529 return 1 - ( 1 - x ) * ( 1 - x ); 13530 }, 13531 easeInOutQuad: function (x) { 13532 return x < 0.5 ? 13533 2 * x * x : 13534 1 - pow( -2 * x + 2, 2 ) / 2; 13535 }, 13536 easeInCubic: function (x) { 13537 return x * x * x; 13538 }, 13539 easeOutCubic: function (x) { 13540 return 1 - pow( 1 - x, 3 ); 13541 }, 13542 easeInOutCubic: function (x) { 13543 return x < 0.5 ? 13544 4 * x * x * x : 13545 1 - pow( -2 * x + 2, 3 ) / 2; 13546 }, 13547 easeInQuart: function (x) { 13548 return x * x * x * x; 13549 }, 13550 easeOutQuart: function (x) { 13551 return 1 - pow( 1 - x, 4 ); 13552 }, 13553 easeInOutQuart: function (x) { 13554 return x < 0.5 ? 13555 8 * x * x * x * x : 13556 1 - pow( -2 * x + 2, 4 ) / 2; 13557 }, 13558 easeInQuint: function (x) { 13559 return x * x * x * x * x; 13560 }, 13561 easeOutQuint: function (x) { 13562 return 1 - pow( 1 - x, 5 ); 13563 }, 13564 easeInOutQuint: function (x) { 13565 return x < 0.5 ? 13566 16 * x * x * x * x * x : 13567 1 - pow( -2 * x + 2, 5 ) / 2; 13568 }, 13569 easeInSine: function (x) { 13570 return 1 - cos( x * PI/2 ); 13571 }, 13572 easeOutSine: function (x) { 13573 return sin( x * PI/2 ); 13574 }, 13575 easeInOutSine: function (x) { 13576 return -( cos( PI * x ) - 1 ) / 2; 13577 }, 13578 easeInExpo: function (x) { 13579 return x === 0 ? 0 : pow( 2, 10 * x - 10 ); 13580 }, 13581 easeOutExpo: function (x) { 13582 return x === 1 ? 1 : 1 - pow( 2, -10 * x ); 13583 }, 13584 easeInOutExpo: function (x) { 13585 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 13586 pow( 2, 20 * x - 10 ) / 2 : 13587 ( 2 - pow( 2, -20 * x + 10 ) ) / 2; 13588 }, 13589 easeInCirc: function (x) { 13590 return 1 - sqrt( 1 - pow( x, 2 ) ); 13591 }, 13592 easeOutCirc: function (x) { 13593 return sqrt( 1 - pow( x - 1, 2 ) ); 13594 }, 13595 easeInOutCirc: function (x) { 13596 return x < 0.5 ? 13597 ( 1 - sqrt( 1 - pow( 2 * x, 2 ) ) ) / 2 : 13598 ( sqrt( 1 - pow( -2 * x + 2, 2 ) ) + 1 ) / 2; 13599 }, 13600 easeInElastic: function (x) { 13601 return x === 0 ? 0 : x === 1 ? 1 : 13602 -pow( 2, 10 * x - 10 ) * sin( ( x * 10 - 10.75 ) * c4 ); 13603 }, 13604 easeOutElastic: function (x) { 13605 return x === 0 ? 0 : x === 1 ? 1 : 13606 pow( 2, -10 * x ) * sin( ( x * 10 - 0.75 ) * c4 ) + 1; 13607 }, 13608 easeInOutElastic: function (x) { 13609 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 13610 -( pow( 2, 20 * x - 10 ) * sin( ( 20 * x - 11.125 ) * c5 )) / 2 : 13611 pow( 2, -20 * x + 10 ) * sin( ( 20 * x - 11.125 ) * c5 ) / 2 + 1; 13612 }, 13613 easeInBack: function (x) { 13614 return c3 * x * x * x - c1 * x * x; 13615 }, 13616 easeOutBack: function (x) { 13617 return 1 + c3 * pow( x - 1, 3 ) + c1 * pow( x - 1, 2 ); 13618 }, 13619 easeInOutBack: function (x) { 13620 return x < 0.5 ? 13621 ( pow( 2 * x, 2 ) * ( ( c2 + 1 ) * 2 * x - c2 ) ) / 2 : 13622 ( pow( 2 * x - 2, 2 ) *( ( c2 + 1 ) * ( x * 2 - 2 ) + c2 ) + 2 ) / 2; 13623 }, 13624 easeInBounce: function (x) { 13625 return 1 - bounceOut( 1 - x ); 13626 }, 13627 easeOutBounce: bounceOut, 13628 easeInOutBounce: function (x) { 13629 return x < 0.5 ? 13630 ( 1 - bounceOut( 1 - 2 * x ) ) / 2 : 13631 ( 1 + bounceOut( 2 * x - 1 ) ) / 2; 13632 } 13633 }); 13634 return $; 13635}); 13636 13637/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) 13638 * Licensed under the MIT License (LICENSE.txt). 13639 * 13640 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 13641 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 13642 * Thanks to: Seamus Leahy for adding deltaX and deltaY 13643 * 13644 * Version: 3.0.6 13645 * 13646 * Requires: 1.2.2+ 13647 */ 13648(function($) { 13649 var types = ['DOMMouseScroll', 'mousewheel']; 13650 if ($.event.fixHooks) { 13651 for (var i = types.length; i;) { 13652 $.event.fixHooks[types[--i]] = $.event.mouseHooks; 13653 } 13654 } 13655 $.event.special.mousewheel = { 13656 setup: function() { 13657 if (this.addEventListener) { 13658 for (var i = types.length; i;) { 13659 this.addEventListener(types[--i], handler, false); 13660 } 13661 } else { 13662 this.onmousewheel = handler; 13663 } 13664 }, 13665 teardown: function() { 13666 if (this.removeEventListener) { 13667 for (var i = types.length; i;) { 13668 this.removeEventListener(types[--i], handler, false); 13669 } 13670 } else { 13671 this.onmousewheel = null; 13672 } 13673 } 13674 }; 13675 $.fn.extend({ 13676 mousewheel: function(fn) { 13677 return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); 13678 }, 13679 unmousewheel: function(fn) { 13680 return this.unbind("mousewheel", fn); 13681 } 13682 }); 13683 13684 function handler(event) { 13685 var orgEvent = event || window.event, 13686 args = [].slice.call(arguments, 1), 13687 delta = 0, 13688 returnValue = true, 13689 deltaX = 0, 13690 deltaY = 0; 13691 event = $.event.fix(orgEvent); 13692 event.type = "mousewheel"; 13693 // Old school scrollwheel delta 13694 if (orgEvent.wheelDelta) { 13695 delta = orgEvent.wheelDelta / 120; 13696 } 13697 if (orgEvent.detail) { 13698 delta = -orgEvent.detail / 3; 13699 } 13700 // New school multidimensional scroll (touchpads) deltas 13701 deltaY = delta; 13702 // Gecko 13703 if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) { 13704 deltaY = 0; 13705 deltaX = -1 * delta; 13706 } 13707 // Webkit 13708 if (orgEvent.wheelDeltaY !== undefined) { 13709 deltaY = orgEvent.wheelDeltaY / 120; 13710 } 13711 if (orgEvent.wheelDeltaX !== undefined) { 13712 deltaX = -1 * orgEvent.wheelDeltaX / 120; 13713 } 13714 // Add event and delta to the front of the arguments 13715 args.unshift(event, delta, deltaX, deltaY); 13716 return ($.event.dispatch || $.event.handle).apply(this, args); 13717 } 13718})(jQuery); 13719/** 13720 * jQuery iLightBox - Revolutionary Lightbox Plugin 13721 * http://www.ilightbox.net/ 13722 * 13723 * @version: 2.2.4 - October 14, 2017 13724 * 13725 * @author: iProDev (Hemn Chawroka) 13726 * http://www.iprodev.com/ 13727 * 13728 */ 13729(function($, window, undefined) { 13730 13731 var extensions = { 13732 flash: ['swf'], 13733 image: ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe', 'webp'], 13734 iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'jsp', 'php', 'pl', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt'], 13735 video: ['avi', 'mov', 'mpg', 'mpeg', 'movie', 'mp4', 'webm', 'ogv', 'ogg', '3gp', 'm4v'] 13736 }, 13737 13738 // Global DOM elements 13739 $win = $(window), 13740 $doc = $(document), 13741
13742 // Support indicators 13743 browser, 13744 transform, 13745 gpuAcceleration, 13746 fullScreenApi = '', 13747 userAgent = navigator.userAgent || navigator.vendor || window.opera, 13748 supportTouch = "ontouchstart" in window || navigator.msMaxTouchPoints || (navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1), 13749 ishybrid = navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1, 13750 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)), 13751 13752 // Events 13753 clickEvent = ishybrid ? "itap.iLightBox click.iLightBox" : supportTouch ? "itap.iLightBox" : "click.iLightBox", 13754 touchStartEvent = ishybrid ? "touchstart.iLightBox mousedown.iLightBox" : supportTouch ? "touchstart.iLightBox" : "mousedown.iLightBox", 13755 touchStopEvent = ishybrid ? "touchend.iLightBox mouseup.iLightBox" : supportTouch ? "touchend.iLightBox" : "mouseup.iLightBox", 13756 touchMoveEvent = ishybrid ? "touchmove.iLightBox mousemove.iLightBox" : supportTouch ? "touchmove.iLightBox" : "mousemove.iLightBox", 13757 13758 // Math shorthands 13759 abs = Math.abs, 13760 sqrt = Math.sqrt, 13761 round = Math.round, 13762 max = Math.max, 13763 min = Math.min, 13764 floor = Math.floor, 13765 random = Math.random, 13766 13767 pluginspages = { 13768 quicktime: 'http://www.apple.com/quicktime/download', 13769 flash: 'http://www.adobe.com/go/getflash' 13770 }, 13771 13772 iLightBox = function(el, options, items, instant) { 13773 var iL = this; 13774 13775 iL.options = options, 13776 iL.selector = options.selector || el, 13777 iL.context = document, 13778 iL.instant = instant; 13779 13780 if (items.length < 1) iL.attachItems(); 13781 else iL.items = items; 13782 13783 iL.vars = { 13784 total: iL.items.length, 13785 start: 0, 13786 current: null, 13787 next: null, 13788 prev: null, 13789 BODY: $('body'), 13790 loadRequests: 0, 13791 overlay: $('<div class="ilightbox-overlay"></div>'), 13792 loader: $('<div class="ilightbox-loader"><div></div></div>'), 13793 toolbar: $('<div class="ilightbox-toolbar"></div>'), 13794 innerToolbar: $('<div class="ilightbox-inner-toolbar"></div>'), 13795 title: $('<div class="ilightbox-title"></div>'), 13796 closeButton: $('<a class="ilightbox-close" title="' + iL.options.text.close + '"></a>'), 13797 fullScreenButton: $('<a class="ilightbox-fullscreen" title="' + iL.options.text.enterFullscreen + '"></a>'), 13798 innerPlayButton: $('<a class="ilightbox-play" title="' + iL.options.text.slideShow + '"></a>'), 13799 innerNextButton: $('<a class="ilightbox-next-button" title="' + iL.options.text.next + '"></a>'), 13800 innerPrevButton: $('<a class="ilightbox-prev-button" title="' + iL.options.text.previous + '"></a>'), 13801 holder: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + '" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13802 nextPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-next" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13803 prevPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-prev" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 13804 nextButton: $('<a class="ilightbox-button ilightbox-next-button" ondragstart="return false;" title="' + iL.options.text.next + '"><span></span></a>'), 13805 prevButton: $('<a class="ilightbox-button ilightbox-prev-button" ondragstart="return false;" title="' + iL.options.text.previous + '"><span></span></a>'),
13806 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>'), 13807 thumbs: false, 13808 nextLock: false, 13809 prevLock: false, 13810 hashLock: false, 13811 isMobile: false, 13812 mobileMaxWidth: 980, 13813 isInFullScreen: false, 13814 isSwipe: false, 13815 mouseID: 0, 13816 cycleID: 0, 13817 isPaused: 0, 13818 captionHeight: 39, 13819 }; 13820 13821 // Hideable elements with mousemove event 13822 iL.vars.hideableElements = iL.vars.nextButton.add(iL.vars.prevButton); 13823 13824 iL.normalizeItems(); 13825 13826 //Check necessary plugins 13827 iL.availPlugins(); 13828 13829 //Set startFrom 13830 iL.options.startFrom = (iL.options.startFrom > 0 && iL.options.startFrom >= iL.vars.total) ? iL.vars.total - 1 : iL.options.startFrom; 13831 13832 //If randomStart 13833 iL.options.startFrom = (iL.options.randomStart) ? floor(random() * iL.vars.total) : iL.options.startFrom; 13834 iL.vars.start = iL.options.startFrom; 13835 13836 if (instant) iL.instantCall(); 13837 else iL.patchItemsEvents(); 13838 13839 if (iL.options.linkId) { 13840 iL.hashChangeHandler(); 13841 $win.iLightBoxHashChange(function() { 13842 iL.hashChangeHandler(); 13843 }); 13844 } 13845 13846 if (supportTouch) { 13847 var RegExp = /(click|mouseenter|mouseleave|mouseover|mouseout)/ig, 13848 replace = "itap"; 13849 iL.options.caption.show = iL.options.caption.show.replace(RegExp, replace), 13850 iL.options.caption.hide = iL.options.caption.hide.replace(RegExp, replace), 13851 iL.options.social.show = iL.options.social.show.replace(RegExp, replace), 13852 iL.options.social.hide = iL.options.social.hide.replace(RegExp, replace); 13853 } 13854 13855 if (iL.options.controls.arrows || $(window).width() < UNCODE.mediaQuery) { 13856 $.extend(iL.options.styles, { 13857 nextOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 13858 prevOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 13859 nextOpacity: 0, 13860 prevOpacity: 0 13861 }); 13862 } 13863 }; 13864 13865 //iLightBox helpers 13866 iLightBox.prototype = { 13867 showLoader: function() { 13868 var iL = this; 13869 iL.vars.loadRequests += 1; 13870 if (iL.options.path.toLowerCase() == "horizontal") iL.vars.loader.addClass('ilightbox-show').stop().animate({ 13871 //top: '-30px' 13872 opacity: '1' 13873 }, iL.options.show.speed, 'easeOutCirc'); 13874 else iL.vars.loader.addClass('ilightbox-show').stop().animate({ 13875 //left: '-30px' 13876 opacity: '1' 13877 }, iL.options.show.speed, 'easeOutCirc'); 13878 }, 13879 13880 hideLoader: function() { 13881 var iL = this; 13882 iL.vars.loadRequests -= 1; 13883 iL.vars.loadRequests = (iL.vars.loadRequests < 0) ? 0 : iL.vars.loadRequests; 13884 if (iL.options.path.toLowerCase() == "horizontal") { 13885 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 13886 //top: '-192px' 13887 opacity: '0' 13888 }, iL.options.show.speed, 'easeInCirc'); 13889 } else { 13890 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 13891 //left: '-192px' 13892 opacity: '0' 13893 }, iL.options.show.speed, 'easeInCirc'); 13894 } 13895 }, 13896 13897 createUI: function() { 13898 var iL = this; 13899 13900 iL.ui = { 13901 currentElement: iL.vars.holder, 13902 nextElement: iL.vars.nextPhoto, 13903 prevElement: iL.vars.prevPhoto, 13904 currentItem: iL.vars.current, 13905 nextItem: iL.vars.next, 13906 prevItem: iL.vars.prev, 13907 hide: function() { 13908 iL.closeAction(); 13909 }, 13910 refresh: function() { 13911 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 13912 }, 13913 fullscreen: function() { 13914 iL.fullScreenAction(); 13915 } 13916 }; 13917 }, 13918 13919 attachItems: function() { 13920 var iL = this, 13921 itemsObject = new Array(), 13922 items = new Array(); 13923 13924 $(iL.selector, iL.context).each(function() { 13925 var t = $(this), 13926 URL = t.attr(iL.options.attr) || null, 13927 options = t.data("options") && eval("({" + t.data("options") + "})") || {}, 13928 caption = t.data('caption'), 13929 title = t.data('title'), 13930 type = t.data('type') || getTypeByExtension(URL), 13931 clone = t.data('lbox-clone') || false; 13932 13933 //Uncode addition ##START## 13934 if (type === false) { 13935 return; 13936 } 13937 //Uncode addition ##END## 13938 13939 if (t.data('lbox-clone') != undefined) return; 13940 13941 //Uncode addition ##START## 13942 if ( typeof t.attr('data-album') != 'undefined' && t.attr('data-album') != '' ) { 13943 var ALBUM_URLS = JSON.parse(t.attr('data-album')), 13944 URL_i, 13945 URLS_LENGHT = ALBUM_URLS.length; 13946 13947 for (URL_i = 0; URL_i < URLS_LENGHT; URL_i++) { 13948 if ( typeof ALBUM_URLS[URL_i].url !== 'undefined' && ALBUM_URLS[URL_i].url != '' ) { 13949 var item_opts = 'width:' + ALBUM_URLS[URL_i].width + ',height:' + ALBUM_URLS[URL_i].height + ',thumbnail: \'' + ALBUM_URLS[URL_i].thumbnail + '\''; 13950 item_opts = item_opts && eval("({" + item_opts + "})") || {}, 13951 items.push({ 13952 URL: ALBUM_URLS[URL_i].url, 13953 caption: ALBUM_URLS[URL_i].caption, 13954 title: ALBUM_URLS[URL_i].title, 13955 type: getTypeByExtension(ALBUM_URLS[URL_i].url), 13956 options: item_opts, 13957 clone: clone 13958 }); 13959 var newT = t; 13960 newT.attr('href',ALBUM_URLS[URL_i].url); 13961 if (!iL.instant) itemsObject.push(newT); 13962 } 13963 } 13964 } else { 13965 //Uncode addition ##END## 13966 items.push({ 13967 URL: URL, 13968 caption: caption, 13969 title: title, 13970 type: type, 13971 options: options, 13972 clone: clone 13973 }); 13974 } 13975 13976 13977 if (iL.vars != undefined) iL.vars.total = items.length; 13978 13979 if (!iL.instant) itemsObject.push(t); 13980 }); 13981 13982 iL.items = items, 13983 iL.itemsObject = itemsObject; 13984 13985 }, 13986 13987 normalizeItems: function() { 13988 var iL = this, 13989 newItems = new Array(); 13990 13991 $.each(iL.items, function(key, val) { 13992 13993 if (typeof val == "string") val = { 13994 url: val 13995 }; 13996 13997 var URL = val.url || val.URL || null, 13998 options = val.options || {}, 13999 caption = val.caption || null, 14000 title = val.title || null, 14001 type = (val.type) ? val.type.toLowerCase() : getTypeByExtension(URL), 14002 ext = (typeof URL != 'object') ? getExtension(URL) : ''; 14003 14004 options.thumbnail = options.thumbnail || ((type == "image") ? URL : null),
14005 options.videoType = options.videoType || null, 14006 options.skin = options.skin || iL.options.skin, 14007 options.width = options.width || null, 14008 options.height = options.height || null, 14009 options.mousewheel = (typeof options.mousewheel != 'undefined') ? options.mousewheel : true, 14010 options.swipe = (typeof options.swipe != 'undefined') ? options.swipe : true, 14011 options.social = (typeof options.social != 'undefined') ? options.social : iL.options.social.buttons && $.extend({}, {}, iL.options.social.buttons); 14012 14013 if (type == "video") { 14014 options.html5video = (typeof options.html5video != 'undefined') ? options.html5video : {}; 14015 14016 options.html5video.webm = options.html5video.webm || options.html5video.WEBM || null; 14017 options.html5video.controls = (typeof options.html5video.controls != 'undefined') ? options.html5video.controls : "controls"; 14018 options.html5video.preload = options.html5video.preload || "metadata"; 14019 options.html5video.autoplay = (typeof options.html5video.autoplay != 'undefined') ? options.html5video.autoplay : false; 14020 //UNCODE addition 14021 options.html5video.loop = (typeof options.html5video.loop != 'undefined') ? options.html5video.loop : false; 14022 } 14023 14024 if (!options.width || !options.height) { 14025 if (type == "video") options.width = 1280, options.height = 720; 14026 else if (type == "iframe") options.width = '100%', options.height = '90%'; 14027 else if (type == "flash") options.width = 1280, options.height = 720; 14028 } 14029 14030 delete val.url; 14031 val.index = key; 14032 val.URL = URL; 14033 val.caption = caption; 14034 val.title = title; 14035 val.type = type; 14036 val.options = options; 14037 val.ext = ext; 14038 14039 newItems.push(val); 14040 }); 14041 14042 iL.items = newItems; 14043 }, 14044 14045 instantCall: function() { 14046 var iL = this, 14047 key = iL.vars.start; 14048 14049 iL.vars.current = key; 14050 iL.vars.next = (iL.items[key + 1]) ? key + 1 : null; 14051 iL.vars.prev = (iL.items[key - 1]) ? key - 1 : null; 14052 14053 iL.addContents(); 14054 iL.patchEvents(); 14055 }, 14056 14057 addContents: function() { 14058 var iL = this, 14059 vars = iL.vars, 14060 opts = iL.options, 14061 viewport = getViewport(), 14062 path = opts.path.toLowerCase(), 14063 recognizingItems = vars.total > 0 && iL.items.filter(function(e, i, arr) { 14064 return ['image', 'flash', 'video'].indexOf(e.type) === -1 && typeof e.recognized === 'undefined' && (opts.smartRecognition || e.options.smartRecognition); 14065 }), 14066 needRecognition = recognizingItems.length > 0; 14067 14068 if (opts.mobileOptimizer && !opts.innerToolbar) 14069 vars.isMobile = viewport.width <= vars.mobileMaxWidth; 14070 14071 vars.overlay.addClass(opts.skin).hide().css('opacity', opts.overlay.opacity); 14072 14073 if (opts.linkId) 14074 vars.overlay[0].setAttribute('linkid', opts.linkId); 14075 14076 //Add Toolbar Buttons 14077 if (opts.controls.toolbar) { 14078 vars.toolbar.addClass(opts.skin).append(vars.closeButton); 14079 if (opts.controls.fullscreen) 14080 vars.toolbar.append(vars.fullScreenButton); 14081 if (opts.controls.slideshow) 14082 vars.toolbar.append(vars.innerPlayButton); 14083 if (vars.total > 1) 14084 vars.toolbar.append(vars.innerPrevButton).append(vars.innerNextButton); 14085 } 14086 14087 //Append elements to body 14088 vars.BODY.addClass('ilightbox-noscroll').append(vars.overlay).append(vars.loader).append(vars.holder).append(vars.nextPhoto).append(vars.prevPhoto); 14089 14090 if (!opts.innerToolbar) 14091 vars.BODY.append(vars.toolbar); 14092 if (opts.controls.arrows) 14093 vars.BODY.append(vars.nextButton).append(vars.prevButton); 14094 14095 if (opts.controls.thumbnail && vars.total > 1) { 14096 vars.BODY.append(vars.thumbnails); 14097 vars.thumbnails.addClass(opts.skin).addClass('ilightbox-' + path); 14098 $('div.ilightbox-thumbnails-grid', vars.thumbnails).empty(); 14099 vars.thumbs = true; 14100 } 14101 14102 //Configure loader and arrows 14103 var loaderCss = (opts.path.toLowerCase() == "horizontal") ? { 14104 left: parseInt((viewport.width / 2) - (vars.loader.outerWidth() / 2)) 14105 } : { 14106 top: parseInt((viewport.height / 2) - (vars.loader.outerHeight() / 2)) 14107 }; 14108 vars.loader.addClass(opts.skin).css(loaderCss); 14109 vars.nextButton.add(vars.prevButton).addClass(opts.skin); 14110 if (path == "horizontal") 14111 vars.loader.add(vars.nextButton).add(vars.prevButton).addClass('horizontal'); 14112 14113 // Configure arrow buttons 14114 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 14115 14116 if (!opts.infinite) { 14117 vars.prevButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 14118 14119 if (vars.current == 0) 14120 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 14121 if (vars.current >= vars.total - 1) 14122 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 14123 } 14124 14125 if (opts.show.effect) { 14126 vars.overlay.stop().fadeIn(opts.show.speed); 14127 vars.toolbar.stop().fadeIn(opts.show.speed); 14128 } else { 14129 vars.overlay.show(); 14130 vars.toolbar.show(); 14131 } 14132 14133 var length = recognizingItems.length; 14134 if (needRecognition) { 14135 iL.showLoader(); 14136 14137 $.each(recognizingItems, function(key, val) { 14138 var resultFnc = function(result) { 14139 var key = -1, 14140 filter = iL.items.filter(function(e, i, arr) { 14141 if (e.URL == result.url) 14142 key = i; 14143 14144 return e.URL == result.url; 14145 }), 14146 self = iL.items[key]; 14147 14148 if (result) 14149 $.extend(true, self, { 14150 URL: result.source, 14151 type: result.type, 14152 recognized: true, 14153 options: { 14154 html5video: result.html5video, 14155 width: (result.type == "image") ? 0 : (result.width || self.width), 14156 height: (result.type == "image") ? 0 : (result.height || self.height), 14157 thumbnail: self.options.thumbnail || result.thumbnail 14158 } 14159 }); 14160 14161 length--; 14162 14163 if (length == 0) { 14164 iL.hideLoader(); 14165 14166 vars.dontGenerateThumbs = false;
14167 iL.generateThumbnails(); 14168 14169 if (opts.show.effect) 14170 setTimeout(function() { 14171 iL.generateBoxes(); 14172 }, opts.show.speed); 14173 else 14174 iL.generateBoxes(); 14175 } 14176 }; 14177 14178 iL.ogpRecognition(this, resultFnc); 14179 }); 14180 } 14181 else { 14182 if (opts.show.effect) 14183 setTimeout(function() { 14184 iL.generateBoxes(); 14185 }, opts.show.speed); 14186 else 14187 iL.generateBoxes(); 14188 } 14189 14190 iL.createUI(); 14191 14192 window.iLightBox = { 14193 close: function() { 14194 iL.closeAction(); 14195 }, 14196 fullscreen: function() { 14197 iL.fullScreenAction(); 14198 }, 14199 moveNext: function() { 14200 iL.moveTo('next'); 14201 }, 14202 movePrev: function() { 14203 iL.moveTo('prev'); 14204 }, 14205 goTo: function(index) { 14206 iL.goTo(index); 14207 }, 14208 refresh: function() { 14209 iL.refresh(); 14210 }, 14211 reposition: function() { 14212 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 14213 }, 14214 setOption: function(options) { 14215 iL.setOption(options); 14216 }, 14217 destroy: function() { 14218 iL.closeAction(); 14219 iL.dispatchItemsEvents(); 14220 } 14221 }; 14222 14223 if (opts.linkId) { 14224 vars.hashLock = true; 14225 window.location.hash = opts.linkId + '/' + vars.current; 14226 setTimeout(function() { 14227 vars.hashLock = false; 14228 }, 55); 14229 } 14230 14231 if (!opts.slideshow.startPaused) { 14232 iL.resume(); 14233 vars.innerPlayButton.removeClass('ilightbox-play').addClass('ilightbox-pause'); 14234 } 14235 14236 //Trigger the onOpen callback 14237 if (typeof iL.options.callback.onOpen == 'function') iL.options.callback.onOpen.call(iL); 14238 }, 14239 14240 loadContent: function(obj, opt, speed) { 14241 var iL = this, 14242 holder, item; 14243 14244 iL.createUI(); 14245 14246 obj.speed = speed || iL.options.effects.loadedFadeSpeed; 14247 14248 if (opt == 'current') { 14249 if (!obj.options.mousewheel) iL.vars.lockWheel = true; 14250 else iL.vars.lockWheel = false; 14251 14252 if (!obj.options.swipe) iL.vars.lockSwipe = true; 14253 else iL.vars.lockSwipe = false; 14254 } 14255 14256 switch (opt) { 14257 case 'current': 14258 holder = iL.vars.holder, item = iL.vars.current; 14259 break; 14260 case 'next': 14261 holder = iL.vars.nextPhoto, item = iL.vars.next; 14262 break; 14263 case 'prev': 14264 holder = iL.vars.prevPhoto, item = iL.vars.prev; 14265 break; 14266 } 14267 14268 holder.removeAttr('style class').addClass('ilightbox-holder' + (supportTouch ? ' supportTouch' : '')).addClass(obj.options.skin); 14269 $('div.ilightbox-inner-toolbar', holder).remove(); 14270 14271 if (obj.title || iL.options.innerToolbar) { 14272 var innerToolbar = iL.vars.innerToolbar.clone(); 14273 if (obj.title && iL.options.show.title) { 14274 var title = iL.vars.title.clone(); 14275 title.empty().html(obj.title); 14276 innerToolbar.append(title); 14277 } 14278 if (iL.options.innerToolbar) { 14279 innerToolbar.append((iL.vars.total > 1) ? iL.vars.toolbar.clone() : iL.vars.toolbar); 14280 } 14281 holder.prepend(innerToolbar); 14282 } 14283 14284 //console.warn('loadContent', arguments); 14285 14286 iL.loadSwitcher(obj, holder, item, opt); 14287 }, 14288 14289 loadSwitcher: function(obj, holder, item, opt) { 14290 var iL = this, 14291 opts = iL.options, 14292 api = { 14293 element: holder, 14294 position: item 14295 }; 14296 14297 switch (obj.type) { 14298 case 'image': 14299 //Trigger the onBeforeLoad callback 14300 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14301 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14302 14303 iL.loadImage(obj.URL, function(img) { 14304 //Trigger the onAfterLoad callback 14305 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14306 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14307 14308 var width = (img) ? img.width : 400, 14309 height = (img) ? img.height : 200; 14310 14311 holder.data({ 14312 naturalWidth: width, 14313 naturalHeight: height 14314 }); 14315 14316 $('div.ilightbox-container', holder).empty().append((img) ? '<img src="' + obj.URL + '" class="ilightbox-image" />' : '<span class="ilightbox-alert">' + opts.errors.loadImage + '</span>'); 14317 14318 //Trigger the onRender callback 14319 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14320 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14321 14322 iL.configureHolder(obj, opt, holder); 14323 }); 14324 14325 break; 14326
14327 case 'video': 14328 holder.data({ 14329 naturalWidth: obj.options.width, 14330 naturalHeight: obj.options.height 14331 }); 14332 14333 if (opt === 'current') { 14334 iL.addContent(holder, obj); 14335 14336 //Trigger the onRender callback 14337 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14338 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14339 } else { 14340 $('div.ilightbox-container', holder).empty(); 14341 } 14342 14343 iL.configureHolder(obj, opt, holder); 14344 14345 break; 14346 14347 case 'iframe': 14348 //iL.showLoader(); 14349 holder.data({ 14350 naturalWidth: obj.options.width, 14351 naturalHeight: obj.options.height 14352 }); 14353 14354 iL.configureHolder(obj, opt, holder); 14355 14356 if (opt === 'current') { 14357 var el = iL.addContent(holder, obj); 14358 14359 //Trigger the onRender callback 14360 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14361 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14362 14363 //Trigger the onBeforeLoad callback 14364 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14365 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14366 14367 el.bind('load', function() { 14368 //Trigger the onAfterLoad callback 14369 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14370 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14371 14372 //iL.hideLoader(); 14373 el.unbind('load'); 14374 }); 14375 } else { 14376 $('div.ilightbox-container', holder).empty(); 14377 } 14378 14379 break; 14380 14381 case 'inline': 14382 var el = $(obj.URL), 14383 content = iL.addContent(holder, obj), 14384 images = findImageInElement(holder); 14385 14386 holder.data({ 14387 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 14388 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 14389 }); 14390 content.children().eq(0).show(); 14391 14392 //Trigger the onRender callback 14393 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14394 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14395 14396 //Trigger the onBeforeLoad callback 14397 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14398 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14399 14400 iL.loadImage(images, function() { 14401 //Trigger the onAfterLoad callback 14402 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14403 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14404 14405 iL.configureHolder(obj, opt, holder); 14406 }); 14407 14408 break; 14409 14410 case 'flash': 14411 var el = iL.addContent(holder, obj); 14412 14413 holder.data({ 14414 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 14415 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 14416 }); 14417 14418 //Trigger the onRender callback 14419 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14420 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14421 14422 iL.configureHolder(obj, opt, holder); 14423 14424 break; 14425 14426 case 'ajax': 14427 var ajax = obj.options.ajax || {}; 14428 //Trigger the onBeforeLoad callback 14429 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14430 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14431 14432 iL.showLoader(); 14433 $.ajax({ 14434 url: obj.URL || opts.ajaxSetup.url, 14435 data: ajax.data || null, 14436 dataType: ajax.dataType || "html", 14437 type: ajax.type || opts.ajaxSetup.type, 14438 cache: ajax.cache || opts.ajaxSetup.cache, 14439 crossDomain: ajax.crossDomain || opts.ajaxSetup.crossDomain, 14440 global: ajax.global || opts.ajaxSetup.global, 14441 ifModified: ajax.ifModified || opts.ajaxSetup.ifModified, 14442 username: ajax.username || opts.ajaxSetup.username, 14443 password: ajax.password || opts.ajaxSetup.password, 14444 beforeSend: ajax.beforeSend || opts.ajaxSetup.beforeSend, 14445 complete: ajax.complete || opts.ajaxSetup.complete, 14446 success: function(data, textStatus, jqXHR) { 14447 iL.hideLoader(); 14448 14449 var el = $(data), 14450 container = $('div.ilightbox-container', holder), 14451 elWidth = iL.items[item].options.width || parseInt(el[0].getAttribute('width')), 14452 elHeight = iL.items[item].options.height || parseInt(el[0].getAttribute('height')), 14453 css = (el[0].getAttribute('width') && el[0].getAttribute('height')) ? { 14454 'overflow': 'hidden' 14455 } : {}; 14456 14457 container.empty().append($('<div class="ilightbox-wrapper"></div>').css(css).html(el)); 14458 holder.show().data({
14459 naturalWidth: (elWidth || container.outerWidth()), 14460 naturalHeight: (elHeight || container.outerHeight()) 14461 }).hide(); 14462 14463 //Trigger the onRender callback 14464 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14465 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14466 14467 var images = findImageInElement(holder); 14468 iL.loadImage(images, function() { 14469 //Trigger the onAfterLoad callback 14470 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14471 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14472 14473 iL.configureHolder(obj, opt, holder); 14474 }); 14475 14476 opts.ajaxSetup.success(data, textStatus, jqXHR); 14477 if (typeof ajax.success == 'function') ajax.success(data, textStatus, jqXHR); 14478 }, 14479 error: function(jqXHR, textStatus, errorThrown) { 14480 //Trigger the onAfterLoad callback 14481 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14482 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14483 14484 iL.hideLoader(); 14485 $('div.ilightbox-container', holder).empty().append('<span class="ilightbox-alert">' + opts.errors.loadContents + '</span>'); 14486 iL.configureHolder(obj, opt, holder); 14487 14488 opts.ajaxSetup.error(jqXHR, textStatus, errorThrown); 14489 if (typeof ajax.error == 'function') ajax.error(jqXHR, textStatus, errorThrown); 14490 } 14491 }); 14492 14493 break; 14494 14495 case 'html': 14496 var object = obj.URL, 14497 el 14498 container = $('div.ilightbox-container', holder); 14499 14500 if (object[0].nodeName) el = object.clone(); 14501 else { 14502 var dom = $(object); 14503 if (dom.selector) el = $('<div>' + dom + '</div>'); 14504 else el = dom; 14505 } 14506 14507 var elWidth = iL.items[item].options.width || parseInt(el.attr('width')), 14508 elHeight = iL.items[item].options.height || parseInt(el.attr('height')); 14509 14510 iL.addContent(holder, obj); 14511 14512 el.appendTo(document.documentElement).hide(); 14513 14514 //Trigger the onRender callback 14515 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 14516 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 14517 14518 var images = findImageInElement(holder); 14519 14520 //Trigger the onBeforeLoad callback 14521 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 14522 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 14523 14524 iL.loadImage(images, function() { 14525 //Trigger the onAfterLoad callback 14526 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 14527 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 14528 14529 holder.show().data({ 14530 naturalWidth: (elWidth || container.outerWidth()), 14531 naturalHeight: (elHeight || container.outerHeight()) 14532 }).hide(); 14533 el.remove(); 14534 14535 iL.configureHolder(obj, opt, holder); 14536 }); 14537 14538 break; 14539 } 14540 }, 14541 14542 configureHolder: function(obj, opt, holder) { 14543 var iL = this, 14544 vars = iL.vars, 14545 opts = iL.options; 14546 14547 if (opt != "current")(opt == "next") ? holder.addClass('ilightbox-next') : holder.addClass('ilightbox-prev'); 14548 14549 if (opt == "current") 14550 var item = vars.current; 14551 else if (opt == "next") 14552 var opacity = opts.styles.nextOpacity, 14553 item = vars.next; 14554 else 14555 var opacity = opts.styles.prevOpacity, 14556 item = vars.prev; 14557 14558 var api = { 14559 element: holder, 14560 position: item 14561 }; 14562 14563 iL.items[item].options.width = iL.items[item].options.width || 0, 14564 iL.items[item].options.height = iL.items[item].options.height || 0; 14565 14566 if (opt == "current") { 14567 if (opts.show.effect) holder.css(transform, gpuAcceleration).fadeIn(obj.speed, function() { 14568 holder.css(transform, ''); 14569 if (obj.caption) { 14570 iL.setCaption(obj, holder); 14571 var caption = $('div.ilightbox-caption', holder), 14572 percent = parseInt((caption.outerHeight() / holder.outerHeight()) * 100); 14573 if (opts.caption.start & percent <= 50) caption.fadeIn(opts.effects.fade
14573Speed); 14574 } 14575 14576 var social = obj.options.social; 14577 if (social) { 14578 iL.setSocial(social, obj.URL, holder); 14579 if (opts.social.start) $('div.ilightbox-social', holder).fadeIn(opts.effects.fadeSpeed); 14580 } 14581 14582 //Generate thumbnails 14583 iL.generateThumbnails(); 14584 14585 //Trigger the onShow callback 14586 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14587 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14588 }); 14589 else { 14590 holder.show(); 14591 14592 //Generate thumbnails 14593 iL.generateThumbnails(); 14594 14595 //Trigger the onShow callback 14596 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14597 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14598 } 14599 } else { 14600 if (opts.show.effect) holder.fadeTo(obj.speed, opacity, function() { 14601 if (opt == "next") vars.nextLock = false; 14602 else vars.prevLock = false; 14603 14604 //Generate thumbnails 14605 iL.generateThumbnails(); 14606 14607 //Trigger the onShow callback 14608 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14609 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14610 }); 14611 else { 14612 holder.css({ 14613 opacity: opacity 14614 }).show(); 14615 if (opt == "next") vars.nextLock = false; 14616 else vars.prevLock = false; 14617 14618 //Generate thumbnails 14619 iL.generateThumbnails(); 14620 14621 //Trigger the onShow callback 14622 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 14623 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 14624 } 14625 } 14626 14627 setTimeout(function() { 14628 iL.repositionPhoto(); 14629 }, 0); 14630 }, 14631 14632 generateBoxes: function() { 14633 var iL = this, 14634 vars = iL.vars, 14635 opts = iL.options; 14636 14637 if (opts.infinite && vars.total >= 3) { 14638 if (vars.current == vars.total - 1) vars.next = 0; 14639 if (vars.current == 0) vars.prev = vars.total - 1; 14640 } else opts.infinite = false; 14641 14642 //UNCODE addition 14643 if ( typeof iL.items[vars.current] == 'undefined' ) 14644 vars.current = 0; 14645 14646 iL.loadContent(iL.items[vars.current], 'current', opts.show.speed); 14647 14648 if (iL.items[vars.next]) iL.loadContent(iL.items[vars.next], 'next', opts.show.speed); 14649 if (iL.items[vars.prev]) iL.loadContent(iL.items[vars.prev], 'prev', opts.show.speed); 14650 }, 14651 14652 generateThumbnails: function() { 14653 var iL = this, 14654 vars = iL.vars, 14655 opts = iL.options, 14656 timeOut = null; 14657 14658 if (vars.thumbs && !iL.vars.dontGenerateThumbs) { 14659 var thumbnails = vars.thumbnails, 14660 container = $('div.ilightbox-thumbnails-container', thumbnails), 14661 grid = $('div.ilightbox-thumbnails-grid', container), 14662 i = 0; 14663 14664 grid.removeAttr('style').empty(); 14665 14666 $.each(iL.items, function(key, val) { 14667 var isActive = (vars.current == key) ? 'ilightbox-active' : '', 14668 opacity = (vars.current == key) ? opts.thumbnails.activeOpacity : opts.thumbnails.normalOpacity, 14669 thumb = val.options.thumbnail, 14670 thumbnail = $('<div class="ilightbox-thumbnail"></div>'), 14671 icon = $('<div class="ilightbox-thumbnail-icon"></div>'); 14672 14673 thumbnail.css({ 14674 opacity: 0 14675 }).addClass(isActive); 14676 14677 if ((val.type == "video" || val.type == "flash") && typeof val.options.icon == 'undefined') { 14678 icon.addClass('ilightbox-thumbnail-video'); 14679 thumbnail.append(icon); 14680 } else if (val.options.icon) { 14681 icon.addClass('ilightbox-thumbnail-' + val.options.icon); 14682 thumbnail.append(icon); 14683 } 14684 14685 if (thumb) iL.loadImage(thumb, function(img) { 14686 i++; 14687 if (img) thumbnail.data({ 14688 naturalWidth: img.width, 14689 naturalHeight: img.height 14690 }).append('<img src="' + thumb + '" border="0" />'); 14691 else thumbnail.data({ 14692 naturalWidth: opts.thumbnails.maxWidth, 14693 naturalHeight: opts.thumbnails.maxHeight 14694 }); 14695 14696 clearTimeout(timeOut); 14697 timeOut = setTimeout(function() { 14698 iL.positionThumbnails(thumbnails, container, grid); 14699 }, 20); 14700 setTimeout(function() { 14701 thumbnail.fadeTo(opts.effects.loadedFadeSpeed, opacity); 14702 }, i * 20); 14703 }); 14704 14705 grid.append(thumbnail); 14706 }); 14707 iL.vars.dontGenerateThumbs = true; 14708 } 14709 }, 14710
14711 positionThumbnails: function(thumbnails, container, grid) { 14712 var iL = this, 14713 vars = iL.vars, 14714 opts = iL.options, 14715 viewport = getViewport(), 14716 path = opts.path.toLowerCase(); 14717 14718 if (!thumbnails) thumbnails = vars.thumbnails; 14719 if (!container) container = $('div.ilightbox-thumbnails-container', thumbnails); 14720 if (!grid) grid = $('div.ilightbox-thumbnails-grid', container); 14721 14722 var thumbs = $('.ilightbox-thumbnail', grid), 14723 widthAvail = (path == 'horizontal') ? viewport.width - opts.styles.pageOffsetX : thumbs.eq(0).outerWidth() - opts.styles.pageOffsetX, 14724 heightAvail = (path == 'horizontal') ? thumbs.eq(0).outerHeight() - opts.styles.pageOffsetY : viewport.height - opts.styles.pageOffsetY, 14725 gridWidth = (path == 'horizontal') ? 0 : widthAvail, 14726 gridHeight = (path == 'horizontal') ? heightAvail : 0, 14727 active = $('.ilightbox-active', grid), 14728 gridCss = {}, 14729 css = {}; 14730 14731 if (arguments.length < 3) { 14732 thumbs.css({ 14733 opacity: opts.thumbnails.normalOpacity 14734 }); 14735 active.css({ 14736 opacity: opts.thumbnails.activeOpacity 14737 }); 14738 } 14739 14740 thumbs.each(function(i) { 14741 var t = $(this), 14742 data = t.data(), 14743 width = (path == 'horizontal') ? 0 : opts.thumbnails.maxWidth; 14744 height = (path == 'horizontal') ? opts.thumbnails.maxHeight : 0; 14745 dims = iL.getNewDimenstions(width, height, data.naturalWidth, data.naturalHeight, true); 14746 14747 t.css({ 14748 width: dims.width, 14749 height: dims.height 14750 }); 14751 if (path == 'horizontal') t.css({ 14752 'float': 'left' 14753 }); 14754 14755 (path == 'horizontal') ? ( 14756 gridWidth += t.outerWidth() 14757 ) : ( 14758 gridHeight += t.outerHeight() 14759 ); 14760 }); 14761 14762 gridCss = { 14763 width: gridWidth, 14764 height: gridHeight 14765 }; 14766 14767 grid.css(gridCss); 14768 14769 gridCss = {}; 14770 14771 var gridOffset = grid.offset(), 14772 activeOffset = (active.length) ? active.offset() : { 14773 top: parseInt(heightAvail / 2), 14774 left: parseInt(widthAvail / 2) 14775 }; 14776 14777 gridOffset.top = (gridOffset.top - $doc.scrollTop()), 14778 gridOffset.left = (gridOffset.left - $doc.scrollLeft()), 14779 activeOffset.top = (activeOffset.top - gridOffset.top - $doc.scrollTop()), 14780 activeOffset.left = (activeOffset.left - gridOffset.left - $doc.scrollLeft()); 14781 14782 (path == 'horizontal') ? ( 14783 gridCss.top = 0, 14784 gridCss.left = parseInt((widthAvail / 2) - activeOffset.left - (active.outerWidth() / 2)) 14785 ) : ( 14786 gridCss.top = parseInt(((heightAvail / 2) - activeOffset.top - (active.outerHeight() / 2))), 14787 gridCss.left = 0 14788 ); 14789 14790 if (arguments.length < 3) grid.stop().animate(gridCss, opts.effects.repositionSpeed, 'easeOutCirc'); 14791 else grid.css(gridCss); 14792 }, 14793 14794 loadImage: function(image, callback) { 14795 if (!$.isArray(image)) image = [image]; 14796 14797 var iL = this, 14798 length = image.length; 14799 14800 if (length > 0) { 14801 iL.showLoader(); 14802 $.each(image, function(index, value) { 14803 var img = new Image(); 14804 img.onload = function() { 14805 length -= 1; 14806 if (length == 0) { 14807 iL.hideLoader(); 14808 callback(img); 14809 } 14810 }; 14811 img.onerror = img.onabort = function() { 14812 length -= 1; 14813 if (length == 0) { 14814 iL.hideLoader(); 14815 callback(false); 14816 } 14817 }; 14818 img.src = image[index]; 14819 }); 14820 } else callback(false); 14821 }, 14822 14823 patchItemsEvents: function() { 14824 var iL = this, 14825 vars = iL.vars, 14826 clickEvent = ishybrid ? "itap.iL click.iL" : supportTouch ? "itap.iL" : "click.iL", 14827 vEvent = ishybrid ? "click.iL itap.iL" : supportTouch ? "click.iL" : "itap.iL"; 14828 14829 if (iL.context && iL.selector) { 14830 var $items = $(iL.selector, iL.context); 14831 14832 $(iL.context).on(clickEvent, iL.selector, function() { 14833 var $this = $(this), 14834 //UNCODE addition 14835 key = typeof $(this).data('lb-index') !== '' && $(this).closest('.owl-item').length ? $(this).data('lb-index') : $items.index($this); 14836 if (UNCODE.isMobile) { 14837 var isCarousel = $this.closest('.owl-carousel'); 14838 if (isCarousel.length) { 14839 if (isCarousel.hasClass('owl-translating')) return false; 14840 } 14841 } 14842 14843 vars.current = key; 14844 vars.next = iL.items[key + 1] ? key + 1 : null; 14845 vars.prev = iL.items[key - 1] ? key - 1 : null; 14846 14847 //UNCODE addition 14848 if ( vars.BODY.hasClass('fp-slide-scrolling') ) 14849 return false;
14850 14851 iL.addContents(); 14852 iL.patchEvents(); 14853 14854 return false; 14855 }).on(vEvent, iL.selector, function() { 14856 return false; 14857 }); 14858 } else 14859 $.each(iL.itemsObject, function(key, val) { 14860 val.on(clickEvent, function() { 14861 vars.current = key; 14862 vars.next = iL.items[key + 1] ? key + 1 : null; 14863 vars.prev = iL.items[key - 1] ? key - 1 : null; 14864 14865 iL.addContents(); 14866 iL.patchEvents(); 14867 14868 return false; 14869 }).on(vEvent, function() { 14870 return false; 14871 }); 14872 }); 14873 }, 14874 14875 dispatchItemsEvents: function() { 14876 var iL = this, 14877 vars = iL.vars, 14878 opts = iL.options; 14879 14880 if (iL.context && iL.selector) 14881 $(iL.context).off('.iL', iL.selector); 14882 else 14883 $.each(iL.itemsObject, function(key, val) { 14884 val.off('.iL'); 14885 }); 14886 }, 14887 14888 refresh: function() { 14889 var iL = this; 14890 14891 iL.dispatchItemsEvents(); 14892 iL.attachItems(); 14893 iL.normalizeItems(); 14894 iL.patchItemsEvents(); 14895 }, 14896 14897 patchEvents: function() { 14898 var iL = this, 14899 vars = iL.vars, 14900 opts = iL.options, 14901 path = opts.path.toLowerCase(), 14902 holders = $('.ilightbox-holder'), 14903 fullscreenEvent = fullScreenApi.fullScreenEventName + '.iLightBox', 14904 durationThreshold = 1000, 14905 horizontalDistanceThreshold = 14906 verticalDistanceThreshold = 100, 14907 buttonsArray = [vars.nextButton[0], vars.prevButton[0], vars.nextButton[0].firstChild, vars.prevButton[0].firstChild]; 14908 14909 $win.bind('resize.iLightBox', function() { 14910 var viewport = getViewport(); 14911 14912 if (opts.mobileOptimizer && !opts.innerToolbar) vars.isMobile = viewport.width <= vars.mobileMaxWidth; 14913 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 14914 14915 iL.repositionPhoto(null); 14916 if (supportTouch) { 14917 clearTimeout(vars.setTime); 14918 vars.setTime = setTimeout(function() { 14919 var scrollTop = getScrollXY().y; 14920 window.scrollTo(0, scrollTop - 30); 14921 window.scrollTo(0, scrollTop + 30); 14922 window.scrollTo(0, scrollTop); 14923 }, 2000); 14924 } 14925 if (vars.thumbs) iL.positionThumbnails(); 14926 }).bind('keydown.iLightBox', function(event) { 14927 if (opts.controls.keyboard) { 14928 switch (event.keyCode) { 14929 case 13: 14930 if (event.shiftKey && opts.keyboard.shift_enter) iL.fullScreenAction(); 14931 break; 14932 case 27: 14933 if (opts.keyboard.esc) iL.closeAction(); 14934 break; 14935 case 37: 14936 if (opts.keyboard.left && !vars.lockKey) iL.moveTo('prev'); 14937 break; 14938 case 38: 14939 if (opts.keyboard.up && !vars.lockKey) iL.moveTo('prev'); 14940 break; 14941 case 39: 14942 if (opts.keyboard.right && !vars.lockKey) iL.moveTo('next'); 14943 break; 14944 case 40: 14945 if (opts.keyboard.down && !vars.lockKey) iL.moveTo('next'); 14946 break; 14947 } 14948 } 14949 }); 14950 14951 if (fullScreenApi.supportsFullScreen) $win.bind(fullscreenEvent, function() { 14952 iL.doFullscreen(); 14953 }); 14954 14955 var holderEventsArr = [opts.caption.show + '.iLightBox', opts.caption.hide + '.iLightBox', opts.social.show + '.iLightBox', opts.social.hide + '.iLightBox'].filter(function(e, i, arr) { 14956 return arr.lastIndexOf(e) === i; 14957 }), 14958 holderEvents = ""; 14959 14960 $.each(holderEventsArr, function(key, val) { 14961 if (key != 0) holderEvents += ' '; 14962 holderEvents += val; 14963 }); 14964 14965 $doc.on(clickEvent, '.ilightbox-overlay', function() { 14966 if (opts.overlay.blur) iL.closeAction(); 14967 }).on(clickEvent, '.ilightbox-next, .ilightbox-next-button', function() { 14968 iL.moveTo('next'); 14969 }).on(clickEvent, '.ilightbox-prev, .ilightbox-prev-button', function() { 14970 iL.moveTo('prev'); 14971 }).on(clickEvent, '.ilightbox-thumbnail', function() { 14972 var t = $(this), 14973 thumbs = $('.ilightbox-thumbnail', vars.thumbnails), 14974 index = thumbs.index(t); 14975 14976 if (index != vars.current) iL.goTo(index); 14977 }).on(holderEvents, '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 14978 var caption = $('div.ilightbox-caption', vars.holder), 14979 social = $('div.ilightbox-social', vars.holder), 14980 fadeSpeed = opts.effects.fadeSpeed; 14981 14982 if (vars.nextLock || vars.prevLock) { 14983 if (e.type == opts.caption.show && !caption.is(':visible')) caption.fadeIn(fadeSpeed); 14984 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.fadeOut(fadeSpeed); 14985 14986 if (e.type == opts.social.show && !social.is(':visible')) social.fadeIn(fadeSpeed); 14987 else if (e.type == opts.social.hide && social.is(':visible')) social.fadeOut(fadeSpeed); 14988 } else { 14989 if (e.type == opts.caption.show && !caption.is(':visible')) caption.stop().fadeIn(fadeSpeed); 14990 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.stop().fadeOut(fadeSpeed); 14991 14992 if (e.type == opts.social.show && !social.is(':visible')) social.stop().fadeIn(fadeSpeed); 14993 else if (e.type == opts.social.hide && social.is(':visible')) social.stop().fadeOut(fadeSpeed); 14994 } 14995 }).on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-wrapper', function(e) { 14996 if (e.type == 'mouseenter') vars.lockWheel = true; 14997 else vars.lockWheel = false;
14998 }).on(clickEvent, '.ilightbox-toolbar a.ilightbox-close, .ilightbox-toolbar a.ilightbox-fullscreen, .ilightbox-toolbar a.ilightbox-play, .ilightbox-toolbar a.ilightbox-pause', function() { 14999 var t = $(this); 15000 15001 if (t.hasClass('ilightbox-fullscreen')) iL.fullScreenAction(); 15002 else if (t.hasClass('ilightbox-play')) { 15003 iL.resume(); 15004 t.addClass('ilightbox-pause').removeClass('ilightbox-play'); 15005 } else if (t.hasClass('ilightbox-pause')) { 15006 iL.pause(); 15007 t.addClass('ilightbox-play').removeClass('ilightbox-pause'); 15008 } else iL.closeAction(); 15009 }).on(touchMoveEvent, '.ilightbox-overlay, .ilightbox-thumbnails-container', function(e) { 15010 // prevent scrolling 15011 e.preventDefault(); 15012 }); 15013 15014 function mouseMoveHandler(e) { 15015 if (!vars.isMobile) { 15016 if (!vars.mouseID) { 15017 vars.hideableElements.show(); 15018 } 15019 15020 vars.mouseID = clearTimeout(vars.mouseID); 15021 15022 if (buttonsArray.indexOf(e.target) === -1) 15023 vars.mouseID = setTimeout(function() { 15024 vars.hideableElements.hide(); 15025 vars.mouseID = clearTimeout(vars.mouseID); 15026 }, 3000); 15027 } 15028 } 15029 15030 if (opts.controls.arrows && !supportTouch) $doc.on('mousemove.iLightBox', mouseMoveHandler); 15031 15032 if (opts.controls.slideshow && opts.slideshow.pauseOnHover) $doc.on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 15033 if (e.type == 'mouseenter' && vars.cycleID) iL.pause(); 15034 else if (e.type == 'mouseleave' && vars.isPaused) iL.resume(); 15035 }); 15036 15037 var switchers = $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails'), 15038 delay = false; 15039 15040 if (opts.controls.mousewheel) switchers.on('mousewheel.iLightBox', function(event, delta) { 15041 event.preventDefault(); 15042 if (delay) return; 15043 delay = true; 15044 if (!vars.lockWheel) { 15045 event.preventDefault(); 15046 if (delta < 0) { 15047 iL.moveTo('next'); 15048 } else if (delta > 0) { 15049 iL.moveTo('prev'); 15050 } 15051 } 15052 setTimeout(function(){
15053 delay = false; 15054 }, 2000); 15055 }); 15056 15057 if (opts.controls.swipe) holders.on(touchStartEvent, function(event) { 15058 if (vars.nextLock || vars.prevLock || vars.total == 1 || vars.lockSwipe) return; 15059 15060 vars.BODY.addClass('ilightbox-closedhand'); 15061 15062 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event, 15063 scrollTop = $doc.scrollTop(), 15064 scrollLeft = $doc.scrollLeft(), 15065 offsets = [ 15066 holders.eq(0).offset(), 15067 holders.eq(1).offset(), 15068 holders.eq(2).offset() 15069 ], 15070 offSet = [{ 15071 top: offsets[0].top - scrollTop, 15072 left: offsets[0].left - scrollLeft 15073 }, { 15074 top: offsets[1].top - scrollTop, 15075 left: offsets[1].left - scrollLeft 15076 }, { 15077 top: offsets[2].top - scrollTop, 15078 left: offsets[2].left - scrollLeft 15079 }], 15080 start = { 15081 time: (new Date()).getTime(), 15082 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 15083 }, 15084 stop; 15085 15086 function moveEachHandler(i) { 15087 var t = $(this), 15088 offset = offSet[i], 15089 scroll = [(start.coords[0] - stop.coords[0]), (start.coords[1] - stop.coords[1])]; 15090 15091 t[0].style[path == "horizontal" ? 'left' : 'top'] = (path == "horizontal" ? offset.left - scroll[0] : offset.top - scroll[1]) + 'px'; 15092 } 15093 15094 function moveHandler(event) { 15095 15096 if (!start) return; 15097 15098 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event; 15099 15100 stop = { 15101 time: (new Date()).getTime(), 15102 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 15103 }; 15104 15105 holders.each(moveEachHandler); 15106 15107 // prevent scrolling 15108 event.preventDefault(); 15109 } 15110 15111 function repositionHolders() { 15112 holders.each(function() { 15113 var t = $(this), 15114 offset = t.data('offset') || { 15115 top: t.offset().top - scrollTop, 15116 left: t.offset().left - scrollLeft 15117 }, 15118 top = offset.top, 15119 left = offset.left; 15120 15121 t.css(transform, gpuAcceleration).stop().animate({ 15122 top: top, 15123 left: left 15124 }, 500, 'easeOutCirc', function() { 15125 t.css(transform, ''); 15126 }); 15127 }); 15128 } 15129 15130 holders.bind(touchMoveEvent, moveHandler); 15131 $doc.one(touchStopEvent, function(event) { 15132 holders.unbind(touchMoveEvent, moveHandler); 15133 15134 vars.BODY.removeClass('ilightbox-closedhand'); 15135 15136 if (start && stop) { 15137 if (path == "horizontal" && stop.time - start.time < durationThreshold && abs(start.coords[0] - stop.coords[0]) > horizontalDistanceThreshold && abs(start.coords[1] - stop.coords[1]) < verticalDistanceThreshold) { 15138 if (start.coords[0] > stop.coords[0]) { 15139 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 15140 else { 15141 vars.isSwipe = true; 15142 iL.moveTo('next'); 15143 } 15144 } else { 15145 if (vars.current == 0 && !opts.infinite) repositionHolders(); 15146 else { 15147 vars.isSwipe = true; 15148 iL.moveTo('prev'); 15149 } 15150 } 15151 } 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) { 15152 if (start.coords[1] > stop.coords[1]) { 15153 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 15154 else { 15155 vars.isSwipe = true; 15156 iL.moveTo('next'); 15157 } 15158 } else { 15159 if (vars.current == 0 && !opts.infinite) repositionHolders(); 15160 else { 15161 vars.isSwipe = true; 15162 iL.moveTo('prev'); 15163 } 15164 } 15165 } else repositionHolders(); 15166 } 15167 start = stop = undefined; 15168 }); 15169 }); 15170 15171 }, 15172 15173 goTo: function(index) { 15174 var iL = this, 15175 vars = iL.vars, 15176 opts = iL.options, 15177 diff = (index - vars.current); 15178 15179 if (opts.infinite) { 15180 if (index == vars.total - 1 && vars.current == 0) diff = -1; 15181 if (vars.current == vars.total - 1 && index == 0) diff = 1; 15182 } 15183 15184 if (diff == 1) iL.moveTo('next'); 15185 else if (diff == -1) iL.moveTo('prev'); 15186 else { 15187 15188 if (vars.nextLock || vars.prevLock) return false; 15189 15190 //Trigger the onBeforeChange callback 15191 if (typeof opts.callback.onBeforeChange == 'function') opts.callback.onBeforeChange.call(iL, iL.ui); 15192 15193 if (opts.linkId) { 15194 vars.hashLock = true; 15195 window.location.hash = opts.linkId + '/' + index; 15196 } 15197 15198 if (iL.items[index]) { 15199 if (!iL.items[index].options.mousewheel) vars.lockWheel = true; 15200 else iL.vars.lockWheel = false;
15201 15202 if (!iL.items[index].options.swipe) vars.lockSwipe = true; 15203 else vars.lockSwipe = false; 15204 } 15205 15206 $.each([vars.holder, vars.nextPhoto, vars.prevPhoto], function(key, val) { 15207 val.css(transform, gpuAcceleration).fadeOut(opts.effects.loadedFadeSpeed); 15208 }); 15209 15210 vars.current = index; 15211 vars.next = index + 1; 15212 vars.prev = index - 1; 15213 15214 iL.createUI(); 15215 15216 setTimeout(function() { 15217 iL.generateBoxes(); 15218 }, opts.effects.loadedFadeSpeed + 50); 15219 15220 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(index).addClass('ilightbox-active'); 15221 iL.positionThumbnails(); 15222 15223 if (opts.linkId) setTimeout(function() { 15224 vars.hashLock = false; 15225 }, 55); 15226 15227 // Configure arrow buttons 15228 if (!opts.infinite) { 15229 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15230 15231 if (vars.current == 0) { 15232 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 15233 } 15234 if (vars.current >= vars.total - 1) { 15235 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 15236 } 15237 } 15238 15239 // Reset next cycle timeout 15240 iL.resetCycle(); 15241 15242 //Trigger the onAfterChange callback 15243 if (typeof opts.callback.onAfterChange == 'function') opts.callback.onAfterChange.call(iL, iL.ui); 15244 } 15245 }, 15246 15247 moveTo: function(side) { 15248 var iL = this, 15249 vars = iL.vars, 15250 opts = iL.options, 15251 path = opts.path.toLowerCase(), 15252 viewport = getViewport(), 15253 switchSpeed = opts.effects.switchSpeed; 15254 15255 if (vars.nextLock || vars.prevLock) return false; 15256 else { 15257 15258 var item = (side == "next") ? vars.next : vars.prev; 15259 15260 if (opts.linkId) { 15261 vars.hashLock = true; 15262 window.location.hash = opts.linkId + '/' + item; 15263 } 15264 15265 if (side == "next") { 15266 if (!iL.items[item]) return false; 15267 var firstHolder = vars.nextPhoto, 15268 secondHolder = vars.holder, 15269 lastHolder = vars.prevPhoto, 15270 firstClass = 'ilightbox-prev', 15271 secondClass = 'ilightbox-next'; 15272 } else if (side == "prev") { 15273 if (!iL.items[item]) return false; 15274 var firstHolder = vars.prevPhoto, 15275 secondHolder = vars.holder, 15276 lastHolder = vars.nextPhoto, 15277 firstClass = 'ilightbox-next', 15278 secondClass = 'ilightbox-prev'; 15279 } 15280 15281 //Trigger the onBeforeChange callback 15282 if (typeof opts.callback.onBeforeChange == 'function') 15283 opts.callback.onBeforeChange.call(iL, iL.ui); 15284 15285 (side == "next") ? vars.nextLock = true: vars.prevLock = true; 15286 15287 var captionFirst = $('div.ilightbox-caption', secondHolder), 15288 socialFirst = $('div.ilightbox-social', secondHolder); 15289 15290 if (captionFirst.length) 15291 captionFirst.stop().fadeOut(switchSpeed, function() { 15292 $(this).remove(); 15293 }); 15294 if (socialFirst.length) 15295 socialFirst.stop().fadeOut(switchSpeed, function() { 15296 $(this).remove(); 15297 }); 15298 15299 if (iL.items[item].caption) { 15300 iL.setCaption(iL.items[item], firstHolder); 15301 var caption = $('div.ilightbox-caption', firstHolder), 15302 percent = parseInt((caption.outerHeight() / firstHolder.outerHeight()) * 100); 15303 if (opts.caption.start && percent <= 50) caption.fadeIn(switchSpeed); 15304 } 15305 15306 var social = iL.items[item].options.social; 15307 if (social) { 15308 iL.setSocial(social, iL.items[item].URL, firstHolder); 15309 if (opts.social.start) $('div.ilightbox-social', firstHolder).fadeIn(opts.effects.fadeSpeed); 15310 } 15311 15312 $.each([firstHolder, secondHolder, lastHolder], function(key, val) { 15313 val.removeClass('ilightbox-next ilightbox-prev'); 15314 }); 15315 15316 var firstOffset = firstHolder.data('offset'), 15317 winW = (viewport.width - (opts.styles.pageOffsetX)), 15318 winH = (viewport.height - (opts.styles.pageOffsetY)), 15319 width = firstOffset.newDims.width, 15320 height = firstOffset.newDims.height, 15321 thumbsOffset = firstOffset.thumbsOffset, 15322 diff = firstOffset.diff, 15323 top = parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)), 15324 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15325 15326 var secondOffset = secondHolder.data('offset'), 15327 object = secondOffset.object; 15328 15329 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 15330 var objRatio = width / height; 15331 height = height - vars.captionHeight; 15332 width = height * objRatio; 15333 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top, 15334 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15335 }*/ 15336 15337 firstHolder.show().css(transform, gpuAcceleration).animate({ 15338 top: top, 15339 left: left, 15340 opacity: 1 15341 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15342 firstHolder.css(transform, ''); 15343 }); 15344 15345 $('div.ilightbox-container', firstHolder).animate({ 15346 width: width, 15347 height: height 15348 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 15349 15350 diff = secondOffset.diff; 15351 15352 width = secondOffset.newDims.width, 15353 height = secondOffset.newDims.height; 15354 15355 width = parseInt(width * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 15356 height = parseInt(height * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 15357 top = (path == 'horizontal') ? parseInt((winH / 2) - object.offsetY - (height / 2) - diff.H - (thumbsOffset.H / 2)) : parseInt(winH - object.offsetX - diff.H - (thumbsOffset.H / 2)); 15358 15359 if (side == 'prev') 15360 left = (path == 'horizontal') ? parseInt(winW - object.offsetX - diff.W - (thumbsOffset.W / 2)) : parseInt((winW / 2) - (width / 2) - diff.W - object.offsetY - (thumbsOffset.W / 2)); 15361 else { 15362 top = (path == 'horizontal') ? top : parseInt(object.offsetX - diff.H - height - (thumbsOffset.H / 2)), 15363 left = (path == 'horizontal') ? parseInt(object.offsetX - diff.W - width - (thumbsOffset.W / 2)) : parseInt((winW / 2) - object.offsetY - (width / 2) - diff.W - (thumbsOffset.W / 2)); 15364 } 15365 15366 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 15367 var objRatio = width / height; 15368 height = height - vars.captionHeight; 15369 width = height * objRatio; 15370 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top; 15371 }*/ 15372 15373 $('div.ilightbox-container', secondHolder).animate({ 15374 width: width, 15375 height: height 15376 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 15377 15378 secondHolder.addClass(firstClass).css(transform, gpuAcceleration).animate({ 15379 top: top, 15380 left: left, 15381 opacity: opts.styles.prevOpacity, 15382 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15383 secondHolder.css(transform, ''); 15384
15385 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(item).addClass('ilightbox-active'); 15386 iL.positionThumbnails(); 15387 15388 if (iL.items[item]) { 15389 if (!iL.items[item].options.mousewheel) vars.lockWheel = true; 15390 else vars.lockWheel = false; 15391 15392 if (!iL.items[item].options.swipe) vars.lockSwipe = true; 15393 else vars.lockSwipe = false; 15394 } 15395 15396 vars.isSwipe = false; 15397 15398 // Remove iframe & video from previous slide 15399 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 15400 $('div.ilightbox-container', secondHolder).empty(); 15401 } 15402 15403 if (side == "next") { 15404 vars.nextPhoto = lastHolder, 15405 vars.prevPhoto = secondHolder, 15406 vars.holder = firstHolder; 15407 15408 vars.nextPhoto.hide(); 15409 15410 vars.next = vars.next + 1, 15411 vars.prev = vars.current, 15412 vars.current = vars.current + 1; 15413 15414 if (opts.infinite) { 15415 if (vars.current > vars.total - 1) vars.current = 0; 15416 if (vars.current == vars.total - 1) vars.next = 0; 15417 if (vars.current == 0) vars.prev = vars.total - 1; 15418 } 15419 15420 iL.createUI(); 15421 15422 if (!iL.items[vars.next]) 15423 vars.nextLock = false; 15424 else 15425 iL.loadContent(iL.items[vars.next], 'next'); 15426 } else { 15427 vars.prevPhoto = lastHolder; 15428 vars.nextPhoto = secondHolder; 15429 vars.holder = firstHolder; 15430 15431 vars.prevPhoto.hide(); 15432 15433 vars.next = vars.current; 15434 vars.current = vars.prev; 15435 vars.prev = vars.current - 1; 15436 15437 if (opts.infinite) { 15438 if (vars.current == vars.total - 1) vars.next = 0; 15439 if (vars.current == 0) vars.prev = vars.total - 1; 15440 } 15441 15442 iL.createUI(); 15443 15444 if (!iL.items[vars.prev]) 15445 vars.prevLock = false; 15446 else 15447 iL.loadContent(iL.items[vars.prev], 'prev'); 15448 } 15449 15450 // Add iframe & video content for current slide 15451 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 15452 iL.loadContent(iL.items[vars.current], 'current'); 15453 } 15454 15455 if (opts.linkId) setTimeout(function() { 15456 vars.hashLock = false; 15457 }, 55); 15458 15459 // Configure arrow buttons 15460 if (!opts.infinite) { 15461 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15462 15463 if (vars.current == 0) 15464 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 15465 if (vars.current >= vars.total - 1) 15466 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 15467 } 15468 15469 iL.repositionPhoto(); 15470 15471 // Reset next cycle timeout 15472 iL.resetCycle(); 15473 15474 //Trigger the onAfterChange callback 15475 if (typeof opts.callback.onAfterChange == 'function') 15476 opts.callback.onAfterChange.call(iL, iL.ui); 15477 }); 15478 15479 top = (path == 'horizontal') ? getPixel(lastHolder, 'top') : ((side == "next") ? parseInt(-(winH / 2) - lastHolder.outerHeight()) : parseInt(top * 2)), 15480 left = (path == 'horizontal') ? ((side == "next") ? parseInt(-(winW / 2) - lastHolder.outerWidth()) : parseInt(left * 2)) : getPixel(lastHolder, 'left'); 15481 15482 lastHolder.css(transform, gpuAcceleration).animate({ 15483 top: top, 15484 left: left, 15485 opacity: opts.styles.nextOpacity 15486 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 15487 lastHolder.css(transform, ''); 15488 }).addClass(secondClass); 15489 } 15490 }, 15491 15492 setCaption: function(obj, target) { 15493 var iL = this, 15494 caption = $('<div class="ilightbox-caption"></div>'); 15495 15496 if (obj.caption) { 15497 caption.html(obj.caption); 15498 $('div.ilightbox-container', target).append(caption); 15499 } 15500 }, 15501 15502 normalizeSocial: function(obj, url) { 15503 var iL = this, 15504 vars = iL.vars, 15505 opts = iL.options, 15506 baseURL = window.location.href; 15507 15508 $.each(obj, function(key, value) { 15509 if (!value) 15510 return true; 15511 15512 var item = key.toLowerCase(), 15513 source, text; 15514 15515 switch (item) { 15516 case 'facebook': 15517 source = "http://www.facebook.com/share.php?v=4&src=bm&u={URL}", 15518 text = "Share on Facebook"; 15519 break; 15520 case 'twitter': 15521 source = "http://twitter.com/home?status={URL}", 15522 text = "Share on Twitter"; 15523 break; 15524 case 'digg': 15525 source = "http://digg.com/submit?phase=2&url={URL}", 15526 text = "Share on Digg"; 15527 break; 15528 case 'reddit': 15529 source = "http://reddit.com/submit?url={URL}", 15530 text = "Share on reddit"; 15531 break; 15532 } 15533 15534 obj[key] = { 15535 URL: value.URL && absolutizeURI(baseURL, value.URL) || opts.linkId && window.location.href || typeof url !== 'string' && baseURL || url && absolutizeURI(baseURL, url) || baseURL, 15536 source: value.source || source || value.URL && absolutizeURI(baseURL, value.URL) || url && absolutizeURI(baseURL, url), 15537 text: value.text || text || "Share on " + key, 15538 width: (typeof(value.width) != 'undefined' && !isNaN(value.width)) ? parseInt(value.width) : 640, 15539 height: value.height || 360 15540 }; 15541 15542 }); 15543 15544 return obj; 15545 }, 15546 15547 setSocial: function(obj, url, target) { 15548 var iL = this, 15549 socialBar = $('<div class="ilightbox-social"></div>'), 15550 buttons = '<ul>'; 15551 15552 obj = iL.normalizeSocial(obj, url); 15553 15554 $.each(obj, function(key, value) { 15555 var item = key.toLowerCase(), 15556 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, '+')); 15557 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>'; 15558 }); 15559 15560 buttons += '</ul>'; 15561 15562 socialBar.html(buttons); 15563 $('div.ilightbox-container', target).append(socialBar); 15564 }, 15565 15566 fullScreenAction: function() { 15567 var iL = this, 15568 vars = iL.vars; 15569 15570 if (fullScreenApi.supportsFullScreen) { 15571 if (fullScreenApi.isFullScreen()) fullScreenApi.cancelFullScreen(document.documentElement); 15572 else fullScreenApi.requestFullScreen(document.documentElement); 15573 } else { 15574 iL.doFullscreen(); 15575 } 15576 }, 15577 15578 doFullscreen: function() { 15579 var iL = this, 15580 vars = iL.vars, 15581 viewport = getViewport(), 15582 opts = iL.options; 15583 15584 if (opts.fullAlone) { 15585 var currentHolder = vars.holder, 15586 current = iL.items[vars.current], 15587 windowWidth = viewport.width, 15588 windowHeight = viewport.height, 15589 elements = [currentHolder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.overlay, vars.toolbar, vars.thumbnails, vars.loader], 15590 hideElements = [vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 15591 15592 if (!vars.isInFullScreen) { 15593 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = true; 15594 vars.overlay.css({ 15595 opacity: 1 15596 }); 15597 15598 $.each(hideElements, function(i, element) { 15599 element.hide(); 15600 }); 15601 15602 vars.fullScreenButton.attr('title', opts.text.exitFullscreen); 15603 15604 if (opts.fullStretchTypes.indexOf(current.type) != -1) currentHolder.data({
15605 naturalWidthOld: currentHolder.data('naturalWidth'), 15606 naturalHeightOld: currentHolder.data('naturalHeight'), 15607 naturalWidth: windowWidth, 15608 naturalHeight: windowHeight 15609 }); 15610 else { 15611 var viewport = current.options.fullViewPort || opts.fullViewPort || '', 15612 newWidth = windowWidth, 15613 newHeight = windowHeight, 15614 width = currentHolder.data('naturalWidth'), 15615 height = currentHolder.data('naturalHeight'); 15616 15617 if (viewport.toLowerCase() == 'fill') { 15618 newHeight = (newWidth / width) * height; 15619 15620 if (newHeight < windowHeight) { 15621 newWidth = (windowHeight / height) * width, 15622 newHeight = windowHeight; 15623 } 15624 } else if (viewport.toLowerCase() == 'fit') { 15625 var dims = iL.getNewDimenstions(newWidth, newHeight, width, height, true); 15626 15627 newWidth = dims.width, 15628 newHeight = dims.height; 15629 } else if (viewport.toLowerCase() == 'stretch') { 15630 newWidth = newWidth, 15631 newHeight = newHeight; 15632 } else { 15633 var scale = (width > newWidth || height > newHeight) ? true : false, 15634 dims = iL.getNewDimenstions(newWidth, newHeight, width, height, scale); 15635 newWidth = dims.width, 15636 newHeight = dims.height; 15637 } 15638 15639 currentHolder.data({ 15640 naturalWidthOld: currentHolder.data('naturalWidth'), 15641 naturalHeightOld: currentHolder.data('naturalHeight'), 15642 naturalWidth: newWidth, 15643 naturalHeight: newHeight 15644 }); 15645 } 15646 15647 $.each(elements, function(key, val) { 15648 val.addClass('ilightbox-fullscreen'); 15649 }); 15650 15651 //Trigger the onEnterFullScreen callback 15652 if (typeof opts.callback.onEnterFullScreen == 'function') opts.callback.onEnterFullScreen.call(iL, iL.ui); 15653 } else { 15654 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = false; 15655 vars.overlay.css({ 15656 opacity: iL.options.overlay.opacity 15657 }); 15658 15659 $.each(hideElements, function(i, element) { 15660 element.show(); 15661 }); 15662 15663 vars.fullScreenButton.attr('title', opts.text.enterFullscreen); 15664 15665 currentHolder.data({ 15666 naturalWidth: currentHolder.data('naturalWidthOld'), 15667 naturalHeight: currentHolder.data('naturalHeightOld'), 15668 naturalWidthOld: null, 15669 naturalHeightOld: null 15670 }); 15671 15672 $.each(elements, function(key, val) { 15673 val.removeClass('ilightbox-fullscreen'); 15674 }); 15675 15676 //Trigger the onExitFullScreen callback 15677 if (typeof opts.callback.onExitFullScreen == 'function') opts.callback.onExitFullScreen.call(iL, iL.ui); 15678 } 15679 } else { 15680 if (!vars.isInFullScreen) vars.isInFullScreen = true; 15681 else vars.isInFullScreen = false; 15682 } 15683 iL.repositionPhoto(true); 15684 }, 15685 15686 closeAction: function() { 15687 var iL = this, 15688 vars = iL.vars, 15689 opts = iL.options; 15690 15691 $win.unbind('.iLightBox'); 15692 $doc.off('.iLightBox'); 15693 15694 if (vars.isInFullScreen) fullScreenApi.cancelFullScreen(document.documentElement); 15695 15696 $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails').off('.iLightBox'); 15697 15698 if (opts.hide.effect) vars.overlay.stop().fadeOut(opts.hide.speed, function() { 15699 vars.overlay.remove(); 15700 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 15701 }); 15702 else { 15703 vars.overlay.remove(); 15704 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 15705 } 15706 15707 var fadeOuts = [vars.toolbar, vars.holder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 15708 15709 $.each(fadeOuts, function(i, element) { 15710 element.removeAttr('style').remove(); 15711 }); 15712 15713 vars.dontGenerateThumbs = vars.isInFullScreen = false; 15714 15715 window.iLightBox = null; 15716 15717 if (opts.linkId) { 15718 vars.hashLock = true; 15719 removeHash(); 15720 setTimeout(function() { 15721 vars.hashLock = false; 15722 }, 55); 15723 } 15724 15725 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15726 15727 //Trigger the onHide callback 15728 if (typeof opts.callback.onHide == 'function') opts.callback.onHide.call(iL, iL.ui); 15729 }, 15730 15731 repositionPhoto: function() { 15732 var iL = this, 15733 vars = iL.vars, 15734 opts = iL.options, 15735 path = opts.path.toLowerCase(), 15736 viewport = getViewport(), 15737 winWidth = viewport.width, 15738 winHeight = viewport.height; 15739 15740 if (viewport.width < UNCODE.mediaQuery) opts.styles.nextOffsetX = 0; 15741 15742 var thumbsOffsetW = (vars.isInFullScreen && opts.fullAlone || vars.isMobile) ? 0 : ((path == 'horizontal') ? 0 : vars.thumbnails.outerWidth()), 15743 thumbsOffsetH = vars.isMobile ? vars.toolbar.outerHeight() : ((vars.isInFullScreen && opts.fullAlone) ? 0 : ((path == 'horizontal') ? vars.thumbnails.outerHeight() : 0)), 15744 width = (vars.isInFullScreen && opts.fullAlone) ? winWidth : (winWidth - (opts.styles.pageOffsetX)), 15745 height = (vars.isInFullScreen && opts.fullAlone) ? winHeight : (winHeight - (opts.styles.pageOffsetY)), 15746 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, 15747 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))); 15748 15749 var elObject = { 15750 type: 'current', 15751 width: width, 15752 height: height, 15753 item: iL.items[vars.current], 15754 offsetW: offsetW, 15755 offsetH: offsetH,
15756 thumbsOffsetW: thumbsOffsetW, 15757 thumbsOffsetH: thumbsOffsetH, 15758 animate: arguments.length, 15759 holder: vars.holder 15760 }; 15761 15762 iL.repositionEl(elObject); 15763 15764 if (iL.items[vars.next]) { 15765 elObject = $.extend(elObject, { 15766 type: 'next', 15767 item: iL.items[vars.next], 15768 offsetX: opts.styles.nextOffsetX, 15769 offsetY: opts.styles.nextOffsetY, 15770 holder: vars.nextPhoto 15771 }); 15772 15773 iL.repositionEl(elObject); 15774 } 15775 15776 if (iL.items[vars.prev]) { 15777 elObject = $.extend(elObject, { 15778 type: 'prev', 15779 item: iL.items[vars.prev], 15780 offsetX: opts.styles.nextOffsetX, 15781 offsetY: opts.styles.prevOffsetY, 15782 holder: vars.prevPhoto 15783 }); 15784 15785 iL.repositionEl(elObject); 15786 } 15787 15788 var loaderCss = (path == "horizontal") ? { 15789 left: parseInt((width / 2) - (vars.loader.outerWidth() / 2)) 15790 } : { 15791 top: parseInt((height / 2) - (vars.loader.outerHeight() / 2)) 15792 }; 15793 vars.loader.css(loaderCss); 15794 }, 15795 15796 repositionEl: function(obj) { 15797 var iL = this, 15798 vars = iL.vars, 15799 opts = iL.options, 15800 path = opts.path.toLowerCase(), 15801 widthAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.width : (obj.width - obj.offsetW)) : (obj.width - obj.offsetW), 15802 heightAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.height : (obj.height - obj.offsetH)) : (obj.height - obj.offsetH), 15803 itemParent = obj.item, 15804 item = obj.item.options, 15805 holder = obj.holder, 15806 offsetX = obj.offsetX || 0, 15807 offsetY = obj.offsetY || 0, 15808 //Uncode change ##START## 15809 toolbarHeight = $('.ilightbox-inner-toolbar', holder).length ? parseInt( $('.ilightbox-inner-toolbar', holder).outerHeight() ) : 0, 15810 //Uncode change ##END## 15811 thumbsOffsetW = obj.thumbsOffsetW, 15812 thumbsOffsetH = obj.thumbsOffsetH; 15813 15814 if (obj.type == 'current') { 15815 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); 15816 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); 15817 } else { 15818 if (typeof item.width == 'number' && item.width) widthAvail = (item.width > widthAvail) ? widthAvail : item.width; 15819 if (typeof item.height == 'number' && item.height) heightAvail = (item.height > heightAvail) ? heightAvail : item.height; 15820 } 15821 15822 15823 //Uncode change ##START## 15824 heightAvail = parseInt(heightAvail - toolbarHeight); 15825 // heightAvail = parseInt(heightAvail - $('.ilightbox-inner-toolbar', holder).outerHeight()); 15826 //Uncode change ##END## 15827 15828 var width = (typeof item.width == 'string' && item.width.indexOf('%') != -1) ? percentToValue(parseInt(item.width.replace('%', '')), obj.width) : holder.data('naturalWidth'), 15829 height = (typeof item.height == 'string' && item.height.indexOf('%') != -1) ? percentToValue(parseInt(item.height.replace('%', '')), obj.height) : holder.data('naturalHeight'); 15830 15831 var dims = ((typeof item.width == 'string' && item.width.indexOf('%') != -1 || typeof item.height == 'string' && item.height.indexOf('%') != -1) ? { 15832 width: width, 15833 height: height 15834 } : iL.getNewDimenstions(widthAvail, heightAvail, width, height)), 15835 newDims = $.extend({}, dims, {}); 15836 15837 if (obj.type == 'prev' || obj.type == 'next') 15838 width = parseInt(dims.width * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)), 15839 height = parseInt(dims.height * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)); 15840 else 15841 width = dims.width, 15842 height = dims.height; 15843 15844 var widthDiff = parseInt((getPixel(holder, 'padding-left') + getPixel(holder, 'padding-right') + getPixel(holder, 'border-left-width') + getPixel(holder, 'border-right-width')) / 2), 15845 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); 15846 15847 switch (obj.type) { 15848 case 'current': 15849 var top = parseInt((obj.height / 2) - (height / 2) - heightDiff - (thumbsOffsetH / 2)), 15850 left = parseInt((obj.width / 2) - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 15851 break; 15852
15853 case 'next': 15854 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(obj.height - offsetX - heightDiff - (thumbsOffsetH / 2)), 15855 left = (path == 'horizontal') ? parseInt(obj.width - offsetX - widthDiff - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - (width / 2) - widthDiff - offsetY - (thumbsOffsetW / 2)); 15856 break; 15857 15858 case 'prev': 15859 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(offsetX - heightDiff - height - (thumbsOffsetH / 2)), 15860 left = (path == 'horizontal') ? parseInt(offsetX - widthDiff - width - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - offsetY - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 15861 break; 15862 } 15863 15864 holder.data('offset', { 15865 top: top, 15866 left: left, 15867 newDims: newDims, 15868 diff: { 15869 W: widthDiff, 15870 H: heightDiff 15871 }, 15872 thumbsOffset: { 15873 W: thumbsOffsetW, 15874 H: thumbsOffsetH 15875 }, 15876 object: obj 15877 }); 15878 15879 var opacityMobile; 15880 if ( isMobile ) { 15881 opacityMobile = { 15882 opacity: 1, 15883 top: top, 15884 left: left 15885 }; 15886 } else { 15887 opacityMobile = { 15888 top: top, 15889 left: left 15890 }; 15891 } 15892 15893 if (obj.animate > 0 && opts.effects.reposition) { 15894 holder.css(transform, gpuAcceleration).stop().animate( 15895 opacityMobile, 15896 opts.effects.repositionSpeed, 'easeOutCirc', function() { 15897 holder.css(transform, ''); 15898 }); 15899 $('div.ilightbox-container', holder).stop().animate({ 15900 width: width, 15901 height: height 15902 }, opts.effects.repositionSpeed, 'easeOutCirc'); 15903 $('div.ilightbox-inner-toolbar', holder).stop().animate({ 15904 width: width 15905 }, opts.effects.repositionSpeed, 'easeOutCirc', function() { 15906 $(this).css('overflow', 'visible'); 15907 }); 15908 } else { 15909 holder.css(opacityMobile); 15910 $('div.ilightbox-container', holder).css({ 15911 width: width, 15912 height: height 15913 }); 15914 $('div.ilightbox-inner-toolbar', holder).css({ 15915 width: width 15916 }); 15917 } 15918 }, 15919 15920 15921 resume: function(priority) { 15922 var iL = this, 15923 vars = iL.vars, 15924 opts = iL.options; 15925 15926 if (!opts.slideshow.pauseTime || opts.controls.slideshow && vars.total <= 1 || priority < vars.isPaused) { 15927 return; 15928 } 15929 15930 vars.isPaused = 0; 15931 15932 if (vars.cycleID) { 15933 vars.cycleID = clearTimeout(vars.cycleID); 15934 } 15935 15936 vars.cycleID = setTimeout(function() { 15937 if (vars.current == vars.total - 1) iL.goTo(0); 15938 else iL.moveTo('next'); 15939 }, opts.slideshow.pauseTime); 15940 }, 15941 15942 pause: function(priority) { 15943 var iL = this, 15944 vars = iL.vars, 15945 opts = iL.options; 15946 15947 if (priority < vars.isPaused) { 15948 return; 15949 } 15950 15951 vars.isPaused = priority || 100; 15952 15953 if (vars.cycleID) { 15954 vars.cycleID = clearTimeout(vars.cycleID); 15955 } 15956 }, 15957 15958 resetCycle: function() { 15959 var iL = this, 15960 vars = iL.vars, 15961 opts = iL.options; 15962 15963 if (opts.controls.slideshow && vars.cycleID && !vars.isPaused) { 15964 iL.resume(); 15965 } 15966 }, 15967 15968 getNewDimenstions: function(width, height, width_old, height_old, thumb) { 15969 var iL = this; 15970 15971 if (!width) factor = height / height_old; 15972 else if (!height) factor = width / width_old; 15973 else factor = min(width / width_old, height / height_old); 15974 15975 if (!thumb) { 15976 if (factor > iL.options.maxScale) factor = iL.options.maxScale; 15977 else if (factor < iL.options.minScale) factor = iL.options.minScale; 15978 } 15979 15980 var final_width = (iL.options.keepAspectRatio) ? round(width_old * factor) : width, 15981 final_height = (iL.options.keepAspectRatio) ? round(height_old * factor) : height; 15982 15983 return { 15984 width: final_width, 15985 height: final_height, 15986 ratio: factor 15987 }; 15988 }, 15989 15990 setOption: function(options) { 15991 var iL = this; 15992 15993 iL.options = $.extend(true, iL.options, options || {}); 15994 iL.refresh(); 15995 }, 15996 15997 availPlugins: function() { 15998 var iL = this, 15999 testEl = document.createElement("video"); 16000 16001 iL.plugins = { 16002 flash: !isMobile, 16003 quicktime: (parseInt(PluginDetect.getVersion("QuickTime")) >= 0) ? true : false, 16004 html5H264: !!(testEl.canPlayType && testEl.canPlayType('video/mp4').replace(/no/, '')), 16005 html5WebM: !!(testEl.canPlayType && testEl.canPlayType('video/webm').replace(/no/, '')), 16006 html5Vorbis: !!(testEl.canPlayType && testEl.canPlayType('video/ogg').replace(/no/, '')), 16007 html5QuickTime: !!(testEl.canPlayType && testEl.canPlayType('video/quicktime').replace(/no/, '')) 16008 }; 16009 }, 16010 16011 addContent: function(element, obj) { 16012 var iL = this, 16013 el; 16014 16015 switch (obj.type) { 16016 case 'video': 16017 var HTML5 = false, 16018 videoType = obj.videoType, 16019 html5video = obj.options.html5video; 16020 16021 if (((videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v') || html5video.h264) && iL.plugins.html5H264) 16022 obj.ext = 'mp4', 16023 obj.URL = html5video.h264 || obj.URL; 16024 else if (html5video.webm && iL.plugins.html5WebM) 16025 obj.ext = 'webm', 16026 obj.URL = html5video.webm || obj.URL; 16027 else if (html5video.ogg && iL.plugins.html5Vorbis) 16028 obj.ext = 'ogv', 16029 obj.URL = html5video.ogg || obj.URL; 16030 16031 if (iL.plugins.html5H264 && (videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v')) HTML5 = true, videoType = "video/mp4"; 16032 else if (iL.plugins.html5WebM && (videoType == 'video/webm' || obj.ext == 'webm')) HTML5 = true, videoType = "video/webm"; 16033 else if (iL.plugins.html5Vorbis && (videoType == 'video/ogg' || obj.ext == 'ogv')) HTML5 = true, videoType = "video/ogg"; 16034 else if (iL.plugins.html5QuickTime && (videoType == 'video/quicktime' || obj.ext == 'mov' || obj.ext == 'qt')) HTML5 = true, videoType = "video/quicktime"; 16035 16036 if (HTML5) { 16037 el = $('<video />
16037', { 16038 "width": "100%", 16039 "height": "100%", 16040 "preload": html5video.preload, 16041 "autoplay": html5video.autoplay, 16042 "loop": html5video.loop, 16043 "poster": html5video.poster, 16044 "controls": html5video.controls, 16045 "controlslist": "nodownload" 16046 }).append($('<source />', { 16047 "src": obj.URL, 16048 "type": videoType 16049 })); 16050 } else { 16051 if (!iL.plugins.quicktime) el = $('<span />', { 16052 "class": "ilightbox-alert", 16053 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.quicktime).replace('{type}', 'QuickTime') 16054 }); 16055 else { 16056 16057 el = $('<object />', { 16058 "type": "video/quicktime", 16059 "pluginspage": pluginspages.quicktime 16060 }).attr({ 16061 "data": obj.URL, 16062 "width": "100%", 16063 "height": "100%" 16064 }).append($('<param />', { 16065 "name": "src", 16066 "value": obj.URL 16067 })).append($('<param />', { 16068 "name": "autoplay", 16069 "value": "false" 16070 })).append($('<param />', { 16071 "name": "loop", 16072 "value": "false" 16073 })).append($('<param />', { 16074 "name": "scale", 16075 "value": "tofit" 16076 })); 16077 16078 if (browser.msie) el = QT_GenerateOBJECTText(obj.URL, '100%', '100%', '', 'SCALE', 'tofit', 'AUTOPLAY', 'false', 'LOOP', 'false'); 16079 } 16080 } 16081 16082 break; 16083 16084 case 'flash': 16085 if (!iL.plugins.flash) el = $('<span />', { 16086 "class": "ilightbox-alert", 16087 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.flash).replace('{type}', 'Adobe Flash player') 16088 }); 16089 else { 16090 var flashvars = "", 16091 i = 0; 16092 16093 if (obj.options.flashvars) $.each(obj.options.flashvars, function(k, v) { 16094 if (i != 0) flashvars += "&"; 16095 flashvars += k + "=" + encodeURIComponent(v); 16096 i++; 16097 }); 16098 else flashvars = null; 16099 16100 el = $('<embed />').attr({ 16101 "type": "application/x-shockwave-flash", 16102 "src": obj.URL, 16103 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 16104 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 16105 "quality": "high", 16106 "bgcolor": "#000000", 16107 "play": "true", 16108 "loop": "true", 16109 "menu": "true", 16110 "wmode": "transparent", 16111 "scale": "showall", 16112 "allowScriptAccess": "always", 16113 "allowFullScreen": "true", 16114 "flashvars": flashvars, 16115 "fullscreen": "yes" 16116 }); 16117 } 16118 16119 break; 16120 16121 case 'iframe': 16122 el = $('<iframe />').attr({ 16123 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 16124 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 16125 src: obj.URL, 16126 frameborder: 0, 16127 'hspace': 0, 16128 'vspace': 0, 16129 'scrolling': supportTouch ? 'auto' : 'scroll', 16130 'webkitAllowFullScreen': '', 16131 'mozallowfullscreen': '', 16132 'allowFullScreen': '' 16133 }); 16134 16135 break; 16136 16137 case 'inline': 16138 el = $('<div class="ilightbox-wrapper"></div>').html($(obj.URL).clone(true)); 16139 16140 break; 16141 16142 case 'html': 16143 var object = obj.URL, 16144 el; 16145 16146 if (object[0].nodeName) { 16147 el = $('<div class="ilightbox-wrapper"></div>').html(object); 16148 } else { 16149 var dom = $(obj.URL), 16150 html = (dom.selector) ? $('<div>' + dom + '</div>') : dom; 16151 el = $('<div class="ilightbox-wrapper"></div>').html(html); 16152 } 16153 16154 break; 16155 } 16156 16157 $('div.ilightbox-container', element).empty().html(el); 16158 16159 // For fixing Chrome about just playing the video for first time 16160 if (el[0].tagName.toLowerCase() === 'video' && browser.webkit) setTimeout(function() { 16161 var src = el[0].currentSrc + '?' + floor(random() * 30000); 16162 el[0].currentSrc = src; 16163 el[0].src = src; 16164 }); 16165 16166 return el; 16167 }, 16168 16169 ogpRecognition: function(obj, callback) { 16170 var iL = this, 16171 url = obj.URL; 16172 16173 iL.showLoader(); 16174 doAjax(url, function(data) { 16175 iL.hideLoader(); 16176 if (data) { 16177 var object = new Object(); 16178 16179 object.length = false, 16180 object.url = data.url; 16181 16182 if (data.status == 200) { 16183 var result = data.results, 16184 type = result.type, 16185 source = result.source; 16186 16187 object.source = source.src, 16188 object.width = source.width && parseInt(source.width) || 0, 16189 object.height = source.height && parseInt(source.height) || 0, 16190 object.type = type, 16191 object.thumbnail = source.thumbnail || result.images && result.images[0], 16192 object.html5video = result.html5video || {}, 16193 object.length = true; 16194 16195 if (source.type == 'application/x-shockwave-flash') object.type = "flash"; 16196 else if (source.type.indexOf("video/") != -1) object.type = "video"; 16197 else if (source.type.indexOf("/html") != -1) object.type = "iframe"; 16198 else if (source.type.indexOf("image/") != -1) object.type = "image"; 16199 16200 } else if (typeof data.response != 'undefined') 16201 throw data.response; 16202 16203 callback.call(this, object.length ? object : false); 16204 } 16205 }); 16206 }, 16207 16208 hashChangeHandler: function(url) { 16209 var iL = this, 16210 vars = iL.vars, 16211 opts = iL.options, 16212 URL = url || window.location.href, 16213 hash = parseURI(URL).hash, 16214 split = hash.split('/'), 16215 index = split[1]; 16216 16217 if (vars.hashLock || ('#' + opts.linkId != split[0] && hash.length > 1)) return; 16218 16219 if (index) { 16220 var target = split[1] || 0; 16221 if (iL.items[target]) {
16222 var overlay = $('.ilightbox-overlay'); 16223 if (overlay.length && overlay.attr('linkid') == opts.linkId) { 16224 iL.goTo(target); 16225 } else { 16226 iL.itemsObject[target].trigger(ishybrid ? "itap click" : supportTouch ? 'itap' : 'click'); 16227 //iL.goTo(target); 16228 } 16229 } else { 16230 var overlay = $('.ilightbox-overlay'); 16231 if (overlay.length) iL.closeAction(); 16232 } 16233 } else { 16234 var overlay = $('.ilightbox-overlay'); 16235 if (overlay.length) iL.closeAction(); 16236 } 16237 } 16238 }; 16239 16240 /** 16241 * Parse style to pixels. 16242 * 16243 * @param {Object} $element jQuery object with element. 16244 * @param {Property} property CSS property to get the pixels from. 16245 * 16246 * @return {Int} 16247 */ 16248 function getPixel($element, property) { 16249 return parseInt($element.css(property), 10) || 0; 16250 } 16251 16252 /** 16253 * Make sure that number is within the limits. 16254 * 16255 * @param {Number} number 16256 * @param {Number} min 16257 * @param {Number} max 16258 * 16259 * @return {Number} 16260 */ 16261 function within(number, min, max) { 16262 return number < min ? min : number > max ? max : number; 16263 } 16264 16265 /** 16266 * Get viewport/window size (width and height). 16267 * 16268 * @return {Object} 16269 */ 16270 function getViewport() { 16271 var e = window, 16272 a = 'inner'; 16273 if (!('innerWidth' in window)) { 16274 a = 'client'; 16275 e = document.documentElement || document.body; 16276 } 16277 return { 16278 width: e[a + 'Width'], 16279 height: e[a + 'Height'] 16280 } 16281 } 16282 16283 /** 16284 * Remove hash tag from the URL 16285 * 16286 * @return {Void} 16287 */ 16288 function removeHash() { 16289 var scroll = getScrollXY(); 16290 16291 //UNCODE change 16292 // window.location.hash = ""; 16293 // history.pushState("", document.title, window.location.pathname + window.location.search); 16294 history.replaceState({}, document.title, window.location.pathname + window.location.search); 16295 16296 // Restore the scroll offset, should be flicker free 16297 window.scrollTo(scroll.x, scroll.y); 16298 } 16299 16300 /** 16301 * Do the ajax requests with callback. 16302 * 16303 * @param {String} url 16304 * @param {Function} callback 16305 * 16306 * @return {Void} 16307 */ 16308 function doAjax(url, callback) { 16309 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'); 16310 $.ajax({ 16311 url: url, 16312 dataType: 'jsonp' 16313 }); 16314 16315 iLCallback = function(data) { 16316 callback.call(this, data); 16317 }; 16318 } 16319 16320 /** 16321 * Find image from DOM elements 16322 * 16323 * @param {Element} element 16324 * 16325 * @return {Void} 16326 */ 16327 function findImageInElement(element) { 16328 var elements = $('*', element), 16329 imagesArr = new Array(); 16330 16331 elements.each(function() { 16332 var url = "", 16333 element = this; 16334 16335 if ($(element).css("background-image") != "none") { 16336 url = $(element).css("background-image"); 16337 } else if (typeof($(element).attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") { 16338 url = $(element).attr("src"); 16339 } 16340 16341 if (url.indexOf("gradient") == -1) { 16342 url = url.replace(/url\(\"/g, ""); 16343 url = url.replace(/url\(/g, ""); 16344 url = url.replace(/\"\)/g, ""); 16345 url = url.replace(/\)/g, ""); 16346 16347 var urls = url.split(","); 16348 16349 for (var i = 0; i < urls.length; i++) { 16350 if (urls[i].length > 0 && $.inArray(urls[i], imagesArr) == -1) { 16351 var extra = ""; 16352 if (browser.msie && browser.version < 9) { 16353 extra = "?" + floor(random() * 3000); 16354 } 16355 imagesArr.push(urls[i] + extra); 16356 } 16357 } 16358 } 16359 }); 16360 16361 return imagesArr; 16362 } 16363 16364 /** 16365 * Get file extension. 16366 * 16367 * @param {String} URL 16368 * 16369 * @return {String} 16370 */ 16371 function getExtension(URL) { 16372 if (URL !== null) { 16373 //UNCODE: fix issue to detect media type with query strings 16374 var ext = URL.indexOf('?') !== -1 ? URL.split('?')[0] : URL; 16375 ext = ext.split('.').pop().toLowerCase(); 16376 16377 return ext; 16378 } 16379 } 16380 16381 /** 16382 * Get type via extension. 16383 * 16384 * @param {String} URL 16385 * 16386 * @return {String} 16387 */ 16388 function getTypeByExtension(URL) { 16389 var type, 16390 ext = getExtension(URL); 16391 16392 //Uncode addition ##START## 16393 if (URL == undefined) { 16394 return false; 16395 } 16396 //Uncode addition ##END## 16397 16398 if (extensions.image.indexOf(ext) !== -1) type = 'image'; 16399 else if (extensions.flash.indexOf(ext) !== -1) type = 'flash'; 16400 else if (extensions.video.indexOf(ext) !== -1) type = 'video'; 16401 else if (ext.substring(0, 1) == "#") type = 'inline'; //Uncode addition 16402 else type = 'iframe'; 16403 16404 return type; 16405 } 16406 16407 /** 16408 * Return value from percent of a number. 16409 * 16410 * @param {Number} percent 16411 * @param {Number} total 16412 * 16413 * @return {Number} 16414 */ 16415 function percentToValue(percent, total) { 16416 return parseInt((total / 100) * percent); 16417 } 16418 16419 /** 16420 * A JavaScript equivalent of PHPâs parse_url. 16421 * 16422 * @param {String} url The URL to parse. 16423 * 16424 * @return {Mixed} 16425 */ 16426 function parseURI(url) { 16427 var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); 16428 // authority = '//' + user + ':' + pass '@' + hostname + ':' port 16429 return (m ? { 16430 href: m[0] || '', 16431 protocol: m[1] || '', 16432 authority: m[2] || '', 16433 host: m[3] || '', 16434 hostname: m[4] || '', 16435 port: m[5] || '', 16436 pathname: m[6] || '', 16437 search: m[7] || '', 16438 hash: m[8] || '' 16439 } : null); 16440 } 16441 16442 /** 16443 * Gets the absolute URI. 16444 * 16445 * @param {String} href The relative URL. 16446 * @param {String} base The base URL. 16447 * 16448 * @return {String} The absolute URL. 16449 */ 16450 function absolutizeURI(base, href) { // RFC 3986 16451 var iL = this; 16452 16453 function removeDotSegments(input) { 16454 var output = []; 16455 input.replace(/^(\.\.?(\/|$))+/, '') 16456 .replace(/\/(\.(\/|$))+/g, '/') 16457 .replace(/\/\.\.$/, '/../') 16458 .replace(/\/?[^\/]*/g, function(p) { 16459 if (p === '/..') { 16460 output.pop(); 16461 } else { 16462 output.push(p); 16463 } 16464 }); 16465 return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); 16466 } 16467 16468 href = parseURI(href || ''); 16469 base = parseURI(base || ''); 16470 16471 return !href || !base ? null : (href.protocol || base.protocol) + 16472 (href.protocol || href.authority ? href.authority : base.authority) + 16473 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)) + 16474 (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) + 16475 href.hash; 16476 } 16477 16478 /** 16479 * A JavaScript equivalent of PHPâs version_compare. 16480 * 16481 * @param {String} v1 16482 * @param {String} v2 16483 * @param {String} operator
16484 * 16485 * @return {Boolean} 16486 */ 16487 function version_compare(v1, v2, operator) { 16488 this.php_js = this.php_js || {}; 16489 this.php_js.ENV = this.php_js.ENV || {}; 16490 var i = 0, 16491 x = 0, 16492 compare = 0, 16493 vm = { 16494 'dev': -6, 16495 'alpha': -5, 16496 'a': -5, 16497 'beta': -4, 16498 'b': -4, 16499 'RC': -3, 16500 'rc': -3, 16501 '#': -2, 16502 'p': 1, 16503 'pl': 1 16504 }, 16505 prepVersion = function(v) { 16506 v = ('' + v).replace(/[_\-+]/g, '.'); 16507 v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.'); 16508 return (!v.length ? [-8] : v.split('.')); 16509 }, 16510 numVersion = function(v) { 16511 return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10)); 16512 }; 16513 v1 = prepVersion(v1); 16514 v2 = prepVersion(v2); 16515 x = max(v1.length, v2.length); 16516 for (i = 0; i < x; i++) { 16517 if (v1[i] == v2[i]) { 16518 continue; 16519 } 16520 v1[i] = numVersion(v1[i]); 16521 v2[i] = numVersion(v2[i]); 16522 if (v1[i] < v2[i]) { 16523 compare = -1; 16524 break; 16525 } else if (v1[i] > v2[i]) { 16526 compare = 1; 16527 break; 16528 } 16529 } 16530 if (!operator) { 16531 return compare; 16532 } 16533 16534 switch (operator) { 16535 case '>': 16536 case 'gt': 16537 return (compare > 0); 16538 case '>=': 16539 case 'ge': 16540 return (compare >= 0); 16541 case '<=': 16542 case 'le': 16543 return (compare <= 0); 16544 case '==': 16545 case '=': 16546 case 'eq': 16547 return (compare === 0); 16548 case '<>': 16549 case '!=': 16550 case 'ne': 16551 return (compare !== 0); 16552 case '': 16553 case '<': 16554 case 'lt': 16555 return (compare < 0); 16556 default: 16557 return null; 16558 } 16559 } 16560 16561 16562 // Begin the iLightBox plugin 16563 $.fn.iLightBox = function() { 16564 16565 var args = arguments, 16566 opt = ($.isPlainObject(args[0])) ? args[0] : args[1], 16567 items = ($.isArray(args[0]) || typeof args[0] == 'string') ? args[0] : args[1]; 16568 16569 if (!opt) opt = {}; 16570 16571 // Default options. Play carefully. 16572 var options = $.extend(true, { 16573 attr: 'href', 16574 path: 'vertical', 16575 skin: 'dark', 16576 linkId: false, 16577 infinite: false, 16578 startFrom: 0, 16579 randomStart: false, 16580 keepAspectRatio: true, 16581 maxScale: 1, 16582 minScale: .2, 16583 innerToolbar: false, 16584 smartRecognition: false, 16585 mobileOptimizer: true, 16586 fullAlone: true, 16587 fullViewPort: null, 16588 fullStretchTypes: 'flash, video', 16589 overlay: { 16590 blur: true, 16591 opacity: .85 16592 }, 16593 controls: { 16594 arrows: false, 16595 slideshow: false, 16596 toolbar: true, 16597 fullscreen: true, 16598 thumbnail: true, 16599 keyboard: true, 16600 mousewheel: true, 16601 swipe: true 16602 }, 16603 keyboard: { 16604 left: true, // previous 16605 right: true, // next 16606 up: true, // previous 16607 down: true, // next 16608 esc: true, // close 16609 shift_enter: true // fullscreen 16610 }, 16611 show: { 16612 effect: true, 16613 speed: 300, 16614 title: true 16615 }, 16616 hide: { 16617 effect: true, 16618 speed: 300 16619 }, 16620 caption: { 16621 start: true, 16622 show: 'mouseenter', 16623 hide: 'mouseleave' 16624 }, 16625 social: { 16626 start: true, 16627 show: 'mouseenter', 16628 hide: 'mouseleave',
16629 buttons: false 16630 }, 16631 styles: { 16632 pageOffsetX: 0, 16633 pageOffsetY: 0, 16634 nextOffsetX: 45, 16635 nextOffsetY: 0, 16636 nextOpacity: 1, 16637 nextScale: 1, 16638 prevOffsetX: 45, 16639 prevOffsetY: 0, 16640 prevOpacity: 1, 16641 prevScale: 1 16642 }, 16643 thumbnails: { 16644 maxWidth: 120, 16645 maxHeight: 80, 16646 normalOpacity: 1, 16647 activeOpacity: .6 16648 }, 16649 effects: { 16650 reposition: true, 16651 repositionSpeed: 200, 16652 switchSpeed: 500, 16653 loadedFadeSpeed: 180, 16654 fadeSpeed: 200 16655 }, 16656 slideshow: { 16657 pauseTime: 5000, 16658 pauseOnHover: false, 16659 startPaused: true 16660 }, 16661 text: { 16662 close: "Press Esc to close", 16663 enterFullscreen: "Enter Fullscreen (Shift+Enter)", 16664 exitFullscreen: "Exit Fullscreen (Shift+Enter)", 16665 slideShow: "Slideshow", 16666 next: "Next", 16667 previous: "Previous" 16668 }, 16669 errors: { 16670 loadImage: "An error occurred when trying to load photo.", 16671 loadContents: "An error occurred when trying to load contents.", 16672 missingPlugin: "The content your are attempting to view requires the <a href='{pluginspage}' target='_blank'>{type} plugin<\/a>." 16673 }, 16674 ajaxSetup: { 16675 url: '', 16676 beforeSend: function(jqXHR, settings) {}, 16677 cache: false, 16678 complete: function(jqXHR, textStatus) {}, 16679 crossDomain: false, 16680 error: function(jqXHR, textStatus, errorThrown) {}, 16681 success: function(data, textStatus, jqXHR) {}, 16682 global: true, 16683 ifModified: false, 16684 username: null, 16685 password: null, 16686 type: 'GET' 16687 }, 16688 callback: {} 16689 }, opt); 16690 16691 var instant = ($.isArray(items) || typeof items == 'string') ? true : false; 16692 16693 items = $.isArray(items) ? items : new Array(); 16694 16695 if (typeof args[0] == 'string') items[0] = args[0]; 16696 16697 if (version_compare($.fn.jquery, '1.8', '>=')) { 16698 var iLB = new iLightBox($(this), options, items, instant); 16699 return { 16700 close: function() { 16701 iLB.closeAction(); 16702 }, 16703 fullscreen: function() { 16704 iLB.fullScreenAction(); 16705 }, 16706 moveNext: function() { 16707 iLB.moveTo('next'); 16708 }, 16709 movePrev: function() { 16710 iLB.moveTo('prev'); 16711 }, 16712 goTo: function(index) { 16713 iLB.goTo(index); 16714 }, 16715 refresh: function() { 16716 iLB.refresh(); 16717 }, 16718 reposition: function() { 16719 (arguments.length > 0) ? iLB.repositionPhoto(true): iLB.repositionPhoto(); 16720 }, 16721 setOption: function(options) { 16722 iLB.setOption(options); 16723 }, 16724 destroy: function() { 16725 iLB.closeAction(); 16726 iLB.dispatchItemsEvents(); 16727 } 16728 }; 16729 } else { 16730 throw "The jQuery version that was loaded is too old. iLightBox requires jQuery 1.8+"; 16731 } 16732 16733 }; 16734 16735 16736 $.iLightBox = function() { 16737 return $.fn.iLightBox(arguments[0], arguments[1]); 16738 }; 16739 16740 function getScrollXY() { 16741 var scrOfX = 0, 16742 scrOfY = 0; 16743 if (typeof(window.pageYOffset) == 'number') { 16744 //Netscape compliant 16745 scrOfY = window.pageYOffset; 16746 scrOfX = window.pageXOffset; 16747 } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) { 16748 //DOM compliant 16749 scrOfY = document.body.scrollTop; 16750 scrOfX = document.body.scrollLeft; 16751 } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) { 16752 //IE6 standards compliant mode 16753 scrOfY = document.documentElement.scrollTop; 16754 scrOfX = document.documentElement.scrollLeft; 16755 } 16756 return { 16757 x: scrOfX, 16758 y: scrOfY 16759 }; 16760 } 16761 16762 (function() { 16763 // add new event shortcuts 16764 $.each(("touchstart touchmove touchend " + 16765 "tap taphold " + 16766 "swipe swipeleft swiperight " + 16767 "scrollstart scrollstop").split(" "), function(i, name) { 16768 16769 $.fn[name] = function(fn) { 16770 return fn ? this.bind(name, fn) : this.trigger(name); 16771 }; 16772 16773 // jQuery < 1.8 16774 // if ($.attrFn) { 16775 // $.attrFn[name] = true; 16776 // } 16777 }); 16778 16779 var tapSettings = { 16780 startEvent: 'touchstart.iTap', 16781 endEvent: 'touchend.iTap' 16782 }; 16783 16784 // tap Event: 16785 $.event.special.itap = { 16786 setup: function() { 16787 16788 var self = this, 16789 $self = $(this), 16790 start, stop; 16791 16792 $self.bind(tapSettings.startEvent, function(event) { 16793 start = getScrollXY(); 16794 16795 $self.one(tapSettings.endEvent, function(event) { 16796 stop = getScrollXY(); 16797 16798 var orgEvent = event || window.event; 16799 event = $.event.fix(orgEvent); 16800 event.type = "itap"; 16801 16802 if ((start && stop) && (start.x == stop.x && start.y == stop.y))($.event.dispatch || $.event.handle).call(self, event); 16803 16804 start = stop = undefined; 16805 }); 16806 }); 16807 }, 16808 16809 teardown: function() { 16810 $(this).unbind(tapSettings.startEvent); 16811 } 16812 }; 16813 }()); 16814 16815 16816 //Fullscreen API 16817 (function() { 16818 fullScreenApi = { 16819 supportsFullScreen: false, 16820 isFullScreen: function() { 16821 return false;
16822 }, 16823 requestFullScreen: function() {}, 16824 cancelFullScreen: function() {}, 16825 fullScreenEventName: '', 16826 prefix: '' 16827 }, 16828 browserPrefixes = 'webkit moz o ms khtml'.split(' '); 16829 16830 // check for native support 16831 if (typeof document.cancelFullScreen != 'undefined') { 16832 fullScreenApi.supportsFullScreen = true; 16833 } else { 16834 // check for fullscreen support by vendor prefix 16835 for (var i = 0, il = browserPrefixes.length; i < il; i++) { 16836 fullScreenApi.prefix = browserPrefixes[i]; 16837 16838 if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') { 16839 fullScreenApi.supportsFullScreen = true; 16840 16841 break; 16842 } 16843 } 16844 } 16845 16846 // update methods to do something useful 16847 if (fullScreenApi.supportsFullScreen) { 16848 fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange'; 16849 16850 fullScreenApi.isFullScreen = function() { 16851 switch (this.prefix) { 16852 case '': 16853 return document.fullScreen; 16854 case 'webkit': 16855 return document.webkitIsFullScreen; 16856 default: 16857 return document[this.prefix + 'FullScreen']; 16858 } 16859 } 16860 fullScreenApi.requestFullScreen = function(el) { 16861 return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen'](); 16862 } 16863 fullScreenApi.cancelFullScreen = function(el) { 16864 return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen'](); 16865 } 16866 } 16867 }()); 16868 16869 // Browser detect 16870 (function() { 16871 function uaMatch(ua) { 16872 ua = ua.toLowerCase(); 16873 16874 var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 16875 /(webkit)[ \/]([\w.]+)/.exec(ua) || 16876 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 16877 /(msie) ([\w.]+)/.exec(ua) || 16878 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; 16879 16880 return { 16881 browser: match[1] || "", 16882 version: match[2] || "0" 16883 }; 16884 } 16885 16886 var matched = uaMatch(navigator.userAgent); 16887 browser = {}; 16888 16889 if (matched.browser) { 16890 browser[matched.browser] = true; 16891 browser.version = matched.version; 16892 } 16893 16894 // Chrome is Webkit, but Webkit is also Safari. 16895 if (browser.chrome) { 16896 browser.webkit = true; 16897 } else if (browser.webkit) { 16898 browser.safari = true; 16899 } 16900 }()); 16901 16902 // Feature detects 16903 (function() { 16904 var prefixes = ['', 'webkit', 'moz', 'ms', 'o']; 16905 var el = document.createElement('div'); 16906 16907 function testProp(prop) { 16908 for (var p = 0, pl = prefixes.length; p < pl; p++) { 16909 var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop; 16910 if (el.style[prefixedProp] !== undefined) { 16911 return prefixedProp; 16912 } 16913 } 16914 } 16915 16916 // Global support indicators 16917 transform = testProp('transform') || ''; 16918 gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : ''; 16919 }()); 16920 16921 16922 /* 16923 PluginDetect v0.7.9 16924 www.pinlady.net/PluginDetect/license/ 16925 [ getVersion onWindowLoaded BetterIE ] 16926 [ Flash QuickTime Shockwave ] 16927 */ 16928 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;
16928d++){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);
16928d.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)}
16928c.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;
16928if(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(); 16929 16930 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)}; 16931 16932 16933 /* 16934 jQuery hashchange event v1.3 16935 https://github.com/cowboy/jquery-hashchange 16936 Copyright (c) 2010 "Cowboy" Ben Alman 16937 Dual licensed under the MIT and GPL licenses. 16938 */ 16939 (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= 16940 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|| 16941 "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;
16941a!==d&&(b.title=k.title,b.open(),e&&b.write('<script>document.domain="'+e+'"\x3c/script>'),b.close(),c.location.hash=a)}}();return h}()})(); 16942 16943 if (!Array.prototype.filter) { 16944 Array.prototype.filter = function(fun /*, thisp */ ) { 16945 "use strict"; 16946 16947 if (this == null) 16948 throw new TypeError(); 16949 16950 var t = Object(this); 16951 var len = t.length >>> 0; 16952 if (typeof fun != "function") 16953 throw new TypeError(); 16954 16955 var res = []; 16956 var thisp = arguments[1]; 16957 for (var i = 0; i < len; i++) { 16958 if (i in t) { 16959 var val = t[i]; // in case fun mutates this 16960 if (fun.call(thisp, val, i, t)) 16961 res.push(val); 16962 } 16963 } 16964 16965 return res; 16966 }; 16967 } 16968 16969 if (!Array.prototype.indexOf) { 16970 Array.prototype.indexOf = function(searchElement, fromIndex) { 16971 var k; 16972 16973 if (this == null) { 16974 throw new TypeError('"this" is null or not defined'); 16975 } 16976 16977 var O = Object(this); 16978 16979 var len = O.length >>> 0; 16980 16981 if (len === 0) { 16982 return -1; 16983 } 16984 16985 var n = +fromIndex || 0; 16986 16987 if (abs(n) === Infinity) { 16988 n = 0; 16989 } 16990 16991 if (n >= len) { 16992 return -1; 16993 } 16994 16995 k = max(n >= 0 ? n : len - abs(n), 0); 16996 16997 while (k < len) { 16998 var kValue; 16999 if (k in O && O[k] === searchElement) { 17000 return k; 17001 } 17002 k++; 17003 } 17004 return -1; 17005 }; 17006 } 17007 17008 if (!Array.prototype.lastIndexOf) { 17009 Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/ ) { 17010 "use strict"; 17011 17012 if (this == null) 17013 throw new TypeError(); 17014 17015 var t = Object(this); 17016 var len = t.length >>> 0; 17017 if (len === 0) 17018 return -1; 17019 17020 var n = len; 17021 if (arguments.length > 1) { 17022 n = Number(arguments[1]); 17023 if (n != n) 17024 n = 0; 17025 else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) 17026 n = (n > 0 || -1) * floor(abs(n)); 17027 } 17028 17029 var k = n >= 0 ? min(n, len - 1) : len - abs(n); 17030 17031 for (; k >= 0; k--) { 17032 if (k in t && t[k] === searchElement) 17033 return k; 17034 } 17035 return -1; 17036 }; 17037 } 17038})(jQuery, this); 17039 17040/*! 17041 * lightgallery | 2.5.0 | June 13th 2022 17042 * http://www.lightgalleryjs.com/ 17043 * Copyright (c) 2020 Sachin Neravath; 17044 * @license GPLv3 17045 */ 17046 17047(function (global, factory) { 17048 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 17049 typeof define === 'function' && define.amd ? define(factory) : 17050 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lightGallery = factory()); 17051}(this, (function () { 'use strict'; 17052 17053 /*! ***************************************************************************** 17054 Copyright (c) Microsoft Corporation. 17055 17056 Permission to use, copy, modify, and/or distribute this software for any 17057 purpose with or without fee is hereby granted. 17058 17059 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 17060 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 17061 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 17062 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17063 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 17064 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17065 PERFORMANCE OF THIS SOFTWARE. 17066 ***************************************************************************** */ 17067 17068 var __assign = function() { 17069 __assign = Object.assign || function __assign(t) { 17070 for (var s, i = 1, n = arguments.length; i < n; i++) { 17071 s = arguments[i]; 17072 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 17073 } 17074 return t; 17075 }; 17076 return __assign.apply(this, arguments); 17077 }; 17078 17079 function __spreadArrays() { 17080 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 17081 for (var r = Array(s), k = 0, i = 0; i < il; i++) 17082 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 17083 r[k] = a[j]; 17084 return r; 17085 } 17086 17087 /** 17088 * List of lightGallery events 17089 * All events should be documented here 17090 * Below interfaces are used to build the website documentations 17091 * */ 17092 var lGEvents = { 17093 afterAppendSlide: 'lgAfterAppendSlide', 17094 init: 'lgInit', 17095 hasVideo: 'lgHasVideo', 17096 containerResize: 'lgContainerResize', 17097 updateSlides: 'lgUpdateSlides', 17098 afterAppendSubHtml: 'lgAfterAppendSubHtml', 17099 beforeOpen: 'lgBeforeOpen', 17100 afterOpen: 'lgAfterOpen', 17101 slideItemLoad: 'lgSlideItemLoad', 17102 beforeSlide: 'lgBeforeSlide', 17103 afterSlide: 'lgAfterSlide', 17104 posterClick: 'lgPosterClick', 17105 dragStart: 'lgDragStart', 17106 dragMove: 'lgDragMove', 17107 dragEnd: 'lgDragEnd', 17108 beforeNextSlide: 'lgBeforeNextSlide', 17109 beforePrevSlide: 'lgBeforePrevSlide', 17110 beforeClose: 'lgBeforeClose', 17111 afterClose: 'lgAfterClose', 17112 rotateLeft: 'lgRotateLeft', 17113 rotateRight: 'lgRotateRight', 17114 flipHorizontal: 'lgFlipHorizontal', 17115 flipVertical: 'lgFlipVertical', 17116 autoplay: 'lgAutoplay', 17117 autoplayStart: 'lgAutoplayStart', 17118 autoplayStop: 'lgAutoplayStop', 17119 }; 17120 17121 var lightGalleryCoreSettings = { 17122 mode: 'lg-slide', 17123 easing: 'ease', 17124 speed: 400, 17125 licenseKey: '0000-0000-000-0000', 17126 height: '100%', 17127 width: '100%', 17128 addClass: '', 17129 startClass: 'lg-start-zoom', 17130 backdropDuration: 300, 17131 container: '', 17132 startAnimationDuration: 400, 17133 zoomFromOrigin: true, 17134 hideBarsDelay: 0, 17135 showBarsAfter: 10000, 17136 slideDelay: 0, 17137 supportLegacyBrowser: true, 17138 allowMediaOverlap: false, 17139 videoMaxSize: '1280-720', 17140 loadYouTubePoster: true, 17141 defaultCaptionHeight: 0, 17142 ariaLabelledby: '', 17143 ariaDescribedby: '', 17144 resetScrollPosition: true, 17145 hideScrollbar: false, 17146 closable: true, 17147 swipeToClose: true, 17148 closeOnTap: true, 17149 showCloseIcon: true, 17150 showMaximizeIcon: false, 17151 loop: true, 17152 escKey: true, 17153 keyPress: true, 17154 trapFocus: true, 17155 controls: true, 17156 slideEndAnimation: true, 17157 hideControlOnEnd: false,
vendor: 15,066 bytes, lines 17158-17705
17158 mousewheel: false, 17159 getCaptionFromTitleOrAlt: true, 17160 appendSubHtmlTo: '.lg-sub-html', 17161 subHtmlSelectorRelative: false, 17162 preload: 2, 17163 numberOfSlideItemsInDom: 10, 17164 selector: '', 17165 selectWithin: '', 17166 nextHtml: '', 17167 prevHtml: '', 17168 index: 0, 17169 iframeWidth: '100%', 17170 iframeHeight: '100%', 17171 iframeMaxWidth: '100%', 17172 iframeMaxHeight: '100%', 17173 download: true, 17174 counter: true, 17175 appendCounterTo: '.lg-toolbar', 17176 swipeThreshold: 50, 17177 enableSwipe: true, 17178 enableDrag: true, 17179 dynamic: false, 17180 dynamicEl: [], 17181 extraProps: [], 17182 exThumbImage: '', 17183 isMobile: undefined, 17184 mobileSettings: { 17185 controls: false, 17186 showCloseIcon: false, 17187 download: false, 17188 }, 17189 plugins: [], 17190 strings: { 17191 closeGallery: 'Close gallery', 17192 toggleMaximize: 'Toggle maximize', 17193 previousSlide: 'Previous slide', 17194 nextSlide: 'Next slide', 17195 download: 'Download', 17196 playVideo: 'Play video', 17197 }, 17198 }; 17199 17200 function initLgPolyfills() { 17201 (function () { 17202 if (typeof window.CustomEvent === 'function') 17203 return false; 17204 function CustomEvent(event, params) { 17205 params = params || { 17206 bubbles: false, 17207 cancelable: false, 17208 detail: null, 17209 }; 17210 var evt = document.createEvent('CustomEvent'); 17211 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); 17212 return evt; 17213 } 17214 window.CustomEvent = CustomEvent; 17215 })(); 17216 (function () { 17217 if (!Element.prototype.matches) { 17218 Element.prototype.matches = 17219 Element.prototype.msMatchesSelector || 17220 Element.prototype.webkitMatchesSelector; 17221 } 17222 })(); 17223 } 17224 var lgQuery = /** @class */ (function () { 17225 function lgQuery(selector) { 17226 this.cssVenderPrefixes = [ 17227 'TransitionDuration', 17228 'TransitionTimingFunction', 17229 'Transform', 17230 'Transition', 17231 ]; 17232 this.selector = this._getSelector(selector); 17233 this.firstElement = this._getFirstEl(); 17234 return this; 17235 } 17236 lgQuery.generateUUID = function () { 17237 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 17238 var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8; 17239 return v.toString(16); 17240 }); 17241 }; 17242 lgQuery.prototype._getSelector = function (selector, context) { 17243 if (context === void 0) { context = document; } 17244 if (typeof selector !== 'string') { 17245 return selector; 17246 } 17247 context = context || document; 17248 var fl = selector.substring(0, 1); 17249 if (fl === '#') { 17250 return context.querySelector(selector); 17251 } 17252 else { 17253 return context.querySelectorAll(selector); 17254 } 17255 }; 17256 lgQuery.prototype._each = function (func) { 17257 if (!this.selector) { 17258 return this; 17259 } 17260 if (this.selector.length !== undefined) { 17261 [].forEach.call(this.selector, func); 17262 } 17263 else { 17264 func(this.selector, 0); 17265 } 17266 return this; 17267 }; 17268 lgQuery.prototype._setCssVendorPrefix = function (el, cssProperty, value) { 17269 // prettier-ignore 17270 var property = cssProperty.replace(/-([a-z])/gi, function (s, group1) { 17271 return group1.toUpperCase(); 17272 }); 17273 if (this.cssVenderPrefixes.indexOf(property) !== -1) { 17274 el.style[property.charAt(0).toLowerCase() + property.slice(1)] = value; 17275 el.style['webkit' + property] = value; 17276 el.style['moz' + property] = value; 17277 el.style['ms' + property] = value; 17278 el.style['o' + property] = value; 17279 } 17280 else { 17281 el.style[property] = value; 17282 } 17283 }; 17284 lgQuery.prototype._getFirstEl = function () { 17285 if (this.selector && this.selector.length !== undefined) { 17286 return this.selector[0]; 17287 } 17288 else { 17289 return this.selector; 17290 } 17291 }; 17292 lgQuery.prototype.isEventMatched = function (event, eventName) { 17293 var eventNamespace = eventName.split('.'); 17294 return event 17295 .split('.') 17296 .filter(function (e) { return e; }) 17297 .every(function (e) { 17298 return eventNamespace.indexOf(e) !== -1; 17299 }); 17300 }; 17301 lgQuery.prototype.attr = function (attr, value) { 17302 if (value === undefined) { 17303 if (!this.firstElement) { 17304 return ''; 17305 } 17306 return this.firstElement.getAttribute(attr); 17307 } 17308 this._each(function (el) { 17309 el.setAttribute(attr, value); 17310 }); 17311 return this; 17312 }; 17313 lgQuery.prototype.find = function (selector) { 17314 return $LG(this._getSelector(selector, this.selector)); 17315 }; 17316 lgQuery.prototype.first = function () { 17317 if (this.selector && this.selector.length !== undefined) { 17318 return $LG(this.selector[0]); 17319 } 17320 else { 17321 return $LG(this.selector); 17322 } 17323 }; 17324 lgQuery.prototype.eq = function (index) { 17325 return $LG(this.selector[index]); 17326 }; 17327 lgQuery.prototype.parent = function () { 17328 return $LG(this.selector.parentElement); 17329 }; 17330 lgQuery.prototype.get = function () { 17331 return this._getFirstEl(); 17332 }; 17333 lgQuery.prototype.removeAttr = function (attributes) { 17334 var attrs = attributes.split(' '); 17335 this._each(function (el) { 17336 attrs.forEach(function (attr) { return el.removeAttribute(attr); }); 17337 }); 17338 return this; 17339 }; 17340 lgQuery.prototype.wrap = function (className) { 17341 if (!this.firstElement) { 17342 return this; 17343 } 17344 var wrapper = document.createElement('div'); 17345 wrapper.className = className; 17346 this.firstElement.parentNode.insertBefore(wrapper, this.firstElement); 17347 this.firstElement.parentNode.removeChild(this.firstElement); 17348 wrapper.appendChild(this.firstElement); 17349 return this; 17350 }; 17351 lgQuery.prototype.addClass = function (classNames) { 17352 if (classNames === void 0) { classNames = ''; } 17353 this._each(function (el) { 17354 // IE doesn't support multiple arguments 17355 classNames.split(' ').forEach(function (className) { 17356 if (className) { 17357 el.classList.add(className); 17358 } 17359 }); 17360 }); 17361 return this; 17362 }; 17363 lgQuery.prototype.removeClass = function (classNames) { 17364 this._each(function (el) { 17365 // IE doesn't support multiple arguments 17366 classNames.split(' ').forEach(function (className) { 17367 if (className) { 17368 el.classList.remove(className); 17369 } 17370 }); 17371 }); 17372 return this; 17373 }; 17374 lgQuery.prototype.hasClass = function (className) { 17375 if (!this.firstElement) { 17376 return false; 17377 } 17378 return this.firstElement.classList.contains(className); 17379 }; 17380 lgQuery.prototype.hasAttribute = function (attribute) { 17381 if (!this.firstElement) { 17382 return false; 17383 } 17384 return this.firstElement.hasAttribute(attribute); 17385 }; 17386 lgQuery.prototype.toggleClass = function (className) { 17387 if (!this.firstElement) { 17388 return this; 17389 } 17390 if (this.hasClass(className)) { 17391 this.removeClass(className); 17392 } 17393 else { 17394 this.addClass(className); 17395 } 17396 return this; 17397 }; 17398 lgQuery.prototype.css = function (property, value) { 17399 var _this = this; 17400 this._each(function (el) { 17401 _this._setCssVendorPrefix(el, property, value); 17402 }); 17403 return this; 17404 }; 17405 // Need to pass separate namespaces for separate elements 17406 lgQuery.prototype.on = function (events, listener) { 17407 var _this = this; 17408 if (!this.selector) { 17409 return this; 17410 } 17411 events.split(' ').forEach(function (event) { 17412 if (!Array.isArray(lgQuery.eventListeners[event])) { 17413 lgQuery.eventListeners[event] = []; 17414 } 17415 lgQuery.eventListeners[event].push(listener); 17416 _this.selector.addEventListener(event.split('.')[0], listener); 17417 }); 17418 return this; 17419 }; 17420 // @todo - test this 17421 lgQuery.prototype.once = function (event, listener) { 17422 var _this = this; 17423 this.on(event, function () { 17424 _this.off(event); 17425 listener(event); 17426 }); 17427 return this; 17428 }; 17429 lgQuery.prototype.off = function (event) { 17430 var _this = this; 17431 if (!this.selector) { 17432 return this; 17433 } 17434 Object.keys(lgQuery.eventListeners).forEach(function (eventName) { 17435 if (_this.isEventMatched(event, eventName)) { 17436 lgQuery.eventListeners[eventName].forEach(function (listener) { 17437 _this.selector.removeEventListener(eventName.split('.')[0], listener); 17438 }); 17439 lgQuery.eventListeners[eventName] = []; 17440 } 17441 }); 17442 return this; 17443 }; 17444 lgQuery.prototype.trigger = function (event, detail) { 17445 if (!this.firstElement) { 17446 return this; 17447 } 17448 var customEvent = new CustomEvent(event.split('.')[0], { 17449 detail: detail || null, 17450 }); 17451 this.firstElement.dispatchEvent(customEvent); 17452 return this; 17453 }; 17454 // Does not support IE 17455 lgQuery.prototype.load = function (url) { 17456 var _this = this; 17457 fetch(url) 17458 .then(function (res) { return res.text(); }) 17459 .then(function (html) { 17460 _this.selector.innerHTML = html; 17461 }); 17462 return this; 17463 }; 17464 lgQuery.prototype.html = function (html) { 17465 if (html === undefined) { 17466 if (!this.firstElement) { 17467 return ''; 17468 } 17469 return this.firstElement.innerHTML; 17470 } 17471 this._each(function (el) { 17472 el.innerHTML = html; 17473 }); 17474 return this; 17475 }; 17476 lgQuery.prototype.append = function (html) { 17477 this._each(function (el) { 17478 if (typeof html === 'string') { 17479 el.insertAdjacentHTML('beforeend', html); 17480 } 17481 else { 17482 el.appendChild(html); 17483 } 17484 }); 17485 return this; 17486 }; 17487 lgQuery.prototype.prepend = function (html) { 17488 this._each(function (el) { 17489 el.insertAdjacentHTML('afterbegin', html); 17490 }); 17491 return this; 17492 }; 17493 lgQuery.prototype.remove = function () { 17494 this._each(function (el) { 17495 el.parentNode.removeChild(el); 17496 }); 17497 return this; 17498 }; 17499 lgQuery.prototype.empty = function () { 17500 this._each(function (el) { 17501 el.innerHTML = ''; 17502 }); 17503 return this; 17504 }; 17505 lgQuery.prototype.scrollTop = function (scrollTop) { 17506 if (scrollTop !== undefined) { 17507 document.body.scrollTop = scrollTop; 17508 document.documentElement.scrollTop = scrollTop; 17509 return this; 17510 } 17511 else { 17512 return (window.pageYOffset || 17513 document.documentElement.scrollTop || 17514 document.body.scrollTop || 17515 0); 17516 } 17517 }; 17518 lgQuery.prototype.scrollLeft = function (scrollLeft) { 17519 if (scrollLeft !== undefined) { 17520 document.body.scrollLeft = scrollLeft; 17521 document.documentElement.scrollLeft = scrollLeft; 17522 return this; 17523 } 17524 else { 17525 return (window.pageXOffset || 17526 document.documentElement.scrollLeft || 17527 document.body.scrollLeft || 17528 0); 17529 } 17530 }; 17531 lgQuery.prototype.offset = function () { 17532 if (!this.firstElement) { 17533 return { 17534 left: 0, 17535 top: 0, 17536 }; 17537 } 17538 var rect = this.firstElement.getBoundingClientRect(); 17539 var bodyMarginLeft = $LG('body').style().marginLeft; 17540 // Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value 17541 return { 17542 left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(), 17543 top: rect.top + this.scrollTop(), 17544 }; 17545 }; 17546 lgQuery.prototype.style = function () { 17547 if (!this.firstElement) { 17548 return {}; 17549 } 17550 return (this.firstElement.currentStyle || 17551 window.getComputedStyle(this.firstElement)); 17552 }; 17553 // Width without padding and border even if box-sizing is used. 17554 lgQuery.prototype.width = function () { 17555 var style = this.style(); 17556 return (this.firstElement.clientWidth - 17557 parseFloat(style.paddingLeft) - 17558 parseFloat(style.paddingRight)); 17559 }; 17560 // Height without padding and border even if box-sizing is used. 17561 lgQuery.prototype.height = function () { 17562 var style = this.style(); 17563 return (this.firstElement.clientHeight - 17564 parseFloat(style.paddingTop) - 17565 parseFloat(style.paddingBottom)); 17566 }; 17567 lgQuery.eventListeners = {}; 17568 return lgQuery; 17569 }()); 17570 function $LG(selector) { 17571 initLgPolyfills(); 17572 return new lgQuery(selector); 17573 } 17574 17575 var defaultDynamicOptions = [ 17576 'src', 17577 'sources', 17578 'subHtml', 17579 'subHtmlUrl', 17580 'html', 17581 'video', 17582 'poster', 17583 'slideName', 17584 'responsive', 17585 'srcset', 17586 'sizes', 17587 'iframe', 17588 'downloadUrl', 17589 'download', 17590 'width', 17591 'facebookShareUrl', 17592 'tweetText', 17593 'iframeTitle', 17594 'twitterShareUrl', 17595 'pinterestShareUrl', 17596 'pinterestText', 17597 'fbHtml', 17598 'disqusIdentifier', 17599 'disqusUrl', 17600 ]; 17601 // Convert html data-attribute to camalcase 17602 function convertToData(attr) { 17603 // FInd a way for lgsize 17604 if (attr === 'href') { 17605 return 'src'; 17606 } 17607 attr = attr.replace('data-', ''); 17608 attr = attr.charAt(0).toLowerCase() + attr.slice(1); 17609 attr = attr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); 17610 return attr; 17611 } 17612 var utils = { 17613 /** 17614 * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option 17615 */ 17616 //Uncode edit ##START## 17617 getSize: function (el, container, spacing, defaultLgSize, galleryItem) { 17618 // getSize: function (el, container, spacing, defaultLgSize) { 17619 //Uncode edit ##END## 17620 if (spacing === void 0) { spacing = 0; } 17621 var LGel = $LG(el); 17622 var lgSize = LGel.attr('data-lg-size') || defaultLgSize; 17623 //Uncode edit ##START## 17624 if ( typeof galleryItem.size && galleryItem.size != null ) { 17625 lgSize = galleryItem.size; 17626 } 17627 //Uncode edit ##END## 17628 if (!lgSize) { 17629 return; 17630 } 17631 var isResponsiveSizes = lgSize.split(','); 17632 // if at-least two viewport sizes are available 17633 if (isResponsiveSizes[1]) { 17634 var wWidth = window.innerWidth; 17635 for (var i = 0; i < isResponsiveSizes.length; i++) { 17636 var size_1 = isResponsiveSizes[i]; 17637 var responsiveWidth = parseInt(size_1.split('-')[2], 10); 17638 if (responsiveWidth > wWidth) { 17639 lgSize = size_1; 17640 break; 17641 } 17642 // take last item as last option 17643 if (i === isResponsiveSizes.length - 1) { 17644 lgSize = size_1; 17645 } 17646 } 17647 } 17648 var size = lgSize.split('-'); 17649 var width = parseInt(size[0], 10); 17650 var height = parseInt(size[1], 10); 17651 var cWidth = container.width(); 17652 var cHeight = container.height() - spacing; 17653 var maxWidth = Math.min(cWidth, width); 17654 var maxHeight = Math.min(cHeight, height); 17655 var ratio = Math.min(maxWidth / width, maxHeight / height); 17656 return { width: width * ratio, height: height * ratio }; 17657 }, 17658 /** 17659 * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option 17660 * @param {jQuery Element} 17661 * @returns {String} Transform CSS string 17662 */ 17663 getTransform: function (el, container, top, bottom, imageSize) { 17664 if (!imageSize) { 17665 return; 17666 } 17667 var LGel = $LG(el).find('img').first(); 17668 if (!LGel.get()) { 17669 return; 17670 } 17671 var containerRect = container.get().getBoundingClientRect(); 17672 var wWidth = containerRect.width; 17673 // using innerWidth to include mobile safari bottom bar 17674 var wHeight = container.height() - (top + bottom); 17675 var elWidth = LGel.width(); 17676 var elHeight = LGel.height(); 17677 var elStyle = LGel.style(); 17678 var x = (wWidth - elWidth) / 2 - 17679 LGel.offset().left + 17680 (parseFloat(elStyle.paddingLeft) || 0) + 17681 (parseFloat(elStyle.borderLeft) || 0) + 17682 $LG(window).scrollLeft() + 17683 containerRect.left; 17684 var y = (wHeight - elHeight) / 2 - 17685 LGel.offset().top + 17686 (parseFloat(elStyle.paddingTop) || 0) + 17687 (parseFloat(elStyle.borderTop) || 0) + 17688 $LG(window).scrollTop() + 17689 top; 17690 var scX = elWidth / imageSize.width; 17691 var scY = elHeight / imageSize.height; 17692 var transform = 'translate3d(' + 17693 (x *= -1) + 17694 'px, ' + 17695 (y *= -1) + 17696 'px, 0) scale3d(' + 17697 scX + 17698 ', ' + 17699 scY + 17700 ', 1)'; 17701 return transform; 17702 }, 17703 getIframeMarkup: function (iframeWidth, iframeHeight, iframeMaxWidth, iframeMaxHeight, src, iframeTitle) { 17704 var title = iframeTitle ? 'title="' + iframeTitle + '"' : ''; 17705 return "<div class=\"lg-video-cont lg-has-iframe\" style=\"width:"
vendor: 2,803 bytes, lines 17705-17777
17705+ iframeWidth + "; max-width:" + iframeMaxWidth + "; height: " + iframeHeight + "; max-height:" + iframeMaxHeight + "\">\n <iframe class=\"lg-object\" frameborder=\"0\" " + title + " src=\"" + src + "\" allowfullscreen=\"true\"></iframe>\n </div>"; 17706 }, 17707 getImgMarkup: function (index, src, altAttr, srcset, sizes, sources) { 17708 var srcsetAttr = srcset ? "srcset=\"" + srcset + "\"" : ''; 17709 var sizesAttr = sizes ? "sizes=\"" + sizes + "\"" : ''; 17710 var imgMarkup = "<img " + altAttr + " " + srcsetAttr + " " + sizesAttr + " class=\"lg-object lg-image\" data-index=\"" + index + "\" src=\"" + src + "\" />"; 17711 var sourceTag = ''; 17712 if (sources) { 17713 var sourceObj = typeof sources === 'string' ? JSON.parse(sources) : sources; 17714 sourceTag = sourceObj.map(function (source) { 17715 var attrs = ''; 17716 Object.keys(source).forEach(function (key) { 17717 // Do not remove the first space as it is required to separate the attributes 17718 attrs += " " + key + "=\"" + source[key] + "\""; 17719 }); 17720 return "<source " + attrs + "></source>"; 17721 }); 17722 } 17723 return "" + sourceTag + imgMarkup; 17724 }, 17725 // Get src from responsive src 17726 getResponsiveSrc: function (srcItms) { 17727 var rsWidth = []; 17728 var rsSrc = []; 17729 var src = ''; 17730 for (var i = 0; i < srcItms.length; i++) { 17731 var _src = srcItms[i].split(' '); 17732 // Manage empty space 17733 if (_src[0] === '') { 17734 _src.splice(0, 1); 17735 } 17736 rsSrc.push(_src[0]); 17737 rsWidth.push(_src[1]); 17738 } 17739 var wWidth = window.innerWidth; 17740 for (var j = 0; j < rsWidth.length; j++) { 17741 if (parseInt(rsWidth[j], 10) > wWidth) { 17742 src = rsSrc[j]; 17743 break; 17744 } 17745 } 17746 return src; 17747 }, 17748 isImageLoaded: function (img) { 17749 if (!img) 17750 return false; 17751 // During the onload event, IE correctly identifies any images that 17752 // werenât downloaded as not complete. Others should too. Gecko-based 17753 // browsers act like NS4 in that they report this incorrectly. 17754 if (!img.complete) { 17755 return false; 17756 } 17757 // However, they do have two very useful properties: naturalWidth and 17758 // naturalHeight. These give the true size of the image. If it failed 17759 // to load, either of these should be zero. 17760 if (img.naturalWidth === 0) { 17761 return false; 17762 } 17763 // No other way of checking: assume itâs ok. 17764 return true; 17765 }, 17766 getVideoPosterMarkup: function (_poster, dummyImg, videoContStyle, playVideoString, _isVideo) { 17767 var videoClass = ''; 17768 if (_isVideo && _isVideo.youtube) { 17769 videoClass = 'lg-has-youtube'; 17770 } 17771 else if (_isVideo && _isVideo.vimeo) { 17772 videoClass = 'lg-has-vimeo'; 17773 } 17774 else { 17775 videoClass = 'lg-has-html5'; 17776 } 17777 return "<div class=\"lg-video-cont " + videoClass + "\" style=\"" + videoContStyle + "\">\n <div class=\"lg-video-play-button\">
vendor: 5,030 bytes, lines 17777-17888
17777\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>"; 17778 }, 17779 getFocusableElements: function (container) { 17780 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])'); 17781 var visibleElements = [].filter.call(elements, function (element) { 17782 var style = window.getComputedStyle(element); 17783 return style.display !== 'none' && style.visibility !== 'hidden'; 17784 }); 17785 return visibleElements; 17786 }, 17787 /** 17788 * @desc Create dynamic elements array from gallery items when dynamic option is false 17789 * It helps to avoid frequent DOM interaction 17790 * and avoid multiple checks for dynamic elments 17791 * 17792 * @returns {Array} dynamicEl 17793 */ 17794 getDynamicOptions: function (items, extraProps, getCaptionFromTitleOrAlt, exThumbImage) { 17795 var dynamicElements = []; 17796 var availableDynamicOptions = __spreadArrays(defaultDynamicOptions, extraProps); 17797 [].forEach.call(items, function (item) { 17798 var dynamicEl = {}; 17799 for (var i = 0; i < item.attributes.length; i++) { 17800 var attr = item.attributes[i]; 17801 if (attr.specified) { 17802 var dynamicAttr = convertToData(attr.name); 17803 var label = ''; 17804 if (availableDynamicOptions.indexOf(dynamicAttr) > -1) { 17805 label = dynamicAttr; 17806 } 17807 if (label) { 17808 dynamicEl[label] = attr.value; 17809 } 17810 } 17811 } 17812 var currentItem = $LG(item); 17813 var alt = currentItem.find('img').first().attr('alt'); 17814 var title = currentItem.attr('title'); 17815 //Uncode edit ##START## 17816 // var thumb = exThumbImage 17817 var thumb = exThumbImage && currentItem.attr(exThumbImage) 17818 //Uncode edit ##END## 17819 ? currentItem.attr(exThumbImage) 17820 : currentItem.find('img').first().attr('src'); 17821 dynamicEl.thumb = thumb; 17822 //Uncode edit ##START## 17823 if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) { 17824 // dynamicEl.subHtml = title || alt || ''; 17825 dynamicEl.subHtml = title || ''; 17826 } 17827 // dynamicEl.alt = alt || title || ''; 17828 dynamicEl.alt = title || ''; 17829 var inlineType = currentItem.attr('data-type'); 17830 dynamicEl.type = inlineType; 17831 //Uncode edit ##END## 17832 dynamicElements.push(dynamicEl); 17833 }); 17834 return dynamicElements; 17835 }, 17836 isMobile: function () { 17837 return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); 17838 }, 17839 /** 17840 * @desc Check the given src is video 17841 * @param {String} src 17842 * @return {Object} video type 17843 * Ex:{ youtube : ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] } 17844 * 17845 * @todo - this information can be moved to dynamicEl to avoid frequent calls 17846 */ 17847 isVideo: function (src, isHTML5VIdeo, index) { 17848 if (!src || src.match(/\.(mp4|m4v|ogg|webm)$/) ) { 17849 if (isHTML5VIdeo) { 17850 return { 17851 html5: true, 17852 }; 17853 } 17854 else { 17855 console.warn('lightGallery :- data-src is not provided on slide item ' + 17856 (index + 1) + 17857 '. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/'); 17858 return; 17859 } 17860 } 17861 var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)([\&|?][\S]*)*/i); 17862 var vimeo = src.match(/\/\/(?:www\.)?(?:player\.)?vimeo.com\/(?:video\/)?([0-9a-z\-_]+)(.*)?/i); 17863 var wistia = src.match(/https?:\/\/(.+)?(wistia\.com|wi\.st)\/(medias|embed)\/([0-9a-z\-_]+)(.*)/); 17864 if (youtube) { 17865 return { 17866 youtube: youtube, 17867 }; 17868 } 17869 else if (vimeo) { 17870 return { 17871 vimeo: vimeo, 17872 }; 17873 } 17874 else if (wistia) { 17875 return { 17876 wistia: wistia, 17877 }; 17878 } 17879 }, 17880 }; 17881 17882 // @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio 17883 // @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html 17884 // Unique id for each gallery 17885 var lgId = 0; 17886 var LightGallery = /** @class */ (function () { 17887 function LightGallery(element, options) { 17888 this.lgOpened = false;
vendor: 4,563 bytes, lines 17889-18023
17889 this.index = 0; 17890 // lightGallery modules 17891 this.plugins = []; 17892 // false when lightGallery load first slide content; 17893 this.lGalleryOn = false; 17894 // True when a slide animation is in progress 17895 this.lgBusy = false; 17896 this.currentItemsInDom = []; 17897 // Scroll top value before lightGallery is opened 17898 this.prevScrollTop = 0; 17899 this.bodyPaddingRight = 0; 17900 this.isDummyImageRemoved = false; 17901 this.dragOrSwipeEnabled = false; 17902 this.mediaContainerPosition = { 17903 top: 0, 17904 bottom: 0, 17905 }; 17906 if (!element) { 17907 return this; 17908 } 17909 lgId++; 17910 this.lgId = lgId; 17911 this.el = element; 17912 this.LGel = $LG(element); 17913 this.generateSettings(options); 17914 this.buildModules(); 17915 // When using dynamic mode, ensure dynamicEl is an array 17916 if (this.settings.dynamic && 17917 this.settings.dynamicEl !== undefined && 17918 !Array.isArray(this.settings.dynamicEl)) { 17919 throw 'When using dynamic mode, you must also define dynamicEl as an Array.'; 17920 } 17921 this.galleryItems = this.getItems(); 17922 this.normalizeSettings(); 17923 // Gallery items 17924 this.init(); 17925 //Uncode edit ##START## 17926 // this.validateLicense(); 17927 //Uncode edit ##END## 17928 return this; 17929 } 17930 LightGallery.prototype.generateSettings = function (options) { 17931 // lightGallery settings 17932 this.settings = __assign(__assign({}, lightGalleryCoreSettings), options); 17933 if (this.settings.isMobile && 17934 typeof this.settings.isMobile === 'function' 17935 ? this.settings.isMobile() 17936 : utils.isMobile()) { 17937 var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings); 17938 this.settings = __assign(__assign({}, this.settings), mobileSettings); 17939 } 17940 }; 17941 LightGallery.prototype.normalizeSettings = function () { 17942 if (this.settings.slideEndAnimation) { 17943 this.settings.hideControlOnEnd = false; 17944 } 17945 if (!this.settings.closable) { 17946 this.settings.swipeToClose = false; 17947 } 17948 // And reset it on close to get the correct value next time 17949 this.zoomFromOrigin = this.settings.zoomFromOrigin; 17950 // At the moment, Zoom from image doesn't support dynamic options 17951 // @todo add zoomFromOrigin support for dynamic images 17952 if (this.settings.dynamic) { 17953 this.zoomFromOrigin = false; 17954 } 17955 if (!this.settings.container) { 17956 this.settings.container = document.body; 17957 } 17958 // settings.preload should not be grater than $item.length 17959 this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length); 17960 }; 17961 LightGallery.prototype.init = function () { 17962 var _this = this; 17963 this.addSlideVideoInfo(this.galleryItems); 17964 this.buildStructure(); 17965 this.LGel.trigger(lGEvents.init, { 17966 instance: this, 17967 }); 17968 if (this.settings.keyPress) { 17969 this.keyPress(); 17970 } 17971 setTimeout(function () { 17972 _this.enableDrag(); 17973 _this.enableSwipe(); 17974 _this.triggerPosterClick(); 17975 }, 50); 17976 this.arrow(); 17977 if (this.settings.mousewheel) { 17978 this.mousewheel(); 17979 } 17980 if (!this.settings.dynamic) { 17981 this.openGalleryOnItemClick(); 17982 } 17983 }; 17984 LightGallery.prototype.openGalleryOnItemClick = function () { 17985 var _this = this; 17986 var _loop_1 = function (index) { 17987 var element = this_1.items[index]; 17988 var $element = $LG(element); 17989 // Using different namespace for click because click event should not unbind if selector is same object('this') 17990 // @todo manage all event listners - should have namespace that represent element 17991 var uuid = lgQuery.generateUUID(); 17992 $element 17993 .attr('data-lg-id', uuid) 17994 .on("click.lgcustom-item-" + uuid, function (e) { 17995 e.preventDefault(); 17996 var currentItemIndex = _this.settings.index || index; 17997 _this.openGallery(currentItemIndex, element); 17998 }); 17999 }; 18000 var this_1 = this; 18001 // Using for loop instead of using bubbling as the items can be any html element. 18002 for (var index = 0; index < this.items.length; index++) { 18003 _loop_1(index); 18004 } 18005 }; 18006 /** 18007 * Module constructor 18008 * Modules are build incrementally. 18009 * Gallery should be opened only once all the modules are initialized. 18010 * use moduleBuildTimeout to make sure this 18011 */ 18012 LightGallery.prototype.buildModules = function () { 18013 var _this = this; 18014 this.settings.plugins.forEach(function (plugin) { 18015 _this.plugins.push(new plugin(_this, $LG)); 18016 }); 18017 }; 18018 LightGallery.prototype.validateLicense = function () { 18019 if (!this.settings.licenseKey) { 18020 console.warn('Please provide a valid license key'); 18021 } 18022 else if (this.settings.licenseKey === '0000-0000-000-0000') { 18023 console.warn("lightGallery: " + this.settings.licenseKey + " license key is not val
vendor: 17,473 bytes, lines 18023-18437
18023id for production use"); 18024 } 18025 }; 18026 LightGallery.prototype.getSlideItem = function (index) { 18027 return $LG(this.getSlideItemId(index)); 18028 }; 18029 LightGallery.prototype.getSlideItemId = function (index) { 18030 return "#lg-item-" + this.lgId + "-" + index; 18031 }; 18032 LightGallery.prototype.getIdName = function (id) { 18033 return id + "-" + this.lgId; 18034 }; 18035 LightGallery.prototype.getElementById = function (id) { 18036 return $LG("#" + this.getIdName(id)); 18037 }; 18038 LightGallery.prototype.manageSingleSlideClassName = function () { 18039 if (this.galleryItems.length < 2) { 18040 this.outer.addClass('lg-single-item'); 18041 } 18042 else { 18043 this.outer.removeClass('lg-single-item'); 18044 } 18045 }; 18046 LightGallery.prototype.buildStructure = function () { 18047 var _this = this; 18048 var container = this.$container && this.$container.get(); 18049 if (container) { 18050 return; 18051 } 18052 var controls = ''; 18053 var subHtmlCont = ''; 18054 // Create controls 18055 if (this.settings.controls) { 18056 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>"; 18057 } 18058 if (this.settings.appendSubHtmlTo !== '.lg-item') { 18059 subHtmlCont = 18060 '<div class="lg-sub-html" role="status" aria-live="polite"></div>'; 18061 } 18062 var addClasses = ''; 18063 if (this.settings.allowMediaOverlap) { 18064 // Do not remove space before last single quote 18065 addClasses += 'lg-media-overlap '; 18066 } 18067 var ariaLabelledby = this.settings.ariaLabelledby 18068 ? 'aria-labelledby="' + this.settings.ariaLabelledby + '"' 18069 : ''; 18070 var ariaDescribedby = this.settings.ariaDescribedby 18071 ? 'aria-describedby="' + this.settings.ariaDescribedby + '"' 18072 : ''; 18073 var containerClassName = "lg-container " + this.settings.addClass + " " + (document.body !== this.settings.container ? 'lg-inline' : ''); 18074 var closeIcon = this.settings.closable && this.settings.showCloseIcon 18075 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['closeGallery'] + "\" id=\"" + this.getIdName('lg-close') + "\" class=\"lg-close lg-icon\"></button>" 18076 : ''; 18077 var maximizeIcon = this.settings.showMaximizeIcon 18078 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['toggleMaximize'] + "\" id=\"" + this.getIdName('lg-maximize') + "\" class=\"lg-maximize lg-icon\"></button>" 18079 : ''; 18080 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' 18081 ? subHtmlCont 18082 : '') + "\n <div id=\"" + this.getIdName('lg-components') + "\" class=\"lg-components\">\n " + (this.settings.appendSubHtmlTo === '.lg-sub-html' 18083 ? subHtmlCont 18084 : '') + "\n </div>\n </div>\n </div>\n "; 18085 $LG(this.settings.container).append(template); 18086 if (document.body !== this.settings.container) { 18087 $LG(this.settings.container).css('position', 'relative'); 18088 } 18089 this.outer = this.getElementById('lg-outer'); 18090 this.$lgComponents = this.getElementById('lg-components'); 18091 this.$backdrop = this.getElementById('lg-backdrop'); 18092 this.$container = this.getElementById('lg-container'); 18093 this.$inner = this.getElementById('lg-inner'); 18094 this.$content = this.getElementById('lg-content'); 18095 this.$toolbar = this.getElementById('lg-toolbar'); 18096 this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms'); 18097 var outerClassNames = this.settings.mode + " "; 18098 this.manageSingleSlideClassName(); 18099 if (this.settings.enableDrag) { 18100 outerClassNames += 'lg-grab '; 18101 } 18102 this.outer.addClass(outerClassNames); 18103 this.$inner.css('transition-timing-function', this.settings.easing); 18104 this.$inner.css('transition-duration', this.settings.speed + 'ms'); 18105 if (this.settings.download) { 18106 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>"); 18107 } 18108 this.counter(); 18109 $LG(window).on("resize.lg.global" + this.lgId + " orientationchange.lg.global" + this.lgId, function () { 18110 _this.refreshOnResize(); 18111 }); 18112 this.hideBars(); 18113 this.manageCloseGallery(); 18114 this.toggleMaximize(); 18115 this.initModules(); 18116 }; 18117 LightGallery.prototype.refreshOnResize = function () { 18118 if (this.lgOpened) { 18119 var currentGalleryItem = this.galleryItems[this.index]; 18120 var __slideVideoInfo = currentGalleryItem.__slideVideoInfo; 18121 this.mediaContainerPosition = this.getMediaContainerPosition(); 18122 var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom; 18123 //Uncode edit ##START## 18124 this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18125 // this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize); 18126 //Uncode edit ##END## 18127 if (__slideVideoInfo) { 18128 this.resizeVideoSlide(this.index, this.currentImageSize); 18129 } 18130 if (this.zoomFromOrigin && !this.isDummyImageRemoved) { 18131 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 18132 this.outer 18133 .find('.lg-current .lg-dummy-img') 18134 .first() 18135 .attr('style', imgStyle); 18136 } 18137 this.LGel.trigger(lGEvents.containerResize); 18138 } 18139 }; 18140 LightGallery.prototype.resizeVideoSlide = function (index, imageSize) { 18141 var lgVideoStyle = this.getVideoContStyle(imageSize); 18142 var currentSlide = this.getSlideItem(index); 18143 currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle); 18144 }; 18145 /** 18146 * Update slides dynamically. 18147 * Add, edit or delete slides dynamically when lightGallery is opened. 18148 * Modify the current gallery items and pass it via updateSlides method 18149 * @note 18150 * - Do not mutate existing lightGallery items directly. 18151 * - Always pass new list of gallery items 18152 * - You need to take care of thumbnails outside the gallery if any 18153 * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method. 18154 * @param items Gallery items 18155 * @param index After the update operation, which slide gallery should navigate to 18156 * @category lGPublicMethods 18157 * @example 18158 * const plugin = lightGallery(); 18159 * 18160 * // Adding slides dynamically 18161 * let galleryItems = [ 18162 * // Access existing lightGallery items 18163 * // galleryItems are automatically generated internally from the gallery HTML markup 18164 * // or directly from galleryItems when dynamic gallery is used 18165 * ...plugin.galleryItems, 18166 * ...[ 18167 * { 18168 * src: 'img/img-1.png', 18169 * thumb: 'img/thumb1.png', 18170 * }, 18171 * ], 18172 * ]; 18173 * plugin.updateSlides( 18174 * galleryItems, 18175 * plugin.index, 18176 * ); 18177 * 18178 * 18179 * // Remove slides dynamically 18180 * galleryItems = JSON.parse( 18181 * JSON.stringify(updateSlideInstance.galleryItems), 18182 * ); 18183 * galleryItems.shift(); 18184 * updateSlideInstance.updateSlides(galleryItems, 1); 18185 * @see <a href="/demos/update-slides/">Demo</a> 18186 */ 18187 LightGallery.prototype.updateSlides = function (items, index) { 18188 if (this.index > items.length - 1) { 18189 this.index = items.length - 1; 18190 } 18191 if (items.length === 1) { 18192 this.index = 0; 18193 } 18194 if (!items.length) { 18195 this.closeGallery(); 18196 return; 18197 } 18198 var currentSrc = this.galleryItems[index].src; 18199 this.galleryItems = items; 18200 this.updateControls(); 18201 this.$inner.empty(); 18202 this.currentItemsInDom = []; 18203 var _index = 0; 18204 // Find the current index based on source value of the slide 18205 this.galleryItems.some(function (galleryItem, itemIndex) { 18206 if (galleryItem.src === currentSrc) { 18207 _index = itemIndex; 18208 return true; 18209 } 18210 return false; 18211 }); 18212 this.currentItemsInDom = this.organizeSlideItems(_index, -1); 18213 this.loadContent(_index, true); 18214 this.getSlideItem(_index).addClass('lg-current'); 18215 this.index = _index; 18216 this.updateCurrentCounter(_index); 18217 this.LGel.trigger(lGEvents.updateSlides); 18218 }; 18219 // Get gallery items based on multiple conditions 18220 LightGallery.prototype.getItems = function () { 18221 // Gallery items 18222 this.items = []; 18223 if (!this.settings.dynamic) { 18224 if (this.settings.selector === 'this') { 18225 this.items.push(this.el); 18226 } 18227 else if (this.settings.selector) { 18228 if (typeof this.settings.selector === 'string') { 18229 if (this.settings.selectWithin) { 18230 var selectWithin = $LG(this.settings.selectWithin); 18231 this.items = selectWithin 18232 .find(this.settings.selector) 18233 .get(); 18234 } 18235 else { 18236 this.items = this.el.querySelectorAll(this.settings.selector); 18237 } 18238 } 18239 else { 18240 this.items = this.settings.selector; 18241 } 18242 } 18243 else { 18244 this.items = this.el.children; 18245 } 18246 return utils.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage); 18247 } 18248 else { 18249 return this.settings.dynamicEl || []; 18250 } 18251 }; 18252 LightGallery.prototype.shouldHideScrollbar = function () { 18253 return (this.settings.hideScrollbar && 18254 document.body === this.settings.container); 18255 }; 18256 LightGallery.prototype.hideScrollbar = function () { 18257 if (!this.shouldHideScrollbar()) { 18258 return; 18259 } 18260 this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight); 18261 var bodyRect = document.documentElement.getBoundingClientRect(); 18262 var scrollbarWidth = window.innerWidth - bodyRect.width; 18263 $LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px'); 18264 $LG(document.body).addClass('lg-overlay-open'); 18265 }; 18266 LightGallery.prototype.resetScrollBar = function () { 18267 if (!this.shouldHideScrollbar()) { 18268 return; 18269 } 18270 $LG(document.body).css('padding-right', this.bodyPaddingRight + 'px'); 18271 $LG(document.body).removeClass('lg-overlay-open'); 18272 }; 18273 /** 18274 * Open lightGallery. 18275 * Open gallery with specific slide by passing index of the slide as parameter. 18276 * @category lGPublicMethods 18277 * @param {Number} index - index of the slide 18278 * @param {HTMLElement} element - Which image lightGallery should zoom from 18279 * 18280 * @example 18281 * const $dynamicGallery = document.getElementById('dynamic-gallery-demo'); 18282 * const dynamicGallery = lightGallery($dynamicGallery, { 18283 * dynamic: true, 18284 * dynamicEl: [ 18285 * { 18286 * src: 'img/1.jpg', 18287 * thumb: 'img/thumb-1.jpg', 18288 * subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>', 18289 * }, 18290 * ... 18291 * ], 18292 * }); 18293 * $dynamicGallery.addEventListener('click', function () { 18294 * // Starts with third item.(Optional). 18295 * // This is useful if you want use dynamic mode with 18296 * // custom thumbnails (thumbnails outside gallery), 18297 * dynamicGallery.openGallery(2); 18298 * }); 18299 * 18300 */ 18301 LightGallery.prototype.openGallery = function (index, element) { 18302 var _this = this; 18303 if (index === void 0) { index = this.settings.index; } 18304 // prevent accidental double execution 18305 if (this.lgOpened) 18306 return; 18307 this.lgOpened = true; 18308 this.outer.removeClass('lg-hide-items'); 18309 this.hideScrollbar(); 18310 // Add display block, but still has opacity 0 18311 this.$container.addClass('lg-show'); 18312 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index); 18313 this.currentItemsInDom = itemsToBeInsertedToDom; 18314 var items = ''; 18315 itemsToBeInsertedToDom.forEach(function (item) { 18316 items = items + ("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 18317 }); 18318 this.$inner.append(items); 18319 this.addHtml(index); 18320 var transform = ''; 18321 this.mediaContainerPosition = this.getMediaContainerPosition(); 18322 var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 18323 if (!this.settings.allowMediaOverlap) { 18324 this.setMediaContainerPosition(top, bottom); 18325 } 18326 var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo; 18327 if (this.zoomFromOrigin && element) { 18328 //Uncode edit ##START## 18329 this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18330 // this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize); 18331 //Uncode edit ##END## 18332 transform = utils.getTransform(element, this.outer, top, bottom, this.currentImageSize); 18333 } 18334 if (!this.zoomFromOrigin || !transform) { 18335 this.outer.addClass(this.settings.startClass); 18336 this.getSlideItem(index).removeClass('lg-complete'); 18337 } 18338 var timeout = this.settings.zoomFromOrigin 18339 ? 100 18340 : this.settings.backdropDuration; 18341 setTimeout(function () { 18342 _this.outer.addClass('lg-components-open'); 18343 }, timeout); 18344 this.index = index; 18345 //Uncode edit ##START## 18346 // this.LGel.trigger(lGEvents.beforeOpen); 18347 this.LGel.trigger(lGEvents.beforeOpen, { 18348 galleryItems: this.galleryItems, 18349 items: this.items, 18350 outer: this.outer, 18351 }); 18352 //Uncode edit ##END## 18353 // add class lg-current to remove initial transition 18354 this.getSlideItem(index).addClass('lg-current'); 18355 this.lGalleryOn = false; 18356 // Store the current scroll top value to scroll back after closing the gallery.. 18357 this.prevScrollTop = $LG(window).scrollTop(); 18358 setTimeout(function () { 18359 // Need to check both zoomFromOrigin and transform values as we need to set set the 18360 // default opening animation if user missed to add the lg-size attribute 18361 if (_this.zoomFromOrigin && transform) { 18362 var currentSlide_1 = _this.getSlideItem(index); 18363 currentSlide_1.css('transform', transform); 18364 setTimeout(function () { 18365 currentSlide_1 18366 .addClass('lg-start-progress lg-start-end-progress') 18367 .css('transition-duration', _this.settings.startAnimationDuration + 'ms'); 18368 _this.outer.addClass('lg-zoom-from-image'); 18369 }); 18370 setTimeout(function () { 18371 currentSlide_1.css('transform', 'translate3d(0, 0, 0)'); 18372 }, 100); 18373 } 18374 setTimeout(function () { 18375 _this.$backdrop.addClass('in'); 18376 _this.$container.addClass('lg-show-in'); 18377 }, 10); 18378 setTimeout(function () { 18379 if (_this.settings.trapFocus && 18380 document.body === _this.settings.container) { 18381 _this.trapFocus(); 18382 } 18383 }, _this.settings.backdropDuration + 50); 18384 // lg-visible class resets gallery opacity to 1 18385 if (!_this.zoomFromOrigin || !transform) { 18386 setTimeout(function () { 18387 _this.outer.addClass('lg-visible'); 18388 }, _this.settings.backdropDuration); 18389 } 18390 // initiate slide function 18391 _this.slide(index, false, false, false); 18392 _this.LGel.trigger(lGEvents.afterOpen); 18393 }); 18394 if (document.body === this.settings.container) { 18395 $LG('html').addClass('lg-on'); 18396 } 18397 }; 18398 /** 18399 * Note - Changing the position of the media on every slide transition creates a flickering effect. 18400 * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption. 18401 * if you have dynamic captions for each media, 18402 * you can provide an appropriate height for the captions via allowMediaOverlap option 18403 */ 18404 LightGallery.prototype.getMediaContainerPosition = function () { 18405 if (this.settings.allowMediaOverlap) { 18406 return { 18407 top: 0, 18408 bottom: 0, 18409 }; 18410 } 18411 var top = this.$toolbar.get().clientHeight || 0; 18412 var subHtml = this.outer.find('.lg-components .lg-sub-html').get(); 18413 var captionHeight = this.settings.defaultCaptionHeight || 18414 (subHtml && subHtml.clientHeight) || 18415 0; 18416 var thumbContainer = this.outer.find('.lg-thumb-outer').get(); 18417 var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0; 18418 var bottom = thumbHeight + captionHeight; 18419 //Uncode edit ##START## 18420 bottom = bottom < 55 ? 55 : bottom; 18421 //Uncode edit ##END## 18422 return { 18423 top: top, 18424 bottom: bottom, 18425 }; 18426 }; 18427 LightGallery.prototype.setMediaContainerPosition = function (top, bottom) { 18428 if (top === void 0) { top = 0; } 18429 if (bottom === void 0) { bottom = 0; } 18430 this.$content.css('top', top + 'px').css('bottom', bottom + 'px'); 18431 }; 18432 LightGallery.prototype.hideBars = function () { 18433 var _this = this; 18434 // Hide controllers if mouse doesn't move for some period 18435 setTimeout(function () { 18436 _this.outer.removeClass('lg-hide-items'); 18437 if (_this.settings.hideBarsDelay > 0) {
vendor: 4,223 bytes, lines 18438-18568
18438 _this.outer.on('mousemove.lg click.lg touchstart.lg', function () { 18439 _this.outer.removeClass('lg-hide-items'); 18440 clearTimeout(_this.hideBarTimeout); 18441 // Timeout will be cleared on each slide movement also 18442 _this.hideBarTimeout = setTimeout(function () { 18443 _this.outer.addClass('lg-hide-items'); 18444 }, _this.settings.hideBarsDelay); 18445 }); 18446 _this.outer.trigger('mousemove.lg'); 18447 } 18448 }, this.settings.showBarsAfter); 18449 }; 18450 LightGallery.prototype.initPictureFill = function ($img) { 18451 if (this.settings.supportLegacyBrowser) { 18452 try { 18453 picturefill({ 18454 elements: [$img.get()], 18455 }); 18456 } 18457 catch (e) { 18458 console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.'); 18459 } 18460 } 18461 }; 18462 /** 18463 * @desc Create image counter 18464 * Ex: 1/10 18465 */ 18466 LightGallery.prototype.counter = function () { 18467 if (this.settings.counter) { 18468 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>"; 18469 this.outer.find(this.settings.appendCounterTo).append(counterHtml); 18470 } 18471 }; 18472 /** 18473 * @desc add sub-html into the slide 18474 * @param {Number} index - index of the slide 18475 */ 18476 LightGallery.prototype.addHtml = function (index) { 18477 var subHtml; 18478 var subHtmlUrl; 18479 if (this.galleryItems[index].subHtmlUrl) { 18480 subHtmlUrl = this.galleryItems[index].subHtmlUrl; 18481 } 18482 else { 18483 subHtml = this.galleryItems[index].subHtml; 18484 } 18485 if (!subHtmlUrl) { 18486 if (subHtml) { 18487 // get first letter of sub-html 18488 // if first letter starts with . or # get the html form the jQuery object 18489 var fL = subHtml.substring(0, 1); 18490 if (fL === '.' || fL === '#') { 18491 if (this.settings.subHtmlSelectorRelative && 18492 !this.settings.dynamic) { 18493 subHtml = $LG(this.items) 18494 .eq(index) 18495 .find(subHtml) 18496 .first() 18497 .html(); 18498 } 18499 else { 18500 subHtml = $LG(subHtml).first().html(); 18501 } 18502 } 18503 } 18504 else { 18505 subHtml = ''; 18506 } 18507 } 18508 if (this.settings.appendSubHtmlTo !== '.lg-item') { 18509 if (subHtmlUrl) { 18510 this.outer.find('.lg-sub-html').load(subHtmlUrl); 18511 } 18512 else { 18513 this.outer.find('.lg-sub-html').html(subHtml); 18514 } 18515 } 18516 else { 18517 var currentSlide = $LG(this.getSlideItemId(index)); 18518 if (subHtmlUrl) { 18519 currentSlide.load(subHtmlUrl); 18520 } 18521 else { 18522 currentSlide.append("<div class=\"lg-sub-html\">" + subHtml + "</div>"); 18523 } 18524 } 18525 // Add lg-empty-html class if title doesn't exist 18526 if (typeof subHtml !== 'undefined' && subHtml !== null) { 18527 if (subHtml === '') { 18528 this.outer 18529 .find(this.settings.appendSubHtmlTo) 18530 .addClass('lg-empty-html'); 18531 } 18532 else { 18533 this.outer 18534 .find(this.settings.appendSubHtmlTo) 18535 .removeClass('lg-empty-html'); 18536 } 18537 } 18538 this.LGel.trigger(lGEvents.afterAppendSubHtml, { 18539 index: index, 18540 }); 18541 }; 18542 /** 18543 * @desc Preload slides 18544 * @param {Number} index - index of the slide 18545 * @todo preload not working for the first slide, Also, should work for the first and last slide as well 18546 */ 18547 LightGallery.prototype.preload = function (index) { 18548 for (var i = 1; i <= this.settings.preload; i++) { 18549 if (i >= this.galleryItems.length - index) { 18550 break; 18551 } 18552 this.loadContent(index + i, false); 18553 } 18554 for (var j = 1; j <= this.settings.preload; j++) { 18555 if (index - j < 0) { 18556 break; 18557 } 18558 this.loadContent(index - j, false); 18559 } 18560 }; 18561 LightGallery.prototype.getDummyImgStyles = function (imageSize) { 18562 if (!imageSize) 18563 return ''; 18564 return "width:" + imageSize.width + "px;\n margin-left: -" + imageSize.width / 2 + "px;\n margin-top: -" + imageSize.height / 2 + "px;\n height:" + imageSize.height + "px"; 18565 }; 18566 LightGallery.prototype.getVideoContStyle = function (imageSize) { 18567 if (!imageSize) 18568 return '';
18569 return "width:" + imageSize.width + "px;\n height:" + imageSize.height + "px"; 18570 }; 18571 LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) { 18572 var $currentItem; 18573 if (!this.settings.dynamic) { 18574 $currentItem = $LG(this.items).eq(index); 18575 } 18576 if ($currentItem) { 18577 var _dummyImgSrc = void 0; 18578 if (!this.settings.exThumbImage) { 18579 _dummyImgSrc = $currentItem.find('img').first().attr('src'); 18580 } 18581 else { 18582 _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage); 18583 } 18584 if (!_dummyImgSrc) 18585 return ''; 18586 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 18587 var dummyImgContent = "<img " + alt + " style=\"" + imgStyle + "\" class=\"lg-dummy-img\" src=\"" + _dummyImgSrc + "\" />"; 18588 $currentSlide.addClass('lg-first-slide'); 18589 this.outer.addClass('lg-first-slide-loading'); 18590 return dummyImgContent; 18591 } 18592 return ''; 18593 }; 18594 LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) { 18595 var currentGalleryItem = this.galleryItems[index]; 18596 var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 18597 // Use the thumbnail as dummy image which will be resized to actual image size and 18598 // displayed on top of actual image 18599 var imgContent = ''; 18600 var altAttr = alt ? 'alt="' + alt + '"' : ''; 18601 if (this.isFirstSlideWithZoomAnimation()) { 18602 imgContent = this.getDummyImageContent($currentSlide, index, altAttr); 18603 } 18604 else { 18605 imgContent = utils.getImgMarkup(index, src, altAttr, srcset, sizes, sources); 18606 } 18607 var imgMarkup = "<picture class=\"lg-img-wrap\"> " + imgContent + "</picture>"; 18608 $currentSlide.prepend(imgMarkup); 18609 }; 18610 LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) { 18611 var mediaObject = $slide.find('.lg-object').first(); 18612 if (utils.isImageLoaded(mediaObject.get()) || 18613 isHTML5VideoWithoutPoster) { 18614 onLoad(); 18615 } 18616 else { 18617 mediaObject.on('load.lg error.lg', function () { 18618 onLoad && onLoad(); 18619 }); 18620 mediaObject.on('error.lg', function () { 18621 onError && onError(); 18622 }); 18623 } 18624 }; 18625 /** 18626 * 18627 * @param $el Current slide item 18628 * @param index 18629 * @param delay Delay is 0 except first time 18630 * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin 18631 * @param isFirstSlide 18632 */ 18633 LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) { 18634 var _this = this; 18635 //Uncode edit ##START## 18636 var $item = _this.galleryItems[index], 18637 type = $item.type; 18638 18639 if ( typeof $item.src !== 'undefined' ) { 18640 var inline_id = $item.src.replace('#', ''), 18641 $inline = document.getElementById(inline_id), 18642 inline_html; 18643 18644 if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) { 18645 inline_html = $inline.innerHTML; 18646 } else { 18647 inline_html = ''; 18648 } 18649 } 18650 //Uncode edit ##END## 18651 this.onSlideObjectLoad(currentSlide, true, function () { 18652 _this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide); 18653 }, function () { 18654 currentSlide.addClass('lg-complete lg-complete_'); 18655 //Uncode edit ##START## 18656 // currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 18657 if ( inline_html !== '' ) { 18658 currentSlide.html(inline_html); 18659 } else { 18660 currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 18661 } 18662 //Uncode edit ##END## 18663 }); 18664 }; 18665 LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) { 18666 var _this = this; 18667 var currentGalleryItem = this.galleryItems[index]; 18668 // Adding delay for video slides without poster for better performance and user experience 18669 // Videos should start playing once once the gallery is completely loaded 18670 var _speed = isFirstSlide &&
vendor: 3,676 bytes, lines 18671-18759
18671 this.getSlideType(currentGalleryItem) === 'video' && 18672 !currentGalleryItem.poster 18673 ? speed 18674 : 0; 18675 setTimeout(function () { 18676 $currentSlide.addClass('lg-complete lg-complete_'); 18677 _this.LGel.trigger(lGEvents.slideItemLoad, { 18678 index: index, 18679 delay: delay || 0, 18680 isFirstSlide: isFirstSlide, 18681 }); 18682 }, _speed); 18683 }; 18684 LightGallery.prototype.isFirstSlideWithZoomAnimation = function () { 18685 return !!(!this.lGalleryOn && 18686 this.zoomFromOrigin && 18687 this.currentImageSize); 18688 }; 18689 // Add video slideInfo 18690 LightGallery.prototype.addSlideVideoInfo = function (items) { 18691 var _this = this; 18692 items.forEach(function (element, index) { 18693 element.__slideVideoInfo = utils.isVideo(element.src, !!element.video, index); 18694 if (element.__slideVideoInfo && 18695 _this.settings.loadYouTubePoster && 18696 !element.poster && 18697 element.__slideVideoInfo.youtube) { 18698 element.poster = "//img.youtube.com/vi/" + element.__slideVideoInfo.youtube[1] + "/maxresdefault.jpg"; 18699 } 18700 }); 18701 }; 18702 /** 18703 * Load slide content into slide. 18704 * This is used to load content into slides that is not visible too 18705 * @param {Number} index - index of the slide. 18706 * @param {Boolean} rec - if true call loadcontent() function again. 18707 */ 18708 LightGallery.prototype.loadContent = function (index, rec) { 18709 var _this = this; 18710 var currentGalleryItem = this.galleryItems[index]; 18711 var $currentSlide = $LG(this.getSlideItemId(index)); 18712 var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 18713 var src = currentGalleryItem.src; 18714 var video = currentGalleryItem.video; 18715 var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video; 18716 if (currentGalleryItem.responsive) { 18717 var srcDyItms = currentGalleryItem.responsive.split(','); 18718 src = utils.getResponsiveSrc(srcDyItms) || src; 18719 } 18720 var videoInfo = currentGalleryItem.__slideVideoInfo; 18721 var lgVideoStyle = ''; 18722 var iframe = !!currentGalleryItem.iframe; 18723 var isFirstSlide = !this.lGalleryOn; 18724 // delay for adding complete class. it is 0 except first time. 18725 var delay = 0; 18726 if (isFirstSlide) { 18727 if (this.zoomFromOrigin && this.currentImageSize) { 18728 delay = this.settings.startAnimationDuration + 10; 18729 } 18730 else { 18731 delay = this.settings.backdropDuration + 10; 18732 } 18733 } 18734 if (!$currentSlide.hasClass('lg-loaded')) { 18735 if (videoInfo) { 18736 var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom; 18737 //Uncode edit ##START## 18738 var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 18739 // var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize); 18740 //Uncode edit ##END## 18741 lgVideoStyle = this.getVideoContStyle(videoSize); 18742 } 18743 if (iframe) { 18744 var markup = utils.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle); 18745 $currentSlide.prepend(markup); 18746 } 18747 else if (poster) { 18748 var dummyImg = ''; 18749 var hasStartAnimation = isFirstSlide && 18750 this.zoomFromOrigin && 18751 this.currentImageSize; 18752 if (hasStartAnimation) { 18753 dummyImg = this.getDummyImageContent($currentSlide, index, ''); 18754 } 18755 var markup = utils.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo); 18756 $currentSlide.prepend(markup); 18757 } 18758 //Uncode edit ##START## 18759 // else if (videoInfo) {
18760 else if (videoInfo || this.getSlideType(currentGalleryItem) === 'audio') { 18761 if (! _html5Video) { 18762 var markup = "<div class=\"lg-video-cont \" style=\"" + lgVideoStyle + "\"></div>"; 18763 } 18764 //Uncode edit ##END## 18765 $currentSlide.prepend(markup); 18766 } 18767 else { 18768 //Uncode edit ##START## 18769 var $item = _this.galleryItems[index], 18770 type = $item.type; 18771 18772 if ( typeof $item.src !== 'undefined' ) { 18773 var inline_id = $item.src.replace('#', ''), 18774 $inline = document.getElementById(inline_id), 18775 inline_html; 18776 18777 if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) { 18778 inline_html = $inline.innerHTML; 18779 } else { 18780 inline_html = ''; 18781 } 18782 } 18783 if ( inline_html !== '' ) { 18784 $currentSlide.html(inline_html); 18785 } else { 18786 this.setImgMarkup(src, $currentSlide, index); 18787 if (srcset || sources) { 18788 var $img = $currentSlide.find('.lg-object'); 18789 this.initPictureFill($img); 18790 } 18791 } 18792 /*this.setImgMarkup(src, $currentSlide, index); 18793 if (srcset || sources) { 18794 var $img = $currentSlide.find('.lg-object'); 18795 this.initPictureFill($img); 18796 }*/ 18797 //Uncode edit ##END## 18798 } 18799 if (poster || videoInfo) { 18800 this.LGel.trigger(lGEvents.hasVideo, { 18801 index: index, 18802 src: src, 18803 html5Video: _html5Video, 18804 hasPoster: !!poster, 18805 }); 18806 } 18807 this.LGel.trigger(lGEvents.afterAppendSlide, { index: index }); 18808 if (this.lGalleryOn && 18809 this.settings.appendSubHtmlTo === '.lg-item') { 18810 this.addHtml(index); 18811 } 18812 } 18813 // For first time add some delay for displaying the start animation. 18814 var _speed = 0; 18815 // Do not change the delay value because it is required for zoom plugin. 18816 // If gallery opened from direct url (hash) speed value should be 0 18817 if (delay && !$LG(document.body).hasClass('lg-from-hash')) { 18818 _speed = delay; 18819 } 18820 // Only for first slide and zoomFromOrigin is enabled 18821 if (this.isFirstSlideWithZoomAnimation()) { 18822 setTimeout(function () { 18823 $currentSlide 18824 .removeClass('lg-start-end-progress lg-start-progress') 18825 .removeAttr('style'); 18826 }, this.settings.startAnimationDuration + 100); 18827 if (!$currentSlide.hasClass('lg-loaded')) { 18828 setTimeout(function () { 18829 if (_this.getSlideType(currentGalleryItem) === 'image') { 18830 var alt = currentGalleryItem.alt; 18831 var altAttr = alt ? 'alt="' + alt + '"' : ''; 18832 $currentSlide 18833 .find('.lg-img-wrap') 18834 .append(utils.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources)); 18835 if (srcset || sources) { 18836 var $img = $currentSlide.find('.lg-object'); 18837 _this.initPictureFill($img); 18838 } 18839 } 18840 if (_this.getSlideType(currentGalleryItem) === 'image' || 18841 (_this.getSlideType(currentGalleryItem) === 'video' && 18842 poster)) { 18843 _this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false); 18844 // load remaining slides once the slide is completely loaded 18845 _this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () { 18846 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 18847 }, function () { 18848 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 18849 }); 18850 } 18851 }, this.settings.startAnimationDuration + 100); 18852 } 18853 } 18854 // SLide content has been added to dom 18855 $currentSlide.addClass('lg-loaded'); 18856 if (!this.isFirstSlideWithZoomAnimation() || 18857 (this.getSlideType(currentGalleryItem) === 'video' && !poster)) { 18858 //Uncode edit ##START## 18859 // this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster)); 18860 this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!( (videoInfo && videoInfo.html5 && !poster) || this.get
vendor: 31,133 bytes, lines 18860-19784
18860SlideType(currentGalleryItem) === 'audio')); 18861 //Uncode edit ##END## 18862 } 18863 // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling 18864 if ((!this.zoomFromOrigin || !this.currentImageSize) && 18865 $currentSlide.hasClass('lg-complete_') && 18866 !this.lGalleryOn) { 18867 setTimeout(function () { 18868 $currentSlide.addClass('lg-complete'); 18869 }, this.settings.backdropDuration); 18870 } 18871 // Content loaded 18872 // Need to set lGalleryOn before calling preload function 18873 this.lGalleryOn = true; 18874 if (rec === true) { 18875 if (!$currentSlide.hasClass('lg-complete_')) { 18876 $currentSlide 18877 .find('.lg-object') 18878 .first() 18879 .on('load.lg error.lg', function () { 18880 _this.preload(index); 18881 }); 18882 } 18883 else { 18884 this.preload(index); 18885 } 18886 } 18887 }; 18888 /** 18889 * @desc Remove dummy image content and load next slides 18890 * Called only for the first time if zoomFromOrigin animation is enabled 18891 * @param index 18892 * @param $currentSlide 18893 * @param speed 18894 */ 18895 LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) { 18896 var _this = this; 18897 setTimeout(function () { 18898 $currentSlide.find('.lg-dummy-img').remove(); 18899 $currentSlide.removeClass('lg-first-slide'); 18900 _this.outer.removeClass('lg-first-slide-loading'); 18901 _this.isDummyImageRemoved = true; 18902 _this.preload(index); 18903 }, speed + 300); 18904 }; 18905 LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) { 18906 var _this = this; 18907 if (numberOfItems === void 0) { numberOfItems = 0; } 18908 var itemsToBeInsertedToDom = []; 18909 // Minimum 2 items should be there 18910 var possibleNumberOfItems = Math.max(numberOfItems, 3); 18911 possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length); 18912 var prevIndexItem = "lg-item-" + this.lgId + "-" + prevIndex; 18913 if (this.galleryItems.length <= 3) { 18914 this.galleryItems.forEach(function (_element, index) { 18915 itemsToBeInsertedToDom.push("lg-item-" + _this.lgId + "-" + index); 18916 }); 18917 return itemsToBeInsertedToDom; 18918 } 18919 if (index < (this.galleryItems.length - 1) / 2) { 18920 for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) { 18921 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 18922 } 18923 var numberOfExistingItems = itemsToBeInsertedToDom.length; 18924 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 18925 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index + idx + 1)); 18926 } 18927 } 18928 else { 18929 for (var idx = index; idx <= this.galleryItems.length - 1 && 18930 idx < index + possibleNumberOfItems / 2; idx++) { 18931 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 18932 } 18933 var numberOfExistingItems = itemsToBeInsertedToDom.length; 18934 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 18935 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index - idx - 1)); 18936 } 18937 } 18938 if (this.settings.loop) { 18939 if (index === this.galleryItems.length - 1) { 18940 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + 0); 18941 } 18942 else if (index === 0) { 18943 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (this.galleryItems.length - 1)); 18944 } 18945 } 18946 if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) { 18947 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + prevIndex); 18948 } 18949 return itemsToBeInsertedToDom; 18950 }; 18951 LightGallery.prototype.organizeSlideItems = function (index, prevIndex) { 18952 var _this = this; 18953 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom); 18954 itemsToBeInsertedToDom.forEach(function (item) { 18955 if (_this.currentItemsInDom.indexOf(item) === -1) { 18956 _this.$inner.append("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 18957 } 18958 }); 18959 this.currentItemsInDom.forEach(function (item) { 18960 if (itemsToBeInsertedToDom.indexOf(item) === -1) { 18961 $LG("#" + item).remove(); 18962 } 18963 }); 18964 return itemsToBeInsertedToDom; 18965 }; 18966 /** 18967 * Get previous index of the slide 18968 */ 18969 LightGallery.prototype.getPreviousSlideIndex = function () { 18970 var prevIndex = 0; 18971 try { 18972 var currentItemId = this.outer 18973 .find('.lg-current') 18974 .first() 18975 .attr('id'); 18976 prevIndex = parseInt(currentItemId.split('-')[3]) || 0; 18977 } 18978 catch (error) { 18979 prevIndex = 0; 18980 } 18981 return prevIndex; 18982 }; 18983 LightGallery.prototype.setDownloadValue = function (index) { 18984 if (this.settings.download) { 18985 var currentGalleryItem = this.galleryItems[index]; 18986 var hideDownloadBtn = currentGalleryItem.downloadUrl === false || 18987 currentGalleryItem.downloadUrl === 'false'; 18988 if (hideDownloadBtn) { 18989 this.outer.addClass('lg-hide-download'); 18990 } 18991 else { 18992 var $download = this.getElementById('lg-download'); 18993 this.outer.removeClass('lg-hide-download'); 18994 $download.attr('href', currentGalleryItem.downloadUrl || 18995 currentGalleryItem.src); 18996 if (currentGalleryItem.download) { 18997 //Uncode edit ##START## 18998 if ( typeof currentGalleryItem.video !== 'undefined' && currentGalleryItem.video ) { 18999 var currentVideo = JSON.parse( currentGalleryItem.video ), 19000 download_name = currentVideo.source[0].src; 19001 $download.attr('href', download_name).removeAttr('download'); 19002 } else { 19003 var download_url = currentGalleryItem.downloadUrl || currentGalleryItem.src, 19004 download_name = download_url.substring(download_url.lastIndexOf('/')+1); 19005 $download.attr('download', download_name); 19006 } 19007 // $download.attr('download', currentGalleryItem.download); 19008 //Uncode edit ##END## 19009 } 19010 } 19011 } 19012 }; 19013 LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) { 19014 var _this = this; 19015 if (this.lGalleryOn) { 19016 previousSlideItem.addClass('lg-slide-progress'); 19017 } 19018 setTimeout(function () { 19019 // remove all transitions 19020 _this.outer.addClass('lg-no-trans'); 19021 _this.outer 19022 .find('.lg-item') 19023 .removeClass('lg-prev-slide lg-next-slide'); 19024 if (direction === 'prev') { 19025 //prevslide 19026 currentSlideItem.addClass('lg-prev-slide'); 19027 previousSlideItem.addClass('lg-next-slide'); 19028 } 19029 else { 19030 // next slide 19031 currentSlideItem.addClass('lg-next-slide'); 19032 previousSlideItem.addClass('lg-prev-slide'); 19033 } 19034 // give 50 ms for browser to add/remove class 19035 setTimeout(function () { 19036 _this.outer.find('.lg-item').removeClass('lg-current'); 19037 currentSlideItem.addClass('lg-current'); 19038 // reset all transitions 19039 _this.outer.removeClass('lg-no-trans'); 19040 }, 50); 19041 }, this.lGalleryOn ? this.settings.slideDelay : 0); 19042 }; 19043 /** 19044 * Goto a specific slide. 19045 * @param {Number} index - index of the slide 19046 * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag 19047 * @param {Boolean} fromThumb - true if slide function called via thumbnail click 19048 * @param {String} direction - Direction of the slide(next/prev) 19049 * @category lGPublicMethods 19050 * @example 19051 * const plugin = lightGallery(); 19052 * // to go to 3rd slide 19053 * plugin.slide(2); 19054 * 19055 */ 19056 LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) { 19057 var _this = this; 19058 var prevIndex = this.getPreviousSlideIndex(); 19059 this.currentItemsInDom = this.organizeSlideItems(index, prevIndex); 19060 // Prevent multiple call, Required for hsh plugin 19061 if (this.lGalleryOn && prevIndex === index) { 19062 return; 19063 } 19064 var numberOfGalleryItems = this.galleryItems.length; 19065 if (!this.lgBusy) { 19066 if (this.settings.counter) { 19067 this.updateCurrentCounter(index); 19068 } 19069 var currentSlideItem = this.getSlideItem(index); 19070 var previousSlideItem_1 = this.getSlideItem(prevIndex); 19071 var currentGalleryItem = this.galleryItems[index]; 19072 var videoInfo = currentGalleryItem.__slideVideoInfo; 19073 this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem)); 19074 this.setDownloadValue(index); 19075 if (videoInfo) { 19076 var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom; 19077 //Uncode edit ##START## 19078 var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 19079 // var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize); 19080 //Uncode edit ##END## 19081 this.resizeVideoSlide(index, videoSize); 19082 } 19083 this.LGel.trigger(lGEvents.beforeSlide, { 19084 prevIndex: prevIndex, 19085 index: index, 19086 fromTouch: !!fromTouch, 19087 fromThumb: !!fromThumb, 19088 //Uncode edit ##START## 19089 currentSlide: currentSlideItem, 19090 previousSlide: previousSlideItem_1, 19091 info: currentGalleryItem, 19092 item: this.items[index] 19093 //Uncode edit ##END## 19094 }); 19095 this.lgBusy = true; 19096 clearTimeout(this.hideBarTimeout); 19097 this.arrowDisable(index); 19098 if (!direction) { 19099 if (index < prevIndex) { 19100 direction = 'prev'; 19101 } 19102 else if (index > prevIndex) { 19103 direction = 'next'; 19104 } 19105 } 19106 if (!fromTouch) { 19107 this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1); 19108 } 19109 else { 19110 this.outer 19111 .find('.lg-item') 19112 .removeClass('lg-prev-slide lg-current lg-next-slide'); 19113 var touchPrev = void 0; 19114 var touchNext = void 0; 19115 if (numberOfGalleryItems > 2) { 19116 touchPrev = index - 1; 19117 touchNext = index + 1; 19118 if (index === 0 && prevIndex === numberOfGalleryItems - 1) { 19119 // next slide 19120 touchNext = 0; 19121 touchPrev = numberOfGalleryItems - 1; 19122 } 19123 else if (index === numberOfGalleryItems - 1 && 19124 prevIndex === 0) { 19125 // prev slide 19126 touchNext = 0; 19127 touchPrev = numberOfGalleryItems - 1; 19128 } 19129 } 19130 else { 19131 touchPrev = 0; 19132 touchNext = 1; 19133 } 19134 if (direction === 'prev') { 19135 this.getSlideItem(touchNext).addClass('lg-next-slide'); 19136 } 19137 else { 19138 this.getSlideItem(touchPrev).addClass('lg-prev-slide'); 19139 } 19140 currentSlideItem.addClass('lg-current'); 19141 } 19142 // Do not put load content in set timeout as it needs to load immediately when the gallery is opened 19143 if (!this.lGalleryOn) { 19144 this.loadContent(index, true); 19145 } 19146 else { 19147 setTimeout(function () { 19148 _this.loadContent(index, true); 19149 // Add title if this.settings.appendSubHtmlTo === lg-sub-html 19150 if (_this.settings.appendSubHtmlTo !== '.lg-item') { 19151 _this.addHtml(index); 19152 } 19153 }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay)); 19154 } 19155 setTimeout(function () { 19156 _this.lgBusy = false; 19157 previousSlideItem_1.removeClass('lg-slide-progress'); 19158 _this.LGel.trigger(lGEvents.afterSlide, { 19159 prevIndex: prevIndex, 19160 index: index, 19161 fromTouch: fromTouch, 19162 fromThumb: fromThumb, 19163 }); 19164 }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay)); 19165 } 19166 this.index = index; 19167 }; 19168 LightGallery.prototype.updateCurrentCounter = function (index) { 19169 this.getElementById('lg-counter-current').html(index + 1 + ''); 19170 }; 19171 LightGallery.prototype.updateCounterTotal = function () { 19172 this.getElementById('lg-counter-all').html(this.galleryItems.length + ''); 19173 }; 19174 LightGallery.prototype.getSlideType = function (item) { 19175 if (item.__slideVideoInfo) { 19176 return 'video'; 19177 } 19178 else if (item.iframe) { 19179 return 'iframe'; 19180 } 19181 //Uncode edit ##START## 19182 else if (typeof item.src !== '' && item.src.search(/.mp3|.m4a/i) > -1) { 19183 return 'audio'; 19184 } 19185 //Uncode edit ##END## 19186 else { 19187 return 'image'; 19188 } 19189 }; 19190 LightGallery.prototype.touchMove = function (startCoords, endCoords, e) { 19191 var distanceX = endCoords.pageX - startCoords.pageX; 19192 var distanceY = endCoords.pageY - startCoords.pageY; 19193 var allowSwipe = false; 19194 if (this.swipeDirection) { 19195 allowSwipe = true; 19196 } 19197 else { 19198 if (Math.abs(distanceX) > 15) { 19199 this.swipeDirection = 'horizontal'; 19200 allowSwipe = true; 19201 } 19202 else if (Math.abs(distanceY) > 15) { 19203 this.swipeDirection = 'vertical'; 19204 allowSwipe = true; 19205 } 19206 } 19207 if (!allowSwipe) { 19208 return; 19209 } 19210 var $currentSlide = this.getSlideItem(this.index); 19211 if (this.swipeDirection === 'horizontal') { 19212 e === null || e === void 0 ? void 0 : e.preventDefault(); 19213 // reset opacity and transition duration 19214 this.outer.addClass('lg-dragging'); 19215 // move current slide 19216 this.setTranslate($currentSlide, distanceX, 0); 19217 // move next and prev slide with current slide 19218 var width = $currentSlide.get().offsetWidth; 19219 var slideWidthAmount = (width * 15) / 100; 19220 var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100); 19221 this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0); 19222 this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0); 19223 } 19224 else if (this.swipeDirection === 'vertical') { 19225 if (this.settings.swipeToClose) { 19226 e === null || e === void 0 ? void 0 : e.preventDefault(); 19227 this.$container.addClass('lg-dragging-vertical'); 19228 var opacity = 1 - Math.abs(distanceY) / window.innerHeight; 19229 this.$backdrop.css('opacity', opacity); 19230 var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2); 19231 this.setTranslate($currentSlide, 0, distanceY, scale, scale); 19232 if (Math.abs(distanceY) > 100) { 19233 this.outer 19234 .addClass('lg-hide-items') 19235 .removeClass('lg-components-open'); 19236 } 19237 } 19238 } 19239 }; 19240 LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) { 19241 var _this = this; 19242 var distance; 19243 // keep slide animation for any mode while dragg/swipe 19244 if (this.settings.mode !== 'lg-slide') { 19245 this.outer.addClass('lg-slide'); 19246 } 19247 // set transition duration 19248 setTimeout(function () { 19249 _this.$container.removeClass('lg-dragging-vertical'); 19250 _this.outer 19251 .removeClass('lg-dragging lg-hide-items') 19252 .addClass('lg-components-open'); 19253 var triggerClick = true; 19254 if (_this.swipeDirection === 'horizontal') { 19255 distance = endCoords.pageX - startCoords.pageX; 19256 var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX); 19257 if (distance < 0 && 19258 distanceAbs > _this.settings.swipeThreshold) { 19259 _this.goToNextSlide(true); 19260 triggerClick = false; 19261 } 19262 else if (distance > 0 && 19263 distanceAbs > _this.settings.swipeThreshold) { 19264 _this.goToPrevSlide(true); 19265 triggerClick = false; 19266 } 19267 } 19268 else if (_this.swipeDirection === 'vertical') { 19269 distance = Math.abs(endCoords.pageY - startCoords.pageY); 19270 if (_this.settings.closable && 19271 _this.settings.swipeToClose && 19272 distance > 100) { 19273 _this.closeGallery(); 19274 return; 19275 } 19276 else { 19277 _this.$backdrop.css('opacity', 1); 19278 } 19279 } 19280 _this.outer.find('.lg-item').removeAttr('style'); 19281 if (triggerClick && 19282 Math.abs(endCoords.pageX - startCoords.pageX) < 5) { 19283 // Trigger click if distance is less than 5 pix 19284 var target = $LG(event.target); 19285 if (_this.isPosterElement(target)) { 19286 _this.LGel.trigger(lGEvents.posterClick); 19287 } 19288 } 19289 _this.swipeDirection = undefined; 19290 }); 19291 // remove slide class once drag/swipe is completed if mode is not slide 19292 setTimeout(function () { 19293 if (!_this.outer.hasClass('lg-dragging') && 19294 _this.settings.mode !== 'lg-slide') { 19295 _this.outer.removeClass('lg-slide'); 19296 } 19297 }, this.settings.speed + 100); 19298 }; 19299 LightGallery.prototype.enableSwipe = function () { 19300 var _this = this; 19301 var startCoords = {}; 19302 var endCoords = {}; 19303 var isMoved = false; 19304 var isSwiping = false; 19305 if (this.settings.enableSwipe) { 19306 this.$inner.on('touchstart.lg', function (e) { 19307 _this.dragOrSwipeEnabled = true; 19308 var $item = _this.getSlideItem(_this.index); 19309 if (($LG(e.target).hasClass('lg-item') || 19310 $item.get().contains(e.target)) && 19311 !_this.outer.hasClass('lg-zoomed') && 19312 !_this.lgBusy && 19313 e.targetTouches.length === 1) { 19314 isSwiping = true; 19315 _this.touchAction = 'swipe'; 19316 _this.manageSwipeClass(); 19317 startCoords = { 19318 pageX: e.targetTouches[0].pageX, 19319 pageY: e.targetTouches[0].pageY, 19320 }; 19321 } 19322 }); 19323 this.$inner.on('touchmove.lg', function (e) { 19324 if (isSwiping && 19325 _this.touchAction === 'swipe' && 19326 e.targetTouches.length === 1) { 19327 endCoords = { 19328 pageX: e.targetTouches[0].pageX, 19329 pageY: e.targetTouches[0].pageY, 19330 }; 19331 _this.touchMove(startCoords, endCoords, e); 19332 isMoved = true; 19333 } 19334 }); 19335 this.$inner.on('touchend.lg', function (event) { 19336 if (_this.touchAction === 'swipe') { 19337 if (isMoved) { 19338 isMoved = false; 19339 _this.touchEnd(endCoords, startCoords, event); 19340 } 19341 else if (isSwiping) { 19342 var target = $LG(event.target); 19343 if (_this.isPosterElement(target)) { 19344 _this.LGel.trigger(lGEvents.posterClick); 19345 } 19346 } 19347 _this.touchAction = undefined; 19348 isSwiping = false; 19349 } 19350 }); 19351 } 19352 }; 19353 LightGallery.prototype.enableDrag = function () { 19354 var _this = this; 19355 var startCoords = {}; 19356 var endCoords = {}; 19357 var isDraging = false; 19358 var isMoved = false; 19359 if (this.settings.enableDrag) { 19360 this.outer.on('mousedown.lg', function (e) { 19361 _this.dragOrSwipeEnabled = true; 19362 var $item = _this.getSlideItem(_this.index); 19363 if ($LG(e.target).hasClass('lg-item') || 19364 $item.get().contains(e.target)) { 19365 if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) { 19366 e.preventDefault(); 19367 if (!_this.lgBusy) { 19368 _this.manageSwipeClass(); 19369 startCoords = { 19370 pageX: e.pageX, 19371 pageY: e.pageY, 19372 }; 19373 isDraging = true; 19374 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 19375 _this.outer.get().scrollLeft += 1; 19376 _this.outer.get().scrollLeft -= 1; 19377 // * 19378 _this.outer 19379 .removeClass('lg-grab') 19380 .addClass('lg-grabbing'); 19381 _this.LGel.trigger(lGEvents.dragStart); 19382 } 19383 } 19384 } 19385 }); 19386 $LG(window).on("mousemove.lg.global" + this.lgId, function (e) { 19387 if (isDraging && _this.lgOpened) { 19388 isMoved = true; 19389 endCoords = { 19390 pageX: e.pageX, 19391 pageY: e.pageY, 19392 }; 19393 _this.touchMove(startCoords, endCoords); 19394 _this.LGel.trigger(lGEvents.dragMove); 19395 } 19396 }); 19397 $LG(window).on("mouseup.lg.global" + this.lgId, function (event) { 19398 if (!_this.lgOpened) { 19399 return; 19400 } 19401 var target = $LG(event.target); 19402 if (isMoved) { 19403 isMoved = false; 19404 _this.touchEnd(endCoords, startCoords, event); 19405 _this.LGel.trigger(lGEvents.dragEnd); 19406 } 19407 else if (_this.isPosterElement(target)) { 19408 _this.LGel.trigger(lGEvents.posterClick); 19409 } 19410 // Prevent execution on click 19411 if (isDraging) { 19412 isDraging = false; 19413 _this.outer.removeClass('lg-grabbing').addClass('lg-grab'); 19414 } 19415 }); 19416 } 19417 }; 19418 LightGallery.prototype.triggerPosterClick = function () { 19419 var _this = this; 19420 this.$inner.on('click.lg', function (event) { 19421 if (!_this.dragOrSwipeEnabled && 19422 _this.isPosterElement($LG(event.target))) { 19423 _this.LGel.trigger(lGEvents.posterClick); 19424 } 19425 }); 19426 }; 19427 LightGallery.prototype.manageSwipeClass = function () { 19428 var _touchNext = this.index + 1; 19429 var _touchPrev = this.index - 1; 19430 if (this.settings.loop && this.galleryItems.length > 2) { 19431 if (this.index === 0) { 19432 _touchPrev = this.galleryItems.length - 1; 19433 } 19434 else if (this.index === this.galleryItems.length - 1) { 19435 _touchNext = 0; 19436 } 19437 } 19438 this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide'); 19439 if (_touchPrev > -1) { 19440 this.getSlideItem(_touchPrev).addClass('lg-prev-slide'); 19441 } 19442 this.getSlideItem(_touchNext).addClass('lg-next-slide'); 19443 }; 19444 /** 19445 * Go to next slide 19446 * @param {Boolean} fromTouch - true if slide function called via touch event 19447 * @category lGPublicMethods 19448 * @example 19449 * const plugin = lightGallery(); 19450 * plugin.goToNextSlide(); 19451 * @see <a href="/demos/methods/">Demo</a> 19452 */ 19453 LightGallery.prototype.goToNextSlide = function (fromTouch) { 19454 var _this = this; 19455 var _loop = this.settings.loop; 19456 if (fromTouch && this.galleryItems.length < 3) { 19457 _loop = false; 19458 } 19459 if (!this.lgBusy) { 19460 if (this.index + 1 < this.galleryItems.length) { 19461 this.index++; 19462 this.LGel.trigger(lGEvents.beforeNextSlide, { 19463 index: this.index, 19464 }); 19465 this.slide(this.index, !!fromTouch, false, 'next'); 19466 } 19467 else { 19468 if (_loop) { 19469 this.index = 0; 19470 this.LGel.trigger(lGEvents.beforeNextSlide, { 19471 index: this.index, 19472 }); 19473 this.slide(this.index, !!fromTouch, false, 'next'); 19474 } 19475 else if (this.settings.slideEndAnimation && !fromTouch) { 19476 this.outer.addClass('lg-right-end'); 19477 setTimeout(function () { 19478 _this.outer.removeClass('lg-right-end'); 19479 }, 400); 19480 } 19481 } 19482 } 19483 }; 19484 /** 19485 * Go to previous slides 19486 * @param {Boolean} fromTouch - true if slide function called via touch event 19487 * @category lGPublicMethods 19488 * @example 19489 * const plugin = lightGallery({}); 19490 * plugin.goToPrevSlide(); 19491 * @see <a href="/demos/methods/">Demo</a> 19492 * 19493 */ 19494 LightGallery.prototype.goToPrevSlide = function (fromTouch) { 19495 var _this = this; 19496 var _loop = this.settings.loop; 19497 if (fromTouch && this.galleryItems.length < 3) { 19498 _loop = false; 19499 } 19500 if (!this.lgBusy) { 19501 if (this.index > 0) { 19502 this.index--; 19503 this.LGel.trigger(lGEvents.beforePrevSlide, { 19504 index: this.index, 19505 fromTouch: fromTouch, 19506 }); 19507 this.slide(this.index, !!fromTouch, false, 'prev'); 19508 } 19509 else { 19510 if (_loop) { 19511 this.index = this.galleryItems.length - 1; 19512 this.LGel.trigger(lGEvents.beforePrevSlide, { 19513 index: this.index, 19514 fromTouch: fromTouch, 19515 }); 19516 this.slide(this.index, !!fromTouch, false, 'prev'); 19517 } 19518 else if (this.settings.slideEndAnimation && !fromTouch) { 19519 this.outer.addClass('lg-left-end'); 19520 setTimeout(function () { 19521 _this.outer.removeClass('lg-left-end'); 19522 }, 400); 19523 } 19524 } 19525 } 19526 }; 19527 LightGallery.prototype.keyPress = function () { 19528 var _this = this; 19529 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 19530 if (_this.lgOpened && 19531 _this.settings.escKey === true && 19532 e.keyCode === 27) { 19533 e.preventDefault(); 19534 if (_this.settings.allowMediaOverlap && 19535 _this.outer.hasClass('lg-can-toggle') && 19536 _this.outer.hasClass('lg-components-open')) { 19537 _this.outer.removeClass('lg-components-open'); 19538 } 19539 else { 19540 _this.closeGallery(); 19541 } 19542 } 19543 if (_this.lgOpened && _this.galleryItems.length > 1) { 19544 if (e.keyCode === 37) { 19545 e.preventDefault(); 19546 _this.goToPrevSlide(); 19547 } 19548 if (e.keyCode === 39) { 19549 e.preventDefault(); 19550 _this.goToNextSlide(); 19551 } 19552 } 19553 }); 19554 }; 19555 LightGallery.prototype.arrow = function () { 19556 var _this = this; 19557 this.getElementById('lg-prev').on('click.lg', function () { 19558 _this.goToPrevSlide(); 19559 }); 19560 this.getElementById('lg-next').on('click.lg', function () { 19561 _this.goToNextSlide(); 19562 }); 19563 }; 19564 LightGallery.prototype.arrowDisable = function (index) { 19565 // Disable arrows if settings.hideControlOnEnd is true 19566 if (!this.settings.loop && this.settings.hideControlOnEnd) { 19567 var $prev = this.getElementById('lg-prev'); 19568 var $next = this.getElementById('lg-next'); 19569 if (index + 1 === this.galleryItems.length) { 19570 $next.attr('disabled', 'disabled').addClass('disabled'); 19571 } 19572 else { 19573 $next.removeAttr('disabled').removeClass('disabled'); 19574 } 19575 if (index === 0) { 19576 $prev.attr('disabled', 'disabled').addClass('disabled'); 19577 } 19578 else { 19579 $prev.removeAttr('disabled').removeClass('disabled'); 19580 } 19581 } 19582 }; 19583 LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) { 19584 if (scaleX === void 0) { scaleX = 1; } 19585 if (scaleY === void 0) { scaleY = 1; } 19586 $el.css('transform', 'translate3d(' + 19587 xValue + 19588 'px, ' + 19589 yValue + 19590 'px, 0px) scale3d(' + 19591 scaleX + 19592 ', ' + 19593 scaleY + 19594 ', 1)'); 19595 }; 19596 LightGallery.prototype.mousewheel = function () { 19597 var _this = this; 19598 var lastCall = 0; 19599 this.outer.on('wheel.lg', function (e) { 19600 if (!e.deltaY || _this.galleryItems.length < 2) { 19601 return; 19602 } 19603 e.preventDefault(); 19604 var now = new Date().getTime(); 19605 if (now - lastCall < 1000) { 19606 return; 19607 } 19608 lastCall = now; 19609 if (e.deltaY > 0) { 19610 _this.goToNextSlide(); 19611 } 19612 else if (e.deltaY < 0) { 19613 _this.goToPrevSlide(); 19614 } 19615 }); 19616 }; 19617 LightGallery.prototype.isSlideElement = function (target) { 19618 return (target.hasClass('lg-outer') || 19619 target.hasClass('lg-item') || 19620 target.hasClass('lg-img-wrap')); 19621 }; 19622 LightGallery.prototype.isPosterElement = function (target) { 19623 var playButton = this.getSlideItem(this.index) 19624 .find('.lg-video-play-button') 19625 .get(); 19626 return (target.hasClass('lg-video-poster') || 19627 target.hasClass('lg-video-play-button') || 19628 (playButton && playButton.contains(target.get()))); 19629 }; 19630 /** 19631 * Maximize minimize inline gallery. 19632 * @category lGPublicMethods 19633 */ 19634 LightGallery.prototype.toggleMaximize = function () { 19635 var _this = this; 19636 this.getElementById('lg-maximize').on('click.lg', function () { 19637 _this.$container.toggleClass('lg-inline'); 19638 _this.refreshOnResize(); 19639 }); 19640 }; 19641 LightGallery.prototype.invalidateItems = function () { 19642 for (var index = 0; index < this.items.length; index++) { 19643 var element = this.items[index]; 19644 var $element = $LG(element); 19645 $element.off("click.lgcustom-item-" + $element.attr('data-lg-id')); 19646 } 19647 }; 19648 LightGallery.prototype.trapFocus = function () { 19649 var _this = this; 19650 this.$container.get().focus({ 19651 preventScroll: true, 19652 }); 19653 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 19654 if (!_this.lgOpened) { 19655 return; 19656 } 19657 var isTabPressed = e.key === 'Tab' || e.keyCode === 9; 19658 if (!isTabPressed) { 19659 return; 19660 } 19661 var focusableEls = utils.getFocusableElements(_this.$container.get()); 19662 var firstFocusableEl = focusableEls[0]; 19663 var lastFocusableEl = focusableEls[focusableEls.length - 1]; 19664 if (e.shiftKey) { 19665 if (document.activeElement === firstFocusableEl) { 19666 lastFocusableEl.focus(); 19667 e.preventDefault(); 19668 } 19669 } 19670 else { 19671 if (document.activeElement === lastFocusableEl) { 19672 firstFocusableEl.focus(); 19673 e.preventDefault(); 19674 } 19675 } 19676 }); 19677 }; 19678 LightGallery.prototype.manageCloseGallery = function () { 19679 var _this = this; 19680 if (!this.settings.closable) 19681 return; 19682 var mousedown = false; 19683 this.getElementById('lg-close').on('click.lg', function () { 19684 _this.closeGallery(); 19685 }); 19686 if (this.settings.closeOnTap) { 19687 // If you drag the slide and release outside gallery gets close on chrome 19688 // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer 19689 this.outer.on('mousedown.lg', function (e) { 19690 var target = $LG(e.target); 19691 if (_this.isSlideElement(target)) { 19692 mousedown = true; 19693 } 19694 else { 19695 mousedown = false; 19696 } 19697 }); 19698 this.outer.on('mousemove.lg', function () { 19699 mousedown = false; 19700 }); 19701 this.outer.on('mouseup.lg', function (e) { 19702 var target = $LG(e.target); 19703 if (_this.isSlideElement(target) && mousedown) { 19704 if (!_this.outer.hasClass('lg-dragging')) { 19705 _this.closeGallery(); 19706 } 19707 } 19708 }); 19709 } 19710 }; 19711 /** 19712 * Close lightGallery if it is opened. 19713 * 19714 * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery 19715 * @return returns the estimated time to close gallery completely including the close animation duration 19716 * @category lGPublicMethods 19717 * @example 19718 * const plugin = lightGallery(); 19719 * plugin.closeGallery(); 19720 * 19721 */ 19722 LightGallery.prototype.closeGallery = function (force) { 19723 var _this = this; 19724 if (!this.lgOpened || (!this.settings.closable && !force)) { 19725 return 0; 19726 } 19727 this.LGel.trigger(lGEvents.beforeClose); 19728 if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) { 19729 $LG(window).scrollTop(this.prevScrollTop); 19730 } 19731 var currentItem = this.items[this.index]; 19732 var transform; 19733 if (this.zoomFromOrigin && currentItem) { 19734 var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom; 19735 var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster; 19736 //Uncode edit ##START## 19737 var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize, this.galleryItems[this.index]); 19738 // var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize); 19739 //Uncode edit ##END## 19740 transform = utils.getTransform(currentItem, this.outer, top_4, bottom, imageSize); 19741 } 19742 if (this.zoomFromOrigin && transform) { 19743 this.outer.addClass('lg-closing lg-zoom-from-image'); 19744 this.getSlideItem(this.index) 19745 .addClass('lg-start-end-progress') 19746 .css('transition-duration', this.settings.startAnimationDuration + 'ms') 19747 .css('transform', transform); 19748 } 19749 else { 19750 this.outer.addClass('lg-hide-items'); 19751 // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true 19752 // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts 19753 this.outer.removeClass('lg-zoom-from-image'); 19754 } 19755 // Unbind all events added by lightGallery 19756 // @todo 19757 //this.$el.off('.lg.tm'); 19758 this.destroyModules(); 19759 this.lGalleryOn = false; 19760 this.isDummyImageRemoved = false; 19761 this.zoomFromOrigin = this.settings.zoomFromOrigin; 19762 clearTimeout(this.hideBarTimeout); 19763 this.hideBarTimeout = false; 19764 $LG('html').removeClass('lg-on'); 19765 this.outer.removeClass('lg-visible lg-components-open'); 19766 // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity. 19767 this.$backdrop.removeClass('in').css('opacity', 0); 19768 var removeTimeout = this.zoomFromOrigin && transform 19769 ? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration) 19770 : this.settings.backdropDuration; 19771 this.$container.removeClass('lg-show-in'); 19772 // Once the closign animation is completed and gallery is invisible 19773 setTimeout(function () { 19774 if (_this.zoomFromOrigin && transform) { 19775 _this.outer.removeClass('lg-zoom-from-image'); 19776 } 19777 _this.$container.removeClass('lg-show'); 19778 // Reset scrollbar 19779 _this.resetScrollBar(); 19780 // Need to remove inline opacity as it is used in the stylesheet as well 19781 _this.$backdrop 19782 .removeAttr('style') 19783 .css('transition-duration', _this.settings.backdropDuration + 'ms'); 19784 _this.outer.removeClass("lg-closing " + _this.settings.startClass);
vendor: 6,259 bytes, lines 19785-19988
19785 _this.getSlideItem(_this.index).removeClass('lg-start-end-progress'); 19786 _this.$inner.empty(); 19787 if (_this.lgOpened) { 19788 _this.LGel.trigger(lGEvents.afterClose, { 19789 instance: _this, 19790 }); 19791 } 19792 if (_this.$container.get()) { 19793 _this.$container.get().blur(); 19794 } 19795 _this.lgOpened = false; 19796 }, removeTimeout + 100); 19797 return removeTimeout + 100; 19798 }; 19799 LightGallery.prototype.initModules = function () { 19800 this.plugins.forEach(function (module) { 19801 try { 19802 module.init(); 19803 } 19804 catch (err) { 19805 console.warn("lightGallery:- make sure lightGallery module is properly initiated"); 19806 } 19807 }); 19808 }; 19809 LightGallery.prototype.destroyModules = function (destroy) { 19810 this.plugins.forEach(function (module) { 19811 try { 19812 if (destroy) { 19813 module.destroy(); 19814 } 19815 else { 19816 module.closeGallery && module.closeGallery(); 19817 } 19818 } 19819 catch (err) { 19820 console.warn("lightGallery:- make sure lightGallery module is properly destroyed"); 19821 } 19822 }); 19823 }; 19824 /** 19825 * Refresh lightGallery with new set of children. 19826 * 19827 * @description This is useful to update the gallery when the child elements are changed without calling destroy method. 19828 * 19829 * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery 19830 * @see <a href="/demos/dynamic-mode/">Demo</a> 19831 * @category lGPublicMethods 19832 * @example 19833 * const plugin = lightGallery(); 19834 * // Delete or add children, then call 19835 * plugin.refresh(); 19836 * 19837 */ 19838 LightGallery.prototype.refresh = function (galleryItems) { 19839 if (!this.settings.dynamic) { 19840 this.invalidateItems(); 19841 } 19842 if (galleryItems) { 19843 this.galleryItems = galleryItems; 19844 } 19845 else { 19846 this.galleryItems = this.getItems(); 19847 } 19848 this.updateControls(); 19849 this.openGalleryOnItemClick(); 19850 this.LGel.trigger(lGEvents.updateSlides); 19851 }; 19852 LightGallery.prototype.updateControls = function () { 19853 this.addSlideVideoInfo(this.galleryItems); 19854 this.updateCounterTotal(); 19855 this.manageSingleSlideClassName(); 19856 }; 19857 /** 19858 * Destroy lightGallery. 19859 * Destroy lightGallery and its plugin instances completely 19860 * 19861 * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance. 19862 * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed. 19863 * You can use refresh method most of the times. 19864 * @category lGPublicMethods 19865 * @example 19866 * const plugin = lightGallery(); 19867 * plugin.destroy(); 19868 * 19869 */ 19870 LightGallery.prototype.destroy = function () { 19871 var _this = this; 19872 var closeTimeout = this.closeGallery(true); 19873 setTimeout(function () { 19874 _this.destroyModules(true); 19875 if (!_this.settings.dynamic) { 19876 _this.invalidateItems(); 19877 } 19878 $LG(window).off(".lg.global" + _this.lgId); 19879 _this.LGel.off('.lg'); 19880 _this.$container.remove(); 19881 }, closeTimeout); 19882 return closeTimeout; 19883 }; 19884 return LightGallery; 19885 }()); 19886 19887 function lightGallery(el, options) { 19888 return new LightGallery(el, options); 19889 } 19890 19891 return lightGallery; 19892 19893}))); 19894 19895/*! 19896 * lightgallery | 2.5.0 | June 13th 2022 19897 * http://www.lightgalleryjs.com/ 19898 * Copyright (c) 2020 Sachin Neravath; 19899 * @license GPLv3 19900 */ 19901 19902(function (global, factory) { 19903 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 19904 typeof define === 'function' && define.amd ? define(factory) : 19905 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgZoom = factory()); 19906}(this, (function () { 'use strict'; 19907 19908 /*! ***************************************************************************** 19909 Copyright (c) Microsoft Corporation. 19910 19911 Permission to use, copy, modify, and/or distribute this software for any 19912 purpose with or without fee is hereby granted. 19913 19914 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 19915 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19916 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 19917 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 19918 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 19919 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19920 PERFORMANCE OF THIS SOFTWARE. 19921 ***************************************************************************** */ 19922 19923 var __assign = function() { 19924 __assign = Object.assign || function __assign(t) { 19925 for (var s, i = 1, n = arguments.length; i < n; i++) { 19926 s = arguments[i]; 19927 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 19928 } 19929 return t; 19930 }; 19931 return __assign.apply(this, arguments); 19932 }; 19933 19934 var zoomSettings = { 19935 scale: 1, 19936 zoom: true, 19937 actualSize: true, 19938 showZoomInOutIcons: false, 19939 actualSizeIcons: { 19940 zoomIn: 'lg-zoom-in', 19941 zoomOut: 'lg-zoom-out', 19942 }, 19943 enableZoomAfter: 300, 19944 zoomPluginStrings: { 19945 zoomIn: 'Zoom in', 19946 zoomOut: 'Zoom out', 19947 viewActualSize: 'View actual size', 19948 }, 19949 }; 19950 19951 /** 19952 * List of lightGallery events 19953 * All events should be documented here 19954 * Below interfaces are used to build the website documentations 19955 * */ 19956 var lGEvents = { 19957 afterAppendSlide: 'lgAfterAppendSlide', 19958 init: 'lgInit', 19959 hasVideo: 'lgHasVideo', 19960 containerResize: 'lgContainerResize', 19961 updateSlides: 'lgUpdateSlides', 19962 afterAppendSubHtml: 'lgAfterAppendSubHtml', 19963 beforeOpen: 'lgBeforeOpen', 19964 afterOpen: 'lgAfterOpen', 19965 slideItemLoad: 'lgSlideItemLoad', 19966 beforeSlide: 'lgBeforeSlide', 19967 afterSlide: 'lgAfterSlide', 19968 posterClick: 'lgPosterClick', 19969 dragStart: 'lgDragStart', 19970 dragMove: 'lgDragMove', 19971 dragEnd: 'lgDragEnd', 19972 beforeNextSlide: 'lgBeforeNextSlide', 19973 beforePrevSlide: 'lgBeforePrevSlide', 19974 beforeClose: 'lgBeforeClose', 19975 afterClose: 'lgAfterClose', 19976 rotateLeft: 'lgRotateLeft', 19977 rotateRight: 'lgRotateRight', 19978 flipHorizontal: 'lgFlipHorizontal', 19979 flipVertical: 'lgFlipVertical', 19980 autoplay: 'lgAutoplay', 19981 autoplayStart: 'lgAutoplayStart', 19982 autoplayStop: 'lgAutoplayStop', 19983 }; 19984 19985 var Zoom = /** @class */ (function () { 19986 function Zoom(instance, $LG) { 19987 // get lightGallery core plugin instance 19988 this.core = instance;
19989 this.$LG = $LG; 19990 this.settings = __assign(__assign({}, zoomSettings), this.core.settings); 19991 return this; 19992 } 19993 // Append Zoom controls. Actual size, Zoom-in, Zoom-out 19994 Zoom.prototype.buildTemplates = function () { 19995 var zoomIcons = this.settings.showZoomInOutIcons 19996 ? "<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>" 19997 : ''; 19998 if (this.settings.actualSize) { 19999 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>"; 20000 } 20001 this.core.outer.addClass('lg-use-transition-for-zoom'); 20002 this.core.$toolbar.first().append(zoomIcons); 20003 }; 20004 /** 20005 * @desc Enable zoom option only once the image is completely loaded 20006 * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted 20007 * 20008 * Zoom styles are defined under lg-zoomable CSS class. 20009 */ 20010 Zoom.prototype.enableZoom = function (event) { 20011 var _this = this; 20012 // delay will be 0 except first time 20013 var _speed = this.settings.enableZoomAfter + event.detail.delay; 20014 // set _speed value 0 if gallery opened from direct url and if it is first slide 20015 if (this.$LG('body').first().hasClass('lg-from-hash') && 20016 event.detail.delay) { 20017 // will execute only once 20018 _speed = 0; 20019 } 20020 else { 20021 // Remove lg-from-hash to enable starting animation. 20022 this.$LG('body').first().removeClass('lg-from-hash'); 20023 } 20024 this.zoomableTimeout = setTimeout(function () { 20025 if (!_this.isImageSlide()) { 20026 return; 20027 } 20028 _this.core.getSlideItem(event.detail.index).addClass('lg-zoomable'); 20029 if (event.detail.index === _this.core.index) { 20030 _this.setZoomEssentials(); 20031 } 20032 }, _speed + 30); 20033 }; 20034 Zoom.prototype.enableZoomOnSlideItemLoad = function () { 20035 // Add zoomable class 20036 this.core.LGel.on(lGEvents.slideItemLoad + ".zoom", this.enableZoom.bind(this)); 20037 }; 20038 Zoom.prototype.getModifier = function (rotateValue, axis, el) { 20039 var originalRotate = rotateValue; 20040 rotateValue = Math.abs(rotateValue); 20041 var transformValues = this.getCurrentTransform(el); 20042 if (!transformValues) { 20043 return 1; 20044 } 20045 var modifier = 1; 20046 if (axis === 'X') { 20047 var flipHorizontalValue = Math.sign(parseFloat(transformValues[0])); 20048 if (rotateValue === 0 || rotateValue === 180) { 20049 modifier = 1; 20050 } 20051 else if (rotateValue === 90) { 20052 if ((originalRotate === -90 && flipHorizontalValue === 1) || 20053 (originalRotate === 90 && flipHorizontalValue === -1)) { 20054 modifier = -1; 20055 } 20056 else { 20057 modifier = 1; 20058 } 20059 } 20060 modifier = modifier * flipHorizontalValue; 20061 } 20062 else { 20063 var flipVerticalValue = Math.sign(parseFloat(transformValues[3])); 20064 if (rotateValue === 0 || rotateValue === 180) { 20065 modifier = 1; 20066 } 20067 else if (rotateValue === 90) { 20068 var sinX = parseFloat(transformValues[1]); 20069 var sinMinusX = parseFloat(transformValues[2]); 20070 modifier = Math.sign(sinX * sinMinusX * originalRotate * flipVerticalValue); 20071 } 20072 modifier = modifier * flipVerticalValue; 20073 } 20074 return modifier; 20075 }; 20076 Zoom.prototype.getImageSize = function ($image, rotateValue, axis) { 20077 var imageSizes = { 20078 y: 'offsetHeight', 20079 x: 'offsetWidth', 20080 }; 20081 if (Math.abs(rotateValue) === 90) { 20082 // Swap axis 20083 if (axis === 'x') { 20084 axis = 'y'; 20085 } 20086 else { 20087 axis = 'x'; 20088 } 20089 } 20090 return $image[imageSizes[axis]]; 20091 }; 20092 Zoom.prototype.getDragCords = function (e, rotateValue) { 20093 if (rotateValue === 90) { 20094 return { 20095 x: e.pageY, 20096 y: e.pageX, 20097 }; 20098 } 20099 else { 20100 return { 20101 x: e.pageX, 20102 y: e.pageY, 20103 }; 20104 } 20105 }; 20106 Zoom.prototype.getSwipeCords = function (e, rotateValue) { 20107 var x = e.targetTouches[0].pageX; 20108 var y = e.targetTouches[0].pageY; 20109 if (rotateValue === 90) { 20110 return { 20111 x: y, 20112 y: x, 20113 }; 20114 } 20115 else { 20116 return { 20117 x: x, 20118 y: y, 20119 }; 20120 } 20121 }; 20122 Zoom.prototype.getDragAllowedAxises = function (rotateValue, scale) { 20123 scale = scale || this.scale || 1; 20124 var allowY = this.imageYSize * scale > this.containerRect.height; 20125 var allowX = this.imageXSize * scale > this.containerRect.width; 20126 if (rotateValue === 90) { 20127 return { 20128 allowX: allowY, 20129 allowY: allowX, 20130 }; 20131 } 20132 else { 20133 return { 20134 allowX: allowX, 20135 allowY: allowY, 20136 }; 20137 } 20138 }; 20139 /** 20140 * 20141 * @param {Element} el 20142 * @return matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0); 20143 * Get the current transform value 20144 */ 20145 Zoom.prototype.getCurrentTransform = function (el) { 20146 if (!el) { 20147 return; 20148 } 20149 var st = window.getComputedStyle(el, null); 20150 var tm = st.getPropertyValue('-webkit-transform') || 20151 st.getPropertyValue('-moz-transform') || 20152 st.getPropertyValue('-ms-transform') || 20153 st.getPropertyValue('-o-transform') || 20154 st.getPropertyValue('transform') || 20155 'none'; 20156 if (tm !== 'none') { 20157 return tm.split('(')[1].split(')')[0].split(','); 20158 } 20159 return; 20160 }; 20161 Zoom.prototype.getCurrentRotation = function (el) { 20162 if (!el) { 20163 return 0; 20164 } 20165 var values = this.getCurrentTransform(el); 20166 if (values) { 20167 return Math.round(Math.atan2(parseFloat(values[1]), parseFloat(values[0])) * 20168 (180 / Math.PI)); 20169 // If you want rotate in 360 20170 //return (angle < 0 ? angle + 360 : angle); 20171 } 20172 return 0; 20173 }; 20174 Zoom.prototype.setZoomEssentials = function () { 20175 var $image = this.core 20176 .getSlideItem(this.core.index) 20177 .find('.lg-image') 20178 .first(); 20179 var rotateEl = this.core 20180 .getSlideItem(this.core.index) 20181 .find('.lg-img-rotate') 20182 .first() 20183 .get(); 20184 this.rotateValue = this.getCurrentRotation(rotateEl); 20185 this.imageYSize = this.getImageSize($image.get(), this.rotateValue, 'y'); 20186 this.imageXSize = this.getImageSize($image.get(), this.rotateValue, 'x'); 20187 this.containerRect = this.core.outer.get().getBoundingClientRect(); 20188 this.modifierX = this.getModifier(this.rotateValue, 'X', rotateEl); 20189 this.modifierY = this.getModifier(this.rotateValue, 'Y', rotateEl); 20190 }; 20191 /** 20192 * @desc Image zoom 20193 * Translate the wrap and scale the image to get better user experience 20194 * 20195 * @param {String} scale - Zoom decrement/increment value 20196 */ 20197 Zoom.prototype.zoomImage = function (scale) { 20198 // Find offset manually to avoid issue after zoom 20199 var offsetX = (this.containerRect.width - this.imageXSize) / 2 + 20200 this.containerRect.left; 20201 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 20202 var topBottomSpacing = Math.abs(top - bottom) / 2; 20203 var offsetY = (this.containerRect.height - 20204 this.imageYSize - 20205 topBottomSpacing * this.modifierX) / 20206 2 + 20207 this.scrollTop + 20208 this.containerRect.top; 20209 var originalX; 20210 var originalY; 20211 if (scale === 1) { 20212 this.positionChanged = false;
20213 } 20214 var dragAllowedAxises = this.getDragAllowedAxises(Math.abs(this.rotateValue), scale); 20215 var allowY = dragAllowedAxises.allowY, allowX = dragAllowedAxises.allowX; 20216 if (this.positionChanged) { 20217 originalX = this.left / (this.scale - 1); 20218 originalY = this.top / (this.scale - 1); 20219 this.pageX = Math.abs(originalX) + offsetX; 20220 this.pageY = Math.abs(originalY) + offsetY; 20221 this.positionChanged = false; 20222 } 20223 var possibleSwipeCords = this.getPossibleSwipeDragCords(this.rotateValue, scale); 20224 var _x = offsetX - this.pageX; 20225 var _y = offsetY - this.pageY; 20226 var x = (scale - 1) * _x; 20227 var y = (scale - 1) * _y; 20228 if (allowX) { 20229 if (this.isBeyondPossibleLeft(x, possibleSwipeCords.minX)) { 20230 x = possibleSwipeCords.minX; 20231 } 20232 else if (this.isBeyondPossibleRight(x, possibleSwipeCords.maxX)) { 20233 x = possibleSwipeCords.maxX; 20234 } 20235 } 20236 else { 20237 if (scale > 1) { 20238 if (x < possibleSwipeCords.minX) { 20239 x = possibleSwipeCords.minX; 20240 } 20241 else if (x > possibleSwipeCords.maxX) { 20242 x = possibleSwipeCords.maxX; 20243 } 20244 } 20245 }
20246 if (allowY) { 20247 if (this.isBeyondPossibleTop(y, possibleSwipeCords.minY)) { 20248 y = possibleSwipeCords.minY; 20249 } 20250 else if (this.isBeyondPossibleBottom(y, possibleSwipeCords.maxY)) { 20251 y = possibleSwipeCords.maxY; 20252 } 20253 } 20254 else { 20255 // If the translate value based on index of beyond the viewport, utilize the available space to prevent image being cut out 20256 if (scale > 1) { 20257 //If image goes beyond viewport top, use the minim possible translate value 20258 if (y < possibleSwipeCords.minY) { 20259 y = possibleSwipeCords.minY; 20260 } 20261 else if (y > possibleSwipeCords.maxY) { 20262 y = possibleSwipeCords.maxY; 20263 } 20264 } 20265 } 20266 this.setZoomStyles({ 20267 x: x, 20268 y: y, 20269 scale: scale, 20270 }); 20271 }; 20272 /** 20273 * @desc apply scale3d to image and translate to image wrap 20274 * @param {style} X,Y and scale 20275 */ 20276 Zoom.prototype.setZoomStyles = function (style) { 20277 var $image = this.core 20278 .getSlideItem(this.core.index) 20279 .find('.lg-image') 20280 .first(); 20281 var $dummyImage = this.core.outer 20282 .find('.lg-current .lg-dummy-img') 20283 .first(); 20284 var $imageWrap = $image.parent(); 20285 this.scale = style.scale; 20286 $image.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 20287 $dummyImage.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 20288 var transform = 'translate3d(' + style.x + 'px, ' + style.y + 'px, 0)'; 20289 $imageWrap.css('transform', transform); 20290 this.left = style.x; 20291 this.top = style.y; 20292 }; 20293 /** 20294 * @param index - Index of the current slide 20295 * @param event - event will be available only if the function is called on clicking/taping the imags 20296 */ 20297 Zoom.prototype.setActualSize = function (index, event) { 20298 var _this = this; 20299 // Allow zoom only on image 20300 if (!this.isImageSlide() || 20301 this.core.outer.hasClass('lg-first-slide-loading')) { 20302 return; 20303 } 20304 var scale = this.getCurrentImageActualSizeScale(); 20305 if (this.core.outer.hasClass('lg-zoomed')) { 20306 this.scale = 1; 20307 } 20308 else { 20309 this.scale = this.getScale(scale); 20310 } 20311 this.setPageCords(event); 20312 this.beginZoom(this.scale); 20313 this.zoomImage(this.scale); 20314 setTimeout(function () { 20315 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 20316 }, 10); 20317 }; 20318 Zoom.prototype.getNaturalWidth = function (index) { 20319 var $image = this.core.getSlideItem(index).find('.lg-image').first(); 20320 var naturalWidth = this.core.galleryItems[index].width; 20321 return naturalWidth 20322 ? parseFloat(naturalWidth) 20323 : $image.get().naturalWidth; 20324 }; 20325 Zoom.prototype.getActualSizeScale = function (naturalWidth, width) { 20326 var _scale; 20327 var scale;
20328 if (naturalWidth > width) { 20329 _scale = naturalWidth / width; 20330 scale = _scale || 2; 20331 } 20332 else { 20333 scale = 1; 20334 } 20335 return scale; 20336 }; 20337 Zoom.prototype.getCurrentImageActualSizeScale = function () { 20338 var $image = this.core 20339 .getSlideItem(this.core.index) 20340 .find('.lg-image') 20341 .first(); 20342 var width = $image.get().offsetWidth; 20343 var naturalWidth = this.getNaturalWidth(this.core.index) || width; 20344 return this.getActualSizeScale(naturalWidth, width); 20345 }; 20346 Zoom.prototype.getPageCords = function (event) { 20347 var cords = {}; 20348 if (event) { 20349 cords.x = event.pageX || event.targetTouches[0].pageX; 20350 cords.y = event.pageY || event.targetTouches[0].pageY; 20351 } 20352 else { 20353 var containerRect = this.core.outer.get().getBoundingClientRect(); 20354 cords.x = containerRect.width / 2 + containerRect.left; 20355 cords.y = 20356 containerRect.height / 2 + this.scrollTop + containerRect.top; 20357 } 20358 return cords; 20359 }; 20360 Zoom.prototype.setPageCords = function (event) { 20361 var pageCords = this.getPageCords(event); 20362 this.pageX = pageCords.x; 20363 this.pageY = pageCords.y; 20364 }; 20365 // If true, zoomed - in else zoomed out 20366 Zoom.prototype.beginZoom = function (scale) { 20367 this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 20368 if (scale > 1) { 20369 this.core.outer.addClass('lg-zoomed'); 20370 var $actualSize = this.core.getElementById('lg-actual-size'); 20371 $actualSize 20372 .removeClass(this.settings.actualSizeIcons.zoomIn) 20373 .addClass(this.settings.actualSizeIcons.zoomOut); 20374 } 20375 else { 20376 this.resetZoom(); 20377 } 20378 return scale > 1; 20379 }; 20380 Zoom.prototype.getScale = function (scale) { 20381 var actualSizeScale = this.getCurrentImageActualSizeScale(); 20382 if (scale < 1) { 20383 scale = 1; 20384 } 20385 else if (scale > actualSizeScale) { 20386 scale = actualSizeScale; 20387 } 20388 return scale; 20389 }; 20390 Zoom.prototype.init = function () { 20391 var _this = this; 20392 if (!this.settings.zoom) { 20393 return; 20394 } 20395 this.buildTemplates(); 20396 this.enableZoomOnSlideItemLoad(); 20397 var tapped = null; 20398 this.core.outer.on('dblclick.lg', function (event) { 20399 if (!_this.$LG(event.target).hasClass('lg-image')) { 20400 return; 20401 } 20402 _this.setActualSize(_this.core.index, event); 20403 }); 20404 this.core.outer.on('touchstart.lg', function (event) { 20405 var $target = _this.$LG(event.target); 20406 if (event.targetTouches.length === 1 && 20407 $target.hasClass('lg-image')) { 20408 if (!tapped) { 20409 tapped = setTimeout(function () { 20410 tapped = null; 20411 }, 300); 20412 } 20413 else { 20414 clearTimeout(tapped); 20415 tapped = null; 20416 event.preventDefault(); 20417 _this.setActualSize(_this.core.index, event); 20418 } 20419 } 20420 }); 20421 // Update zoom on resize and orientationchange 20422 this.core.LGel.on(lGEvents.containerResize + ".zoom " + lGEvents.rotateRight + ".zoom " + lGEvents.rotateLeft + ".zoom " + lGEvents.flipHorizontal + ".zoom " + lGEvents.flipVertical + ".zoom", function () { 20423 if (!_this.core.lgOpened || !_this.isImageSlide()) 20424 return; 20425 _this.setPageCords(); 20426 _this.setZoomEssentials(); 20427 _this.zoomImage(_this.scale); 20428 }); 20429 // Update zoom on resize and orientationchange 20430 this.$LG(window).on("scroll.lg.zoom.global" + this.core.lgId, function () { 20431 if (!_this.core.lgOpened) 20432 return; 20433 _this.scrollTop = _this.$LG(window).scrollTop(); 20434 }); 20435 this.core.getElementById('lg-zoom-out').on('click.lg', function () { 20436 if (_this.core.outer.find('.lg-current .lg-image').get()) { 20437 _this.scale -= _this.settings.scale; 20438 _this.scale = _this.getScale(_this.scale); 20439 _this.beginZoom(_this.scale); 20440 _this.zoomImage(_this.scale); 20441 } 20442 }); 20443 this.core.getElementById('lg-zoom-in').on('click.lg', function () { 20444 _this.zoomIn(); 20445 }); 20446 this.core.getElementById('lg-actual-size').on('click.lg', function () { 20447 _this.setActualSize(_this.core.index); 20448 }); 20449 this.core.LGel.on(lGEvents.beforeOpen + ".zoom", function () { 20450 _this.core.outer.find('.lg-item').removeClass('lg-zoomable'); 20451 }); 20452 this.core.LGel.on(lGEvents.afterOpen + ".zoom", function () { 20453 _this.scrollTop = _this.$LG(window).scrollTop(); 20454 // Set the initial value center 20455 _this.pageX = _this.core.outer.width() / 2;
20456 _this.pageY = _this.core.outer.height() / 2 + _this.scrollTop; 20457 _this.scale = 1; 20458 }); 20459 // Reset zoom on slide change 20460 this.core.LGel.on(lGEvents.afterSlide + ".zoom", function (event) { 20461 var prevIndex = event.detail.prevIndex; 20462 _this.scale = 1; 20463 _this.positionChanged = false; 20464 _this.resetZoom(prevIndex); 20465 if (_this.isImageSlide()) { 20466 _this.setZoomEssentials(); 20467 } 20468 }); 20469 // Drag option after zoom 20470 this.zoomDrag(); 20471 this.pinchZoom(); 20472 this.zoomSwipe(); 20473 // Store the zoomable timeout value just to clear it while closing 20474 this.zoomableTimeout = false; 20475 this.positionChanged = false; 20476 }; 20477 Zoom.prototype.zoomIn = function (scale) { 20478 // Allow zoom only on image 20479 if (!this.isImageSlide()) { 20480 return; 20481 } 20482 if (scale) { 20483 this.scale = scale; 20484 } 20485 else { 20486 this.scale += this.settings.scale; 20487 } 20488 this.scale = this.getScale(this.scale); 20489 this.beginZoom(this.scale); 20490 this.zoomImage(this.scale); 20491 }; 20492 // Reset zoom effect 20493 Zoom.prototype.resetZoom = function (index) { 20494 this.core.outer.removeClass('lg-zoomed lg-zoom-drag-transition'); 20495 var $actualSize = this.core.getElementById('lg-actual-size'); 20496 var $item = this.core.getSlideItem(index !== undefined ? index : this.core.index); 20497 $actualSize 20498 .removeClass(this.settings.actualSizeIcons.zoomOut) 20499 .addClass(this.settings.actualSizeIcons.zoomIn); 20500 $item.find('.lg-img-wrap').first().removeAttr('style'); 20501 $item.find('.lg-image').first().removeAttr('style'); 20502 this.scale = 1; 20503 this.left = 0; 20504 this.top = 0; 20505 // Reset pagx pagy values to center 20506 this.setPageCords(); 20507 }; 20508 Zoom.prototype.getTouchDistance = function (e) { 20509 return Math.sqrt((e.targetTouches[0].pageX - e.targetTouches[1].pageX) * 20510 (e.targetTouches[0].pageX - e.targetTouches[1].pageX) + 20511 (e.targetTouches[0].pageY - e.targetTouches[1].pageY) * 20512 (e.targetTouches[0].pageY - e.targetTouches[1].pageY)); 20513 }; 20514 Zoom.prototype.pinchZoom = function () { 20515 var _this = this; 20516 var startDist = 0; 20517 var pinchStarted = false; 20518 var initScale = 1; 20519 var $item = this.core.getSlideItem(this.core.index); 20520 this.core.$inner.on('touchstart.lg', function (e) { 20521 $item = _this.core.getSlideItem(_this.core.index); 20522 if (!_this.isImageSlide()) { 20523 return; 20524 } 20525 if (e.targetTouches.length === 2 && 20526 !_this.core.outer.hasClass('lg-first-slide-loading') && 20527 (_this.$LG(e.target).hasClass('lg-item') || 20528 $item.get().contains(e.target))) { 20529 initScale = _this.scale || 1; 20530 _this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 20531 _this.core.touchAction = 'pinch'; 20532 startDist = _this.getTouchDistance(e); 20533 } 20534 }); 20535 this.core.$inner.on('touchmove.lg', function (e) { 20536 if (e.targetTouches.length === 2 && 20537 _this.core.touchAction === 'pinch' && 20538 (_this.$LG(e.target).hasClass('lg-item') || 20539 $item.get().contains(e.target))) { 20540 e.preventDefault(); 20541 var endDist = _this.getTouchDistance(e); 20542 var distance = startDist - endDist; 20543 if (!pinchStarted && Math.abs(distance) > 5) { 20544 pinchStarted = true; 20545 } 20546 if (pinchStarted) { 20547 _this.scale = Math.max(1, initScale + -distance * 0.008); 20548 _this.zoomImage(_this.scale); 20549 } 20550 } 20551 }); 20552 this.core.$inner.on('touchend.lg', function (e) { 20553 if (_this.core.touchAction === 'pinch' && 20554 (_this.$LG(e.target).hasClass('lg-item') || 20555 $item.get().contains(e.target))) { 20556 pinchStarted = false; 20557 startDist = 0; 20558 if (_this.scale <= 1) { 20559 _this.resetZoom(); 20560 } 20561 else { 20562 _this.scale = _this.getScale(_this.scale); 20563 _this.zoomImage(_this.scale); 20564 _this.core.outer.addClass('lg-zoomed'); 20565 } 20566 _this.core.touchAction = undefined; 20567 } 20568 }); 20569 }; 20570 Zoom.prototype.touchendZoom = function (startCoords, endCoords, allowX, allowY, touchDuration, rotateValue) { 20571 var distanceXnew = endCoords.x - startCoords.x; 20572 var distanceYnew = endCoords.y - startCoords.y; 20573 var speedX = Math.abs(distanceXnew) / touchDuration + 1; 20574 var speedY = Math.abs(distanceYnew) / touchDuration + 1; 20575 if (speedX > 2) { 20576 speedX += 1; 20577 } 20578 if (speedY > 2) { 20579 speedY += 1; 20580 } 20581 distanceXnew = distanceXnew * speedX; 20582 distanceYnew = distanceYnew * speedY; 20583 var _LGel = this.core 20584 .getSlideItem(this.core.index) 20585 .find('.lg-img-wrap') 20586 .first(); 20587 var distance = {}; 20588 distance.x = this.left + distanceXnew * this.modifierX; 20589 distance.y = this.top + distanceYnew * this.modifierY; 20590 var possibleSwipeCords = this.getPossibleSwipeDragCords(rotateValue); 20591 if (Math.abs(distanceXnew) > 15 || Math.abs(distanceYnew) > 15) { 20592 if (allowY) { 20593 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 20594 distance.y = possibleSwipeCords.minY; 20595 } 20596 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 20597 distance.y = possibleSwipeCords.maxY; 20598 } 20599 } 20600 if (allowX) { 20601 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 20602 distance.x = possibleSwipeCords.minX; 20603 } 20604 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 20605 distance.x = possibleSwipeCords.maxX; 20606 } 20607 } 20608 if (allowY) { 20609 this.top = distance.y; 20610 } 20611 else { 20612 distance.y = this.top; 20613 } 20614 if (allowX) { 20615 this.left = distance.x; 20616 } 20617 else { 20618 distance.x = this.left; 20619 } 20620 this.setZoomSwipeStyles(_LGel, distance); 20621 this.positionChanged = true; 20622 } 20623 }; 20624 Zoom.prototype.getZoomSwipeCords = function (startCoords, endCoords, allowX, allowY, possibleSwipeCords) { 20625 var distance = {}; 20626 if (allowY) { 20627 distance.y = 20628 this.top + (endCoords.y - startCoords.y) * this.modifierY; 20629 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 20630 var diffMinY = possibleSwipeCords.minY - distance.y; 20631 distance.y = possibleSwipeCords.minY - diffMinY / 6; 20632 } 20633 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 20634 var diffMaxY = distance.y - possibleSwipeCords.maxY; 20635 distance.y = possibleSwipeCords.maxY + diffMaxY / 6; 20636 } 20637 } 20638 else { 20639 distance.y = this.top; 20640 }
20641 if (allowX) { 20642 distance.x = 20643 this.left + (endCoords.x - startCoords.x) * this.modifierX; 20644 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 20645 var diffMinX = possibleSwipeCords.minX - distance.x; 20646 distance.x = possibleSwipeCords.minX - diffMinX / 6; 20647 } 20648 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 20649 var difMaxX = distance.x - possibleSwipeCords.maxX; 20650 distance.x = possibleSwipeCords.maxX + difMaxX / 6; 20651 } 20652 } 20653 else { 20654 distance.x = this.left; 20655 } 20656 return distance; 20657 }; 20658 Zoom.prototype.isBeyondPossibleLeft = function (x, minX) { 20659 return x >= minX; 20660 }; 20661 Zoom.prototype.isBeyondPossibleRight = function (x, maxX) { 20662 return x <= maxX; 20663 }; 20664 Zoom.prototype.isBeyondPossibleTop = function (y, minY) { 20665 return y >= minY; 20666 }; 20667 Zoom.prototype.isBeyondPossibleBottom = function (y, maxY) { 20668 return y <= maxY; 20669 }; 20670 Zoom.prototype.isImageSlide = function () { 20671 var currentItem = this.core.galleryItems[this.core.index]; 20672 return this.core.getSlideType(currentItem) === 'image'; 20673 }; 20674 Zoom.prototype.getPossibleSwipeDragCords = function (rotateValue, scale) { 20675 var dataScale = scale || this.scale || 1; 20676 var elDataScale = Math.abs(dataScale); 20677 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 20678 var topBottomSpacing = Math.abs(top - bottom) / 2; 20679 var minY = (this.imageYSize - this.containerRect.height) / 2 + 20680 topBottomSpacing * this.modifierX; 20681 var maxY = this.containerRect.height - this.imageYSize * elDataScale + minY; 20682 var minX = (this.imageXSize - this.containerRect.width) / 2; 20683 var maxX = this.containerRect.width - this.imageXSize * elDataScale + minX; 20684 var possibleSwipeCords = { 20685 minY: minY, 20686 maxY: maxY, 20687 minX: minX, 20688 maxX: maxX, 20689 }; 20690 if (Math.abs(rotateValue) === 90) { 20691 possibleSwipeCords = { 20692 minY: minX, 20693 maxY: maxX, 20694 minX: minY, 20695 maxX: maxY, 20696 }; 20697 } 20698 return possibleSwipeCords; 20699 }; 20700 Zoom.prototype.setZoomSwipeStyles = function (LGel, distance) { 20701 LGel.css('transform', 'translate3d(' + distance.x + 'px, ' + distance.y + 'px, 0)'); 20702 }; 20703 Zoom.prototype.zoomSwipe = function () { 20704 var _this = this; 20705 var startCoords = {}; 20706 var endCoords = {}; 20707 var isMoved = false; 20708 // Allow x direction drag 20709 var allowX = false; 20710 // Allow Y direction drag 20711 var allowY = false; 20712 var startTime = new Date(); 20713 var endTime = new Date(); 20714 var possibleSwipeCords; 20715 var _LGel; 20716 var $item = this.core.getSlideItem(this.core.index); 20717 this.core.$inner.on('touchstart.lg', function (e) { 20718 // Allow zoom only on image 20719 if (!_this.isImageSlide()) { 20720 return; 20721 } 20722 $item = _this.core.getSlideItem(_this.core.index); 20723 if ((_this.$LG(e.target).hasClass('lg-item') || 20724 $item.get().contains(e.target)) && 20725 e.targetTouches.length === 1 && 20726 _this.core.outer.hasClass('lg-zoomed')) { 20727 e.preventDefault(); 20728 startTime = new Date(); 20729 _this.core.touchAction = 'zoomSwipe'; 20730 _LGel = _this.core 20731 .getSlideItem(_this.core.index) 20732 .find('.lg-img-wrap') 20733 .first(); 20734 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 20735 allowY = dragAllowedAxises.allowY; 20736 allowX = dragAllowedAxises.allowX; 20737 if (allowX || allowY) { 20738 startCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 20739 } 20740 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 20741 // reset opacity and transition duration 20742 _this.core.outer.addClass('lg-zoom-dragging lg-zoom-drag-transition'); 20743 } 20744 }); 20745 this.core.$inner.on('touchmove.lg', function (e) { 20746 if (e.targetTouches.length === 1 && 20747 _this.core.touchAction === 'zoomSwipe' && 20748 (_this.$LG(e.target).hasClass('lg-item') || 20749 $item.get().contains(e.target))) { 20750 e.preventDefault(); 20751 _this.core.touchAction = 'zoomSwipe'; 20752 endCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 20753 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 20754 if (Math.abs(endCoords.x - startCoords.x) > 15 || 20755 Math.abs(endCoords.y - startCoords.y) > 15) { 20756 isMoved = true; 20757 _this.setZoomSwipeStyles(_LGel, distance); 20758 } 20759 } 20760 }); 20761 this.core.$inner.on('touchend.lg', function (e) { 20762 if (_this.core.touchAction === 'zoomSwipe' && 20763 (_this.$LG(e.target).hasClass('lg-item') || 20764 $item.get().contains(e.target))) { 20765 _this.core.touchAction = undefined; 20766 _this.core.outer.removeClass('lg-zoom-dragging'); 20767 if (!isMoved) { 20768 return; 20769 } 20770 isMoved = false;
20771 endTime = new Date(); 20772 var touchDuration = endTime.valueOf() - startTime.valueOf(); 20773 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 20774 } 20775 }); 20776 }; 20777 Zoom.prototype.zoomDrag = function () { 20778 var _this = this; 20779 var startCoords = {}; 20780 var endCoords = {}; 20781 var isDragging = false; 20782 var isMoved = false; 20783 // Allow x direction drag 20784 var allowX = false; 20785 // Allow Y direction drag 20786 var allowY = false; 20787 var startTime; 20788 var endTime; 20789 var possibleSwipeCords; 20790 var _LGel; 20791 this.core.outer.on('mousedown.lg.zoom', function (e) { 20792 // Allow zoom only on image 20793 if (!_this.isImageSlide()) { 20794 return; 20795 } 20796 var $item = _this.core.getSlideItem(_this.core.index); 20797 if (_this.$LG(e.target).hasClass('lg-item') || 20798 $item.get().contains(e.target)) { 20799 startTime = new Date(); 20800 _LGel = _this.core 20801 .getSlideItem(_this.core.index) 20802 .find('.lg-img-wrap') 20803 .first(); 20804 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 20805 allowY = dragAllowedAxises.allowY; 20806 allowX = dragAllowedAxises.allowX; 20807 if (_this.core.outer.hasClass('lg-zoomed')) { 20808 if (_this.$LG(e.target).hasClass('lg-object') && 20809 (allowX || allowY)) { 20810 e.preventDefault(); 20811 startCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20812 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 20813 isDragging = true; 20814 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 20815 _this.core.outer.get().scrollLeft += 1; 20816 _this.core.outer.get().scrollLeft -= 1; 20817 _this.core.outer 20818 .removeClass('lg-grab') 20819 .addClass('lg-grabbing lg-zoom-drag-transition lg-zoom-dragging'); 20820 // reset opacity and transition duration 20821 } 20822 } 20823 } 20824 }); 20825 this.$LG(window).on("mousemove.lg.zoom.global" + this.core.lgId, function (e) { 20826 if (isDragging) { 20827 isMoved = true; 20828 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20829 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 20830 _this.setZoomSwipeStyles(_LGel, distance); 20831 } 20832 }); 20833 this.$LG(window).on("mouseup.lg.zoom.global" + this.core.lgId, function (e) { 20834 if (isDragging) { 20835 endTime = new Date(); 20836 isDragging = false; 20837 _this.core.outer.removeClass('lg-zoom-dragging'); 20838 // Fix for chrome mouse move on click 20839 if (isMoved && 20840 (startCoords.x !== endCoords.x || 20841 startCoords.y !== endCoords.y)) { 20842 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 20843 var touchDuration = endTime.valueOf() - startTime.valueOf(); 20844 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 20845 } 20846 isMoved = false; 20847 } 20848 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 20849 }); 20850 }; 20851 Zoom.prototype.closeGallery = function () { 20852 this.resetZoom(); 20853 }; 20854 Zoom.prototype.destroy = function () { 20855 // Unbind all events added by lightGallery zoom plugin 20856 this.$LG(window).off(".lg.zoom.global" + this.core.lgId); 20857 this.core.LGel.off('.lg.zoom'); 20858 this.core.LGel.off('.zoom'); 20859 clearTimeout(this.zoomableTimeout); 20860 this.zoomableTimeout = false; 20861 }; 20862 return Zoom; 20863 }()); 20864 20865 return Zoom; 20866 20867}))); 20868/*! 20869 * lightgallery | 2.5.0 | June 13th 2022 20870 * http://www.lightgalleryjs.com/ 20871 * Copyright (c) 2020 Sachin Neravath; 20872 * @license GPLv3 20873 */ 20874 20875(function (global, factory) { 20876 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20877 typeof define === 'function' && define.amd ? define(factory) : 20878 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgFullscreen = factory()); 20879}(this, (function () { 'use strict'; 20880 20881 /*! ***************************************************************************** 20882 Copyright (c) Microsoft Corporation. 20883 20884 Permission to use, copy, modify, and/or distribute this software for any 20885 purpose with or without fee is hereby granted. 20886 20887 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20888 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20889 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20890 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20891 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20892 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20893 PERFORMANCE OF THIS SOFTWARE. 20894 ***************************************************************************** */ 20895 20896 var __assign = function() { 20897 __assign = Object.assign || function __assign(t) { 20898 for (var s, i = 1, n = arguments.length; i < n; i++) { 20899 s = arguments[i]; 20900 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20901 } 20902 return t; 20903 }; 20904 return __assign.apply(this, arguments); 20905 }; 20906 20907 var fullscreenSettings = { 20908 fullScreen: true, 20909 fullscreenPluginStrings: { 20910 toggleFullscreen: 'Toggle Fullscreen', 20911 }, 20912 }; 20913 20914 var FullScreen = /** @class */ (function () { 20915 function FullScreen(instance, $LG) { 20916 // get lightGallery core plugin instance 20917 this.core = instance;
20918 this.$LG = $LG; 20919 // extend module default settings with lightGallery core settings 20920 this.settings = __assign(__assign({}, fullscreenSettings), this.core.settings); 20921 return this; 20922 } 20923 FullScreen.prototype.init = function () { 20924 var fullScreen = ''; 20925 if (this.settings.fullScreen) { 20926 // check for fullscreen browser support 20927 if (!document.fullscreenEnabled && 20928 !document.webkitFullscreenEnabled && 20929 !document.mozFullScreenEnabled && 20930 !document.msFullscreenEnabled) { 20931 return; 20932 } 20933 else { 20934 fullScreen = "<button type=\"button\" aria-label=\"" + this.settings.fullscreenPluginStrings['toggleFullscreen'] + "\" class=\"lg-fullscreen lg-icon\"></button>"; 20935 this.core.$toolbar.append(fullScreen); 20936 this.fullScreen(); 20937 } 20938 } 20939 }; 20940 FullScreen.prototype.isFullScreen = function () { 20941 return (document.fullscreenElement || 20942 document.mozFullScreenElement || 20943 document.webkitFullscreenElement || 20944 document.msFullscreenElement); 20945 }; 20946 FullScreen.prototype.requestFullscreen = function () { 20947 var el = document.documentElement; 20948 if (el.requestFullscreen) { 20949 el.requestFullscreen(); 20950 } 20951 else if (el.msRequestFullscreen) { 20952 el.msRequestFullscreen(); 20953 } 20954 else if (el.mozRequestFullScreen) { 20955 el.mozRequestFullScreen(); 20956 } 20957 else if (el.webkitRequestFullscreen) { 20958 el.webkitRequestFullscreen(); 20959 } 20960 }; 20961 FullScreen.prototype.exitFullscreen = function () { 20962 if (document.exitFullscreen) { 20963 document.exitFullscreen(); 20964 } 20965 else if (document.msExitFullscreen) { 20966 document.msExitFullscreen(); 20967 } 20968 else if (document.mozCancelFullScreen) { 20969 document.mozCancelFullScreen(); 20970 } 20971 else if (document.webkitExitFullscreen) { 20972 document.webkitExitFullscreen(); 20973 } 20974 }; 20975 // https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode 20976 FullScreen.prototype.fullScreen = function () { 20977 var _this = this; 20978 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 () { 20979 if (!_this.core.lgOpened) 20980 return; 20981 _this.core.outer.toggleClass('lg-fullscreen-on'); 20982 }); 20983 this.core.outer 20984 .find('.lg-fullscreen') 20985 .first() 20986 .on('click.lg', function () { 20987 if (_this.isFullScreen()) { 20988 _this.exitFullscreen(); 20989 } 20990 else { 20991 _this.requestFullscreen(); 20992 } 20993 }); 20994 }; 20995 FullScreen.prototype.closeGallery = function () { 20996 // exit from fullscreen if activated 20997 if (this.isFullScreen()) { 20998 this.exitFullscreen(); 20999 } 21000 }; 21001 FullScreen.prototype.destroy = function () { 21002 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); 21003 }; 21004 return FullScreen; 21005 }()); 21006 21007 return FullScreen; 21008 21009}))); 21010 21011/*! 21012 * lightgallery | 2.5.0 | June 13th 2022 21013 * http://www.lightgalleryjs.com/ 21014 * Copyright (c) 2020 Sachin Neravath; 21015 * @license GPLv3 21016 */ 21017 21018(function (global, factory) { 21019 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21020 typeof define === 'function' && define.amd ? define(factory) : 21021 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgHash = factory()); 21022}(this, (function () { 'use strict'; 21023 21024 /*! ***************************************************************************** 21025 Copyright (c) Microsoft Corporation. 21026 21027 Permission to use, copy, modify, and/or distribute this software for any 21028 purpose with or without fee is hereby granted. 21029 21030 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21031 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21032 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21033 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21034 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21035 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21036 PERFORMANCE OF THIS SOFTWARE. 21037 ***************************************************************************** */ 21038 21039 var __assign = function() { 21040 __assign = Object.assign || function __assign(t) { 21041 for (var s, i = 1, n = arguments.length; i < n; i++) { 21042 s = arguments[i]; 21043 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21044 } 21045 return t; 21046 }; 21047 return __assign.apply(this, arguments); 21048 }; 21049 21050 /** 21051 * List of lightGallery events 21052 * All events should be documented here 21053 * Below interfaces are used to build the website documentations 21054 * */ 21055 var lGEvents = { 21056 afterAppendSlide: 'lgAfterAppendSlide', 21057 init: 'lgInit', 21058 hasVideo: 'lgHasVideo', 21059 containerResize: 'lgContainerResize', 21060 updateSlides: 'lgUpdateSlides', 21061 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21062 beforeOpen: 'lgBeforeOpen', 21063 afterOpen: 'lgAfterOpen', 21064 slideItemLoad: 'lgSlideItemLoad', 21065 beforeSlide: 'lgBeforeSlide', 21066 afterSlide: 'lgAfterSlide', 21067 posterClick: 'lgPosterClick', 21068 dragStart: 'lgDragStart', 21069 dragMove: 'lgDragMove', 21070 dragEnd: 'lgDragEnd', 21071 beforeNextSlide: 'lgBeforeNextSlide', 21072 beforePrevSlide: 'lgBeforePrevSlide', 21073 beforeClose: 'lgBeforeClose', 21074 afterClose: 'lgAfterClose', 21075 rotateLeft: 'lgRotateLeft', 21076 rotateRight: 'lgRotateRight', 21077 flipHorizontal: 'lgFlipHorizontal', 21078 flipVertical: 'lgFlipVertical', 21079 autoplay: 'lgAutoplay', 21080 autoplayStart: 'lgAutoplayStart', 21081 autoplayStop: 'lgAutoplayStop', 21082 }; 21083 21084 var hashSettings = { 21085 hash: true, 21086 galleryId: '1', 21087 customSlideName: false, 21088 }; 21089 21090 var Hash = /** @class */ (function () { 21091 function Hash(instance, $LG) { 21092 // get lightGallery core plugin instance 21093 this.core = instance;
21094 this.$LG = $LG; 21095 // extend module default settings with lightGallery core settings 21096 this.settings = __assign(__assign({}, hashSettings), this.core.settings); 21097 return this; 21098 } 21099 Hash.prototype.init = function () { 21100 var _this = this; 21101 if (!this.settings.hash) { 21102 return; 21103 } 21104 this.oldHash = window.location.hash; 21105 setTimeout(function () { 21106 _this.buildFromHash(); 21107 }, 100); 21108 // Change hash value on after each slide transition 21109 this.core.LGel.on(lGEvents.afterSlide + ".hash", this.onAfterSlide.bind(this)); 21110 this.core.LGel.on(lGEvents.afterClose + ".hash", this.onCloseAfter.bind(this)); 21111 // Listen hash change and change the slide according to slide value 21112 this.$LG(window).on("hashchange.lg.hash.global" + this.core.lgId, this.onHashchange.bind(this)); 21113 }; 21114 Hash.prototype.onAfterSlide = function (event) { 21115 var slideName = this.core.galleryItems[event.detail.index].slideName; 21116 slideName = this.settings.customSlideName 21117 ? slideName || event.detail.index 21118 : event.detail.index; 21119 if (history.replaceState) { 21120 history.replaceState(null, '', window.location.pathname + 21121 window.location.search + 21122 '#lg=' + 21123 this.settings.galleryId + 21124 '&slide=' + 21125 slideName); 21126 } 21127 else { 21128 window.location.hash = 21129 'lg=' + this.settings.galleryId + '&slide=' + slideName; 21130 } 21131 }; 21132 /** 21133 * Get index of the slide from custom slideName. Has to be a public method. Used in hash plugin 21134 * @param {String} hash 21135 * @returns {Number} Index of the slide. 21136 */ 21137 Hash.prototype.getIndexFromUrl = function (hash) { 21138 if (hash === void 0) { hash = window.location.hash; } 21139 var slideName = hash.split('&slide=')[1]; 21140 var _idx = 0; 21141 if (this.settings.customSlideName) { 21142 for (var index = 0; index < this.core.galleryItems.length; index++) { 21143 var dynamicEl = this.core.galleryItems[index]; 21144 if (dynamicEl.slideName === slideName) { 21145 _idx = index; 21146 break; 21147 } 21148 } 21149 } 21150 else { 21151 _idx = parseInt(slideName, 10); 21152 } 21153 return isNaN(_idx) ? 0 : _idx; 21154 }; 21155 // Build Gallery if gallery id exist in the URL 21156 Hash.prototype.buildFromHash = function () { 21157 // if dynamic option is enabled execute immediately 21158 var _hash = window.location.hash; 21159 //Uncode edit ##START## 21160 // if (_hash.indexOf('lg=' + this.settings.galleryId) > 0) { 21161 if (_hash.indexOf('lg=' + this.settings.galleryId + '&') > 0) { 21162 //Uncode edit ##END## 21163 // This class is used to remove the initial animation if galleryId present in the URL 21164 this.$LG(document.body).addClass('lg-from-hash'); 21165 var index = this.getIndexFromUrl(_hash); 21166 this.core.openGallery(index); 21167 return true; 21168 } 21169 }; 21170 Hash.prototype.onCloseAfter = function () { 21171 // Reset to old hash value 21172 if (this.oldHash && 21173 this.oldHash.indexOf('lg=' + this.settings.galleryId) < 0) { 21174 if (history.replaceState) { 21175 history.replaceState(null, '', this.oldHash); 21176 } 21177 else { 21178 window.location.hash = this.oldHash; 21179 } 21180 } 21181 else { 21182 if (history.replaceState) { 21183 history.replaceState(null, document.title, window.location.pathname + window.location.search); 21184 } 21185 else { 21186 window.location.hash = ''; 21187 } 21188 } 21189 }; 21190 Hash.prototype.onHashchange = function () { 21191 if (!this.core.lgOpened) 21192 return; 21193 var _hash = window.location.hash; 21194 var index = this.getIndexFromUrl(_hash); 21195 // it galleryId doesn't exist in the url close the gallery 21196 if (_hash.indexOf('lg=' + this.settings.galleryId) > -1) { 21197 this.core.slide(index, false, false); 21198 } 21199 else if (this.core.lGalleryOn) { 21200 this.core.closeGallery(); 21201 } 21202 }; 21203 Hash.prototype.closeGallery = function () { 21204 if (this.settings.hash) { 21205 this.$LG(document.body).removeClass('lg-from-hash'); 21206 } 21207 }; 21208 Hash.prototype.destroy = function () { 21209 this.core.LGel.off('.lg.hash'); 21210 this.core.LGel.off('.hash'); 21211 this.$LG(window).off("hashchange.lg.hash.global" + this.core.lgId); 21212 }; 21213 return Hash; 21214 }()); 21215 21216 return Hash; 21217 21218}))); 21219/*! 21220 * lightgallery | 2.5.0 | June 13th 2022 21221 * http://www.lightgalleryjs.com/ 21222 * Copyright (c) 2020 Sachin Neravath; 21223 * @license GPLv3 21224 */ 21225 21226(function (global, factory) { 21227 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21228 typeof define === 'function' && define.amd ? define(factory) : 21229 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgShare = factory()); 21230}(this, (function () { 'use strict'; 21231 21232 /*! ***************************************************************************** 21233 Copyright (c) Microsoft Corporation. 21234 21235 Permission to use, copy, modify, and/or distribute this software for any 21236 purpose with or without fee is hereby granted. 21237 21238 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21239 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21240 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21241 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21242 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21243 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21244 PERFORMANCE OF THIS SOFTWARE. 21245 ***************************************************************************** */ 21246 21247 var __assign = function() { 21248 __assign = Object.assign || function __assign(t) { 21249 for (var s, i = 1, n = arguments.length; i < n; i++) { 21250 s = arguments[i]; 21251 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21252 } 21253 return t; 21254 }; 21255 return __assign.apply(this, arguments); 21256 }; 21257 21258 function __spreadArrays() { 21259 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 21260 for (var r = Array(s), k = 0, i = 0; i < il; i++) 21261 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 21262 r[k] = a[j]; 21263 return r; 21264 } 21265 21266 var shareSettings = { 21267 share: true, 21268 facebook: true, 21269 facebookDropdownText: 'Facebook', 21270 twitter: true, 21271 twitterDropdownText: 'Twitter', 21272 pinterest: true, 21273 pinterestDropdownText: 'Pinterest', 21274 additionalShareOptions: [], 21275 sharePluginStrings: { share: 'Share' }, 21276 }; 21277 21278 function getFacebookShareLink(galleryItem) { 21279 var facebookBaseUrl = '//www.facebook.com/sharer/sharer.php?u='; 21280 return (facebookBaseUrl + 21281 encodeURIComponent(galleryItem.facebookShareUrl || window.location.href)); 21282 } 21283 21284 function getTwitterShareLink(galleryItem) { 21285 var twitterBaseUrl = '//twitter.com/intent/tweet?text='; 21286 var url = encodeURIComponent(galleryItem.twitterShareUrl || window.location.href); 21287 var text = galleryItem.tweetText;
21288 return twitterBaseUrl + text + '&url=' + url; 21289 } 21290 21291 function getPinterestShareLink(galleryItem) { 21292 var pinterestBaseUrl = 'http://www.pinterest.com/pin/create/button/?url='; 21293 var description = galleryItem.pinterestText; 21294 var media = encodeURIComponent(galleryItem.src); 21295 var url = encodeURIComponent(galleryItem.pinterestShareUrl || window.location.href); 21296 return (pinterestBaseUrl + 21297 url + 21298 '&media=' + 21299 media + 21300 '&description=' + 21301 description); 21302 } 21303 21304 /** 21305 * List of lightGallery events 21306 * All events should be documented here 21307 * Below interfaces are used to build the website documentations 21308 * */ 21309 var lGEvents = { 21310 afterAppendSlide: 'lgAfterAppendSlide', 21311 init: 'lgInit', 21312 hasVideo: 'lgHasVideo', 21313 containerResize: 'lgContainerResize', 21314 updateSlides: 'lgUpdateSlides', 21315 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21316 beforeOpen: 'lgBeforeOpen', 21317 afterOpen: 'lgAfterOpen', 21318 slideItemLoad: 'lgSlideItemLoad', 21319 beforeSlide: 'lgBeforeSlide', 21320 afterSlide: 'lgAfterSlide', 21321 posterClick: 'lgPosterClick', 21322 dragStart: 'lgDragStart', 21323 dragMove: 'lgDragMove', 21324 dragEnd: 'lgDragEnd', 21325 beforeNextSlide: 'lgBeforeNextSlide', 21326 beforePrevSlide: 'lgBeforePrevSlide', 21327 beforeClose: 'lgBeforeClose', 21328 afterClose: 'lgAfterClose', 21329 rotateLeft: 'lgRotateLeft', 21330 rotateRight: 'lgRotateRight', 21331 flipHorizontal: 'lgFlipHorizontal', 21332 flipVertical: 'lgFlipVertical', 21333 autoplay: 'lgAutoplay', 21334 autoplayStart: 'lgAutoplayStart', 21335 autoplayStop: 'lgAutoplayStop', 21336 }; 21337 21338 var Share = /** @class */ (function () { 21339 function Share(instance) { 21340 this.shareOptions = []; 21341 // get lightGallery core plugin instance 21342 this.core = instance; 21343 // extend module default settings with lightGallery core settings 21344 this.settings = __assign(__assign({}, shareSettings), this.core.settings); 21345 return this; 21346 } 21347 Share.prototype.init = function () { 21348 if (!this.settings.share) { 21349 return; 21350 } 21351 this.shareOptions = __spreadArrays(this.getDefaultShareOptions(), this.settings.additionalShareOptions); 21352 this.setLgShareMarkup(); 21353 this.core.outer 21354 .find('.lg-share .lg-dropdown') 21355 .append(this.getShareListHtml()); 21356 this.core.LGel.on(lGEvents.afterSlide + ".share", this.onAfterSlide.bind(this)); 21357 }; 21358 Share.prototype.getShareListHtml = function () { 21359 var shareHtml = ''; 21360 this.shareOptions.forEach(function (shareOption) { 21361 shareHtml += shareOption.dropdownHTML; 21362 }); 21363 return shareHtml; 21364 }; 21365 Share.prototype.setLgShareMarkup = function () { 21366 var _this = this; 21367 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>"); 21368 this.core.outer.append('<div class="lg-dropdown-overlay"></div>'); 21369 var $shareButton = this.core.outer.find('.lg-share'); 21370 $shareButton.first().on('click.lg', function () { 21371 _this.core.outer.toggleClass('lg-dropdown-active'); 21372 if (_this.core.outer.hasClass('lg-dropdown-active')) { 21373 _this.core.outer.attr('aria-expanded', true); 21374 } 21375 else { 21376 _this.core.outer.attr('aria-expanded', false); 21377 } 21378 }); 21379 this.core.outer 21380 .find('.lg-dropdown-overlay') 21381 .first() 21382 .on('click.lg', function () { 21383 _this.core.outer.removeClass('lg-dropdown-active'); 21384 _this.core.outer.attr('aria-expanded', false); 21385 }); 21386 }; 21387 Share.prototype.onAfterSlide = function (event) { 21388 var _this = this; 21389 var index = event.detail.index; 21390 var currentItem = this.core.galleryItems[index]; 21391 setTimeout(function () { 21392 _this.shareOptions.forEach(function (shareOption) { 21393 var selector = shareOption.selector; 21394 _this.core.outer 21395 .find(selector) 21396 .attr('href', shareOption.generateLink(currentItem)); 21397 }); 21398 }, 100); 21399 }; 21400 Share.prototype.getShareListItemHTML = function (type, text) { 21401 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>"; 21402 }; 21403 Share.prototype.getDefaultShareOptions = function () { 21404 return __spreadArrays((this.settings.facebook 21405 ? [ 21406 { 21407 type: 'facebook', 21408 generateLink: getFacebookShareLink,
21409 dropdownHTML: this.getShareListItemHTML('facebook', this.settings.facebookDropdownText), 21410 selector: '.lg-share-facebook', 21411 }, 21412 ] 21413 : []), (this.settings.twitter 21414 ? [ 21415 { 21416 type: 'twitter', 21417 generateLink: getTwitterShareLink, 21418 dropdownHTML: this.getShareListItemHTML('twitter', this.settings.twitterDropdownText), 21419 selector: '.lg-share-twitter', 21420 }, 21421 ] 21422 : []), (this.settings.pinterest 21423 ? [ 21424 { 21425 type: 'pinterest', 21426 generateLink: getPinterestShareLink, 21427 dropdownHTML: this.getShareListItemHTML('pinterest', this.settings.pinterestDropdownText), 21428 selector: '.lg-share-pinterest', 21429 }, 21430 ] 21431 : [])); 21432 }; 21433 Share.prototype.destroy = function () { 21434 this.core.outer.find('.lg-dropdown-overlay').remove(); 21435 this.core.outer.find('.lg-share').remove(); 21436 this.core.LGel.off('.lg.share'); 21437 this.core.LGel.off('.share'); 21438 }; 21439 return Share; 21440 }()); 21441 21442 return Share; 21443 21444}))); 21445/*! 21446 * lightgallery | 2.5.0 | June 13th 2022 21447 * http://www.lightgalleryjs.com/ 21448 * Copyright (c) 2020 Sachin Neravath; 21449 * @license GPLv3 21450 */ 21451 21452(function (global, factory) { 21453 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21454 typeof define === 'function' && define.amd ? define(factory) : 21455 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgThumbnail = factory()); 21456}(this, (function () { 'use strict'; 21457 21458 /*! ***************************************************************************** 21459 Copyright (c) Microsoft Corporation. 21460 21461 Permission to use, copy, modify, and/or distribute this software for any 21462 purpose with or without fee is hereby granted. 21463 21464 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21465 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21466 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21467 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21468 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21469 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21470 PERFORMANCE OF THIS SOFTWARE. 21471 ***************************************************************************** */ 21472 21473 var __assign = function() { 21474 __assign = Object.assign || function __assign(t) { 21475 for (var s, i = 1, n = arguments.length; i < n; i++) { 21476 s = arguments[i]; 21477 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21478 } 21479 return t; 21480 }; 21481 return __assign.apply(this, arguments); 21482 }; 21483 21484 var thumbnailsSettings = { 21485 thumbnail: true, 21486 animateThumb: true, 21487 currentPagerPosition: 'middle', 21488 alignThumbnails: 'middle', 21489 thumbWidth: 100, 21490 thumbHeight: '80px', 21491 thumbMargin: 5, 21492 appendThumbnailsTo: '.lg-components', 21493 toggleThumb: false, 21494 enableThumbDrag: true, 21495 enableThumbSwipe: true, 21496 thumbnailSwipeThreshold: 10, 21497 loadYouTubeThumbnail: true, 21498 youTubeThumbSize: 1, 21499 thumbnailPluginStrings: { 21500 toggleThumbnails: 'Toggle thumbnails', 21501 }, 21502 }; 21503 21504 /** 21505 * List of lightGallery events 21506 * All events should be documented here 21507 * Below interfaces are used to build the website documentations 21508 * */ 21509 var lGEvents = { 21510 afterAppendSlide: 'lgAfterAppendSlide', 21511 init: 'lgInit', 21512 hasVideo: 'lgHasVideo', 21513 containerResize: 'lgContainerResize', 21514 updateSlides: 'lgUpdateSlides', 21515 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21516 beforeOpen: 'lgBeforeOpen', 21517 afterOpen: 'lgAfterOpen', 21518 slideItemLoad: 'lgSlideItemLoad', 21519 beforeSlide: 'lgBeforeSlide', 21520 afterSlide: 'lgAfterSlide', 21521 posterClick: 'lgPosterClick', 21522 dragStart: 'lgDragStart', 21523 dragMove: 'lgDragMove', 21524 dragEnd: 'lgDragEnd', 21525 beforeNextSlide: 'lgBeforeNextSlide', 21526 beforePrevSlide: 'lgBeforePrevSlide', 21527 beforeClose: 'lgBeforeClose', 21528 afterClose: 'lgAfterClose', 21529 rotateLeft: 'lgRotateLeft', 21530 rotateRight: 'lgRotateRight', 21531 flipHorizontal: 'lgFlipHorizontal', 21532 flipVertical: 'lgFlipVertical', 21533 autoplay: 'lgAutoplay', 21534 autoplayStart: 'lgAutoplayStart', 21535 autoplayStop: 'lgAutoplayStop', 21536 }; 21537 21538 var Thumbnail = /** @class */ (function () { 21539 function Thumbnail(instance, $LG) { 21540 this.thumbOuterWidth = 0; 21541 this.thumbTotalWidth = 0; 21542 this.translateX = 0; 21543 this.thumbClickable = false;
21544 // get lightGallery core plugin instance 21545 this.core = instance; 21546 this.$LG = $LG; 21547 return this; 21548 } 21549 Thumbnail.prototype.init = function () { 21550 // extend module default settings with lightGallery core settings 21551 this.settings = __assign(__assign({}, thumbnailsSettings), this.core.settings); 21552 this.thumbOuterWidth = 0; 21553 this.thumbTotalWidth = 21554 this.core.galleryItems.length * 21555 (this.settings.thumbWidth + this.settings.thumbMargin); 21556 // Thumbnail animation value 21557 this.translateX = 0; 21558 this.setAnimateThumbStyles(); 21559 if (!this.core.settings.allowMediaOverlap) { 21560 this.settings.toggleThumb = false; 21561 } 21562 if (this.settings.thumbnail) { 21563 this.build(); 21564 if (this.settings.animateThumb) { 21565 if (this.settings.enableThumbDrag) { 21566 this.enableThumbDrag(); 21567 } 21568 if (this.settings.enableThumbSwipe) { 21569 this.enableThumbSwipe(); 21570 } 21571 this.thumbClickable = false; 21572 } 21573 else { 21574 this.thumbClickable = true; 21575 } 21576 this.toggleThumbBar(); 21577 this.thumbKeyPress(); 21578 } 21579 }; 21580 Thumbnail.prototype.build = function () { 21581 var _this = this; 21582 this.setThumbMarkup(); 21583 this.manageActiveClassOnSlideChange(); 21584 this.$lgThumb.first().on('click.lg touchend.lg', function (e) { 21585 var $target = _this.$LG(e.target); 21586 if (!$target.hasAttribute('data-lg-item-id')) { 21587 return; 21588 } 21589 setTimeout(function () { 21590 // In IE9 and bellow touch does not support 21591 // Go to slide if browser does not support css transitions 21592 if (_this.thumbClickable && !_this.core.lgBusy) { 21593 var index = parseInt($target.attr('data-lg-item-id')); 21594 _this.core.slide(index, false, true, false); 21595 } 21596 }, 50); 21597 }); 21598 //Uncode edit ##START## 21599 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 21600 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 21601 //Uncode edit ##END## 21602 var index = event.detail.index; 21603 _this.animateThumb(index); 21604 }); 21605 //Uncode edit ##START## 21606 // this.core.LGel.on(lGEvents.beforeOpen + ".thumb", function () { 21607 this.core.LGel.on(lGEvents.beforeOpen, function () { 21608 //Uncode edit ##END## 21609 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21610 }); 21611 //Uncode edit ##START## 21612 // this.core.LGel.on(lGEvents.updateSlides + ".thumb", function () { 21613 this.core.LGel.on(lGEvents.updateSlides, function () { 21614 //Uncode edit ##END## 21615 _this.rebuildThumbnails(); 21616 }); 21617 //Uncode edit ##START## 21618 // this.core.LGel.on(lGEvents.containerResize + ".thumb", function () { 21619 this.core.LGel.on(lGEvents.containerResize, function () { 21620 //Uncode edit ##END## 21621 if (!_this.core.lgOpened) 21622 return; 21623 setTimeout(function () { 21624 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21625 _this.animateThumb(_this.core.index); 21626 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 21627 }, 50); 21628 }); 21629 }; 21630 Thumbnail.prototype.setThumbMarkup = function () { 21631 var thumbOuterClassNames = 'lg-thumb-outer '; 21632 if (this.settings.alignThumbnails) { 21633 thumbOuterClassNames += "lg-thumb-align-" + this.settings.alignThumbnails; 21634 } 21635 var html = "<div class=\"" + thumbOuterClassNames + "\">\n <div class=\"lg-thumb lg-group\">\n </div>\n </div>"; 21636 this.core.outer.addClass('lg-has-thumb'); 21637 if (this.settings.appendThumbnailsTo === '.lg-components') { 21638 this.core.$lgComponents.append(html); 21639 } 21640 else { 21641 this.core.outer.append(html); 21642 } 21643 this.$thumbOuter = this.core.outer.find('.lg-thumb-outer').first(); 21644 this.$lgThumb = this.core.outer.find('.lg-thumb').first(); 21645 if (this.settings.animateThumb) { 21646 this.core.outer 21647 .find('.lg-thumb') 21648 .css('transition-duration', this.core.settings.speed + 'ms') 21649 .css('width', this.thumbTotalWidth + 'px') 21650 .css('position', 'relative'); 21651 } 21652 this.setThumbItemHtml(this.core.galleryItems); 21653 }; 21654 Thumbnail.prototype.enableThumbDrag = function () { 21655 var _this = this; 21656 var thumbDragUtils = { 21657 cords: { 21658 startX: 0, 21659 endX: 0, 21660 }, 21661 isMoved: false, 21662 newTranslateX: 0, 21663 startTime: new Date(), 21664 endTime: new Date(), 21665 touchMoveTime: 0, 21666 }; 21667 var isDragging = false;
21668 this.$thumbOuter.addClass('lg-grab'); 21669 this.core.outer 21670 .find('.lg-thumb') 21671 .first() 21672 .on('mousedown.lg.thumb', function (e) { 21673 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21674 // execute only on .lg-object 21675 e.preventDefault(); 21676 thumbDragUtils.cords.startX = e.pageX; 21677 thumbDragUtils.startTime = new Date(); 21678 _this.thumbClickable = false; 21679 isDragging = true; 21680 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 21681 _this.core.outer.get().scrollLeft += 1; 21682 _this.core.outer.get().scrollLeft -= 1; 21683 // * 21684 _this.$thumbOuter 21685 .removeClass('lg-grab') 21686 .addClass('lg-grabbing'); 21687 } 21688 }); 21689 this.$LG(window).on("mousemove.lg.thumb.global" + this.core.lgId, function (e) { 21690 if (!_this.core.lgOpened) 21691 return; 21692 if (isDragging) { 21693 thumbDragUtils.cords.endX = e.pageX; 21694 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 21695 } 21696 }); 21697 this.$LG(window).on("mouseup.lg.thumb.global" + this.core.lgId, function () { 21698 if (!_this.core.lgOpened) 21699 return; 21700 if (thumbDragUtils.isMoved) { 21701 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 21702 } 21703 else { 21704 _this.thumbClickable = true; 21705 } 21706 if (isDragging) { 21707 isDragging = false; 21708 _this.$thumbOuter.removeClass('lg-grabbing').addClass('lg-grab'); 21709 } 21710 }); 21711 }; 21712 Thumbnail.prototype.enableThumbSwipe = function () { 21713 var _this = this; 21714 var thumbDragUtils = { 21715 cords: { 21716 startX: 0, 21717 endX: 0, 21718 }, 21719 isMoved: false, 21720 newTranslateX: 0, 21721 startTime: new Date(), 21722 endTime: new Date(), 21723 touchMoveTime: 0, 21724 }; 21725 this.$lgThumb.on('touchstart.lg', function (e) { 21726 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21727 e.preventDefault(); 21728 thumbDragUtils.cords.startX = e.targetTouches[0].pageX; 21729 _this.thumbClickable = false; 21730 thumbDragUtils.startTime = new Date(); 21731 } 21732 }); 21733 this.$lgThumb.on('touchmove.lg', function (e) { 21734 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 21735 e.preventDefault(); 21736 thumbDragUtils.cords.endX = e.targetTouches[0].pageX; 21737 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 21738 } 21739 }); 21740 this.$lgThumb.on('touchend.lg', function () { 21741 if (thumbDragUtils.isMoved) { 21742 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 21743 } 21744 else { 21745 _this.thumbClickable = true; 21746 } 21747 }); 21748 }; 21749 // Rebuild thumbnails 21750 Thumbnail.prototype.rebuildThumbnails = function () { 21751 var _this = this; 21752 // Remove transitions 21753 this.$thumbOuter.addClass('lg-rebuilding-thumbnails'); 21754 setTimeout(function () { 21755 _this.thumbTotalWidth = 21756 _this.core.galleryItems.length * 21757 (_this.settings.thumbWidth + _this.settings.thumbMargin); 21758 _this.$lgThumb.css('width', _this.thumbTotalWidth + 'px'); 21759 _this.$lgThumb.empty(); 21760 _this.setThumbItemHtml(_this.core.galleryItems); 21761 _this.animateThumb(_this.core.index); 21762 }, 50); 21763 setTimeout(function () { 21764 _this.$thumbOuter.removeClass('lg-rebuilding-thumbnails'); 21765 }, 200); 21766 }; 21767 // @ts-check 21768 Thumbnail.prototype.setTranslate = function (value) { 21769 this.$lgThumb.css('transform', 'translate3d(-' + value + 'px, 0px, 0px)'); 21770 }; 21771 Thumbnail.prototype.getPossibleTransformX = function (left) { 21772 if (left > this.thumbTotalWidth - this.thumbOuterWidth) { 21773 left = this.thumbTotalWidth - this.thumbOuterWidth; 21774 } 21775 if (left < 0) { 21776 left = 0; 21777 } 21778 return left; 21779 }; 21780 Thumbnail.prototype.animateThumb = function (index) { 21781 this.$lgThumb.css('transition-duration', this.core.settings.speed + 'ms'); 21782 if (this.settings.animateThumb) { 21783 var position = 0; 21784 switch (this.settings.currentPagerPosition) { 21785 case 'left': 21786 position = 0; 21787 break; 21788 case 'middle': 21789 position = 21790 this.thumbOuterWidth / 2 - this.settings.thumbWidth / 2; 21791 break; 21792 case 'right': 21793 position = this.thumbOuterWidth - this.settings.thumbWidth; 21794 } 21795 this.translateX = 21796 (this.settings.thumbWidth + this.settings.thumbMargin) * index - 21797 1 - 21798 position; 21799 if (this.translateX > this.thumbTotalWidth - this.thumbOuterWidth) { 21800 this.translateX = this.thumbTotalWidth - this.thumbOuterWidth; 21801 } 21802 if (this.translateX < 0) { 21803 this.translateX = 0; 21804 } 21805 this.setTranslate(this.translateX); 21806 } 21807 };
21808 Thumbnail.prototype.onThumbTouchMove = function (thumbDragUtils) { 21809 thumbDragUtils.newTranslateX = this.translateX; 21810 thumbDragUtils.isMoved = true; 21811 thumbDragUtils.touchMoveTime = new Date().valueOf(); 21812 thumbDragUtils.newTranslateX -= 21813 thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 21814 thumbDragUtils.newTranslateX = this.getPossibleTransformX(thumbDragUtils.newTranslateX); 21815 // move current slide 21816 this.setTranslate(thumbDragUtils.newTranslateX); 21817 this.$thumbOuter.addClass('lg-dragging'); 21818 return thumbDragUtils; 21819 }; 21820 Thumbnail.prototype.onThumbTouchEnd = function (thumbDragUtils) { 21821 thumbDragUtils.isMoved = false; 21822 thumbDragUtils.endTime = new Date(); 21823 this.$thumbOuter.removeClass('lg-dragging'); 21824 var touchDuration = thumbDragUtils.endTime.valueOf() - 21825 thumbDragUtils.startTime.valueOf(); 21826 var distanceXnew = thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 21827 var speedX = Math.abs(distanceXnew) / touchDuration; 21828 // Some magical numbers 21829 // Can be improved 21830 if (speedX > 0.15 && 21831 thumbDragUtils.endTime.valueOf() - thumbDragUtils.touchMoveTime < 30) { 21832 speedX += 1; 21833 if (speedX > 2) { 21834 speedX += 1; 21835 } 21836 speedX = 21837 speedX + 21838 speedX * (Math.abs(distanceXnew) / this.thumbOuterWidth); 21839 this.$lgThumb.css('transition-duration', Math.min(speedX - 1, 2) + 'settings'); 21840 distanceXnew = distanceXnew * speedX; 21841 this.translateX = this.getPossibleTransformX(this.translateX - distanceXnew); 21842 this.setTranslate(this.translateX); 21843 } 21844 else { 21845 this.translateX = thumbDragUtils.newTranslateX; 21846 } 21847 if (Math.abs(thumbDragUtils.cords.endX - thumbDragUtils.cords.startX) < 21848 this.settings.thumbnailSwipeThreshold) { 21849 this.thumbClickable = true; 21850 } 21851 return thumbDragUtils; 21852 }; 21853 Thumbnail.prototype.getThumbHtml = function (thumb, index) { 21854 var slideVideoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 21855 var thumbImg; 21856 if (slideVideoInfo.youtube) { 21857 if (this.settings.loadYouTubeThumbnail) { 21858 thumbImg = 21859 '//img.youtube.com/vi/' + 21860 slideVideoInfo.youtube[1] + 21861 '/' + 21862 this.settings.youTubeThumbSize + 21863 '.jpg'; 21864 } 21865 else { 21866 thumbImg = thumb; 21867 } 21868 } 21869 else { 21870 thumbImg = thumb; 21871 } 21872 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>"; 21873 }; 21874 Thumbnail.prototype.getThumbItemHtml = function (items) { 21875 var thumbList = ''; 21876 for (var i = 0; i < items.length; i++) { 21877 thumbList += this.getThumbHtml(items[i].thumb, i); 21878 } 21879 return thumbList; 21880 }; 21881 Thumbnail.prototype.setThumbItemHtml = function (items) { 21882 var thumbList = this.getThumbItemHtml(items); 21883 this.$lgThumb.html(thumbList); 21884 }; 21885 Thumbnail.prototype.setAnimateThumbStyles = function () { 21886 if (this.settings.animateThumb) { 21887 this.core.outer.addClass('lg-animate-thumb'); 21888 } 21889 }; 21890 // Manage thumbnail active calss
21891 Thumbnail.prototype.manageActiveClassOnSlideChange = function () { 21892 var _this = this; 21893 // manage active class for thumbnail 21894 //Uncode edit ##START## 21895 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 21896 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 21897 //Uncode edit ##END## 21898 var $thumb = _this.core.outer.find('.lg-thumb-item'); 21899 var index = event.detail.index; 21900 $thumb.removeClass('active'); 21901 $thumb.eq(index).addClass('active'); 21902 }); 21903 }; 21904 // Toggle thumbnail bar 21905 Thumbnail.prototype.toggleThumbBar = function () { 21906 var _this = this; 21907 if (this.settings.toggleThumb) { 21908 this.core.outer.addClass('lg-can-toggle'); 21909 this.core.$toolbar.append('<button type="button" aria-label="' + 21910 this.settings.thumbnailPluginStrings['toggleThumbnails'] + 21911 '" class="lg-toggle-thumb lg-icon"></button>'); 21912 this.core.outer 21913 .find('.lg-toggle-thumb') 21914 .first() 21915 .on('click.lg', function () { 21916 _this.core.outer.toggleClass('lg-components-open'); 21917 }); 21918 } 21919 }; 21920 Thumbnail.prototype.thumbKeyPress = function () { 21921 var _this = this; 21922 this.$LG(window).on("keydown.lg.thumb.global" + this.core.lgId, function (e) { 21923 if (!_this.core.lgOpened || !_this.settings.toggleThumb) 21924 return; 21925 if (e.keyCode === 38) { 21926 e.preventDefault(); 21927 _this.core.outer.addClass('lg-components-open'); 21928 } 21929 else if (e.keyCode === 40) { 21930 e.preventDefault(); 21931 _this.core.outer.removeClass('lg-components-open'); 21932 } 21933 }); 21934 }; 21935 Thumbnail.prototype.destroy = function () { 21936 if (this.settings.thumbnail) { 21937 this.$LG(window).off(".lg.thumb.global" + this.core.lgId); 21938 this.core.LGel.off('.lg.thumb'); 21939 this.core.LGel.off('.thumb'); 21940 this.$thumbOuter.remove(); 21941 this.core.outer.removeClass('lg-has-thumb'); 21942 } 21943 }; 21944 return Thumbnail; 21945 }()); 21946 21947 return Thumbnail; 21948 21949}))); 21950/*! 21951 * lightgallery | 2.5.0 | June 13th 2022 21952 * http://www.lightgalleryjs.com/ 21953 * Copyright (c) 2020 Sachin Neravath; 21954 * @license GPLv3 21955 */ 21956 21957(function (global, factory) { 21958 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21959 typeof define === 'function' && define.amd ? define(factory) : 21960 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgVideo = factory()); 21961}(this, (function () { 'use strict'; 21962 21963 /*! ***************************************************************************** 21964 Copyright (c) Microsoft Corporation. 21965 21966 Permission to use, copy, modify, and/or distribute this software for any 21967 purpose with or without fee is hereby granted. 21968 21969 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21970 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21971 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21972 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21973 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21974 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21975 PERFORMANCE OF THIS SOFTWARE. 21976 ***************************************************************************** */ 21977 21978 var __assign = function() { 21979 __assign = Object.assign || function __assign(t) { 21980 for (var s, i = 1, n = arguments.length; i < n; i++) { 21981 s = arguments[i]; 21982 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21983 } 21984 return t; 21985 }; 21986 return __assign.apply(this, arguments); 21987 }; 21988 21989 var videoSettings = { 21990 autoplayFirstVideo: true, 21991 youTubePlayerParams: false, 21992 vimeoPlayerParams: false, 21993 wistiaPlayerParams: false, 21994 gotoNextSlideOnVideoEnd: true, 21995 autoplayVideoOnSlide: false, 21996 videojs: false, 21997 videojsTheme: '', 21998 videojsOptions: {}, 21999 }; 22000 22001 /** 22002 * List of lightGallery events 22003 * All events should be documented here 22004 * Below interfaces are used to build the website documentations 22005 * */ 22006 var lGEvents = { 22007 afterAppendSlide: 'lgAfterAppendSlide', 22008 init: 'lgInit', 22009 hasVideo: 'lgHasVideo', 22010 containerResize: 'lgContainerResize', 22011 updateSlides: 'lgUpdateSlides', 22012 afterAppendSubHtml: 'lgAfterAppendSubHtml', 22013 beforeOpen: 'lgBeforeOpen', 22014 afterOpen: 'lgAfterOpen', 22015 slideItemLoad: 'lgSlideItemLoad', 22016 beforeSlide: 'lgBeforeSlide', 22017 afterSlide: 'lgAfterSlide', 22018 posterClick: 'lgPosterClick', 22019 dragStart: 'lgDragStart', 22020 dragMove: 'lgDragMove', 22021 dragEnd: 'lgDragEnd', 22022 beforeNextSlide: 'lgBeforeNextSlide', 22023 beforePrevSlide: 'lgBeforePrevSlide', 22024 beforeClose: 'lgBeforeClose', 22025 afterClose: 'lgAfterClose', 22026 rotateLeft: 'lgRotateLeft', 22027 rotateRight: 'lgRotateRight', 22028 flipHorizontal: 'lgFlipHorizontal', 22029 flipVertical: 'lgFlipVertical', 22030 autoplay: 'lgAutoplay', 22031 autoplayStart: 'lgAutoplayStart', 22032 autoplayStop: 'lgAutoplayStop', 22033 }; 22034 22035 var param = function (obj) { 22036 return Object.keys(obj) 22037 .map(function (k) { 22038 return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]); 22039 }) 22040 .join('&'); 22041 }; 22042 var getVimeoURLParams = function (defaultParams, videoInfo) { 22043 if (!videoInfo || !videoInfo.vimeo) 22044 return '';
22045 var urlParams = videoInfo.vimeo[2] || ''; 22046 var defaultPlayerParams = defaultParams && Object.keys(defaultParams).length !== 0 22047 ? '&' + param(defaultParams) 22048 : ''; 22049 // Support private video 22050 var urlWithHash = videoInfo.vimeo[0].split('/').pop() || ''; 22051 var urlWithHashWithParams = urlWithHash.split('?')[0] || ''; 22052 var hash = urlWithHashWithParams.split('#')[0]; 22053 var isPrivate = videoInfo.vimeo[1] !== hash; 22054 if (isPrivate) { 22055 urlParams = urlParams.replace("/" + hash, ''); 22056 } 22057 urlParams = 22058 urlParams[0] == '?' ? '&' + urlParams.slice(1) : urlParams || ''; 22059 // For vimeo last params gets priority if duplicates found 22060 // Uncode edit ##START## 22061 var vimeoPlayerParams = '?autoplay=0'; 22062 if ( videoInfo.autoplay !== '' ) { 22063 vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' ); 22064 vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay(&|$)'), '$1$2' ); 22065 } else { 22066 if ( typeof SiteParameters !== 'undefined' && typeof SiteParameters.vimeoPlayerParams !== 'undefined' && SiteParameters.vimeoPlayerParams !== '' ) { 22067 vimeoPlayerParams = SiteParameters.vimeoPlayerParams; 22068 } 22069 } 22070 if ( videoInfo.muted !== '' ) { 22071 vimeoPlayerParams += '&muted=' + (videoInfo.muted === 'yes'); 22072 } else { 22073 if ( urlParams.indexOf('muted=') < 0 && vimeoPlayerParams.indexOf('muted=') < 0 ) { 22074 vimeoPlayerParams += '&muted=1'; 22075 } 22076 } 22077 // var vimeoPlayerParams = "?autoplay=0&muted=1" + (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 22078 vimeoPlayerParams += (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 22079 // Uncode edit ##END## 22080 return vimeoPlayerParams; 22081 }; 22082 22083 /** 22084 * Video module for lightGallery 22085 * Supports HTML5, YouTube, Vimeo, wistia videos 22086 * 22087 * 22088 * @ref Wistia 22089 * https://wistia.com/support/integrations/wordpress(How to get url) 22090 * https://wistia.com/support/developers/embed-options#using-embed-options 22091 * https://wistia.com/support/developers/player-api 22092 * https://wistia.com/support/developers/construct-an-embed-code 22093 * http://jsfiddle.net/xvnm7xLm/ 22094 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video 22095 * https://wistia.com/support/embed-and-share/sharing-videos 22096 * https://private-sharing.wistia.com/medias/mwhrulrucj 22097 * 22098 * @ref Youtube 22099 * https://developers.google.com/youtube/player_parameters#enablejsapi 22100 * https://developers.google.com/youtube/iframe_api_reference 22101 * https://developer.chrome.com/blog/autoplay/#iframe-delegation 22102 * 22103 * @ref Vimeo 22104 * https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url 22105 * https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode 22106 * https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters 22107 */ 22108 var Video = /** @class */ (function () { 22109 function Video(instance) { 22110 // get lightGallery core plugin instance 22111 this.core = instance; 22112 this.settings = __assign(__assign({}, videoSettings), this.core.settings); 22113 return this; 22114 } 22115 Video.prototype.init = function () { 22116 var _this = this; 22117 /** 22118 * Event triggered when video url found without poster 22119 * Append video HTML 22120 * Play if autoplayFirstVideo is true 22121 */ 22122 this.core.LGel.on(lGEvents.hasVideo + ".video", this.onHasVideo.bind(this)); 22123 this.core.LGel.on(lGEvents.posterClick + ".video", function () { 22124 var $el = _this.core.getSlideItem(_this.core.index); 22125 _this.loadVideoOnPosterClick($el); 22126 }); 22127 this.core.LGel.on(lGEvents.slideItemLoad + ".video", this.onSlideItemLoad.bind(this)); 22128 // @desc fired immediately before each slide transition. 22129 this.core.LGel.on(lGEvents.beforeSlide + ".video", this.onBeforeSlide.bind(this)); 22130 // @desc fired immediately after each slide transition. 22131 this.core.LGel.on(lGEvents.afterSlide + ".video", this.onAfterSlide.bind(this)); 22132 }; 22133 /** 22134 * @desc Event triggered when a slide is completely loaded 22135 * 22136 * @param {Event} event - lightGalley custom event 22137 */ 22138 Video.prototype.onSlideItemLoad = function (event) { 22139 var _this = this; 22140 var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index; 22141 // Should check the active slide as well as user may have moved to different slide before the first slide is loaded 22142 if (this.settings.autoplayFirstVideo && 22143 isFirstSlide && 22144 index === this.core.index) { 22145 // Delay is just for the transition effect on video load 22146 setTimeout(function () { 22147 _this.loadAndPlayVideo(index); 22148 }, 200); 22149 } 22150 // Should not call on first slide. should check only if the slide is active 22151 if (!isFirstSlide && 22152 this.settings.autoplayVideoOnSlide && 22153 index === this.core.index) { 22154 setTimeout(function () { 22155 _this.loadAndPlayVideo(index); 22156 }, 500); 22157 } 22158 }; 22159 /** 22160 * @desc Event triggered when video url or poster found 22161 * Append video HTML is poster is not given 22162 * Play if autoplayFirstVideo is true 22163 * 22164 * @param {Event} event - Javascript Event object. 22165 */ 22166 Video.prototype.onHasVideo = function (event) { 22167 var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster; 22168 if (!hasPoster) { 22169 // All functions are called separately if poster exist in loadVideoOnPosterClick function 22170 this.appendVideos(this.core.getSlideItem(index), { 22171 src: src, 22172 addClass: 'lg-object', 22173 index: index, 22174 html5Video: html5Video, 22175 // Uncode edit ##START## 22176 autoplay: event.target.getAttribute('data-lb-autoplay'), 22177 muted: event.target.getAttribute('data-lb-muted'), 22178 // Uncode edit ##END## 22179 }); 22180 // Automatically navigate to next slide once video reaches the end. 22181 this.gotoNextSlideOnVideoEnd(src, index); 22182 } 22183 }; 22184 /** 22185 * @desc fired immediately before each slide transition. 22186 * Pause the previous video 22187 * Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos. 22188 * 22189 * @param {Event} event - Javascript Event object. 22190 * @param {number} prevIndex - Previous index of the slide. 22191 * @param {number} index - Current index of the slide 22192 */ 22193 Video.prototype.onBeforeSlide = function (event) { 22194 if (this.core.lGalleryOn) { 22195 var prevIndex = event.detail.prevIndex; 22196 this.pauseVideo(prevIndex); 22197 } 22198 // Uncode edit ##START## 22199 var _a = event.detail, index = _a.index; 22200 var $slide = this.core.getSlideItem(index); 22201
22202 var iframe = $slide.selector.querySelector('iframe'); 22203 if ( iframe != null ) { 22204 22205 var data_play = iframe.getAttribute('data-autoplay'); 22206 if ( typeof data_play !== 'undefined' && data_play === '1' ) { 22207 this.loadAndPlayVideo(index); 22208 22209 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}, 22210 $videoElement = this.core.getSlideItem(index).find('.lg-video-object').first(); 22211 if (videoInfo.vimeo) { 22212 var vimeoPlayer = new Vimeo.Player($videoElement.get()); 22213 vimeoPlayer.on('play', function () { 22214 vimeoPlayer.setCurrentTime(0); 22215 }); 22216 } else if ( videoInfo.youtube ) { 22217 try { 22218 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"seekTo\",\"args\":[0, true]}", '*'); 22219 } 22220 catch (e) { 22221 console.warn(e); 22222 } 22223 } 22224 } 22225 } 22226 // Uncode edit ##END## 22227 }; 22228 /** 22229 * @desc fired immediately after each slide transition. 22230 * Play video if autoplayVideoOnSlide option is enabled. 22231 * 22232 * @param {Event} event - Javascript Event object. 22233 * @param {number} prevIndex - Previous index of the slide. 22234 * @param {number} index - Current index of the slide 22235 * @todo should check on onSlideLoad as well if video is not loaded on after slide 22236 */ 22237 Video.prototype.onAfterSlide = function (event) { 22238 var _this = this; 22239 var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex; 22240 // Do not call on first slide 22241 var $slide = this.core.getSlideItem(index); 22242 if (this.settings.autoplayVideoOnSlide && index !== prevIndex) { 22243 if ($slide.hasClass('lg-complete')) { 22244 setTimeout(function () { 22245 _this.loadAndPlayVideo(index); 22246 }, 100); 22247 } 22248 } 22249 }; 22250 Video.prototype.loadAndPlayVideo = function (index) { 22251 var $slide = this.core.getSlideItem(index); 22252 var currentGalleryItem = this.core.galleryItems[index]; 22253 if (currentGalleryItem.poster) { 22254 this.loadVideoOnPosterClick($slide, true); 22255 } 22256 else { 22257 //Uncode edit ##START## 22258 // this.playVideo(index); 22259 var iframe = $slide.selector.querySelector('iframe'); 22260 if ( iframe != null ) { 22261 var data_play = iframe.getAttribute('data-autoplay'); 22262 if ( typeof data_play !== 'undefined' ) { 22263 if ( data_play === '1' && this.core.index == index ) { 22264 this.playVideo(index); 22265 } else { 22266 this.pauseVideo(index); 22267 } 22268 } 22269 } 22270 //Uncode edit ##END## 22271 } 22272 }; 22273 /** 22274 * Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 22275 * @param {number} index - Index of the slide 22276 */ 22277 Video.prototype.playVideo = function (index) { 22278 this.controlVideo(index, 'play'); 22279 }; 22280 /** 22281 * Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 22282 * @param {number} index - Index of the slide 22283 */ 22284 Video.prototype.pauseVideo = function (index) { 22285 this.controlVideo(index, 'pause'); 22286 }; 22287 // Uncode edit ##START## 22288 //Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) { 22289 Video.prototype.getVideoHtml = function (src, addClass, index, html5Video, autoplay, muted) { 22290 // Uncode edit ##END## 22291 var video = ''; 22292 var videoInfo = this.core.galleryItems[index] 22293 .__slideVideoInfo || {}; 22294 var currentGalleryItem = this.core.galleryItems[index]; 22295 var videoTitle = currentGalleryItem.title || currentGalleryItem.alt; 22296 videoTitle = videoTitle ? 'title="' + videoTitle + '"' : ''; 22297 var commonIframeProps = "allowtransparency=\"true\"\n frameborder=\"0\"\n scrolling=\"no\"\n allowfullscreen\n mozallowfullscreen\n webkitallowfullscreen\n oallowfullscreen\n msallowfullscreen"; 22298 if (videoInfo.youtube) { 22299 var videoId = 'lg-youtube' + index; 22300 var slideUrlParams = videoInfo.youtube[2] 22301 ? videoInfo.youtube[2] + '&' 22302 : ''; 22303 // For youtube first parms gets priority if duplicates found 22304 // Uncode edit ##START## 22305 // var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&autoplay=0&mute=1&enablejsapi=1"; 22306 var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&enablejsapi=1"; 22307 if ( ( slideUrlParams.indexOf('autoplay=') < 0 && youTubePlayerParams.indexOf('autoplay=') < 0 ) ) { 22308 youTubePlayerParams += '&autoplay=0'; 22309 } 22310 if ( slideUrlParams.indexOf('mute=') < 0 && youTubePlayerParams.indexOf('mute=') < 0 ) { 22311 youTubePlayerParams += '&mute=1'; 22312 } 22313 var data_video = ''; 22314 if ( autoplay !== '' ) { 22315 //youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1autoplay=' + (autoplay === 'yes' ? 1 : 0) + '$3' ); 22316 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' ); 22317 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay'), '$1' ); 22318 data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"'; 22319 } 22320 // if ( muted !== '' ) { 22321 // youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1mute=' + (muted === 'yes' ? 1 : 0) + '$3' ); 22322 // } 22323 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1$3' ); 22324 22325 youTubePlayerParams = youTubePlayerParams.replace('??', '?'); 22326 // Uncode edit ##END## 22327 var playerParams = youTubePlayerParams + 22328 (this.settings.youTubePlayerParams 22329 ? '&' + param(this.settings.youTubePlayerParams) 22330 : ''); 22331 // Uncode edit ##START## 22332 // 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>"; 22333 var nocookie = typeof SiteParameters.uncode_nocookie !== 'undefined' ? SiteParameters.uncode_nocookie : ''; 22334 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>"; 22335 var tag = document.createElement('script'); 22336 tag.src = "//www.youtube.com/player_api"; 22337 var firstScriptTag = document.getElementsByTagName('script')[0]; 22338 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 22339 22340 // Replace the 'ytplayer' element with an <iframe> and 22341 // YouTube player after the API code downloads. 22342 var ytIframeplayer, 22343 setMute = muted === 'yes' ? 0 : 100; 22344 window.onYouTubePlayerAPIReady = function() { 22345 ytIframeplayer = new YT.Player(videoId, { 22346 videoId: videoInfo.youtube[1], 22347 events: { 22348 'onReady': function (event) { 22349 event.target.setVolume(setMute); 22350 } 22351 } 22352 }); 22353 } 22354 // Uncode edit ##END## 22355 } 22356 else if (videoInfo.vimeo) { 22357 var videoId = 'lg-vimeo' + index; 22358 // Uncode edit ##START## 22359 videoInfo.autoplay = autoplay; 22360 videoInfo.muted = muted; 22361 // Uncode edit ##END## 22362 var playerParams = getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo); 22363 // Uncode edit ##START## 22364 // 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>"; 22365 var data_video = ''; 22366 if ( autoplay !== '' ) { 22367 data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"'; 22368 } 22369 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>"; 22370 // Uncode edit ##END## 22371 } 22372 else if (videoInfo.wistia) { 22373 var wistiaId = 'lg-wistia' + index; 22374 var playerParams = param(this.settings.wistiaPlayerParams); 22375 playerParams = playerParams ? '?' + playerParams : ''; 22376 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>"; 22377 } 22378 else if (videoInfo.html5) { 22379 var html5VideoMarkup = ''; 22380 for (var i = 0; i < html5Video.source.length; i++) { 22381 html5VideoMarkup += "<source src=\"" + html5Video.source[i].src + "\" type=\"" + html5Video.source[i].type + "\">"; 22382 } 22383 if (html5Video.tracks) { 22384 var _loop_1 = function (i) { 22385 var trackAttributes = ''; 22386 var track = html5Video.tracks[i]; 22387 Object.keys(track || {}
22387).forEach(function (key) { 22388 trackAttributes += key + "=\"" + track[key] + "\" "; 22389 }); 22390 html5VideoMarkup += "<track " + trackAttributes + ">"; 22391 }; 22392 for (var i = 0; i < html5Video.tracks.length; i++) { 22393 _loop_1(i); 22394 } 22395 } 22396 var html5VideoAttrs_1 = ''; 22397 var videoAttributes_1 = html5Video.attributes || {}; 22398 Object.keys(videoAttributes_1 || {}).forEach(function (key) { 22399 html5VideoAttrs_1 += key + "=\"" + videoAttributes_1[key] + "\" "; 22400 }); 22401 video = "<video class=\"lg-video-object lg-html5 " + (this.settings.videojs && this.settings.videojsTheme 22402 ? this.settings.videojsTheme + ' ' 22403 : '') + " " + (this.settings.videojs ? ' video-js' : '') + "\" " + html5VideoAttrs_1 + ">\n " + html5VideoMarkup + "\n Your browser does not support HTML5 video.\n </video>"; 22404 } 22405 return video; 22406 }; 22407 /** 22408 * @desc - Append videos to the slide 22409 * 22410 * @param {HTMLElement} el - slide element 22411 * @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo 22412 */ 22413 Video.prototype.appendVideos = function (el, videoParams) { 22414 var _a; 22415 // Uncode edit ##START## 22416 // var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video); 22417 var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video, videoParams.autoplay, videoParams.muted); 22418 // Uncode edit ##END## 22419 el.find('.lg-video-cont').append(videoHtml); 22420 var $videoElement = el.find('.lg-video-object').first(); 22421 if (videoParams.html5Video) { 22422 $videoElement.on('mousedown.lg.video', function (e) { 22423 e.stopPropagation(); 22424 }); 22425 } 22426 if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) { 22427 try { 22428 return videojs($videoElement.get(), this.settings.videojsOptions); 22429 } 22430 catch (e) { 22431 console.warn('lightGallery:- Make sure you have included videojs'); 22432 } 22433 } 22434 }; 22435 Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) { 22436 var _this = this; 22437 var $videoElement = this.core 22438 .getSlideItem(index) 22439 .find('.lg-video-object') 22440 .first(); 22441 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 22442 if (this.settings.gotoNextSlideOnVideoEnd) { 22443 if (videoInfo.html5) { 22444 $videoElement.on('ended', function () { 22445 _this.core.goToNextSlide(); 22446 }); 22447 } 22448 else if (videoInfo.vimeo) { 22449 try { 22450 // https://github.com/vimeo/player.js/#ended 22451 new Vimeo.Player($videoElement.get()).on('ended', function () { 22452 _this.core.goToNextSlide(); 22453 }); 22454 } 22455 catch (e) { 22456 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 22457 } 22458 } 22459 else if (videoInfo.wistia) { 22460 try { 22461 window._wq = window._wq || []; 22462 // @todo Event is gettign triggered multiple times 22463 window._wq.push({ 22464 id: $videoElement.attr('id'), 22465 onReady: function (video) { 22466 video.bind('end', function () { 22467 _this.core.goToNextSlide(); 22468 }); 22469 }, 22470 }); 22471 } 22472 catch (e) { 22473 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 22474 } 22475 } 22476 } 22477 }; 22478 Video.prototype.controlVideo = function (index, action) { 22479 var $videoElement = this.core 22480 .getSlideItem(index) 22481 .find('.lg-video-object') 22482 .first(); 22483 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 22484 if (!$videoElement.get()) 22485 return; 22486 if (videoInfo.youtube) { 22487 try { 22488 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"" + action + "Video\",\"args\":\"\"}", '*'); 22489 } 22490 catch (e) { 22491 console.warn("lightGallery:- " + e); 22492 } 22493 } 22494 else if (videoInfo.vimeo) { 22495 try { 22496 new Vimeo.Player($videoElement.get())[action](); 22497 } 22498 catch (e) { 22499 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 22500 } 22501 } 22502 else if (videoInfo.html5) { 22503 if (this.settings.videojs) { 22504 try { 22505 videojs($videoElement.get())[action](); 22506 } 22507 catch (e) { 22508 console.warn('lightGallery:- Make sure you have included videojs'); 22509 } 22510 } 22511 else { 22512 $videoElement.get()[action](); 22513 } 22514 } 22515 else if (videoInfo.wistia) { 22516 try { 22517 window._wq = window._wq || []; 22518 // @todo Find a way to destroy wistia player instance 22519 window._wq.push({ 22520 id: $videoElement.attr('id'), 22521 onReady: function (video) { 22522 video[action](); 22523 }, 22524 }); 22525 } 22526 catch (e) { 22527 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 22528 } 22529 } 22530 }; 22531 Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) { 22532 var _this = this; 22533 // check slide has poster 22534 if (!$el.hasClass('lg-video-loaded')) { 22535 // check already video element present
22536 if (!$el.hasClass('lg-has-video')) { 22537 $el.addClass('lg-has-video'); 22538 var _html = void 0; 22539 var _src = this.core.galleryItems[this.core.index].src; 22540 var video = this.core.galleryItems[this.core.index].video; 22541 if (video) { 22542 _html = 22543 typeof video === 'string' ? JSON.parse(video) : video; 22544 } 22545 var videoJsPlayer_1 = this.appendVideos($el, { 22546 src: _src, 22547 addClass: '', 22548 index: this.core.index, 22549 html5Video: _html, 22550 }); 22551 this.gotoNextSlideOnVideoEnd(_src, this.core.index); 22552 var $tempImg = $el.find('.lg-object').first().get(); 22553 // @todo make sure it is working 22554 $el.find('.lg-video-cont').first().append($tempImg); 22555 $el.addClass('lg-video-loading'); 22556 videoJsPlayer_1 && 22557 videoJsPlayer_1.ready(function () { 22558 videoJsPlayer_1.on('loadedmetadata', function () { 22559 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 22560 }); 22561 }); 22562 $el.find('.lg-video-object') 22563 .first() 22564 .on('load.lg error.lg loadedmetadata.lg', function () { 22565 setTimeout(function () { 22566 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 22567 }, 50); 22568 }); 22569 } 22570 else { 22571 this.playVideo(this.core.index); 22572 } 22573 } 22574 else if (forcePlay) { 22575 this.playVideo(this.core.index); 22576 } 22577 }; 22578 Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) { 22579 $el.addClass('lg-video-loaded'); 22580 this.playVideo(index); 22581 }; 22582 Video.prototype.destroy = function () { 22583 this.core.LGel.off('.lg.video'); 22584 this.core.LGel.off('.video'); 22585 }; 22586 return Video; 22587 }()); 22588 22589 return Video; 22590 22591}))); 22592 22593 22594/*! @vimeo/player v2.17.1 | (c) 2022 Vimeo | MIT License | https://github.com/vimeo/player.js */ 22595!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:{}}
22595),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 22595
22595var 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)}
22595},{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 22595-23802
22595))}(),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}); 22596 22597/** 22598 * Owl carousel 22599 * @version 2.0.0-beta.3 22600 * @author Bartosz Wojciechowski 22601 * @license The MIT License (MIT) 22602 * @todo Lazy Load Icon 22603 * @todo prevent animationend bubling 22604 * @todo itemsScaleUp 22605 * @todo Test Zepto 22606 * @todo stagePadding calculate wrong active classes 22607 */ 22608;(function($, window, document, undefined) { 22609 22610 /** 22611 * Creates a carousel. 22612 * @class The Owl Carousel. 22613 * @public 22614 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 22615 * @param {Object} [options] - The options 22616 */ 22617 function Owl(element, options) { 22618 22619 /** 22620 * Current settings for the carousel. 22621 * @public 22622 */ 22623 this.settings = null; 22624 22625 /** 22626 * Current options set by the caller including defaults. 22627 * @public 22628 */ 22629 this.options = $.extend({}, Owl.Defaults, options); 22630 22631 /** 22632 * Plugin element. 22633 * @public 22634 */ 22635 this.$element = $(element); 22636 22637 /** 22638 * Proxied event handlers. 22639 * @protected 22640 */ 22641 this._handlers = {}; 22642 22643 /** 22644 * References to the running plugins of this carousel. 22645 * @protected 22646 */ 22647 this._plugins = {}; 22648 22649 /** 22650 * Currently suppressed events to prevent them from beeing retriggered. 22651 * @protected 22652 */ 22653 this._supress = {}; 22654 22655 /** 22656 * Absolute current position. 22657 * @protected 22658 */ 22659 this._current = null; 22660 22661 /** 22662 * Animation speed in milliseconds. 22663 * @protected 22664 */ 22665 this._speed = null; 22666 22667 /** 22668 * Coordinates of all items in pixel. 22669 * @todo The name of this member is missleading. 22670 * @protected 22671 */ 22672 this._coordinates = []; 22673 22674 /** 22675 * Current breakpoint. 22676 * @todo Real media queries would be nice. 22677 * @protected 22678 */ 22679 this._breakpoint = null; 22680 22681 /** 22682 * Current width of the plugin element. 22683 */ 22684 this._width = null; 22685 22686 /** 22687 * All real items. 22688 * @protected 22689 */ 22690 this._items = []; 22691 22692 /** 22693 * All cloned items. 22694 * @protected 22695 */ 22696 this._clones = []; 22697 22698 /** 22699 * Merge values of all items. 22700 * @todo Maybe this could be part of a plugin. 22701 * @protected 22702 */ 22703 this._mergers = []; 22704 22705 /** 22706 * Widths of all items. 22707 */ 22708 this._widths = []; 22709 22710 /** 22711 * Invalidated parts within the update process. 22712 * @protected 22713 */ 22714 this._invalidated = {}; 22715 22716 /** 22717 * Ordered list of workers for the update process. 22718 * @protected 22719 */ 22720 this._pipe = []; 22721 22722 /** 22723 * Current state information for the drag operation. 22724 * @todo #261 22725 * @protected 22726 */ 22727 this._drag = { 22728 time: null, 22729 target: null, 22730 pointer: null, 22731 stage: { 22732 start: null, 22733 current: null 22734 }, 22735 direction: null 22736 }; 22737 22738 /** 22739 * Current state information and their tags. 22740 * @type {Object} 22741 * @protected 22742 */ 22743 this._states = { 22744 current: {}, 22745 tags: { 22746 'initializing': [ 'busy' ], 22747 'animating': [ 'busy' ], 22748 'dragging': [ 'interacting' ] 22749 } 22750 }; 22751 22752 $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { 22753 this._handlers[handler] = $.proxy(this[handler], this); 22754 }, this)); 22755 22756 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 22757 this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] 22758 = new plugin(this); 22759 }, this)); 22760 22761 $.each(Owl.Workers, $.proxy(function(priority, worker) { 22762 this._pipe.push({ 22763 'filter': worker.filter, 22764 'run': $.proxy(worker.run, this) 22765 }); 22766 }, this)); 22767 22768 this.setup(); 22769 this.initialize(); 22770 } 22771 22772 /** 22773 * Default options for the carousel. 22774 * @public 22775 */ 22776 Owl.Defaults = { 22777 items: 3, 22778 loop: false, 22779 center: false, 22780 rewind: false, 22781 22782 mouseDrag: true, 22783 touchDrag: true, 22784 pullDrag: true, 22785 freeDrag: false, 22786 22787 margin: 0, 22788 stagePadding: 0, 22789 22790 merge: false, 22791 mergeFit: true, 22792 autoWidth: false, 22793 22794 startPosition: 0, 22795 rtl: false, 22796 22797 smartSpeed: 250, 22798 fluidSpeed: false, 22799 dragEndSpeed: false, 22800 22801 responsive: {}, 22802 responsiveRefreshRate: 200, 22803 responsiveBaseElement: window, 22804 22805 fallbackEasing: 'swing', 22806 22807 info: false, 22808 22809 nestedItemSelector: false, 22810 itemElement: 'div', 22811 stageElement: 'div', 22812 22813 refreshClass: 'owl-refresh', 22814 loadedClass: 'owl-loaded', 22815 loadingClass: 'owl-loading', 22816 rtlClass: 'owl-rtl', 22817 responsiveClass: 'owl-responsive', 22818 dragClass: 'owl-drag', 22819 itemClass: 'owl-item', 22820 stageClass: 'owl-stage', 22821 stageOuterClass: 'owl-stage-outer', 22822 grabClass: 'owl-grab' 22823 }; 22824 22825 /** 22826 * Enumeration for width. 22827 * @public 22828 * @readonly 22829 * @enum {String} 22830 */ 22831 Owl.Width = { 22832 Default: 'default', 22833 Inner: 'inner', 22834 Outer: 'outer' 22835 }; 22836 22837 /** 22838 * Enumeration for types. 22839 * @public 22840 * @readonly 22841 * @enum {String} 22842 */ 22843 Owl.Type = { 22844 Event: 'event', 22845 State: 'state' 22846 }; 22847 22848 /** 22849 * Contains all registered plugins. 22850 * @public 22851 */ 22852 Owl.Plugins = {}; 22853 22854 /** 22855 * List of workers involved in the update process. 22856 */ 22857 Owl.Workers = [ { 22858 filter: [ 'width', 'settings' ], 22859 run: function() { 22860 this._width = (this.$element.closest('.px-gutter').length) ? 12 * Math.ceil(this.$element.width() / 12) : this.$element.width(); 22861 //this._width = (UNCODE.isMobile) ? this.$element.width() : 12 * Math.ceil(this.$element.width() / 12); 22862 } 22863 }, { 22864 filter: [ 'width', 'items', 'settings' ], 22865 run: function(cache) { 22866 cache.current = this._items && this._items[this.relative(this._current)]; 22867 } 22868 }, { 22869 filter: [ 'items', 'settings' ], 22870 run: function() { 22871 this.$stage.children('.cloned').remove(); 22872 } 22873 }, { 22874 filter: [ 'width', 'items', 'settings' ], 22875 run: function(cache) { 22876 var margin = this.settings.margin || '', 22877 grid = !this.settings.autoWidth, 22878 rtl = this.settings.rtl, 22879 css = { 22880 'width': 'auto', 22881 'margin-left': rtl ? margin : '', 22882 'margin-right': rtl ? '' : margin 22883 }; 22884 22885 !grid && this.$stage.children().css(css); 22886 22887 cache.css = css; 22888 } 22889 }, { 22890 filter: [ 'width', 'items', 'settings' ], 22891 run: function(cache) { 22892 //UNCODE edit to fix Chrome stage padding issue 22893 var width = Math.round((this.width() / this.settings.items).toFixed(3) - this.settings.margin), 22894 merge = null, 22895 iterator = this._items.length, 22896 grid = !this.settings.autoWidth, 22897 widths = []; 22898 22899 cache.items = { 22900 merge: false, 22901 width: width 22902 }; 22903 22904 while (iterator--) { 22905 merge = this._mergers[iterator]; 22906 merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; 22907 22908 cache.items.merge = merge > 1 || cache.items.merge; 22909 22910 widths[iterator] = !grid ? this._items[iterator].width() : width * merge; 22911 } 22912 22913 this._widths = widths; 22914 } 22915 }, { 22916 filter: [ 'items', 'settings' ], 22917 run: function() { 22918 var clones = [], 22919 items = this._items, 22920 settings = this.settings, 22921 view = Math.max(settings.items * 2, 4), 22922 size = Math.ceil(items.length / 2) * 2, 22923 repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, 22924 append = '', 22925 prepend = ''; 22926 22927 repeat /= 2; 22928 22929 while (repeat--) { 22930 clones.push(this.normalize(clones.length / 2, true)); 22931 append = append + items[clones[clones.length - 1]][0].outerHTML; 22932 clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); 22933 prepend = items[clones[clones.length - 1]][0].outerHTML + prepend; 22934 } 22935 22936 this._clones = clones; 22937 22938 // var appendVideo = $(append).find('.uncode-video-container'); 22939 // if (appendVideo.length) { 22940 // appendVideo.attr('data-id', Math.round(Math.random() * 100000)); 22941 // } 22942 // var prependVideo = $(prepend).find('.uncode-video-container'); 22943 // if (prependVideo.length) { 22944 // prependVideo.attr('data-id', Math.round(Math.random() * 100000)); 22945 // } 22946 $(append).addClass('cloned').appendTo(this.$stage); 22947 $(prepend).addClass('cloned').prependTo(this.$stage); 22948 } 22949 }, { 22950 filter: [ 'width', 'items', 'settings' ], 22951 run: function() { 22952 var rtl = this.settings.rtl ? 1 : -1, 22953 size = this._clones.length + this._items.length, 22954 iterator = -1, 22955 previous = 0, 22956 current = 0, 22957 coordinates = []; 22958 22959 while (++iterator < size) { 22960 previous = coordinates[iterator - 1] || 0; 22961 current = this._widths[this.relative(iterator)] + this.settings.margin; 22962 coordinates.push(previous + current * rtl); 22963 } 22964 22965 this._coordinates = coordinates; 22966 } 22967 }, { 22968 filter: [ 'width', 'items', 'settings' ], 22969 run: function() { 22970 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 22971 padding = stagePadding, 22972 coordinates = this._coordinates, 22973 css = { 22974 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, 22975 'padding-left': padding || '', 22976 'padding-right': padding || '' 22977 }; 22978 22979 this.$stage.css(css); 22980 } 22981 }, { 22982 filter: [ 'width', 'items', 'settings' ], 22983 run: function(cache) { 22984 var iterator = this._coordinates.length, 22985 grid = !this.settings.autoWidth, 22986 items = this.$stage.children(); 22987 22988 if (grid && cache.items.merge) { 22989 while (iterator--) { 22990 cache.css.width = this._widths[this.relative(iterator)]; 22991 items.eq(iterator).css(cache.css); 22992 } 22993 } else if (grid) { 22994 cache.css.width = cache.items.width; 22995 items.css(cache.css); 22996 } 22997 } 22998 }, { 22999 filter: [ 'items' ], 23000 run: function() { 23001 this._coordinates.length < 1 && this.$stage.removeAttr('style'); 23002 } 23003 }, { 23004 filter: [ 'width', 'items', 'settings' ], 23005 run: function(cache) { 23006 cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; 23007 cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); 23008 this.reset(cache.current); 23009 } 23010 }, { 23011 filter: [ 'position' ], 23012 run: function() { 23013 this.animate(this.coordinates(this._current)); 23014 } 23015 }, { 23016 filter: [ 'width', 'position', 'items', 'settings' ], 23017 run: function() { 23018 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 23019 rtl = this.settings.rtl ? 1 : -1, 23020 padding = this.settings.stagePadding * 2, 23021 begin = this.coordinates(this.current()) + padding, 23022 end = begin + this.width() * rtl, 23023 inner, outer, matches = [], i, n; 23024 23025 for (i = 0, n = this._coordinates.length; i < n; i++) { 23026 inner = this._coordinates[i - 1] || 0; 23027 outer = Math.abs(this._coordinates[i]) + padding * rtl; 23028 23029 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 23030 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 23031 matches.push(i); 23032 } 23033 } 23034 23035 this.$stage.children('.active').removeClass('active'); 23036 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); 23037 23038 if (this.settings.center) { 23039 this.$stage.children('.center').removeClass('center'); 23040 this.$stage.children().eq(this.current()).addClass('center'); 23041 } 23042 } 23043 } ]; 23044 23045 /** 23046 * Initializes the carousel. 23047 * @protected 23048 */ 23049 Owl.prototype.initialize = function() { 23050 this.enter('initializing'); 23051 this.trigger('initialize'); 23052 23053 this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); 23054 23055 if (this.settings.autoWidth && !this.is('pre-loading')) { 23056 var imgs, nestedSelector, width; 23057 imgs = this.$element.find('img'); 23058 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 23059 width = this.$element.children(nestedSelector).width(); 23060 23061 if (imgs.length && width <= 0) { 23062 this.preloadAutoWidthImages(imgs); 23063 } 23064 } 23065 23066 this.$element.addClass(this.options.loadingClass); 23067 23068 // create stage 23069 this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>') 23070 .wrap('<div class="' + this.settings.stageOuterClass + '"/>'); 23071 23072 // append stage 23073 this.$element.append(this.$stage.parent()); 23074 23075 // append content 23076 this.replace(this.$element.children().not(this.$stage.parent())); 23077 23078 // check visibility 23079 if (this.$element.is(':visible')) { 23080 // update view 23081 this.refresh(); 23082 } else { 23083 // invalidate width 23084 this.invalidate('width'); 23085 } 23086 23087 this.$element 23088 .removeClass(this.options.loadingClass) 23089 .addClass(this.options.loadedClass); 23090 23091 // register event handlers 23092 this.registerEventHandlers(); 23093 23094 this.leave('initializing'); 23095 this.trigger('initialized'); 23096 }; 23097 23098 /** 23099 * Setups the current settings. 23100 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 23101 * @todo Support for media queries by using `matchMedia` would be nice. 23102 * @public 23103 */ 23104 Owl.prototype.setup = function() { 23105 var viewport = this.viewport(), 23106 overwrites = this.options.responsive, 23107 match = -1, 23108 settings = null; 23109 23110 if (!overwrites) { 23111 settings = $.extend({}, this.options); 23112 } else { 23113 $.each(overwrites, function(breakpoint) { 23114 if (breakpoint <= viewport && breakpoint > match) { 23115 match = Number(breakpoint); 23116 } 23117 }); 23118 23119 settings = $.extend({}, this.options, overwrites[match]); 23120 delete settings.responsive; 23121 23122 // responsive class 23123 if (settings.responsiveClass) { 23124 this.$element.attr('class', 23125 this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) 23126 ); 23127 } 23128 } 23129 23130 if (this.settings === null || this._breakpoint !== match) { 23131 this.trigger('change', { property: { name: 'settings', value: settings } }); 23132 this._breakpoint = match; 23133 this.settings = settings; 23134 this.invalidate('settings'); 23135 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 23136 } 23137 }; 23138 23139 /** 23140 * Updates option logic if necessery. 23141 * @protected 23142 */ 23143 Owl.prototype.optionsLogic = function() { 23144 if (this.settings.autoWidth) { 23145 this.settings.stagePadding = false; 23146 this.settings.merge = false; 23147 } 23148 }; 23149 23150 /** 23151 * Prepares an item before add. 23152 * @todo Rename event parameter `content` to `item`. 23153 * @protected 23154 * @returns {jQuery|HTMLElement} - The item container. 23155 */ 23156 Owl.prototype.prepare = function(item, index) { 23157 var event = this.trigger('prepare', { content: item }); 23158 if (!event.data) { 23159 event.data = $('<' + this.settings.itemElement + '/>') 23160 .addClass(this.options.itemClass).attr('data-index', index + 1).append(item) 23161 } 23162 23163 this.trigger('prepared', { content: event.data }); 23164 23165 return event.data; 23166 }; 23167 23168 /** 23169 * Updates the view. 23170 * @public 23171 */ 23172 Owl.prototype.update = function() { 23173 var i = 0, 23174 n = this._pipe.length, 23175 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 23176 cache = {}; 23177 23178 while (i < n) { 23179 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 23180 this._pipe[i].run(cache); 23181 } 23182 i++; 23183 } 23184 23185 this._invalidated = {}; 23186 23187 !this.is('valid') && this.enter('valid'); 23188 }; 23189 23190 /** 23191 * Gets the width of the view. 23192 * @public 23193 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 23194 * @returns {Number} - The width of the view in pixel. 23195 */ 23196 Owl.prototype.width = function(dimension) { 23197 dimension = dimension || Owl.Width.Default; 23198 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200; 23199 switch (dimension) { 23200 case Owl.Width.Inner: 23201 case Owl.Width.Outer: 23202 return this._width; 23203 default: 23204 return this._width - stagePadding * 2 + this.settings.margin; 23205 } 23206 }; 23207 23208 /** 23209 * Refreshes the carousel primarily for adaptive purposes. 23210 * @public 23211 */ 23212 Owl.prototype.refresh = function() { 23213 this.enter('refreshing'); 23214 this.trigger('refresh'); 23215 23216 this.setup(); 23217 23218 this.optionsLogic(); 23219 23220 this.$element.addClass(this.options.refreshClass); 23221 23222 this.update(); 23223 23224 this.$element.removeClass(this.options.refreshClass); 23225 23226 this.leave('refreshing'); 23227 this.trigger('refreshed'); 23228 }; 23229 23230 /** 23231 * Checks window `resize` event. 23232 * @protected 23233 */ 23234 Owl.prototype.onThrottledResize = function() { 23235 window.clearTimeout(this.resizeTimer); 23236 this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); 23237 }; 23238 23239 /** 23240 * Checks window `resize` event. 23241 * @protected 23242 */ 23243 Owl.prototype.onResize = function() { 23244 if (!this._items.length) { 23245 return false; 23246 } 23247 23248 if (this._width === this.$element.width()) { 23249 return false; 23250 } 23251 23252 if (!this.$element.is(':visible')) { 23253 return false; 23254 } 23255 23256 this.enter('resizing'); 23257 23258 if (this.trigger('resize').isDefaultPrevented()) { 23259 this.leave('resizing'); 23260 return false; 23261 } 23262 23263 this.invalidate('width'); 23264 23265 this.refresh(); 23266 23267 this.leave('resizing'); 23268 this.trigger('resized'); 23269 }; 23270 23271 /** 23272 * Registers event handlers. 23273 * @todo Check `msPointerEnabled` 23274 * @todo #261 23275 * @protected 23276 */ 23277 Owl.prototype.registerEventHandlers = function() { 23278 if ($.support.transition) { 23279 this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); 23280 } 23281 23282 if (this.settings.responsive !== false) { 23283 this.on(window, 'resize', this._handlers.onThrottledResize); 23284 } 23285 23286 if (this.settings.mouseDrag) { 23287 this.$element.addClass(this.options.dragClass); 23288 this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); 23289 this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); 23290 } 23291 23292 if (this.settings.touchDrag){ 23293 this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); 23294 this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); 23295 } 23296 }; 23297 23298 /** 23299 * Handles `touchstart` and `mousedown` events. 23300 * @todo Horizontal swipe threshold as option 23301 * @todo #261 23302 * @protected 23303 * @param {Event} event - The event arguments. 23304 */ 23305 Owl.prototype.onDragStart = function(event) { 23306 var stage = null; 23307 23308 if (event.which === 3) { 23309 return; 23310 } 23311 23312 if ($.support.transform) { 23313 stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); 23314 stage = { 23315 x: stage[stage.length === 16 ? 12 : 4], 23316 y: stage[stage.length === 16 ? 13 : 5] 23317 }; 23318 } else { 23319 stage = this.$stage.position(); 23320 stage = { 23321 x: this.settings.rtl ? 23322 stage.left + this.$stage.width() - this.width() + this.settings.margin : 23323 stage.left, 23324 y: stage.top 23325 }; 23326 } 23327 23328 if (this.is('animating')) { 23329 $.support.transform ? this.animate(stage.x) : this.$stage.stop() 23330 this.invalidate('position'); 23331 } 23332 23333 this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); 23334 23335 this.speed(0); 23336 23337 this._drag.time = new Date().getTime(); 23338 this._drag.target = $(event.target); 23339 this._drag.stage.start = stage; 23340 this._drag.stage.current = stage; 23341 this._drag.pointer = this.pointer(event); 23342 23343 $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); 23344 23345 $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { 23346 var delta = this.difference(this._drag.pointer, this.pointer(event)); 23347 23348 $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); 23349 23350 if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { 23351 return; 23352 } 23353 23354 event.preventDefault(); 23355 23356 this.enter('dragging'); 23357 this.trigger('drag'); 23358 }, this)); 23359 }; 23360 23361 /** 23362 * Handles the `touchmove` and `mousemove` events. 23363 * @todo #261 23364 * @protected 23365 * @param {Event} event - The event arguments. 23366 */ 23367 Owl.prototype.onDragMove = function(event) { 23368 var minimum = null, 23369 maximum = null, 23370 pull = null, 23371 delta = this.difference(this._drag.pointer, this.pointer(event)), 23372 stage = this.difference(this._drag.stage.start, delta); 23373 23374 if (!this.is('dragging')) { 23375 return; 23376 } 23377 23378 event.preventDefault(); 23379 23380 if (this.settings.loop) { 23381 minimum = this.coordinates(this.minimum()); 23382 maximum = this.coordinates(this.maximum() + 1) - minimum; 23383 stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; 23384 } else { 23385 minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 23386 maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 23387 pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; 23388 stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); 23389 } 23390 23391 this._drag.stage.current = stage; 23392 23393 this.animate(stage.x); 23394 }; 23395 23396 /** 23397 * Handles the `touchend` and `mouseup` events. 23398 * @todo #261 23399 * @todo Threshold for click event 23400 * @protected 23401 * @param {Event} event - The event arguments. 23402 */ 23403 Owl.prototype.onDragEnd = function(event) { 23404 var delta = this.difference(this._drag.pointer, this.pointer(event)), 23405 stage = this._drag.stage.current, 23406 direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; 23407 23408 $(document).off('.owl.core'); 23409 23410 this.$element.removeClass(this.options.grabClass); 23411 23412 if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { 23413 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 23414 this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); 23415 this.invalidate('position'); 23416 this.update(); 23417 23418 this._drag.direction = direction; 23419 23420 if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { 23421 this._drag.target.one('click.owl.core', function() { return false; }); 23422 } 23423 } 23424 23425 if (!this.is('dragging')) { 23426 return; 23427 } 23428 23429 this.leave('dragging'); 23430 this.trigger('dragged'); 23431 }; 23432 23433 /** 23434 * Gets absolute position of the closest item for a coordinate. 23435 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 23436 * @protected 23437 * @param {Number} coordinate - The coordinate in pixel. 23438 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. 23439 * @return {Number} - The absolute position of the closest item. 23440 */ 23441 Owl.prototype.closest = function(coordinate, direction) { 23442 var position = -1, 23443 pull = 30, 23444 width = this.width(), 23445 coordinates = this.coordinates(); 23446 23447 if (!this.settings.freeDrag) { 23448 // check closest item 23449 $.each(coordinates, $.proxy(function(index, value) { 23450 if (coordinate > value - pull && coordinate < value + pull) { 23451 position = index; 23452 } else if (this.op(coordinate, '<', value) 23453 && this.op(coordinate, '>', coordinates[index + 1] || value - width)) { 23454 position = direction === 'left' ? index + 1 : index; 23455 } 23456 return position === -1; 23457 }, this)); 23458 } 23459 23460 if (!this.settings.loop) { 23461 // non loop boundries 23462 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 23463 position = coordinate = this.minimum(); 23464 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 23465 position = coordinate = this.maximum(); 23466 } 23467 } 23468 23469 return position; 23470 }; 23471 23472 /** 23473 * Animates the stage. 23474 * @todo #270 23475 * @public 23476 * @param {Number} coordinate - The coordinate in pixels. 23477 */ 23478 Owl.prototype.animate = function(coordinate) { 23479 var animate = this.speed() > 0; 23480 23481 this.is('animating') && this.onTransitionEnd(); 23482 23483 if (animate) { 23484 this.enter('animating'); 23485 this.trigger('translate'); 23486 } 23487 23488 if ($.support.transform3d && $.support.transition) { 23489 this.$stage.css({ 23490 transform: 'translate3d(' + coordinate + 'px,0px,0px)', 23491 transition: (this.speed() / 1000) + 's' 23492 }); 23493 } else if (animate) { 23494 this.$stage.animate({ 23495 left: coordinate + 'px' 23496 }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); 23497 } else { 23498 this.$stage.css({ 23499 left: coordinate + 'px' 23500 }); 23501 } 23502 }; 23503 23504 /** 23505 * Checks whether the carousel is in a specific state or not. 23506 * @param {String} state - The state to check. 23507 * @returns {Boolean} - The flag which indicates if the carousel is busy. 23508 */ 23509 Owl.prototype.is = function(state) { 23510 return this._states.current[state] && this._states.current[state] > 0; 23511 }; 23512 23513 /** 23514 * Sets the absolute position of the current item. 23515 * @public 23516 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 23517 * @returns {Number} - The absolute position of the current item. 23518 */ 23519 Owl.prototype.current = function(position) { 23520 if (position === undefined) { 23521 return this._current; 23522 } 23523 23524 if (this._items.length === 0) { 23525 return undefined; 23526 } 23527 23528 position = this.normalize(position); 23529 23530 if (this._current !== position) { 23531 var event = this.trigger('change', { property: { name: 'position', value: position } }); 23532 23533 if (event.data !== undefined) { 23534 position = this.normalize(event.data); 23535 } 23536 23537 this._current = position; 23538 23539 this.invalidate('position'); 23540 23541 this.trigger('changed', { property: { name: 'position', value: this._current } }); 23542 } 23543 23544 return this._current; 23545 }; 23546 23547 /** 23548 * Invalidates the given part of the update routine. 23549 * @param {String} [part] - The part to invalidate. 23550 * @returns {Array.<String>} - The invalidated parts. 23551 */ 23552 Owl.prototype.invalidate = function(part) { 23553 if ($.type(part) === 'string') { 23554 this._invalidated[part] = true; 23555 this.is('valid') && this.leave('valid'); 23556 } 23557 return $.map(this._invalidated, function(v, i) { return i }); 23558 }; 23559 23560 /** 23561 * Resets the absolute position of the current item. 23562 * @public 23563 * @param {Number} position - The absolute position of the new item. 23564 */ 23565 Owl.prototype.reset = function(position) { 23566 position = this.normalize(position); 23567 23568 if (position === undefined) { 23569 return; 23570 } 23571 23572 this._speed = 0; 23573 this._current = position; 23574 23575 this.suppress([ 'translate', 'translated' ]); 23576 23577 this.animate(this.coordinates(position)); 23578 23579 this.release([ 'translate', 'translated' ]); 23580 }; 23581 23582 /** 23583 * Normalizes an absolute or a relative position of an item. 23584 * @public 23585 * @param {Number} position - The absolute or relative position to normalize. 23586 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 23587 * @returns {Number} - The normalized position. 23588 */ 23589 Owl.prototype.normalize = function(position, relative) { 23590 var n = this._items.length, 23591 m = relative ? 0 : this._clones.length; 23592 23593 if (!$.isNumeric(position) || n < 1) { 23594 position = undefined; 23595 } else if (position < 0 || position >= n + m) { 23596 position = ((position - m / 2) % n + n) % n + m / 2; 23597 } 23598 23599 return position; 23600 }; 23601 23602 /** 23603 * Converts an absolute position of an item into a relative one. 23604 * @public 23605 * @param {Number} position - The absolute position to convert. 23606 * @returns {Number} - The converted position. 23607 */ 23608 Owl.prototype.relative = function(position) { 23609 position -= this._clones.length / 2; 23610 return this.normalize(position, true); 23611 }; 23612 23613 /** 23614 * Gets the maximum position for the current item. 23615 * @public 23616 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 23617 * @returns {Number} 23618 */ 23619 Owl.prototype.maximum = function(relative) { 23620 var settings = this.settings, 23621 maximum = this._coordinates.length, 23622 boundary = Math.abs(this._coordinates[maximum - 1]) - this._width, 23623 i = -1, j; 23624 23625 if (settings.loop) { 23626 maximum = this._clones.length / 2 + this._items.length - 1; 23627 } else if (settings.autoWidth || settings.merge) { 23628 // binary search 23629 while (maximum - i > 1) { 23630 Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary 23631 ? i = j : maximum = j; 23632 } 23633 } else if (settings.center) { 23634 maximum = this._items.length - 1; 23635 } else { 23636 maximum = this._items.length - settings.items; 23637 } 23638 23639 if (relative) { 23640 maximum -= this._clones.length / 2; 23641 } 23642 23643 return Math.max(maximum, 0); 23644 }; 23645 23646 /** 23647 * Gets the minimum position for the current item. 23648 * @public 23649 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 23650 * @returns {Number} 23651 */ 23652 Owl.prototype.minimum = function(relative) { 23653 return relative ? 0 : this._clones.length / 2; 23654 }; 23655 23656 /** 23657 * Gets an item at the specified relative position. 23658 * @public 23659 * @param {Number} [position] - The relative position of the item. 23660 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 23661 */ 23662 Owl.prototype.items = function(position) { 23663 if (position === undefined) { 23664 return this._items.slice(); 23665 } 23666 23667 position = this.normalize(position, true); 23668 return this._items[position]; 23669 }; 23670 23671 /** 23672 * Gets an item at the specified relative position. 23673 * @public 23674 * @param {Number} [position] - The relative position of the item. 23675 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 23676 */ 23677 Owl.prototype.mergers = function(position) { 23678 if (position === undefined) { 23679 return this._mergers.slice(); 23680 } 23681 23682 position = this.normalize(position, true); 23683 return this._mergers[position]; 23684 }; 23685 23686 /** 23687 * Gets the absolute positions of clones for an item. 23688 * @public 23689 * @param {Number} [position] - The relative position of the item. 23690 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 23691 */ 23692 Owl.prototype.clones = function(position) { 23693 var odd = this._clones.length / 2, 23694 even = odd + this._items.length, 23695 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 23696 23697 if (position === undefined) { 23698 return $.map(this._clones, function(v, i) { return map(i) }); 23699 } 23700 23701 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 23702 }; 23703 23704 /** 23705 * Sets the current animation speed. 23706 * @public 23707 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 23708 * @returns {Number} - The current animation speed in milliseconds. 23709 */ 23710 Owl.prototype.speed = function(speed) { 23711 if (speed !== undefined) { 23712 this._speed = speed; 23713 } 23714 23715 return this._speed; 23716 }; 23717 23718 /** 23719 * Gets the coordinate of an item. 23720 * @todo The name of this method is missleanding. 23721 * @public 23722 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 23723 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 23724 */ 23725 Owl.prototype.coordinates = function(position) { 23726 var coordinate = null; 23727 23728 if (position === undefined) { 23729 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 23730 return this.coordinates(index); 23731 }, this)); 23732 } 23733 23734 if (this.settings.center) { 23735 coordinate = this._coordinates[position]; 23736 coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1); 23737 } else { 23738 coordinate = this._coordinates[position - 1] || 0; 23739 } 23740 23741 return coordinate; 23742 }; 23743 23744 /** 23745 * Calculates the speed for a translation. 23746 * @protected 23747 * @param {Number} from - The absolute position of the start item. 23748 * @param {Number} to - The absolute position of the target item. 23749 * @param {Number} [factor=undefined] - The time factor in milliseconds. 23750 * @returns {Number} - The time in milliseconds for the translation. 23751 */ 23752 Owl.prototype.duration = function(from, to, factor) { 23753 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 23754 }; 23755 23756 /** 23757 * Slides to the specified item. 23758 * @public 23759 * @param {Number} position - The position of the item. 23760 * @param {Number} [speed] - The time in milliseconds for the transition. 23761 */ 23762 Owl.prototype.to = function(position, speed) { 23763 var current = this.current(), 23764 revert = null, 23765 distance = position - this.relative(current), 23766 direction = (distance > 0) - (distance < 0), 23767 items = this._items.length, 23768 minimum = this.minimum(), 23769 maximum = this.maximum(); 23770 23771 if (this.settings.loop) { 23772 if (!this.settings.rewind && Math.abs(distance) > items / 2) { 23773 distance += direction * -1 * items; 23774 } 23775 23776 position = current + distance; 23777 revert = ((position - minimum) % items + items) % items + minimum; 23778 23779 if (revert !== position && revert - distance <= maximum && revert - distance > 0) { 23780 current = revert - distance; 23781 position = revert; 23782 this.reset(current); 23783 } 23784 } else if (this.settings.rewind) { 23785 maximum += 1; 23786 position = (position % maximum + maximum) % maximum; 23787 } else { 23788 position = Math.max(minimum, Math.min(maximum, position)); 23789 } 23790 23791 this.speed(this.duration(current, position, speed)); 23792 this.current(position); 23793 23794 if (this.$element.is(':visible')) { 23795 this.update(); 23796 } 23797 }; 23798 23799 /** 23800 * Slides to the next item. 23801 * @public 23802 * @param {Number}
vendor: 12,284 bytes, lines 23802-24222
23802 [speed] - The time in milliseconds for the transition. 23803 */ 23804 Owl.prototype.next = function(speed) { 23805 speed = speed || false; 23806 this.to(this.relative(this.current()) + 1, speed); 23807 }; 23808 23809 /** 23810 * Slides to the previous item. 23811 * @public 23812 * @param {Number} [speed] - The time in milliseconds for the transition. 23813 */ 23814 Owl.prototype.prev = function(speed) { 23815 speed = speed || false; 23816 this.to(this.relative(this.current()) - 1, speed); 23817 }; 23818 23819 /** 23820 * Handles the end of an animation. 23821 * @protected 23822 * @param {Event} event - The event arguments. 23823 */ 23824 Owl.prototype.onTransitionEnd = function(event) { 23825 23826 // if css2 animation then event object is undefined 23827 if (event !== undefined) { 23828 event.stopPropagation(); 23829 23830 // Catch only owl-stage transitionEnd event 23831 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 23832 return false; 23833 } 23834 } 23835 23836 this.leave('animating'); 23837 this.trigger('translated'); 23838 }; 23839 23840 /** 23841 * Gets viewport width. 23842 * @protected 23843 * @return {Number} - The width in pixel. 23844 */ 23845 Owl.prototype.viewport = function() { 23846 var width; 23847 if (this.options.responsiveBaseElement !== window) { 23848 width = $(this.options.responsiveBaseElement).width(); 23849 } else if (window.innerWidth) { 23850 width = window.innerWidth; 23851 } else if (document.documentElement && document.documentElement.clientWidth) { 23852 width = document.documentElement.clientWidth; 23853 } else { 23854 throw 'Can not detect viewport width.'; 23855 } 23856 23857 return width; 23858 }; 23859 23860 /** 23861 * Replaces the current content. 23862 * @public 23863 * @param {HTMLElement|jQuery|String} content - The new content. 23864 */ 23865 Owl.prototype.replace = function(content) { 23866 this.$stage.empty(); 23867 this._items = []; 23868 23869 if (content) { 23870 content = (content instanceof jQuery) ? content : $(content); 23871 } 23872 23873 if (this.settings.nestedItemSelector) { 23874 content = content.find('.' + this.settings.nestedItemSelector); 23875 } 23876 23877 content.filter(function() { 23878 return this.nodeType === 1; 23879 }).each($.proxy(function(index, item) { 23880 item = this.prepare(item, index); 23881 this.$stage.append(item); 23882 this._items.push(item); 23883 this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 23884 }, this)); 23885 23886 this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 23887 23888 this.invalidate('items'); 23889 }; 23890 23891 /** 23892 * Adds an item. 23893 * @todo Use `item` instead of `content` for the event arguments. 23894 * @public 23895 * @param {HTMLElement|jQuery|String} content - The item content to add. 23896 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 23897 */ 23898 Owl.prototype.add = function(content, position) { 23899 var current = this.relative(this._current); 23900 23901 position = position === undefined ? this._items.length : this.normalize(position, true); 23902 content = content instanceof jQuery ? content : $(content); 23903 23904 this.trigger('add', { content: content, position: position }); 23905 23906 content = this.prepare(content, this._items[current].index()); 23907 23908 if (this._items.length === 0 || position === this._items.length) { 23909 this._items.length === 0 && this.$stage.append(content); 23910 this._items.length !== 0 && this._items[position - 1].after(content); 23911 this._items.push(content); 23912 this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 23913 } else { 23914 this._items[position].before(content); 23915 this._items.splice(position, 0, content); 23916 this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 23917 } 23918 23919 this._items[current] && this.reset(this._items[current].index()); 23920 23921 this.invalidate('items'); 23922 23923 this.trigger('added', { content: content, position: position }); 23924 }; 23925 23926 /** 23927 * Removes an item by its position. 23928 * @todo Use `item` instead of `content` for the event arguments. 23929 * @public 23930 * @param {Number} position - The relative position of the item to remove. 23931 */ 23932 Owl.prototype.remove = function(position) { 23933 position = this.normalize(position, true); 23934 23935 if (position === undefined) { 23936 return; 23937 } 23938 23939 this.trigger('remove', { content: this._items[position], position: position }); 23940 23941 this._items[position].remove(); 23942 this._items.splice(position, 1); 23943 this._mergers.splice(position, 1); 23944 23945 this.invalidate('items'); 23946 23947 this.trigger('removed', { content: null, position: position }); 23948 }; 23949 23950 /** 23951 * Preloads images with auto width. 23952 * @todo Replace by a more generic approach 23953 * @protected 23954 */ 23955 Owl.prototype.preloadAutoWidthImages = function(images) { 23956 images.each($.proxy(function(i, element) { 23957 this.enter('pre-loading'); 23958 element = $(element); 23959 $(new Image()).one('load', $.proxy(function(e) { 23960 element.attr('src', e.target.src); 23961 element.css('opacity', 1); 23962 this.leave('pre-loading'); 23963 !this.is('pre-loading') && !this.is('initializing') && this.refresh(); 23964 }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina')); 23965 }, this)); 23966 }; 23967 23968 /** 23969 * Destroys the carousel. 23970 * @public 23971 */ 23972 Owl.prototype.destroy = function() { 23973 23974 this.$element.off('.owl.core'); 23975 this.$stage.off('.owl.core'); 23976 $(document).off('.owl.core'); 23977 23978 if (this.settings.responsive !== false) { 23979 window.clearTimeout(this.resizeTimer); 23980 this.off(window, 'resize', this._handlers.onThrottledResize); 23981 } 23982 23983 for (var i in this._plugins) { 23984 this._plugins[i].destroy(); 23985 } 23986 23987 this.$stage.children('.cloned').remove(); 23988 23989 this.$stage.unwrap(); 23990 this.$stage.children().contents().unwrap(); 23991 this.$stage.children().unwrap(); 23992 23993 this.$element 23994 .removeClass(this.options.refreshClass) 23995 .removeClass(this.options.loadingClass) 23996 .removeClass(this.options.loadedClass) 23997 .removeClass(this.options.rtlClass) 23998 .removeClass(this.options.dragClass) 23999 .removeClass(this.options.grabClass) 24000 .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) 24001 .removeData('owl.carousel'); 24002 }; 24003 24004 /** 24005 * Operators to calculate right-to-left and left-to-right. 24006 * @protected 24007 * @param {Number} [a] - The left side operand. 24008 * @param {String} [o] - The operator. 24009 * @param {Number} [b] - The right side operand. 24010 */ 24011 Owl.prototype.op = function(a, o, b) { 24012 var rtl = this.settings.rtl; 24013 switch (o) { 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 case '<=': 24021 return rtl ? a >= b : a <= b; 24022 default: 24023 break; 24024 } 24025 }; 24026 24027 /** 24028 * Attaches to an internal event. 24029 * @protected 24030 * @param {HTMLElement} element - The event source. 24031 * @param {String} event - The event name. 24032 * @param {Function} listener - The event handler to attach. 24033 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. 24034 */ 24035 Owl.prototype.on = function(element, event, listener, capture) { 24036 if (element.addEventListener) { 24037 element.addEventListener(event, listener, capture); 24038 } else if (element.attachEvent) { 24039 element.attachEvent('on' + event, listener); 24040 } 24041 }; 24042 24043 /** 24044 * Detaches from an internal event. 24045 * @protected 24046 * @param {HTMLElement} element - The event source. 24047 * @param {String} event - The event name. 24048 * @param {Function} listener - The attached event handler to detach. 24049 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 24050 */ 24051 Owl.prototype.off = function(element, event, listener, capture) { 24052 if (element.removeEventListener) { 24053 element.removeEventListener(event, listener, capture); 24054 } else if (element.detachEvent) { 24055 element.detachEvent('on' + event, listener); 24056 } 24057 }; 24058 24059 /** 24060 * Triggers a public event. 24061 * @todo Remove `status`, `relatedTarget` should be used instead. 24062 * @protected 24063 * @param {String} name - The event name. 24064 * @param {*} [data=null] - The event data. 24065 * @param {String} [namespace=carousel] - The event namespace. 24066 * @param {String} [state] - The state which is associated with the event. 24067 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. 24068 * @returns {Event} - The event arguments. 24069 */ 24070 Owl.prototype.trigger = function(name, data, namespace, state, enter) { 24071 var status = { 24072 item: { count: this._items.length, index: this.current() } 24073 }, handler = $.camelCase( 24074 $.grep([ 'on', name, namespace ], function(v) { return v }) 24075 .join('-').toLowerCase() 24076 ), event = $.Event( 24077 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 24078 $.extend({ relatedTarget: this }, status, data) 24079 ); 24080 24081 if (!this._supress[name]) { 24082 $.each(this._plugins, function(name, plugin) { 24083 if (plugin.onTrigger) { 24084 plugin.onTrigger(event); 24085 } 24086 }); 24087 24088 this.register({ type: Owl.Type.Event, name: name }); 24089 this.$element.trigger(event); 24090 24091 if (this.settings && typeof this.settings[handler] === 'function') { 24092 this.settings[handler].call(this, event); 24093 } 24094 } 24095 24096 return event; 24097 }; 24098 24099 /** 24100 * Enters a state. 24101 * @param name - The state name. 24102 */ 24103 Owl.prototype.enter = function(name) { 24104 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 24105 if (this._states.current[name] === undefined) { 24106 this._states.current[name] = 0; 24107 } 24108 24109 this._states.current[name]++; 24110 }, this)); 24111 }; 24112 24113 /** 24114 * Leaves a state. 24115 * @param name - The state name. 24116 */ 24117 Owl.prototype.leave = function(name) { 24118 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 24119 this._states.current[name]--; 24120 }, this)); 24121 }; 24122 24123 /** 24124 * Registers an event or state. 24125 * @public 24126 * @param {Object} object - The event or state to register. 24127 */ 24128 Owl.prototype.register = function(object) { 24129 if (object.type === Owl.Type.Event) { 24130 if (!$.event.special[object.name]) { 24131 $.event.special[object.name] = {}; 24132 } 24133 24134 if (!$.event.special[object.name].owl) { 24135 var _default = $.event.special[object.name]._default; 24136 $.event.special[object.name]._default = function(e) { 24137 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 24138 return _default.apply(this, arguments); 24139 } 24140 return e.namespace && e.namespace.indexOf('owl') > -1; 24141 }; 24142 $.event.special[object.name].owl = true; 24143 } 24144 } else if (object.type === Owl.Type.State) { 24145 if (!this._states.tags[object.name]) { 24146 this._states.tags[object.name] = object.tags; 24147 } else { 24148 this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); 24149 } 24150 24151 this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { 24152 return $.inArray(tag, this._states.tags[object.name]) === i; 24153 }, this)); 24154 } 24155 }; 24156 24157 /** 24158 * Suppresses events. 24159 * @protected 24160 * @param {Array.<String>} events - The events to suppress. 24161 */ 24162 Owl.prototype.suppress = function(events) { 24163 $.each(events, $.proxy(function(index, event) { 24164 this._supress[event] = true; 24165 }, this)); 24166 }; 24167 24168 /** 24169 * Releases suppressed events. 24170 * @protected 24171 * @param {Array.<String>} events - The events to release. 24172 */ 24173 Owl.prototype.release = function(events) { 24174 $.each(events, $.proxy(function(index, event) { 24175 delete this._supress[event]; 24176 }, this)); 24177 }; 24178 24179 /** 24180 * Gets unified pointer coordinates from event. 24181 * @todo #261 24182 * @protected 24183 * @param {Event} - The `mousedown` or `touchstart` event. 24184 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 24185 */ 24186 Owl.prototype.pointer = function(event) { 24187 var result = { x: null, y: null }; 24188 24189 event = event.originalEvent || event || window.event; 24190 24191 event = event.touches && event.touches.length ? 24192 event.touches[0] : event.changedTouches && event.changedTouches.length ? 24193 event.changedTouches[0] : event; 24194 24195 if (event.pageX) { 24196 result.x = event.pageX; 24197 result.y = event.pageY; 24198 } else { 24199 result.x = event.clientX; 24200 result.y = event.clientY; 24201 } 24202 24203 return result; 24204 }; 24205 24206 /** 24207 * Gets the difference of two vectors. 24208 * @todo #261 24209 * @protected 24210 * @param {Object} - The first vector. 24211 * @param {Object} - The second vector. 24212 * @returns {Object} - The difference. 24213 */ 24214 Owl.prototype.difference = function(first, second) { 24215 return { 24216 x: first.x - second.x, 24217 y: first.y - second.y 24218 }; 24219 }; 24220 24221 /** 24222 * The jQuery Plugin for the Owl Carousel
vendor: 32,216 bytes, lines 24223-25505
24223 * @todo Navigation plugin `next` and `prev` 24224 * @public 24225 */ 24226 $.fn.owlCarousel = function(option) { 24227 var args = Array.prototype.slice.call(arguments, 1); 24228 24229 return this.each(function() { 24230 var $this = $(this), 24231 data = $this.data('owl.carousel'); 24232 24233 if (!data) { 24234 data = new Owl(this, typeof option == 'object' && option); 24235 $this.data('owl.carousel', data); 24236 24237 $.each([ 24238 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' 24239 ], function(i, event) { 24240 data.register({ type: Owl.Type.Event, name: event }); 24241 data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { 24242 if (e.namespace && e.relatedTarget !== this) { 24243 this.suppress([ event ]); 24244 data[event].apply(this, [].slice.call(arguments, 1)); 24245 this.release([ event ]); 24246 } 24247 }, data)); 24248 }); 24249 } 24250 24251 if (typeof option == 'string' && option.charAt(0) !== '_') { 24252 data[option].apply(data, args); 24253 } 24254 }); 24255 }; 24256 24257 /** 24258 * The constructor for the jQuery Plugin 24259 * @public 24260 */ 24261 $.fn.owlCarousel.Constructor = Owl; 24262 24263})(window.Zepto || window.jQuery, window, document); 24264 24265/** 24266 * AutoRefresh Plugin 24267 * @version 2.0.0-beta.3 24268 * @author Artus Kolanowski 24269 * @license The MIT License (MIT) 24270 */ 24271;(function($, window, document, undefined) { 24272 24273 /** 24274 * Creates the auto refresh plugin. 24275 * @class The Auto Refresh Plugin 24276 * @param {Owl} carousel - The Owl Carousel 24277 */ 24278 var AutoRefresh = function(carousel) { 24279 /** 24280 * Reference to the core. 24281 * @protected 24282 * @type {Owl} 24283 */ 24284 this._core = carousel; 24285 24286 /** 24287 * Refresh interval. 24288 * @protected 24289 * @type {number} 24290 */ 24291 this._interval = null; 24292 24293 /** 24294 * Whether the element is currently visible or not. 24295 * @protected 24296 * @type {Boolean} 24297 */ 24298 this._visible = null; 24299 24300 /** 24301 * All event handlers. 24302 * @protected 24303 * @type {Object} 24304 */ 24305 this._handlers = { 24306 'initialized.owl.carousel': $.proxy(function(e) { 24307 if (e.namespace && this._core.settings.autoRefresh) { 24308 this.watch(); 24309 } 24310 }, this) 24311 }; 24312 24313 // set default options 24314 this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options); 24315 24316 // register event handlers 24317 this._core.$element.on(this._handlers); 24318 }; 24319 24320 /** 24321 * Default options. 24322 * @public 24323 */ 24324 AutoRefresh.Defaults = { 24325 autoRefresh: true, 24326 autoRefreshInterval: 500 24327 }; 24328 24329 /** 24330 * Watches the element. 24331 */ 24332 AutoRefresh.prototype.watch = function() { 24333 if (this._interval) { 24334 return; 24335 } 24336 24337 this._visible = this._core.$element.is(':visible'); 24338 this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval); 24339 }; 24340 24341 /** 24342 * Refreshes the element. 24343 */ 24344 AutoRefresh.prototype.refresh = function() { 24345 if (this._core.$element.is(':visible') === this._visible) { 24346 return; 24347 } 24348 24349 this._visible = !this._visible; 24350 24351 this._core.$element.toggleClass('owl-hidden', !this._visible); 24352 24353 this._visible && (this._core.invalidate('width') && this._core.refresh()); 24354 }; 24355 24356 /** 24357 * Destroys the plugin. 24358 */ 24359 AutoRefresh.prototype.destroy = function() { 24360 var handler, property; 24361 24362 window.clearInterval(this._interval); 24363 24364 for (handler in this._handlers) { 24365 this._core.$element.off(handler, this._handlers[handler]); 24366 } 24367 for (property in Object.getOwnPropertyNames(this)) { 24368 typeof this[property] != 'function' && (this[property] = null); 24369 } 24370 }; 24371 24372 $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh; 24373 24374})(window.Zepto || window.jQuery, window, document); 24375 24376/** 24377 * Lazy Plugin 24378 * @version 2.0.0-beta.3 24379 * @author Bartosz Wojciechowski 24380 * @license The MIT License (MIT) 24381 */ 24382;(function($, window, document, undefined) { 24383 24384 /** 24385 * Creates the lazy plugin. 24386 * @class The Lazy Plugin 24387 * @param {Owl} carousel - The Owl Carousel 24388 */ 24389 var Lazy = function(carousel) { 24390 24391 /** 24392 * Reference to the core. 24393 * @protected 24394 * @type {Owl} 24395 */ 24396 this._core = carousel; 24397 24398 /** 24399 * Already loaded items. 24400 * @protected 24401 * @type {Array.<jQuery>} 24402 */ 24403 this._loaded = []; 24404 24405 /** 24406 * Event handlers. 24407 * @protected 24408 * @type {Object} 24409 */ 24410 this._handlers = { 24411 'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) { 24412 if (!e.namespace) { 24413 return; 24414 } 24415 24416 if (!this._core.settings || !this._core.settings.lazyLoad) { 24417 return; 24418 } 24419 24420 if ((e.property && e.property.name == 'position') || e.type == 'initialized') { 24421 var settings = this._core.settings, 24422 n = (settings.center && Math.ceil(settings.items / 2) || settings.items), 24423 i = ((settings.center && n * -1) || 0), 24424 position = ((e.property && e.property.value) || this._core.current()) + i, 24425 clones = this._core.clones().length, 24426 load = $.proxy(function(i, v) { this.load(v) }, this); 24427 24428 while (i++ < n) { 24429 this.load(clones / 2 + this._core.relative(position)); 24430 clones && $.each(this._core.clones(this._core.relative(position)), load); 24431 position++; 24432 } 24433 } 24434 }, this) 24435 }; 24436 24437 // set the default options 24438 this._core.options = $.extend({}, Lazy.Defaults, this._core.options); 24439 24440 // register event handler 24441 this._core.$element.on(this._handlers); 24442 } 24443 24444 /** 24445 * Default options. 24446 * @public 24447 */ 24448 Lazy.Defaults = { 24449 lazyLoad: false 24450 } 24451 24452 /** 24453 * Loads all resources of an item at the specified position. 24454 * @param {Number} position - The absolute position of the item. 24455 * @protected 24456 */ 24457 Lazy.prototype.load = function(position) { 24458 var $item = this._core.$stage.children().eq(position), 24459 $elements = $item && $item.find('.owl-lazy'); 24460 24461 if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { 24462 return; 24463 } 24464 24465 $elements.each($.proxy(function(index, element) { 24466 var $element = $(element), image, 24467 url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src'); 24468 24469 this._core.trigger('load', { element: $element, url: url }, 'lazy'); 24470 24471 if ($element.is('img')) { 24472 $element.one('load.owl.lazy', $.proxy(function() { 24473 $element.css('opacity', 1); 24474 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 24475 }, this)).attr('src', url); 24476 } else { 24477 image = new Image(); 24478 image.onload = $.proxy(function() { 24479 $element.css({ 24480 'background-image': 'url(' + url + ')', 24481 'opacity': '1' 24482 }); 24483 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 24484 }, this); 24485 image.src = url; 24486 } 24487 }, this)); 24488 24489 this._loaded.push($item.get(0)); 24490 } 24491 24492 /** 24493 * Destroys the plugin. 24494 * @public 24495 */ 24496 Lazy.prototype.destroy = function() { 24497 var handler, property; 24498 24499 for (handler in this.handlers) { 24500 this._core.$element.off(handler, this.handlers[handler]); 24501 } 24502 for (property in Object.getOwnPropertyNames(this)) { 24503 typeof this[property] != 'function' && (this[property] = null); 24504 } 24505 }; 24506 24507 $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; 24508 24509})(window.Zepto || window.jQuery, window, document); 24510 24511/** 24512 * AutoHeight Plugin 24513 * @version 2.0.0-beta.3 24514 * @author Bartosz Wojciechowski 24515 * @license The MIT License (MIT) 24516 */ 24517;(function($, window, document, undefined) { 24518 24519 /** 24520 * Creates the auto height plugin. 24521 * @class The Auto Height Plugin 24522 * @param {Owl} carousel - The Owl Carousel 24523 */ 24524 var AutoHeight = function(carousel) { 24525 /** 24526 * Reference to the core. 24527 * @protected 24528 * @type {Owl} 24529 */ 24530 this._core = carousel; 24531 24532 /** 24533 * All event handlers. 24534 * @protected 24535 * @type {Object} 24536 */ 24537 this._handlers = { 24538 'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) { 24539 if (e.namespace && this._core.settings.autoHeight) { 24540 this.update(); 24541 } 24542 }, this), 24543 'changed.owl.carousel': $.proxy(function(e) { 24544 if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){ 24545 this.update(); 24546 } 24547 }, this), 24548 'loaded.owl.lazy': $.proxy(function(e) { 24549 if (e.namespace && this._core.settings.autoHeight 24550 && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) { 24551 this.update(); 24552 } 24553 }, this) 24554 }; 24555 24556 // set default options 24557 this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); 24558 24559 // register event handlers 24560 this._core.$element.on(this._handlers); 24561 }; 24562 24563 /** 24564 * Default options. 24565 * @public 24566 */ 24567 AutoHeight.Defaults = { 24568 autoHeight: false, 24569 autoHeightClass: 'owl-height' 24570 }; 24571 24572 /** 24573 * Updates the view. 24574 */ 24575 AutoHeight.prototype.update = function() { 24576 var start = this._core._current, 24577 end = start + this._core.settings.items, 24578 visible = this._core.$stage.children().toArray().slice(start, end); 24579 heights = [], 24580 maxheight = 0; 24581 24582 $.each(visible, function(index, item) { 24583 heights.push($(item).height()); 24584 }); 24585 24586 maxheight = Math.max.apply(null, heights); 24587 24588 this._core.$stage.parent() 24589 .height(maxheight) 24590 .addClass(this._core.settings.autoHeightClass); 24591 }; 24592 24593 AutoHeight.prototype.destroy = function() { 24594 var handler, property; 24595 24596 for (handler in this._handlers) { 24597 this._core.$element.off(handler, this._handlers[handler]); 24598 } 24599 for (property in Object.getOwnPropertyNames(this)) { 24600 typeof this[property] != 'function' && (this[property] = null); 24601 } 24602 }; 24603 24604 $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; 24605 24606})(window.Zepto || window.jQuery, window, document); 24607 24608/** 24609 * Video Plugin 24610 * @version 2.0.0-beta.3 24611 * @author Bartosz Wojciechowski 24612 * @license The MIT License (MIT) 24613 */ 24614;(function($, window, document, undefined) { 24615 24616 /** 24617 * Creates the video plugin. 24618 * @class The Video Plugin 24619 * @param {Owl} carousel - The Owl Carousel 24620 */ 24621 var Video = function(carousel) { 24622 /** 24623 * Reference to the core. 24624 * @protected 24625 * @type {Owl} 24626 */ 24627 this._core = carousel; 24628 24629 /** 24630 * Cache all video URLs. 24631 * @protected 24632 * @type {Object} 24633 */ 24634 this._videos = {}; 24635 24636 /** 24637 * Current playing item. 24638 * @protected 24639 * @type {jQuery} 24640 */ 24641 this._playing = null; 24642 24643 /** 24644 * All event handlers. 24645 * @todo The cloned content removale is too late 24646 * @protected 24647 * @type {Object} 24648 */ 24649 this._handlers = { 24650 'initialized.owl.carousel': $.proxy(function(e) { 24651 if (e.namespace) { 24652 this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] }); 24653 } 24654 }, this), 24655 'resize.owl.carousel': $.proxy(function(e) { 24656 if (e.namespace && this._core.settings.video && this.isInFullScreen()) { 24657 e.preventDefault(); 24658 } 24659 }, this), 24660 'refreshed.owl.carousel': $.proxy(function(e) { 24661 if (e.namespace && this._core.is('resizing')) { 24662 this._core.$stage.find('.cloned .owl-video-frame').remove(); 24663 } 24664 }, this), 24665 'changed.owl.carousel': $.proxy(function(e) { 24666 if (e.namespace && e.property.name === 'position' && this._playing) { 24667 this.stop(); 24668 } 24669 }, this), 24670 'prepared.owl.carousel': $.proxy(function(e) { 24671 if (!e.namespace) { 24672 return; 24673 } 24674 24675 var $element = $(e.content).find('.owl-video'); 24676 24677 if ($element.length) { 24678 $element.css('display', 'none'); 24679 this.fetch($element, $(e.content)); 24680 } 24681 }, this) 24682 }; 24683 24684 // set default options 24685 this._core.options = $.extend({}, Video.Defaults, this._core.options); 24686 24687 // register event handlers 24688 this._core.$element.on(this._handlers); 24689 24690 this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 24691 this.play(e); 24692 }, this)); 24693 }; 24694 24695 /** 24696 * Default options. 24697 * @public 24698 */ 24699 Video.Defaults = { 24700 video: false, 24701 videoHeight: false, 24702 videoWidth: false 24703 }; 24704 24705 /** 24706 * Gets the video ID and the type (YouTube/Vimeo only). 24707 * @protected 24708 * @param {jQuery} target - The target containing the video data. 24709 * @param {jQuery} item - The item containing the video. 24710 */ 24711 Video.prototype.fetch = function(target, item) { 24712 var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube', 24713 id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'), 24714 width = target.attr('data-width') || this._core.settings.videoWidth, 24715 height = target.attr('data-height') || this._core.settings.videoHeight, 24716 url = target.attr('href'); 24717 24718 if (url) { 24719 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+)?/); 24720 24721 if (id[3].indexOf('youtu') > -1) { 24722 type = 'youtube'; 24723 } else if (id[3].indexOf('vimeo') > -1) { 24724 type = 'vimeo'; 24725 } else { 24726 throw new Error('Video URL not supported.'); 24727 } 24728 id = id[6]; 24729 } else { 24730 throw new Error('Missing video URL.'); 24731 } 24732 24733 this._videos[url] = { 24734 type: type, 24735 id: id, 24736 width: width, 24737 height: height 24738 }; 24739 24740 item.attr('data-video', url); 24741 24742 this.thumbnail(target, this._videos[url]); 24743 }; 24744 24745 /** 24746 * Creates video thumbnail. 24747 * @protected 24748 * @param {jQuery} target - The target containing the video data. 24749 * @param {Object} info - The video info object. 24750 * @see `fetch` 24751 */ 24752 Video.prototype.thumbnail = function(target, video) { 24753 var tnLink, 24754 icon, 24755 path, 24756 dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '', 24757 customTn = target.find('img'), 24758 srcType = 'src', 24759 lazyClass = '', 24760 settings = this._core.settings, 24761 create = function(path) { 24762 icon = '<div class="owl-video-play-icon"></div>'; 24763 24764 if (settings.lazyLoad) { 24765 tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>'; 24766 } else { 24767 tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>'; 24768 } 24769 target.after(tnLink); 24770 target.after(icon); 24771 }; 24772 24773 // wrap video content into owl-video-wrapper div 24774 target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>'); 24775 24776 if (this._core.settings.lazyLoad) { 24777 srcType = 'data-src'; 24778 lazyClass = 'owl-lazy'; 24779 } 24780 24781 // custom thumbnail 24782 if (customTn.length) { 24783 create(customTn.attr(srcType)); 24784 customTn.remove(); 24785 return false; 24786 } 24787 24788 if (video.type === 'youtube') { 24789 path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; 24790 create(path); 24791 } else if (video.type === 'vimeo') { 24792 $.ajax({ 24793 type: 'GET', 24794 url: '//vimeo.com/api/v2/video/' + video.id + '.json', 24795 jsonp: 'callback', 24796 dataType: 'jsonp', 24797 success: function(data) { 24798 path = data[0].thumbnail_large; 24799 create(path); 24800 } 24801 }); 24802 } 24803 }; 24804 24805 /** 24806 * Stops the current video. 24807 * @public 24808 */ 24809 Video.prototype.stop = function() { 24810 this._core.trigger('stop', null, 'video'); 24811 this._playing.find('.owl-video-frame').remove(); 24812 this._playing.removeClass('owl-video-playing'); 24813 this._playing = null; 24814 this._core.leave('playing'); 24815 this._core.trigger('stopped', null, 'video'); 24816 }; 24817 24818 /** 24819 * Starts the current video. 24820 * @public 24821 * @param {Event} event - The event arguments. 24822 */ 24823 Video.prototype.play = function(event) { 24824 var target = $(event.target), 24825 item = target.closest('.' + this._core.settings.itemClass), 24826 video = this._videos[item.attr('data-video')], 24827 width = video.width || '100%', 24828 height = video.height || this._core.$stage.height(), 24829 html; 24830 24831 if (this._playing) { 24832 return; 24833 } 24834 24835 this._core.enter('playing'); 24836 this._core.trigger('play', null, 'video'); 24837 24838 item = this._core.items(this._core.relative(item.index())); 24839 24840 this._core.reset(item.index()); 24841 24842 if (video.type === 'youtube') { 24843 html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' + 24844 video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>'; 24845 } else if (video.type === 'vimeo') { 24846 html = '<iframe src="//player.vimeo.com/video/' + video.id + 24847 '?autoplay=1" width="' + width + '" height="' + height + 24848 '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'; 24849 } 24850 24851 $('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video')); 24852 24853 this._playing = item.addClass('owl-video-playing'); 24854 }; 24855 24856 /** 24857 * Checks whether an video is currently in full screen mode or not. 24858 * @todo Bad style because looks like a readonly method but changes members. 24859 * @protected 24860 * @returns {Boolean} 24861 */ 24862 Video.prototype.isInFullScreen = function() { 24863 var element = document.fullscreenElement || document.mozFullScreenElement || 24864 document.webkitFullscreenElement; 24865 24866 return element && $(element).parent().hasClass('owl-video-frame'); 24867 }; 24868 24869 /** 24870 * Destroys the plugin. 24871 */ 24872 Video.prototype.destroy = function() { 24873 var handler, property; 24874 24875 this._core.$element.off('click.owl.video'); 24876 24877 for (handler in this._handlers) { 24878 this._core.$element.off(handler, this._handlers[handler]); 24879 } 24880 for (property in Object.getOwnPropertyNames(this)) { 24881 typeof this[property] != 'function' && (this[property] = null); 24882 } 24883 }; 24884 24885 $.fn.owlCarousel.Constructor.Plugins.Video = Video; 24886 24887})(window.Zepto || window.jQuery, window, document); 24888 24889/** 24890 * Animate Plugin 24891 * @version 2.0.0-beta.3 24892 * @author Bartosz Wojciechowski 24893 * @license The MIT License (MIT) 24894 */ 24895;(function($, window, document, undefined) { 24896 24897 /** 24898 * Creates the animate plugin. 24899 * @class The Navigation Plugin 24900 * @param {Owl} scope - The Owl Carousel 24901 */ 24902 var Animate = function(scope) { 24903 this.core = scope; 24904 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 24905 this.swapping = true; 24906 this.previous = undefined; 24907 this.next = undefined; 24908 24909 this.handlers = { 24910 'change.owl.carousel': $.proxy(function(e) { 24911 if (e.namespace && e.property.name == 'position') { 24912 this.previous = this.core.current(); 24913 this.next = e.property.value; 24914 } 24915 }, this), 24916 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 24917 if (e.namespace) { 24918 this.swapping = e.type == 'translated'; 24919 } 24920 }, this), 24921 'translate.owl.carousel': $.proxy(function(e) { 24922 if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 24923 this.swap(); 24924 } 24925 }, this) 24926 }; 24927 24928 this.core.$element.on(this.handlers); 24929 }; 24930 24931 /** 24932 * Default options. 24933 * @public 24934 */ 24935 Animate.Defaults = { 24936 animateOut: false, 24937 animateIn: false 24938 }; 24939 24940 /** 24941 * Toggles the animation classes whenever an translations starts. 24942 * @protected 24943 * @returns {Boolean|undefined} 24944 */ 24945 Animate.prototype.swap = function() { 24946 24947 if (this.core.settings.items !== 1) { 24948 return; 24949 } 24950 24951 if (!$.support.animation || !$.support.transition) { 24952 return; 24953 } 24954 24955 this.core.speed(0); 24956 24957 var left, 24958 clear = $.proxy(this.clear, this), 24959 previous = this.core.$stage.children().eq(this.previous), 24960 next = this.core.$stage.children().eq(this.next), 24961 incoming = this.core.settings.animateIn, 24962 outgoing = this.core.settings.animateOut; 24963 24964 if (this.core.current() === this.previous) { 24965 return; 24966 } 24967 24968 if (outgoing) { 24969 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 24970 previous.css( { 'left': left + 'px' } ) 24971 .addClass('animated owl-animated-out') 24972 .addClass(outgoing) 24973 .on($.support.animation.end, clear); 24974 } 24975 24976 if (incoming) { 24977 next.addClass('animated owl-animated-in') 24978 .addClass(incoming) 24979 .on($.support.animation.end, clear); 24980 } 24981 }; 24982 24983 Animate.prototype.clear = function(e) { 24984 if ($(e.target).hasClass('animated')) { 24985 $(e.target).css( { 'left': '' } ) 24986 .removeClass('animated owl-animated-out owl-animated-in') 24987 .removeClass(this.core.settings.animateIn) 24988 .removeClass(this.core.settings.animateOut); 24989 this.core.onTransitionEnd(); 24990 } 24991 }; 24992 24993 /** 24994 * Destroys the plugin. 24995 * @public 24996 */ 24997 Animate.prototype.destroy = function() { 24998 var handler, property; 24999 25000 for (handler in this.handlers) { 25001 this.core.$element.off(handler, this.handlers[handler]); 25002 } 25003 for (property in Object.getOwnPropertyNames(this)) { 25004 typeof this[property] != 'function' && (this[property] = null); 25005 } 25006 }; 25007 25008 $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; 25009 25010})(window.Zepto || window.jQuery, window, document); 25011 25012/** 25013 * Autoplay Plugin 25014 * @version 2.0.0-beta.3 25015 * @author Bartosz Wojciechowski 25016 * @author Artus Kolanowski 25017 * @license The MIT License (MIT) 25018 */ 25019;(function($, window, document, undefined) { 25020 25021 /** 25022 * Creates the autoplay plugin. 25023 * @class The Autoplay Plugin 25024 * @param {Owl} scope - The Owl Carousel 25025 */ 25026 var Autoplay = function(carousel) { 25027 /** 25028 * Reference to the core. 25029 * @protected 25030 * @type {Owl} 25031 */ 25032 this._core = carousel; 25033 25034 /** 25035 * The autoplay interval. 25036 * @type {Number} 25037 */ 25038 this._interval = null; 25039 25040 /** 25041 * Indicates whenever the autoplay is paused. 25042 * @type {Boolean} 25043 */ 25044 this._paused = false; 25045 25046 /** 25047 * All event handlers. 25048 * @protected 25049 * @type {Object} 25050 */ 25051 this._handlers = { 25052 'changed.owl.carousel': $.proxy(function(e) { 25053 if (e.namespace && e.property.name === 'settings') { 25054 if (this._core.settings.autoplay) { 25055 this.play(); 25056 } else { 25057 this.stop(); 25058 } 25059 } 25060 }, this), 25061 'initialized.owl.carousel': $.proxy(function(e) { 25062 if (e.namespace && this._core.settings.autoplay) { 25063 this.play(); 25064 } 25065 }, this), 25066 'play.owl.autoplay': $.proxy(function(e, t, s) { 25067 if (e.namespace) { 25068 this.play(t, s); 25069 } 25070 }, this), 25071 'stop.owl.autoplay': $.proxy(function(e) { 25072 if (e.namespace) { 25073 this.stop(); 25074 } 25075 }, this), 25076 'mouseover.owl.autoplay': $.proxy(function() { 25077 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 25078 this.pause(); 25079 } 25080 }, this), 25081 'mouseleave.owl.autoplay': $.proxy(function() { 25082 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 25083 this.play(); 25084 } 25085 }, this) 25086 }; 25087 25088 // register event handlers 25089 this._core.$element.on(this._handlers); 25090 25091 // set default options 25092 this._core.options = $.extend({}, Autoplay.Defaults, this._core.options); 25093 }; 25094 25095 /** 25096 * Default options. 25097 * @public 25098 */ 25099 Autoplay.Defaults = { 25100 autoplay: false, 25101 autoplayTimeout: 5000, 25102 autoplayHoverPause: false, 25103 autoplaySpeed: false 25104 }; 25105 25106 /** 25107 * Starts the autoplay. 25108 * @public 25109 * @param {Number} [timeout] - The interval before the next animation starts. 25110 * @param {Number} [speed] - The animation speed for the animations. 25111 */ 25112 Autoplay.prototype.play = function(timeout, speed) { 25113 this._paused = false; 25114 25115 if (this._core.is('rotating')) { 25116 return; 25117 } 25118 25119 this._core.enter('rotating'); 25120 25121 this._interval = window.setInterval($.proxy(function() { 25122 if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) { 25123 return; 25124 } 25125 this._core.next(speed || this._core.settings.autoplaySpeed); 25126 }, this), timeout || this._core.settings.autoplayTimeout); 25127 }; 25128 25129 /** 25130 * Stops the autoplay. 25131 * @public 25132 */ 25133 Autoplay.prototype.stop = function() { 25134 if (!this._core.is('rotating')) { 25135 return; 25136 } 25137 25138 window.clearInterval(this._interval); 25139 this._core.leave('rotating'); 25140 }; 25141 25142 /** 25143 * Stops the autoplay. 25144 * @public 25145 */ 25146 Autoplay.prototype.pause = function() { 25147 if (!this._core.is('rotating')) { 25148 return; 25149 } 25150 25151 this._paused = true; 25152 }; 25153 25154 /** 25155 * Destroys the plugin. 25156 */ 25157 Autoplay.prototype.destroy = function() { 25158 var handler, property; 25159 25160 this.stop(); 25161 25162 for (handler in this._handlers) { 25163 this._core.$element.off(handler, this._handlers[handler]); 25164 } 25165 for (property in Object.getOwnPropertyNames(this)) { 25166 typeof this[property] != 'function' && (this[property] = null); 25167 } 25168 }; 25169 25170 $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; 25171 25172})(window.Zepto || window.jQuery, window, document); 25173 25174/** 25175 * Navigation Plugin 25176 * @version 2.0.0-beta.3 25177 * @author Artus Kolanowski 25178 * @license The MIT License (MIT) 25179 */ 25180;(function($, window, document, undefined) { 25181 'use strict'; 25182 25183 /** 25184 * Creates the navigation plugin. 25185 * @class The Navigation Plugin 25186 * @param {Owl} carousel - The Owl Carousel. 25187 */ 25188 var Navigation = function(carousel) { 25189 /** 25190 * Reference to the core. 25191 * @protected 25192 * @type {Owl} 25193 */ 25194 this._core = carousel; 25195 25196 /** 25197 * Indicates whether the plugin is initialized or not. 25198 * @protected 25199 * @type {Boolean} 25200 */ 25201 this._initialized = false; 25202 25203 /** 25204 * The current paging indexes. 25205 * @protected 25206 * @type {Array} 25207 */ 25208 this._pages = []; 25209 25210 /** 25211 * All DOM elements of the user interface. 25212 * @protected 25213 * @type {Object} 25214 */ 25215 this._controls = {}; 25216 25217 /** 25218 * Markup for an indicator. 25219 * @protected 25220 * @type {Array.<String>} 25221 */ 25222 this._templates = []; 25223 25224 /** 25225 * The carousel element. 25226 * @type {jQuery} 25227 */ 25228 this.$element = this._core.$element; 25229 25230 /** 25231 * Overridden methods of the carousel. 25232 * @protected 25233 * @type {Object} 25234 */ 25235 this._overrides = { 25236 next: this._core.next, 25237 prev: this._core.prev, 25238 to: this._core.to 25239 }; 25240 25241 /** 25242 * All event handlers. 25243 * @protected 25244 * @type {Object} 25245 */ 25246 this._handlers = { 25247 'prepared.owl.carousel': $.proxy(function(e) { 25248 if (e.namespace && this._core.settings.dotsData) { 25249 this._templates.push('<div class="' + this._core.settings.dotClass + '">' + 25250 $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot') + '</div>'); 25251 } 25252 }, this), 25253 'added.owl.carousel': $.proxy(function(e) { 25254 if (e.namespace && this._core.settings.dotsData) { 25255 this._templates.splice(e.position, 0, this._templates.pop()); 25256 } 25257 }, this), 25258 'remove.owl.carousel': $.proxy(function(e) { 25259 if (e.namespace && this._core.settings.dotsData) { 25260 this._templates.splice(e.position, 1); 25261 } 25262 }, this), 25263 'changed.owl.carousel': $.proxy(function(e) { 25264 if (e.namespace && e.property.name == 'position') { 25265 this.draw(); 25266 } 25267 }, this), 25268 'initialized.owl.carousel': $.proxy(function(e) { 25269 if (e.namespace && !this._initialized) { 25270 this._core.trigger('initialize', null, 'navigation'); 25271 this.initialize(); 25272 this.update(); 25273 this.draw(); 25274 this._initialized = true; 25275 this._core.trigger('initialized', null, 'navigation'); 25276 } 25277 }, this), 25278 'refreshed.owl.carousel': $.proxy(function(e) { 25279 if (e.namespace && this._initialized) { 25280 this._core.trigger('refresh', null, 'navigation'); 25281 this.update(); 25282 this.draw(); 25283 this._core.trigger('refreshed', null, 'navigation'); 25284 } 25285 }, this) 25286 }; 25287 25288 // set default options 25289 this._core.options = $.extend({}, Navigation.Defaults, this._core.options); 25290 25291 // register event handlers 25292 this.$element.on(this._handlers); 25293 }; 25294 25295 /** 25296 * Default options. 25297 * @public 25298 * @todo Rename `slideBy` to `navBy` 25299 */ 25300 Navigation.Defaults = { 25301 nav: false, 25302 navText: [ 'prev', 'next' ], 25303 navSpeed: false, 25304 navElement: 'div', 25305 navContainer: false, 25306 navContainerClass: 'owl-nav', 25307 navClass: [ 'owl-prev', 'owl-next' ], 25308 slideBy: 1, 25309 dotClass: 'owl-dot', 25310 dotsClass: 'owl-dots', 25311 dots: true, 25312 dotsEach: false, 25313 dotsData: false, 25314 dotsSpeed: false, 25315 dotsContainer: false 25316 }; 25317 25318 /** 25319 * Initializes the layout of the plugin and extends the carousel. 25320 * @protected 25321 */ 25322 Navigation.prototype.initialize = function() { 25323 var override, 25324 settings = this._core.settings; 25325 25326 // create DOM structure for relative navigation 25327 this._controls.$relative = (settings.navContainer ? $(settings.navContainer) 25328 : $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled'); 25329 25330 this._controls.$previous = $('<' + settings.navElement + '>') 25331 .addClass(settings.navClass[0]) 25332 .html(settings.navText[0]) 25333 .prependTo(this._controls.$relative) 25334 .on('click', $.proxy(function(e) { 25335 this.prev(settings.navSpeed); 25336 }, this)); 25337 this._controls.$next = $('<' + settings.navElement + '>') 25338 .addClass(settings.navClass[1]) 25339 .html(settings.navText[1]) 25340 .appendTo(this._controls.$relative) 25341 .on('click', $.proxy(function(e) { 25342 this.next(settings.navSpeed); 25343 }, this)); 25344 25345 // create DOM structure for absolute navigation 25346 if (!settings.dotsData) { 25347 this._templates = [ $('<div>') 25348 .addClass(settings.dotClass) 25349 .append($('<span>')) 25350 .prop('outerHTML') ]; 25351 } 25352 25353 this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer) 25354 : $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled'); 25355 25356 this._controls.$absolute.on('click', 'div', $.proxy(function(e) { 25357 var index = $(e.target).parent().is(this._controls.$absolute) 25358 ? $(e.target).index() : $(e.target).parent().index(); 25359 25360 e.preventDefault(); 25361 25362 this.to(index, settings.dotsSpeed); 25363 }, this)); 25364 25365 // override public methods of the carousel 25366 for (override in this._overrides) { 25367 this._core[override] = $.proxy(this[override], this); 25368 } 25369 }; 25370 25371 /** 25372 * Destroys the plugin. 25373 * @protected 25374 */ 25375 Navigation.prototype.destroy = function() { 25376 var handler, control, property, override; 25377 25378 for (handler in this._handlers) { 25379 this.$element.off(handler, this._handlers[handler]); 25380 } 25381 for (control in this._controls) { 25382 this._controls[control].remove(); 25383 } 25384 for (override in this.overides) { 25385 this._core[override] = this._overrides[override]; 25386 } 25387 for (property in Object.getOwnPropertyNames(this)) { 25388 typeof this[property] != 'function' && (this[property] = null); 25389 } 25390 }; 25391 25392 /** 25393 * Updates the internal state. 25394 * @protected 25395 */ 25396 Navigation.prototype.update = function() { 25397 var i, j, k, 25398 lower = this._core.clones().length / 2, 25399 upper = lower + this._core.items().length, 25400 maximum = this._core.maximum(true), 25401 settings = this._core.settings, 25402 size = settings.center || settings.autoWidth || settings.dotsData 25403 ? 1 : settings.dotsEach || settings.items; 25404 25405 if (settings.slideBy !== 'page') { 25406 settings.slideBy = Math.min(settings.slideBy, settings.items); 25407 } 25408 25409 if (settings.dots || settings.slideBy == 'page') { 25410 this._pages = []; 25411 25412 for (i = lower, j = 0, k = 0; i < upper; i++) { 25413 if (j >= size || j === 0) { 25414 this._pages.push({ 25415 start: Math.min(maximum, i - lower), 25416 end: i - lower + size - 1 25417 }); 25418 if (Math.min(maximum, i - lower) === maximum) { 25419 break; 25420 } 25421 j = 0, ++k; 25422 } 25423 j += this._core.mergers(this._core.relative(i)); 25424 } 25425 } 25426 }; 25427 25428 /** 25429 * Draws the user interface. 25430 * @todo The option `dotsData` wont work. 25431 * @protected 25432 */ 25433 Navigation.prototype.draw = function() { 25434 var difference, 25435 settings = this._core.settings, 25436 disabled = this._core.items().length <= settings.items, 25437 index = this._core.relative(this._core.current()), 25438 loop = settings.loop || settings.rewind; 25439 25440 this._controls.$relative.toggleClass('disabled', !settings.nav || disabled); 25441 25442 if (settings.nav) { 25443 this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true)); 25444 this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true)); 25445 } 25446 25447 this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled); 25448 25449 if (settings.dots) { 25450 difference = this._pages.length - this._controls.$absolute.children().length; 25451 25452 if (settings.dotsData && difference !== 0) { 25453 this._controls.$absolute.html(this._templates.join('')); 25454 } else if (difference > 0) { 25455 this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0])); 25456 } else if (difference < 0) { 25457 this._controls.$absolute.children().slice(difference).remove(); 25458 } 25459 25460 this._controls.$absolute.find('.active').removeClass('active'); 25461 this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 25462 } 25463 }; 25464 25465 /** 25466 * Extends event data. 25467 * @protected 25468 * @param {Event} event - The event object which gets thrown. 25469 */ 25470 Navigation.prototype.onTrigger = function(event) { 25471 var settings = this._core.settings; 25472 25473 event.page = { 25474 index: $.inArray(this.current(), this._pages), 25475 count: this._pages.length, 25476 size: settings && (settings.center || settings.autoWidth || settings.dotsData 25477 ? 1 : settings.dotsEach || settings.items) 25478 }; 25479 }; 25480 25481 /** 25482 * Gets the current page position of the carousel. 25483 * @protected 25484 * @returns {Number} 25485 */ 25486 Navigation.prototype.current = function() { 25487 var current = this._core.relative(this._core.current()); 25488 return $.grep(this._pages, $.proxy(function(page, index) { 25489 return page.start <= current && page.end >= current; 25490 }, this)).pop(); 25491 }; 25492 25493 /** 25494 * Gets the current succesor/predecessor position. 25495 * @protected 25496 * @returns {Number} 25497 */ 25498 Navigation.prototype.getPosition = function(successor) { 25499 var position, length, 25500 settings = this._core.settings; 25501 25502 if (settings.slideBy == 'page') { 25503 position = $.inArray(this.current(), this._pages); 25504 length = this._pages.length; 25505 successor ? ++position : --position;
vendor: 5,674 bytes, lines 25506-25730
25506 position = this._pages[((position % length) + length) % length].start; 25507 } else { 25508 position = this._core.relative(this._core.current()); 25509 length = this._core.items().length; 25510 successor ? position += settings.slideBy : position -= settings.slideBy; 25511 } 25512 25513 return position; 25514 }; 25515 25516 /** 25517 * Slides to the next item or page. 25518 * @public 25519 * @param {Number} [speed=false] - The time in milliseconds for the transition. 25520 */ 25521 Navigation.prototype.next = function(speed) { 25522 $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); 25523 }; 25524 25525 /** 25526 * Slides to the previous item or page. 25527 * @public 25528 * @param {Number} [speed=false] - The time in milliseconds for the transition. 25529 */ 25530 Navigation.prototype.prev = function(speed) { 25531 $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); 25532 }; 25533 25534 /** 25535 * Slides to the specified item or page. 25536 * @public 25537 * @param {Number} position - The position of the item or page. 25538 * @param {Number} [speed] - The time in milliseconds for the transition. 25539 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 25540 */ 25541 Navigation.prototype.to = function(position, speed, standard) { 25542 var length; 25543 25544 if (!standard) { 25545 length = this._pages.length; 25546 $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); 25547 } else { 25548 $.proxy(this._overrides.to, this._core)(position, speed); 25549 } 25550 }; 25551 25552 $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; 25553 25554})(window.Zepto || window.jQuery, window, document); 25555 25556/** 25557 * Hash Plugin 25558 * @version 2.0.0-beta.3 25559 * @author Artus Kolanowski 25560 * @license The MIT License (MIT) 25561 */ 25562;(function($, window, document, undefined) { 25563 'use strict'; 25564 25565 /** 25566 * Creates the hash plugin. 25567 * @class The Hash Plugin 25568 * @param {Owl} carousel - The Owl Carousel 25569 */ 25570 var Hash = function(carousel) { 25571 /** 25572 * Reference to the core. 25573 * @protected 25574 * @type {Owl} 25575 */ 25576 this._core = carousel; 25577 25578 /** 25579 * Hash index for the items. 25580 * @protected 25581 * @type {Object} 25582 */ 25583 this._hashes = {}; 25584 25585 /** 25586 * The carousel element. 25587 * @type {jQuery} 25588 */ 25589 this.$element = this._core.$element; 25590 25591 /** 25592 * All event handlers. 25593 * @protected 25594 * @type {Object} 25595 */ 25596 this._handlers = { 25597 'initialized.owl.carousel': $.proxy(function(e) { 25598 if (e.namespace && this._core.settings.startPosition === 'URLHash') { 25599 $(window).trigger('hashchange.owl.navigation'); 25600 } 25601 }, this), 25602 'prepared.owl.carousel': $.proxy(function(e) { 25603 if (e.namespace) { 25604 var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash'); 25605 25606 if (!hash) { 25607 return; 25608 } 25609 25610 this._hashes[hash] = e.content; 25611 } 25612 }, this), 25613 'changed.owl.carousel': $.proxy(function(e) { 25614 if (e.namespace && e.property.name === 'position') { 25615 var current = this._core.items(this._core.relative(this._core.current())), 25616 hash = $.map(this._hashes, function(item, hash) { 25617 return item === current ? hash : null; 25618 }).join(); 25619 25620 if (!hash || window.location.hash.slice(1) === hash) { 25621 return; 25622 } 25623 25624 window.location.hash = hash; 25625 } 25626 }, this) 25627 }; 25628 25629 // set default options 25630 this._core.options = $.extend({}, Hash.Defaults, this._core.options); 25631 25632 // register the event handlers 25633 this.$element.on(this._handlers); 25634 25635 // register event listener for hash navigation 25636 /*$(window).on('hashchange.owl.navigation', $.proxy(function(e) { 25637 var hash = window.location.hash.substring(1), 25638 items = this._core.$stage.children(), 25639 position = this._hashes[hash] && items.index(this._hashes[hash]); 25640 25641 if (position === undefined || position === this._core.current()) { 25642 return; 25643 } 25644 25645 this._core.to(this._core.relative(position), false, true); 25646 }, this));*/ 25647 }; 25648 25649 /** 25650 * Default options. 25651 * @public 25652 */ 25653 Hash.Defaults = { 25654 URLhashListener: false 25655 }; 25656 25657 /** 25658 * Destroys the plugin. 25659 * @public 25660 */ 25661 Hash.prototype.destroy = function() { 25662 var handler, property; 25663 25664 $(window).off('hashchange.owl.navigation'); 25665 25666 for (handler in this._handlers) { 25667 this._core.$element.off(handler, this._handlers[handler]); 25668 } 25669 for (property in Object.getOwnPropertyNames(this)) { 25670 typeof this[property] != 'function' && (this[property] = null); 25671 } 25672 }; 25673 25674 $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; 25675 25676})(window.Zepto || window.jQuery, window, document); 25677 25678/** 25679 * Support Plugin 25680 * 25681 * @version 2.0.0-beta.3 25682 * @author Vivid Planet Software GmbH 25683 * @author Artus Kolanowski 25684 * @license The MIT License (MIT) 25685 */ 25686;(function($, window, document, undefined) { 25687 25688 var style = $('<support>').get(0).style, 25689 prefixes = 'Webkit Moz O ms'.split(' '), 25690 events = { 25691 transition: { 25692 end: { 25693 WebkitTransition: 'webkitTransitionEnd', 25694 MozTransition: 'transitionend', 25695 OTransition: 'oTransitionEnd', 25696 transition: 'transitionend' 25697 } 25698 }, 25699 animation: { 25700 end: { 25701 WebkitAnimation: 'webkitAnimationEnd', 25702 MozAnimation: 'animationend', 25703 OAnimation: 'oAnimationEnd', 25704 animation: 'animationend' 25705 } 25706 } 25707 }, 25708 tests = { 25709 csstransforms: function() { 25710 return !!test('transform'); 25711 }, 25712 csstransforms3d: function() { 25713 return !!test('perspective'); 25714 }, 25715 csstransitions: function() { 25716 return !!test('transition'); 25717 }, 25718 cssanimations: function() { 25719 return !!test('animation'); 25720 } 25721 }; 25722 25723 function test(property, prefixed) { 25724 var result = false, 25725 upper = property.charAt(0).toUpperCase() + property.slice(1); 25726 25727 $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) { 25728 if (style[property] !== undefined) { 25729 result = prefixed ? property : true; 25730 return false;
25731 } 25732 }); 25733 25734 return result; 25735 } 25736 25737 function prefixed(property) { 25738 return test(property, true); 25739 } 25740 25741 if (tests.csstransitions()) { 25742 /* jshint -W053 */ 25743 $.support.transition = new String(prefixed('transition')) 25744 $.support.transition.end = events.transition.end[ $.support.transition ]; 25745 } 25746 25747 if (tests.cssanimations()) { 25748 /* jshint -W053 */ 25749 $.support.animation = new String(prefixed('animation')) 25750 $.support.animation.end = events.animation.end[ $.support.animation ]; 25751 } 25752 25753 if (tests.csstransforms()) { 25754 /* jshint -W053 */ 25755 $.support.transform = new String(prefixed('transform')); 25756 $.support.transform3d = tests.csstransforms3d(); 25757 } 25758 25759})(window.Zepto || window.jQuery, window, document); 25760 25761(function(window, document, undefined) { 25762 25763 /** 25764 * Find the absolute position of an element 25765 */ 25766 var absPos = function(element) { 25767 var offsetLeft, offsetTop; 25768 offsetLeft = offsetTop = 0; 25769 if (element.offsetParent) { 25770 do { 25771 offsetLeft += element.offsetLeft; 25772 offsetTop += element.offsetTop; 25773 } while (element = element.offsetParent); 25774 } 25775 return [offsetLeft, offsetTop]; 25776 }; 25777 25778 /** 25779 * @constructor Progress Circle class 25780 * @param params.canvas Canvas on which the circles will be drawn. 25781 * @param params.minRadius Inner radius of the innermost circle, in px. 25782 * @param params.arcWidth Width of each circle(to be more accurate, ring). 25783 * @param params.gapWidth Space between each circle. 25784 * @param params.centerX X coordinate of the center of circles. 25785 * @param params.centerY Y coordinate of the center of circles. 25786 * @param params.infoLineBaseAngle Base angle of the info line. 25787 * @param params.infoLineAngleInterval Angles between the info lines. 25788 */ 25789 var ProgressCircle = function(params) { 25790 this.canvas = params.canvas; 25791 this.minRadius = params.minRadius || 15; 25792 this.arcWidth = params.arcWidth || 5; 25793 this.gapWidth = params.gapWidth || 3; 25794 this.centerX = params.centerX || this.canvas.width / 2; 25795 this.centerY = params.centerY || this.canvas.height / 2;
25796 this.infoLineLength = params.infoLineLength || 60; 25797 this.horizLineLength = params.horizLineLength || 10; 25798 this.infoLineAngleInterval = params.infoLineAngleInterval || Math.PI / 8; 25799 this.infoLineBaseAngle = params.infoLineBaseAngle || Math.PI / 6; 25800 25801 this.context = this.canvas.getContext('2d'); 25802 25803 this.width = this.canvas.width; 25804 this.height = this.canvas.height; 25805 25806 this.circles = []; 25807 this.runningCount = 0; 25808 }; 25809 25810 ProgressCircle.prototype = { 25811 constructor: ProgressCircle, 25812 25813 /** 25814 * @method Adds an progress monitor entry. 25815 * @param params.fillColor Color to fill in the circle. 25816 * @param params.outlineColor Color to outline the circle. 25817 * @param params.progressListener Callback function to fetch the progress. 25818 * @param params.infoListener Callback function to fetch the info. 25819 * @returns this 25820 */ 25821 addEntry: function(params) { 25822 this.circles.push(new Circle({ 25823 canvas: this.canvas, 25824 context: this.context, 25825 centerX: this.centerX, 25826 centerY: this.centerY, 25827 innerRadius: this.minRadius + this.circles.length * 25828 (this.gapWidth + this.arcWidth), 25829 arcWidth: this.arcWidth,
25830 infoLineLength: this.infoLineLength, 25831 horizLineLength: this.horizLineLength, 25832 25833 id: this.circles.length, 25834 fillColor: params.fillColor, 25835 outlineColor: params.outlineColor, 25836 progressListener: params.progressListener, 25837 infoListener: params.infoListener, 25838 infoLineAngle: this.infoLineBaseAngle + 25839 this.circles.length * this.infoLineAngleInterval, 25840 })); 25841 25842 return this; 25843 }, 25844 25845 /** 25846 * @method Starts the monitor and updates with the given interval. 25847 * @param interval Interval between updates, in millisecond. 25848 * @returns this 25849 */ 25850 start: function(interval) { 25851 var self = this; 25852 this.timer = setInterval(function() { 25853 self._update(); 25854 }, interval || 33); 25855 25856 return this; 25857 }, 25858 25859 /** 25860 * @method Stop the animation. 25861 */ 25862 stop: function() { 25863 clearTimeout(this.timer); 25864 }, 25865 25866 /** 25867 * @private 25868 * @method Call update on each circle and redraw them. 25869 * @returns this 25870 */ 25871 _update: function() { 25872 this._clear(); 25873 this.circles.forEach(function(circle, idx, array) { 25874 circle.update(); 25875 }); 25876 25877 return this; 25878 }, 25879 25880 /** 25881 * @private 25882 * @method Clear the canvas. 25883 * @returns this 25884 */ 25885 _clear: function() { 25886 this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); 25887 25888 return this; 25889 }, 25890 25891 }; 25892 25893 /** 25894 * @private 25895 * @class Individual progress circle. 25896 * @param params.canvas Canvas on which the circle will be drawn. 25897 * @param params.context Context of the canvas. 25898 * @param params.innerRadius Inner radius of the circle, in px. 25899 * @param params.arcWidth Width of each arc(circle). 25900 * @param params.gapWidth Distance between each arc. 25901 * @param params.centerX X coordinate of the center of circles. 25902 * @param params.centerY Y coordinate of the center of circles. 25903 * @param params.fillColor Color to fill in the circle. 25904 * @param params.outlineColor Color to outline the circle. 25905 * @param params.progressListener Callback function to fetch the progress. 25906 * @param params.infoListener Callback function to fetch the info. 25907 * @param params.infoLineAngle Angle of info line. 25908 */ 25909 var Circle = function(params) { 25910 this.id = params.id; 25911 this.canvas = params.canvas; 25912 this.context = params.context; 25913 this.centerX = params.centerX; 25914 this.centerY = params.centerY; 25915 this.arcWidth = params.arcWidth; 25916 this.innerRadius = params.innerRadius || 0; 25917 this.fillColor = params.fillColor || '#fff'; 25918 this.outlineColor = params.outlineColor || this.fillColor; 25919 this.progressListener = params.progressListener;
25920 this.infoLineLength = params.infoLineLength || 250; 25921 this.horizLineLength = params.horizLineLength || 50; 25922 this.infoListener = params.infoListener; 25923 this.infoLineAngle = params.infoLineAngle; 25924 25925 this.outerRadius = this.innerRadius + this.arcWidth; 25926 25927 // If the info listener is not registered, then don't calculate 25928 // the related coordinates 25929 if (!this.infoListener) return; 25930 25931 // calculate the info-line turning points 25932 var angle = this.infoLineAngle, 25933 arcDistance = (this.innerRadius + this.outerRadius) / 2, 25934 25935 sinA = Math.sin(angle), 25936 cosA = Math.cos(angle); 25937 25938 this.infoLineStartX = this.centerX + sinA * arcDistance; 25939 this.infoLineStartY = this.centerY - cosA * arcDistance; 25940 25941 this.infoLineMidX = this.centerX + sinA * this.infoLineLength; 25942 this.infoLineMidY = this.centerY - cosA * this.infoLineLength; 25943 25944 this.infoLineEndX = this.infoLineMidX + 25945 (sinA < 0 ? -this.horizLineLength : this.horizLineLength); 25946 this.infoLineEndY = this.infoLineMidY; 25947 25948 var infoText = document.createElement('div'), 25949 style = infoText.style; 25950 25951 style.color = this.fillColor; 25952 style.position = 'absolute'; 25953 style.left = this.infoLineEndX + absPos(this.canvas)[0] + 'px'; 25954 // style.top will be calculated in the `drawInfo` method. Since 25955 // user may want to change the size of the font, so the top offset 25956 // must be updated in each loop. 25957 infoText.className = 'ProgressCircleInfo'; // For css styling 25958 infoText.id = 'progress_circle_info_' + this.id; 25959 document.body.appendChild(infoText); 25960 this.infoText = infoText; 25961 }; 25962 25963 Circle.prototype = { 25964 constructor: Circle, 25965 25966 update: function() { 25967 this.progress = this.progressListener(); 25968 this._draw(); 25969 25970 if (this.infoListener) { 25971 this.info = this.infoListener(); 25972 this._drawInfo(); 25973 } 25974 }, 25975 25976 /** 25977 * @private 25978 * @method Draw the circle on the canvas. 25979 * @returns this 25980 */ 25981 _draw: function() { 25982 var ctx = this.context, 25983 25984 ANGLE_OFFSET = -Math.PI / 2, 25985 25986 startAngle = 0 + ANGLE_OFFSET, 25987 endAngle= startAngle + this.progress * Math.PI * 2, 25988 25989 x = this.centerX, 25990 y = this.centerY, 25991 25992 innerRadius = this.innerRadius - this.arcWidth - 1, 25993 outerRadius = this.outerRadius - this.arcWidth - 1; 25994 25995 if ( innerRadius < 0 ) 25996 return; 25997 25998 ctx.fillStyle = this.fillColor; 25999 ctx.strokeStyle = this.outlineColor; 26000 26001 ctx.beginPath(); 26002 ctx.arc(x, y, innerRadius, startAngle, endAngle, false); 26003 ctx.arc(x, y, outerRadius, endAngle, startAngle, true); 26004 ctx.closePath(); 26005 ctx.stroke(); 26006 ctx.fill(); 26007 26008 return this; 26009 }, 26010 26011 /** 26012 * @private 26013 * @method Draw the info lines and info text. 26014 * @returns this 26015 */ 26016 _drawInfo: function() { 26017 26018 var pointList, lineHeight; 26019 26020 pointList = [ 26021 [this.infoLineStartX, this.infoLineStartY], 26022 [this.infoLineMidX, this.infoLineMidY], 26023 [this.infoLineEndX, this.infoLineEndY], 26024 ]; 26025 this._drawSegments(pointList, false); 26026 26027 this.infoText.innerHTML = this.info; 26028 26029 lineHeight = this.infoText.offsetHeight; 26030 this.infoText.style.top = this.infoLineEndY + 26031 absPos(this.canvas)[1] - lineHeight / 2 + 'px'; 26032 26033 return this; 26034 }, 26035 26036 /** 26037 * @private 26038 * @method Helper function to draw the segments 26039 * @param pointList An array of points in the form of [x, y]. 26040 * @param close Whether to connect the first and last point. 26041 */ 26042 _drawSegments: function(pointList, close) { 26043 var ctx = this.context; 26044 26045 ctx.beginPath(); 26046 ctx.moveTo(pointList[0][0], pointList[0][1]); 26047 for (var i = 1; i < pointList.length; ++i) { 26048 ctx.lineTo(pointList[i][0], pointList[i][1]); 26049 } 26050 26051 if (close) { 26052 ctx.closePath(); 26053 } 26054 ctx.stroke(); 26055 }, 26056 }; 26057 26058 window.ProgressCircle = ProgressCircle; 26059 26060})(window, document); 26061 26062 26063 26064 26065/* ========================================================= 26066 * jquery.vc_chart.js v1.0 26067 * ========================================================= 26068 * Copyright 2013 Wpbakery 26069 * 26070 * Jquery chart plugin for the Visual Composer. 26071 * ========================================================= */ 26072(function($){ 26073 /** 26074 * Pie chart animated. 26075 * @param element - DOM element 26076 * @param options - settings object. 26077 * @constructor 26078 */ 26079 var VcChart = function(element, options) { 26080 this.el = element; 26081 this.$el = $(this.el); 26082 var $this = this; 26083 $this.options = $.extend({ 26084 color: 'wpb_button', 26085 units: '', 26086 width: '', 26087 label_selector: '.vc_pie_chart_value', 26088 back_selector: '.vc_pie_chart_back', 26089 responsive: true 26090 }, options); 26091 $this.init(); 26092 }; 26093 VcChart.prototype = { 26094 constructor: VcChart, 26095 _progress_v: 0, 26096 animated: false, 26097 colors: { 26098 'wpb_button': 'rgba(247, 247, 247, 1)', 26099 'btn-primary': 'rgba(0, 136, 204, 1)', 26100 'btn-info': 'rgba(88, 185, 218, 1)', 26101 'btn-success': 'rgba(106, 177, 101, 1)', 26102 'btn-warning': 'rgba(255, 153, 0, 1)', 26103 'btn-danger': 'rgba(255, 103, 91, 1)', 26104 'btn-inverse': 'rgba(85, 85, 85, 1)' 26105 }, 26106 init: function() { 26107 this.setupColor(); 26108 this.value = this.$el.data('pie-value')/100; 26109 this.label_value = this.$el.data('pie-label-value') || this.$el.data('pie-value'); 26110 this.$wrapper = $('.vc_pie_wrapper', this.$el); 26111 this.$label = $(this.options.label_selector, this.$el); 26112 this.$back = $(this.options.back_selector, this.$el); 26113 this.$canvas = this.$el.find('canvas'); 26114 this.arcWidth = this.$el.data('pie-width') * 2; 26115 this.draw(); 26116 this.setWayPoint(); 26117 if(this.options.responsive === true) this.setResponsive(); 26118 if (UNCODE.isMobile) this._progress_v = this.value; 26119 }, 26120 setupColor: function() { 26121 // if(typeof this.colors[this.options.color] !== 'undefined') { 26122 // this.color = this.colors[this.options.color]; 26123 // } else if(typeof this.options.color === 'string' && this.options.color.match(/^rgba?\([^\)]+\)/)) { 26124 // this.color = this.options.color; 26125 // } else { 26126 // this.color = 'rgba(247, 247, 247, 0.2)'; 26127 // } 26128 if(typeof this.options.color !== 'undefined') { 26129 this.color = this.options.color; 26130 } else this.color = 'rgba(247, 247, 247, 0.2)'; 26131 26132 }, 26133 setResponsive: function() { 26134 var that = this; 26135 if (!UNCODE.isMobile) { 26136 $(window).resize(function(){ 26137 if(that.animated === true) that.circle.stop(); 26138 that.draw(true); 26139 }); 26140 } 26141 }, 26142 draw: function(redraw) { 26143 var w = this.$el.addClass('vc_ready').width() * 2, 26144 border_w = this.arcWidth, 26145 radius; 26146 if(!w) w = this.$el.parents(':visible').first().width()-2; 26147 //w = Math.round(w/100*80); 26148 //if (w < 250) w = 250; 26149 radius = w/2; 26150 this.$wrapper.css({"width" : (w / 2) + "px"}); 26151 this.$label.css({"width" : (w / 2), "height" : (w / 2), "line-height" : (w / 2)+"px"}); 26152 this.$back.css({"width" : (w / 2), "height" : (w / 2)}); 26153 this.$canvas.attr({"width" : w + "px", "height" : w + "px"}); 26154 this.$el.addClass('vc_ready'); 26155 this.circle = new ProgressCircle({ 26156 canvas: this.$canvas.get(0), 26157 minRadius: radius, 26158 arcWidth: border_w 26159 }); 26160 if(redraw === true && this.animated === true) { 26161 this._progress_v = this.value; 26162 this.circle.addEntry({ 26163 fillColor: this.color, 26164 progressListener: $.proxy(this.setProgress, this) 26165 }).start(); 26166 } 26167 }, 26168 setProgress: function() { 26169 if (this._progress_v >= this.value) { 26170 this.circle.stop(); 26171 this.animated = true; 26172 this.$label.html(this.label_value + this.options.units); 26173 return this._progress_v; 26174 } 26175 this._progress_v += 0.01; 26176 if (!isNaN(this.label_value)) { 26177 var label_value = this._progress_v/this.value*this.label_value; 26178 var val = Math.round(label_value) + this.options.units; 26179 this.$label.html(val); 26180 } else this.$label.html(this.label_value + this.options.units); 26181 return this._progress_v; 26182 }, 26183 animate: function() { 26184 if(this.animated !== true) { 26185 this.circle.addEntry({ 26186 fillColor: this.color, 26187 progressListener: $.proxy(this.setProgress, this) 26188 }).start(10); 26189 } 26190 }, 26191 setWayPoint: function() { 26192 if (typeof $.fn.waypoint !== 'undefined' && !UNCODE.isMobile) { 26193 this.$el.waypoint($.proxy(this.animate, this), { offset: '85%' }); 26194 } else { 26195 this.animate(); 26196 } 26197 } 26198 }; 26199 /** 26200 * jQuery plugin 26201 * @param option - object with settings 26202 * @return {*} 26203 */ 26204 $.fn.vcChat = function(option, value) { 26205 return this.each(function () { 26206 var $this = $(this), 26207 data = $this.data('vc_chart'), 26208 options = typeof option === 'object' ? option : { 26209 color: $this.data('pie-color'), 26210 units: $this.data('pie-units') 26211 }; 26212 if (typeof option == 'undefined') $this.data('vc_chart', (data = new VcChart(this, options))); 26213 if (typeof option == 'string') data[option](value); 26214 }); 26215 }; 26216 /** 26217 * Allows users to rewrite function inside theme. 26218 */ 26219 if ( typeof window['vc_pieChart'] !== 'function' ) { 26220 window.vc_pieChart = function() { 26221 $('.vc_pie_chart:visible:not(.vc_ready)').vcChat(); 26222 } 26223 } 26224 $(document).ready(function(){ 26225 !window.vc_iframe && vc_pieChart(); 26226 26227 /** 26228 * Tab and collapse integration. 26229 */ 26230 $('.nav-tabs a').on('shown.bs.tab', function(e){ 26231 var $cont = $(e.target).closest('.tab-container'), 26232 $active = $('.tab-pane.active', $cont); 26233 $('.vc_pie_chart:not(.vc_ready)', $active).vcChat(); 26234 }); 26235 26236 $('.panel-collapse').on('shown.bs.collapse', function (e) { 26237 $('.vc_pie_chart:not(.vc_ready)', e.target).vcChat(); 26238 }) 26239 }); 26240 26241})(window.jQuery); 26242 26243/* Progress bar 26244 ---------------------------------------------------------- */ 26245function uncode_progress_bar() { 26246 jQuery.each(jQuery('.vc_progress_bar'), function(index, val) { 26247 if (UNCODE.isUnmodalOpen && !val.closest('#unmodal-content')) { 26248 return; 26249 } 26250 if (!UNCODE.isMobile) { 26251 new Waypoint({ 26252 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 26253 element: val, 26254 handler: function() { 26255 var element = jQuery(this.element); 26256 element.find('.vc_single_bar').each(function(index) { 26257 var $this = jQuery(this), 26258 bar = $this.find('.vc_bar'), 26259 val = bar.data('percentage-value'); 26260 setTimeout(function() { 26261 bar.css({ 26262 "width": val + '%' 26263 }); 26264 }, index * 200); 26265 }); 26266 }, 26267 offset: '80%' 26268 }); 26269 } else { 26270 var element = jQuery(val); 26271 element.find('.vc_single_bar').each(function(index) { 26272 var $this = jQuery(this), 26273 bar = $this.find('.vc_bar'), 26274 val = bar.data('percentage-value'); 26275 setTimeout(function() { 26276 bar.css({ 26277 "width": val + '%' 26278 }); 26279 }, index * 200); 26280 }); 26281 } 26282 }); 26283}; 26284uncode_progress_bar(); 26285 26286/*! 26287 * jquery.counterup.js 1.0 26288 * 26289 * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal 26290 * Released under the GPL v2 License 26291 * 26292 * Date: Nov 26, 2013 26293 */ 26294(function($) { 26295 "use strict"; 26296 $.fn.counterUp = function(options) { 26297 // Defaults 26298 var settings = $.extend({ 26299 'time': 400, 26300 'delay': 10 26301 }, options); 26302 return this.each(function() { 26303 // Store the object 26304 var $this = $(this); 26305 var $settings = settings; 26306 var counterUpper = function() { 26307 var nums = []; 26308 var divisions = $settings.time / $settings.delay; 26309 var numReal = $this.attr('data-val'), 26310 num = numReal; 26311 var isComma = /[0-9]+,[0-9]+/.test(num); 26312 num = num.replace(/,/g, ''); 26313 var isInt = /^[0-9]+$/.test(num); 26314 var isFloat = /^[0-9]+\.[0-9]+$/.test(num); 26315 var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0; 26316 // Generate list of incremental numbers to display 26317 for (var i = divisions; i >= 1; i--) { 26318 // Preserve as int if input was int 26319 var newNum = parseInt(num / divisions * i); 26320 // Preserve float if input was float 26321 if (isFloat) { 26322 newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces); 26323 } 26324 // Preserve commas if input had commas 26325 if (isComma) { 26326 while (/(\d+)(\d{3})/.test(newNum.toString())) { 26327 newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2'); 26328 } 26329 } 26330 nums.unshift(newNum); 26331 } 26332 nums.push(numReal); 26333 $this.data('counterup-nums', nums); 26334 $this.text('0'); 26335 // Updates the number until we're done 26336 var f = function() { 26337 if ($this.data('counterup-nums') != null) { 26338 $this.text($this.data('counterup-nums').shift()); 26339 if ($this.data('counterup-nums').length) { 26340 setTimeout($this.data('counterup-func'), $settings.delay); 26341 } else { 26342 delete $this.data('counterup-nums'); 26343 $this.data('counterup-nums', null); 26344 $this.data('counterup-func', null); 26345 } 26346 } 26347 }; 26348 $this.data('counterup-func', f); 26349 // Start the count up 26350 setTimeout($this.data('counterup-func'), $settings.delay); 26351 }; 26352 // Perform counts when the element gets into view 26353 new Waypoint({ 26354 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 26355 element: this, 26356 handler: function() { 26357 counterUpper(); 26358 if (!UNCODE.isUnmodalOpen) { 26359 this.destroy(); 26360 } 26361 }, 26362 offset: '100%' 26363 }); 26364 }); 26365 }; 26366})(jQuery); 26367 26368/*! 26369 * The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/) 26370 * Copyright (c) 2016 Edson Hilios 26371 * 26372 * Permission is hereby granted, free of charge, to any person obtaining a copy of 26373 * this software and associated documentation files (the "Software"), to deal in 26374 * the Software without restriction, including without limitation the rights to 26375 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 26376 * the Software, and to permit persons to whom the Software is furnished to do so, 26377 * subject to the following conditions: 26378 * 26379 * The above copyright notice and this permission notice shall be included in all 26380 * copies or substantial portions of the Software. 26381 * 26382 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26383 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 26384 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 26385 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26386 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26387 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26388 */ 26389(function(factory) { 26390 "use strict"; 26391 if (typeof define === "function" && define.amd) { 26392 define([ "jquery" ], factory); 26393 } else { 26394 factory(jQuery); 26395 } 26396})(function($) { 26397 "use strict"; 26398 var instances = [], matchers = [], defaultOptions = { 26399 precision: 100, 26400 elapse: false, 26401 defer: false 26402 }; 26403 matchers.push(/^[0-9]*$/.source); 26404 matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 26405 matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 26406 matchers = new RegExp(matchers.join("|")); 26407 function parseDateString(dateString) { 26408 if (dateString instanceof Date) { 26409 return dateString; 26410 } 26411 if (String(dateString).match(matchers)) { 26412 if (String(dateString).match(/^[0-9]*$/)) { 26413 dateString = Number(dateString); 26414 } 26415 if (String(dateString).match(/\-/)) { 26416 dateString = String(dateString).replace(/\-/g, "/"); 26417 } 26418 return new Date(dateString); 26419 } else { 26420 throw new Error("Couldn't cast `" + dateString + "` to a date object."); 26421 } 26422 } 26423 var DIRECTIVE_KEY_MAP = { 26424 Y: "years", 26425 m: "months", 26426 n: "daysToMonth", 26427 d: "daysToWeek", 26428 w: "weeks", 26429 W: "weeksToMonth", 26430 H: "hours", 26431 M: "minutes", 26432 S: "seconds", 26433 D: "totalDays", 26434 I: "totalHours", 26435 N: "totalMinutes", 26436 T: "totalSeconds" 26437 }; 26438 function escapedRegExp(str) { 26439 var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); 26440 return new RegExp(sanitize); 26441 } 26442 function strftime(offsetObject) { 26443 return function(format) { 26444 var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi); 26445 if (directives) { 26446 for (var i = 0, len = directives.length; i < len; ++i) { 26447 var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null; 26448 directive = directive[2]; 26449 if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) { 26450 value = DIRECTIVE_KEY_MAP[directive]; 26451 value = Number(offsetObject[value]); 26452 } 26453 if (value !== null) { 26454 if (modifier === "!") { 26455 value = pluralize(plural, value); 26456 } 26457 if (modifier === "") { 26458 if (value < 10) { 26459 value = "0" + value.toString(); 26460 } 26461 } 26462 format = format.replace(regexp, value.toString()); 26463 } 26464 } 26465 } 26466 format = format.replace(/%%/, "%"); 26467 return format; 26468 }; 26469 } 26470 function pluralize(format, count) { 26471 var plural = "s", singular = ""; 26472 if (format) { 26473 format = format.rep
vendor: 8,618 bytes, lines 26473-26617
26473lace(/(:|;|\s)/gi, "").split(/\,/); 26474 if (format.length === 1) { 26475 plural = format[0]; 26476 } else { 26477 singular = format[0]; 26478 plural = format[1]; 26479 } 26480 } 26481 if (Math.abs(count) > 1) { 26482 return plural; 26483 } else { 26484 return singular; 26485 } 26486 } 26487 var Countdown = function(el, finalDate, options) { 26488 this.el = el; 26489 this.$el = $(el); 26490 this.interval = null; 26491 this.offset = {}; 26492 this.options = $.extend({}, defaultOptions); 26493 this.instanceNumber = instances.length; 26494 instances.push(this); 26495 this.$el.data("countdown-instance", this.instanceNumber); 26496 if (options) { 26497 if (typeof options === "function") { 26498 this.$el.on("update.countdown", options); 26499 this.$el.on("stoped.countdown", options); 26500 this.$el.on("finish.countdown", options); 26501 } else { 26502 this.options = $.extend({}, defaultOptions, options); 26503 } 26504 } 26505 this.setFinalDate(finalDate); 26506 if (this.options.defer === false) { 26507 this.start(); 26508 } 26509 }; 26510 $.extend(Countdown.prototype, { 26511 start: function() { 26512 if (this.interval !== null) { 26513 clearInterval(this.interval); 26514 } 26515 var self = this; 26516 this.update(); 26517 this.interval = setInterval(function() { 26518 self.update.call(self); 26519 }, this.options.precision); 26520 }, 26521 stop: function() { 26522 clearInterval(this.interval); 26523 this.interval = null; 26524 this.dispatchEvent("stoped"); 26525 }, 26526 toggle: function() { 26527 if (this.interval) { 26528 this.stop(); 26529 } else { 26530 this.start(); 26531 } 26532 }, 26533 pause: function() { 26534 this.stop(); 26535 }, 26536 resume: function() { 26537 this.start(); 26538 }, 26539 remove: function() { 26540 this.stop.call(this); 26541 instances[this.instanceNumber] = null; 26542 delete this.$el.data().countdownInstance; 26543 }, 26544 setFinalDate: function(value) { 26545 this.finalDate = parseDateString(value); 26546 }, 26547 update: function() { 26548 if (this.$el.closest("html").length === 0) { 26549 this.remove(); 26550 return; 26551 } 26552 var hasEventsAttached = $._data(this.el, "events") !== undefined, now = new Date(), newTotalSecsLeft; 26553 newTotalSecsLeft = this.finalDate.getTime() - now.getTime(); 26554 newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3); 26555 newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft); 26556 if (this.totalSecsLeft === newTotalSecsLeft || !hasEventsAttached) { 26557 return; 26558 } else { 26559 this.totalSecsLeft = newTotalSecsLeft; 26560 } 26561 this.elapsed = now >= this.finalDate; 26562 this.offset = { 26563 seconds: this.totalSecsLeft % 60, 26564 minutes: Math.floor(this.totalSecsLeft / 60) % 60, 26565 hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24, 26566 days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 26567 daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 26568 daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368), 26569 weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7), 26570 weeksToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7) % 4, 26571 months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368), 26572 years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()), 26573 totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24), 26574 totalHours: Math.floor(this.totalSecsLeft / 60 / 60), 26575 totalMinutes: Math.floor(this.totalSecsLeft / 60), 26576 totalSeconds: this.totalSecsLeft 26577 }; 26578 if (!this.options.elapse && this.totalSecsLeft === 0) { 26579 this.stop(); 26580 this.dispatchEvent("finish"); 26581 } else { 26582 this.dispatchEvent("update"); 26583 } 26584 }, 26585 dispatchEvent: function(eventName) { 26586 var event = $.Event(eventName + ".countdown"); 26587 event.finalDate = this.finalDate; 26588 event.elapsed = this.elapsed; 26589 event.offset = $.extend({}, this.offset); 26590 event.strftime = strftime(this.offset); 26591 this.$el.trigger(event); 26592 } 26593 }); 26594 $.fn.countdown = function() { 26595 var argumentsArray = Array.prototype.slice.call(arguments, 0); 26596 return this.each(function() { 26597 var instanceNumber = $(this).data("countdown-instance"); 26598 if (instanceNumber !== undefined) { 26599 var instance = instances[instanceNumber], method = argumentsArray[0]; 26600 if (Countdown.prototype.hasOwnProperty(method)) { 26601 instance[method].apply(instance, argumentsArray.slice(1)); 26602 } else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) { 26603 instance.setFinalDate.call(instance, method); 26604 instance.start(); 26605 } else { 26606 $.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method)); 26607 } 26608 } else { 26609 new Countdown(this, argumentsArray[0], argumentsArray[1]); 26610 } 26611 }); 26612 }; 26613}); 26614 26615!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; 26616function getStyles(config){ 26617 // 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;
26617left: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+"}" 26618}; 26619 var ShareUtils; 26620 26621if ((!("classList" in document.documentElement)) && Object.defineProperty && typeof HTMLElement !== "undefined") { 26622 Object.defineProperty(HTMLElement.prototype, "classList", { 26623 get: function() { 26624 var ret, self, update; 26625 update = function(fn) { 26626 return function(value) { 26627 var classes, index; 26628 classes = self.className.split(/\s+/); 26629 index = classes.indexOf(value); 26630 fn(classes, index, value); 26631 self.className = classes.join(" "); 26632 }; 26633 }; 26634 self = this; 26635 ret = { 26636 add: update(function(classes, index, value) { 26637 ~index || classes.push(value); 26638 }), 26639 remove: update(function(classes, index) { 26640 ~index && classes.splice(index, 1); 26641 }), 26642 toggle: update(function(classes, index, value) { 26643 if (~index) { 26644 classes.splice(index, 1); 26645 } else { 26646 classes.push(value); 26647 } 26648 }), 26649 contains: function(value) { 26650 return !!~self.className.split(/\s+/).indexOf(value); 26651 }, 26652 item: function(i) { 26653 return self.className.split(/\s+/)[i] || null; 26654 } 26655 }; 26656 Object.defineProperty(ret, "length", { 26657 get: function() { 26658 return self.className.split(/\s+/).length; 26659 } 26660 }); 26661 return ret; 26662 } 26663 }); 26664} 26665 26666String.prototype.to_rfc3986 = function() { 26667 var tmp; 26668 tmp = encodeURIComponent(this); 26669 return tmp.replace(/[!'()*]/g, function(c) { 26670 return "%" + c.charCodeAt(0).toString(16); 26671 }); 26672}; 26673 26674ShareUtils = (function() { 26675 function ShareUtils() {} 26676 26677 ShareUtils.prototype.extend = function(to, from, overwrite) { 26678 var hasProp, prop; 26679 for (prop in from) { 26680 hasProp = to[prop] !== undefined; 26681 if (hasProp && typeof from[prop] === "object") { 26682 this.extend(to[prop], from[prop], overwrite); 26683 } else { 26684 if (overwrite || !hasProp) { 26685 to[prop] = from[prop]; 26686 } 26687 } 26688 } 26689 }; 26690 26691 ShareUtils.prototype.hide = function(el) { 26692 return el.style.display = "none"; 26693 }; 26694 26695 ShareUtils.prototype.show = function(el) { 26696 return el.style.display = "block"; 26697 }; 26698 26699 ShareUtils.prototype.has_class = function(el, class_name) { 26700 return el.classList.contains(class_name); 26701 }; 26702 26703 ShareUtils.prototype.add_class = function(el, class_name) { 26704 return el.classList.add(class_name); 26705 }; 26706 26707 ShareUtils.prototype.remove_class = function(el, class_name) { 26708 return el.classList.remove(class_name); 26709 }; 26710 26711 ShareUtils.prototype.is_encoded = function(str) { 26712 str = str.to_rfc3986(); 26713 return decodeURIComponent(str) !== str; 26714 }; 26715 26716 ShareUtils.prototype.encode = function(str) { 26717 if (typeof str === "undefined" || this.is_encoded(str)) { 26718 return str; 26719 } else { 26720 return str.to_rfc3986(); 26721 } 26722 }; 26723 26724 ShareUtils.prototype.popup = function(url, params) { 26725 var k, popup, qs, v; 26726 if (params == null) { 26727 params = {}; 26728 } 26729 popup = { 26730 width: 500, 26731 height: 350 26732 }; 26733 popup.top = (screen.height / 2) - (popup.height / 2); 26734 popup.left = (screen.width / 2) - (popup.width / 2); 26735 qs = ((function() { 26736 var _results; 26737 _results = []; 26738 for (k in params) { 26739 v = params[k]; 26740 _results.push("" + k + "=" + (this.encode(v))); 26741 } 26742 return _results; 26743 }).call(this)).join('&'); 26744 if (qs) { 26745 qs = "?" + qs; 26746 } 26747 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="
26747+ popup.width + ",height=" + popup.height); 26748 }; 26749 26750 return ShareUtils; 26751 26752})(); 26753var Share, 26754 __hasProp = {}.hasOwnProperty, 26755 __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; }; 26756 26757Share = (function(_super) { 26758 __extends(Share, _super); 26759 26760 function Share(element, options) { 26761 this.element = element; 26762 this.el = { 26763 head: document.getElementsByTagName('head')[0], 26764 body: document.getElementsByTagName('body')[0] 26765 }; 26766 this.config = { 26767 enabled_networks: 0, 26768 protocol: ['http', 'https'].indexOf(window.location.href.split(':')[0]) === -1 ? 'https://' : '//', 26769 url: window.location.href.replace("&", "%26"), 26770 caption: null, 26771 title: this.default_title(), 26772 image: this.default_image(), 26773 description: this.default_description(), 26774 ui: { 26775 flyout: 'top center', 26776 button_text: 'Share', 26777 button_font: true, 26778 icon_font: true 26779 }, 26780 networks: { 26781 twitter: { 26782 enabled: true, 26783 url: null, 26784 title: null, 26785 description: null 26786 }, 26787 facebook: { 26788 enabled: true, 26789 load_sdk: true, 26790 url: null, 26791 app_id: null, 26792 title: null, 26793 caption: null, 26794 description: null, 26795 image: null 26796 }, 26797 pinterest: { 26798 enabled: true, 26799 url: null, 26800 image: null, 26801 description: null 26802 }, 26803 reddit: { 26804 enabled: true, 26805 url: null, 26806 title: null 26807 }, 26808 linkedin: { 26809 enabled: true, 26810 url: null, 26811 title: null, 26812 description: null 26813 }, 26814 xing: { 26815 enabled: true, 26816 url: null, 26817 title: null, 26818 image: null, 26819 description: null 26820 }, 26821 whatsapp: { 26822 enabled: true, 26823 title: null, 26824 url: null 26825 }, 26826 email: { 26827 enabled: true, 26828 title: null, 26829 description: null, 26830 url: null 26831 } 26832 } 26833 }; 26834 this.setup(element, options); 26835 return this; 26836 } 26837 26838 Share.prototype.setup = function(element, opts) { 26839 var index, instance, instances, _i, _len; 26840 instances = document.querySelectorAll(element); 26841 this.extend(this.config, opts, true); 26842 this.set_global_configuration(); 26843 this.normalize_network_configuration(); 26844 if (this.config.ui.icon_font) { 26845 this.inject_icons(); 26846 } 26847 if (this.config.ui.button_font) { 26848 this.inject_fonts(); 26849 } 26850 if (this.config.networks.facebook.enabled && this.config.networks.facebook.load_sdk) { 26851 this.inject_facebook_sdk(); 26852 } 26853 for (index = _i = 0, _len = instances.length; _i < _len; index = ++_i) { 26854 instance = instances[index]; 26855 this.setup_instance(element, index); 26856 } 26857 }; 26858 26859 Share.prototype.setup_instance = function(element, index) { 26860 var button, instance, label, network, networks, _i, _len, _results, 26861 _this = this; 26862 instance = document.querySelectorAll(element)[index]; 26863 this.hide(instance); 26864 this.add_class(instance, "sharer-" + index); 26865 instance = document.querySelectorAll(element)[index]; 26866 this.inject_css(instance); 26867 this.inject_html(instance); 26868 this.show(instance); 26869 label = instance.getElementsByTagName("label")[0]; 26870 button = instance.getElementsByClassName("social")[0]; 26871 networks = instance.getElementsByTagName('li'); 26872 this.add_class(button, "networks-" + this.config.enabled_networks); 26873 label.addEventListener("click", function() { 26874 return _this.event_toggle(button); 26875 }); 26876 _this = this; 26877 _results = []; 26878 for (index = _i = 0, _len = networks.length; _i < _len; index = ++_i) { 26879 network = networks[index]; 26880 _results.push(network.addEventListener("click", function() { 26881 _this.event_network(instance, this); 26882 return _this.event_close(button); 26883 })); 26884 } 26885 return _results; 26886 }; 26887 26888 Share.prototype.event_toggle = function(button) { 26889 if (this.has_class(button, "active")) { 26890 return this.event_close(button); 26891 } else { 26892 return this.event_open(button); 26893 } 26894 }; 26895 26896 Share.prototype.event_open = function(button) { 26897 if (this.has_class(button, "load")) { 26898 this.remove_class(button, "load"); 26899 } 26900 return this.add_class(button, "active"); 26901 }; 26902 26903 Share.prototype.event_close = function(button) { 26904 return this.remove_class(button, "active"); 26905 }; 26906 26907 Share.prototype.event_network = function(instance, network) { 26908 var name; 26909 name = network.getAttribute("data-network"); 26910 this.hook("before", name, instance);
26911 this["network_" + name](); 26912 return this.hook("after", name, instance); 26913 }; 26914 26915 Share.prototype.open = function() { 26916 return this["public"]("open"); 26917 }; 26918 26919 Share.prototype.close = function() { 26920 return this["public"]("close"); 26921 }; 26922 26923 Share.prototype.toggle = function() { 26924 return this["public"]("toggle"); 26925 }; 26926 26927 Share.prototype["public"] = function(action) { 26928 var button, index, instance, _i, _len, _ref, _results; 26929 _ref = document.querySelectorAll(this.element); 26930 _results = []; 26931 for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { 26932 instance = _ref[index]; 26933 button = instance.getElementsByClassName("social")[0]; 26934 _results.push(this["event_" + action](button)); 26935 } 26936 return _results; 26937 }; 26938 26939 Share.prototype.network_facebook = function() { 26940 if (this.config.networks.facebook.load_sdk) { 26941 if (!window.FB) { 26942 return console.error("The Facebook JS SDK hasn't loaded yet."); 26943 } 26944 return FB.ui({ 26945 method: 'feed', 26946 name: this.config.networks.facebook.title, 26947 link: this.config.networks.facebook.url, 26948 picture: this.config.networks.facebook.image, 26949 caption: this.config.networks.facebook.caption, 26950 description: this.config.networks.facebook.description 26951 }); 26952 } else { 26953 return this.popup('https://www.facebook.com/sharer/sharer.php', { 26954 u: this.config.networks.facebook.url 26955 }); 26956 } 26957 }; 26958 26959 Share.prototype.network_twitter = function() { 26960 return this.popup('https://twitter.com/intent/tweet', { 26961 text: this.config.networks.twitter.title, 26962 url: this.config.networks.twitter.url 26963 }); 26964 }; 26965 26966 Share.prototype.network_pinterest = function() { 26967 return this.popup('https://www.pinterest.com/pin/create/button', { 26968 url: this.config.networks.pinterest.url, 26969 media: this.config.networks.pinterest.image, 26970 description: this.config.networks.pinterest.description 26971 }); 26972 }; 26973 26974 Share.prototype.network_linkedin = function() { 26975 return this.popup('https://www.linkedin.com/shareArticle', { 26976 url: this.config.networks.linkedin.url, 26977 title: this.config.networks.linkedin.title, 26978 summary: this.config.networks.linkedin.description 26979 }); 26980 } 26981 26982 Share.prototype.network_xing = function() { 26983 return this.popup('https://www.xing.com/spi/shares/new', { 26984 url: this.config.networks.xing.url, 26985 image: this.config.networks.xing.image, 26986 title: this.config.networks.xing.title, 26987 summary: this.config.networks.xing.description 26988 }); 26989 } 26990 26991 Share.prototype.network_whatsapp = function() { 26992 return this.popup('https://api.whatsapp.com/send', { 26993 text: this.config.networks.whatsapp.title + '%20' + this.config.networks.whatsapp.url, 26994 }); 26995 } 26996 26997 Share.prototype.network_email = function() { 26998 return this.popup('mailto:', { 26999 subject: this.config.networks.email.title, 27000 body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description, 27001 }); 27002 }; 27003 27004 Share.prototype.inject_icons = function() { 27005 // return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css"); 27006 }; 27007 27008 Share.prototype.inject_fonts = function() { 27009 // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text); 27010 }; 27011 27012 Share.prototype.inject_stylesheet = function(url) { 27013 var link; 27014 if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) { 27015 link = document.createElement("link"); 27016 link.setAttribute("rel", "stylesheet"); 27017 link.setAttribute("href", url); 27018 return this.el.head.appendChild(link); 27019 } 27020 }; 27021 27022 Share.prototype.inject_css = function(instance) { 27023 var css, meta, selector, style; 27024 selector = "." + (instance.getAttribute('class').split(" ").join(".")); 27025 if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) { 27026 this.config.selector = selector; 27027 css = getStyles(this.config); 27028 style = document.createElement("style"); 27029 style.type = "text/css"; 27030 if (style.styleSheet) { 27031 style.styleSheet.cssText = css; 27032 } else { 27033 style.appendChild(document.createTextNode(css)); 27034 } 27035 this.el.head.appendChild(style); 27036 delete this.config.selector; 27037 meta = document.createElement("meta"); 27038 meta.setAttribute("name", "sharer" + selector); 27039 return this.el.head.appendChild(meta); 27040 } 27041 }; 27042 27043 Share.prototype.inject_html = function(instance) { 27044 //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>"; 27045 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>"; 27046 }; 27047 27048 Share.prototype.inject_facebook_sdk = function() { 27049 var fb_root, script; 27050 if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) { 27051 script = document.createElement("script"); 27052 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')"; 27053 fb_root = document.createElement("div"); 27054 fb_root.id = "fb-root"; 27055 this.el.body.appendChild(fb_root); 27056 return this.el.body.appendChild(script); 27057 } 27058 }; 27059 27060 Share.prototype.hook = function(type, network, instance) { 27061 var fn, opts; 27062 fn = this.config.networks[network][type]; 27063 if (typeof fn === "function") { 27064 opts = fn.call(this.config.networks[network], instance); 27065 if (opts !== void 0) { 27066 opts = this.normalize_filter_config_updates(opts); 27067 this.extend(this.config.networks[network], opts, true); 27068 this.normalize_network_configuration(); 27069 } 27070 } 27071 }; 27072 27073 Share.prototype.default_title = function() { 27074 var content; 27075 if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) { 27076 return encodeURIComponent(content.getAttribute('content')); 27077 } else if (content = document.querySelector('title')) { 27078 return encodeURIComponent(content.innerText); 27079 } 27080 }; 27081 27082 Share.prototype.default_image = function() { 27083 var content; 27084 if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) { 27085 return content.getAttribute('content'); 27086 } 27087 }; 27088 27089 Share.prototype.default_description = function() { 27090 var content; 27091 if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) { 27092 return encodeURIComponent(content.getAttribute('content')); 27093 } else { 27094 return ''; 27095 } 27096 }; 27097 27098 Share.prototype.set_global_configuration = function() { 27099 var display, network, option, options, _ref, _results; 27100 _ref = this.config.networks; 27101 _results = []; 27102 for (network in _ref) { 27103 options = _ref[network]; 27104 for (option in options) { 27105 if (this.config.networks[network][option] == null) { 27106 this.config.networks[network][option] = this.config[option]; 27107 } 27108 } 27109 if (this.config.networks[network].enabled) { 27110 display = 'block'; 27111 this.config.enabled_networks += 1; 27112 } else { 27113 display = 'none'; 27114 } 27115 _results.push(this.config.networks[network].display = display); 27116 } 27117 return _results; 27118 }; 27119 27120 Share.prototype.normalize_network_configuration = function() { 27121 if (!this.config.networks.facebook.app_id) { 27122 this.config.networks.facebook.load_sdk = false;
27123 } 27124 if (!this.is_encoded(this.config.networks.twitter.description)) { 27125 this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description); 27126 } 27127 if (typeof this.config.networks.facebook.app_id === 'number') { 27128 return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString(); 27129 } 27130 }; 27131 27132 Share.prototype.normalize_filter_config_updates = function(opts) { 27133 if (this.config.networks.facebook.app_id !== opts.app_id) { 27134 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."); 27135 delete opts.app_id; 27136 } 27137 if (this.config.networks.facebook.load_sdk !== opts.load_sdk) { 27138 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."); 27139 delete opts.app_id; 27140 } 27141 return opts; 27142 }; 27143 27144 return Share; 27145 27146})(ShareUtils); 27147 return Share; 27148}); 27149 27150// Generated by CoffeeScript 1.9.2 27151 27152// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net 27153 27154(function() { 27155 var $, win; 27156 27157 $ = this.jQuery || window.jQuery; 27158 27159 win = $(window); 27160 27161 $.fn.stick_in_parent = function(opts) { 27162 var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class; 27163 if (opts == null) { 27164 opts = {}; 27165 } 27166 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; 27167 if (offset_top == null) { 27168 offset_top = 0; 27169 } 27170 if (parent_selector == null) { 27171 parent_selector = void 0; 27172 } 27173 if (inner_scrolling == null) { 27174 inner_scrolling = true; 27175 } 27176 if (sticky_class == null) { 27177 sticky_class = "is_stuck"; 27178 } 27179 doc = $(document); 27180 if (enable_bottoming == null) { 27181 enable_bottoming = true; 27182 } 27183 outer_width = function(el) { 27184 var _el, computed, w; 27185 if (window.getComputedStyle) { 27186 _el = el[0]; 27187 computed = window.getComputedStyle(el[0]); 27188 w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right")); 27189 if (computed.getPropertyValue("box-sizing") !== "border-box") { 27190 w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right")); 27191 } 27192 return w; 27193 } else { 27194 return el.outerWidth(true); 27195 } 27196 }; 27197 fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) { 27198 var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick; 27199 if (elm.data("sticky_kit")) { 27200 return; 27201 } 27202 elm.data("sticky_kit", true); 27203 last_scroll_height = doc.height(); 27204 parent = elm.parent(); 27205 if (parent_selector != null) { 27206 parent = parent.closest(parent_selector); 27207 } 27208 if (!parent.length) { 27209 throw "failed to find stick parent"; 27210 } 27211 fixed = false; 27212 bottomed = false; 27213 spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />"); 27214 if (spacer) { 27215 spacer.css('position', elm.css('position')); 27216 } 27217 recalc = function() { 27218 var border_top, padding_top, restore; 27219 if (detached) { 27220 return; 27221 } 27222 last_scroll_height = doc.height(); 27223 border_top = parseInt(parent.css("border-top-width"), 10); 27224 padding_top = parseInt(parent.css("padding-top"), 10); 27225 padding_bottom = parseInt(parent.css("padding-bottom"), 10); 27226 parent_top = parent.offset().top + border_top + padding_top; 27227 parent_height = parent.height(); 27228 if (fixed) { 27229 fixed = false;
vendor: 6,068 bytes, lines 27230-27424
27230 bottomed = false; 27231 if (manual_spacer == null) { 27232 elm.insertAfter(spacer); 27233 spacer.detach(); 27234 } 27235 elm.css({ 27236 position: "", 27237 top: "", 27238 width: "", 27239 bottom: "" 27240 }).removeClass(sticky_class); 27241 restore = true; 27242 } 27243 top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top; 27244 height = elm.outerHeight(true); 27245 el_float = elm.css("float"); 27246 if (spacer) { 27247 spacer.css({ 27248 width: outer_width(elm), 27249 height: height, 27250 display: elm.css("display"), 27251 "vertical-align": elm.css("vertical-align"), 27252 "float": el_float 27253 }); 27254 } 27255 if (restore) { 27256 return tick(); 27257 } 27258 }; 27259 recalc(); 27260 if (height === parent_height) { 27261 return; 27262 } 27263 last_pos = void 0; 27264 offset = offset_top; 27265 recalc_counter = recalc_every; 27266 tick = function() { 27267 var css, delta, recalced, scroll, will_bottom, win_height; 27268 if (detached) { 27269 return; 27270 } 27271 recalced = false; 27272 if (recalc_counter != null) { 27273 recalc_counter -= 1; 27274 if (recalc_counter <= 0) { 27275 recalc_counter = recalc_every; 27276 recalc(); 27277 recalced = true; 27278 } 27279 } 27280 if (!recalced && doc.height() !== last_scroll_height) { 27281 recalc(); 27282 recalced = true; 27283 } 27284 scroll = win.scrollTop(); 27285 if (last_pos != null) { 27286 delta = scroll - last_pos; 27287 } 27288 last_pos = scroll; 27289 if (fixed) { 27290 if (enable_bottoming) { 27291 will_bottom = scroll + height + offset > parent_height + parent_top; 27292 if (bottomed && !will_bottom) { 27293 bottomed = false; 27294 elm.css({ 27295 position: "fixed", 27296 bottom: "", 27297 top: offset 27298 }).trigger("sticky_kit:unbottom"); 27299 } 27300 } 27301 if (scroll < top) { 27302 fixed = false; 27303 offset = offset_top; 27304 if (manual_spacer == null) { 27305 if (el_float === "left" || el_float === "right") { 27306 elm.insertAfter(spacer); 27307 } 27308 spacer.detach(); 27309 } 27310 css = { 27311 position: "", 27312 width: "", 27313 top: "" 27314 }; 27315 elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick"); 27316 } 27317 if (inner_scrolling) { 27318 win_height = win.height(); 27319 if (height + offset_top > win_height) { 27320 if (!bottomed) { 27321 offset -= delta; 27322 offset = Math.max(win_height - height, offset); 27323 offset = Math.min(offset_top, offset); 27324 if (fixed) { 27325 elm.css({ 27326 top: offset + "px" 27327 }); 27328 } 27329 } 27330 } 27331 } 27332 } else { 27333 if (scroll > top) { 27334 fixed = true; 27335 css = { 27336 position: "fixed", 27337 top: offset 27338 }; 27339 css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px"; 27340 elm.css(css).addClass(sticky_class); 27341 if (manual_spacer == null) { 27342 elm.after(spacer); 27343 if (el_float === "left" || el_float === "right") { 27344 spacer.append(elm); 27345 } 27346 } 27347 elm.trigger("sticky_kit:stick"); 27348 } 27349 } 27350 if (fixed && enable_bottoming) { 27351 if (will_bottom == null) { 27352 will_bottom = scroll + height + offset > parent_height + parent_top; 27353 } 27354 if (!bottomed && will_bottom) { 27355 bottomed = true; 27356 if (parent.css("position") === "static") { 27357 parent.css({ 27358 position: "relative" 27359 }); 27360 } 27361 return elm.css({ 27362 position: "absolute", 27363 bottom: padding_bottom, 27364 top: "auto" 27365 }).trigger("sticky_kit:bottom"); 27366 } 27367 } 27368 }; 27369 recalc_and_tick = function() { 27370 recalc(); 27371 return tick(); 27372 }; 27373 detach = function() { 27374 detached = true; 27375 win.off("touchmove", tick); 27376 win.off("scroll", tick); 27377 win.off("resize", recalc_and_tick); 27378 $(document.body).off("sticky_kit:recalc", recalc_and_tick); 27379 elm.off("sticky_kit:detach", detach); 27380 elm.removeData("sticky_kit"); 27381 elm.css({ 27382 position: "", 27383 bottom: "", 27384 top: "", 27385 width: "" 27386 }); 27387 parent.position("position", ""); 27388 if (fixed) { 27389 if (manual_spacer == null) { 27390 if (el_float === "left" || el_float === "right") { 27391 elm.insertAfter(spacer); 27392 } 27393 spacer.remove(); 27394 } 27395 return elm.removeClass(sticky_class); 27396 } 27397 }; 27398 win.on("touchmove", tick); 27399 win.on("scroll", tick); 27400 win.on("resize", recalc_and_tick); 27401 $(document.body).on("sticky_kit:recalc", recalc_and_tick); 27402 elm.on("sticky_kit:detach", detach); 27403 return setTimeout(tick, 0); 27404 }; 27405 for (i = 0, len = this.length; i < len; i++) { 27406 elm = this[i]; 27407 fn($(elm)); 27408 } 27409 return this; 27410 }; 27411 27412}).call(this); 27413/* ========================================================================== 27414 * bootstrap-tab-history.js 27415 * Author: Michael Narayan <[email protected]> 27416 * Repository: https://github.com/mnarayan01/bootstrap-tab-history/ 27417 * ========================================================================== 27418 * Licensed under the Apache License, Version 2.0 (the "License"); you may 27419 * not use this file except in compliance with the License. You may obtain a 27420 * copy of the License at 27421 * 27422 * http://www.apache.org/licenses/LICENSE-2.0 27423 * 27424 * Unless required by applicable law or agreed to in writing, softw
27424are 27425 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 27426 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 27427 * License for the specific language governing permissions and limitations 27428 * under the License. 27429 * ========================================================================== */ 27430 27431/* ========================================================================== */ 27432/* JSHint directives */ 27433/* */ 27434/* global BootstrapTabHistory: true */ 27435/* */ 27436/* global document */ 27437/* global jQuery */ 27438/* global history */ 27439/* global window */ 27440/* ========================================================================== */ 27441 27442/** 27443 * Integrate [HTML5 history state tracking](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history) 27444 * with [`bootstrap/tab.js`](http://getbootstrap.com/javascript/#tabs). To enable tracking on a tab element, simply set 27445 * the `data-tab-history` attribute to true (or a string denoting a tab grouping). 27446 * 27447 * See the README for additional information. 27448 * 27449 * Functionality based upon bootstrap/tab.js v3.1.0; reference it when making any changes. 27450 */ 27451 27452BootstrapTabHistory = { 27453 options: { 27454 /** 27455 * When the anchor portion of the URI is used to activate a tab, scroll down to the given offset, rather than the 27456 * element with the given `id` attribute. Set to null to disable. Only relevant if showTabsBasedOnAnchor is true. 27457 * 27458 * May be overriden on a per-element basis by the attribute `data-tab-history-anchor-y-offset`. 27459 * 27460 * @public 27461 * @type {?number} 27462 */ 27463 defaultAnchorYOffset: 0, 27464 /** 27465 * Either 'push' or 'replace', for whether to use `history.pushState` or `history.replaceState`, resp. 27466 * 27467 * May be overriden on a per-element basis by the attribute `data-tab-history-changer`. 27468 * 27469 * @public 27470 * @type {string} 27471 */ 27472 defaultChanger: 'replace', 27473 /** 27474 * If true, update the URL in onShownTab in the calls to `history.pushState` and `history.replaceState`. Otherwise, 27475 * `null` is passed as the third parameter to these calls. 27476 * 27477 * May be overriden on a per-element basis by the attribute `data-tab-history-update-url`. 27478 * 27479 * @public 27480 * @type {boolean} 27481 */ 27482 defaultUpdateURL: false, 27483 /** 27484 * Should the anchor portion of the loaded URI be used to activate a single tab if no history was present on page 27485 * load. 27486 * 27487 * @public 27488 * @type {boolean} 27489 */ 27490 showTabsBasedOnAnchor: true 27491 } 27492}; 27493 27494(function () { 27495 'use strict'; 27496 27497 jQuery(function () { 27498 if(history && history.pushState && history.replaceState) { 27499 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 27500 27501 if(bootstrapTabHistory) { 27502 showTabsBasedOnState(bootstrapTabHistory); 27503 } else { 27504 showTabsBasedOnAnchor(); 27505 } 27506 27507 backfillHistoryState(); 27508 27509 jQuery(document).on('shown.bs.tab show.bs.collapse', onShownTab); 27510 jQuery(window).on('popstate', onPopState); 27511 } else { 27512 showTabsBasedOnAnchor(); 27513 } 27514 }); 27515 27516 /** 27517 * Used to prevent onShownTab from registering shown events that we triggered via showTabsBasedOnState. 27518 * 27519 * @type {boolean} 27520 */ 27521 var showingTabsBasedOnState = false; 27522 27523 /** 27524 * Used to update `history.state` to reflect the default active tabs on initial page load. This supports proper 27525 * `history.back` handling when `data-tab-history-update-url` is true. 27526 */ 27527 function backfillHistoryState() { 27528 var newState = null; 27529 27530 jQuery('li.active > [data-tab-history], .panel-title.active [data-tab-history]').each(function () {//edited by Uncode 27531 var $activeTabElement = jQuery(this); 27532 var selector = getTabSelector($activeTabElement); 27533 27534 if(selector) { 27535 var tabGroup = getTabGroup($activeTabElement); 27536 27537 if(tabGroup) { 27538 newState = createNewHistoryState(newState || history.state, tabGroup, selector); 27539 } 27540 } 27541 }); 27542 27543 if(newState) { 27544 history.replaceState(newState, '', null); 27545 } 27546 } 27547 27548 /** 27549 * Clone the existing state, ensure its bootstrapTabHistory attribute is an Object, and add the provided tabGroup to 27550 * said bootstrapTabHistory attribute. 27551 * 27552 * @param {?object} existingState 27553 * @param {!string} tabGroup 27554 * @param {!string} selector 27555 * @returns {!object} 27556 */ 27557 function createNewHistoryState(existingState, tabGroup, selector) { 27558 // Clone history.state and ensure it has a bootstrapTabHistory entry. 27559 var newState = jQuery.extend(true, {}, existingState, { 27560 bootstrapTabHistory: {} 27561 }); 27562 27563 newState.bootstrapTabHistory[tabGroup] = selector; 27564 27565 return newState; 27566 } 27567 27568 /** 27569 * @param {jQuery} $tab
27570 * @returns {?string} 27571 */ 27572 function getTabGroup($tab) { 27573 return parseTruthyAttributeValue($tab.data('tab-history')); 27574 } 27575 27576 /** 27577 * @param {jQuery} $tab 27578 * @returns {?string} 27579 */ 27580 function getTabSelector($tab) { 27581 return $tab.data('target') || $tab.attr('href'); 27582 } 27583 27584 /** 27585 * Receives the `shown.bs.tab` event. Updates `history.state` as appropriate. 27586 * 27587 * @param {jQuery.Event} shownEvt 27588 */ 27589 function onShownTab(shownEvt) { 27590 if(!showingTabsBasedOnState) { 27591 var $activatedTab = jQuery(shownEvt.target); 27592 if ( $activatedTab.hasClass('panel-collapse') ) 27593 $activatedTab = $activatedTab.closest('.panel').find('a'); 27594 var selector = getTabSelector($activatedTab); 27595 27596 if(selector) { 27597 var tabGroup = getTabGroup($activatedTab); 27598 27599 if(tabGroup) { 27600 var historyChanger = $activatedTab.data('tab-history-changer') || BootstrapTabHistory.options.defaultChanger; 27601 var newState = createNewHistoryState(history.state, tabGroup, selector); 27602 var updateURL = (function ($activatedTab) { 27603 if(selector[0] === '#') { 27604 var elementUpdateURLOption = parseTruthyAttributeValue($activatedTab.data('tab-history-update-url')); 27605 27606 if(elementUpdateURLOption === undefined) { 27607 return BootstrapTabHistory.options.defaultUpdateURL; 27608 } else { 27609 return elementUpdateURLOption; 27610 } 27611 } else { 27612 return false; 27613 } 27614 })($activatedTab); 27615 27616 switch(historyChanger) { 27617 case 'push': 27618 history.pushState(newState, '', updateURL ? selector : null); 27619 break; 27620 case 'replace': 27621 history.replaceState(newState, '', updateURL ? selector : null); 27622 break; 27623 default: 27624 throw new Error('Unknown tab-history-changer: ' + historyChanger); 27625 } 27626 } 27627 } 27628 } 27629 } 27630 27631 /** 27632 * Receives the `popstate` event. Shows tabs based on the value of `history.state` as appropriate. 27633 */ 27634 function onPopState() { 27635 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 27636 27637 if(bootstrapTabHistory) { 27638 showTabsBasedOnState(bootstrapTabHistory); 27639 } 27640 } 27641 27642 /** 27643 * Returns the given value, _unless_ that value is an empty string, in which case `true` is returned. 27644 * 27645 * Rationale: HAML data attributes which are set to `true` are rendered as a blank string. 27646 * 27647 * @param {*} value 27648 * @returns {*} 27649 */ 27650 function parseTruthyAttributeValue(value) { 27651 if(value) { 27652 return value; 27653 } else if(value === '') { 27654 return true; 27655 } else { 27656 return value; 27657 } 27658 } 27659 27660 /** 27661 * Show tabs based upon the anchor component of `window.location`. 27662 */ 27663 function showTabsBasedOnAnchor() { 27664 if(BootstrapTabHistory.options.showTabsBasedOnAnchor) { 27665 var anchor = window.location && window.location.hash; 27666 27667 if(anchor) { 27668 var $tabElement = showTabForSelector(anchor); 27669 27670 if($tabElement && window.addEventListener && window.removeEventListener) { 27671 var anchorYOffset = (function ($tabElement) { 27672 var elementSetting = $tabElement.data('tab-history-anchor-y-offset'); 27673 27674 if(elementSetting === undefined) { 27675 return BootstrapTabHistory.options.defaultAnchorYOffset; 27676 } else { 27677 return elementSetting; 27678 } 27679 })($tabElement); 27680 27681 // HACK: This prevents scrolling to the tab on page load. This relies on the fact that we should never get 27682 // here on `history.forward`, `history.back`, or `location.reload`, since in all those situations the 27683 // `history.state` object should have been used (unless the browser did not support the modern History API). 27684 if(anchorYOffset || anchorYOffset === 0) { 27685 var scrollListener = function resetAnchorScroll () { 27686 window.removeEventListener('scroll', scrollListener); 27687 window.scrollTo(0, anchorYOffset); 27688 }; 27689 27690 window.addEventListener('scroll', scrollListener); 27691 } 27692 } 27693 } 27694 } 27695 } 27696 27697 /** 27698 * Show a tab which corresponds to the provided selector. 27699 * 27700 * @param {string} selector - A CSS selector. 27701 * @returns {?jQuery} - The tab which was found to show (even if said tab was already active). 27702 */ 27703 function showTabForSelector(selector) { 27704 var $tabElement = (function (selector) { 27705 var $ret = null; 27706 27707 jQuery('[data-toggle="tab"], [data-toggle="pill"], [data-toggle="collapse"]').each(function () { 27708 var $potentialTab = jQuery(this); 27709 27710 if(($potentialTab.attr('href') === selector || $potentialTab.data('target') === selector ) && getTabGroup($potentialTab)) { 27711 $ret = $potentialTab; 27712 return false;
vendor: 43,483 bytes, lines 27713-28929
27713 } else { 27714 return null; 27715 } 27716 }); 27717 27718 return $ret; 27719 })(selector); 27720 27721 if($tabElement) { 27722 if ( !$tabElement.parent().hasClass('active') ) { 27723 $tabElement.trigger('click'); 27724 } 27725 //$tabElement.tab('show'); 27726 } 27727 27728 return $tabElement; 27729 } 27730 27731 /** 27732 * Iterate through the provided set of tab tab groups, showing the tabs based on the stored selectors. 27733 * 27734 * @param {object} bootstrapTabHistory - Each of the values is passed to showTabForSelector; the keys are actually irrelevant. 27735 */ 27736 function showTabsBasedOnState(bootstrapTabHistory) { 27737 showingTabsBasedOnState = true; 27738 27739 try { 27740 for(var k in bootstrapTabHistory) { 27741 if(bootstrapTabHistory.hasOwnProperty(k)) { 27742 showTabForSelector(bootstrapTabHistory[k]); 27743 } 27744 } 27745 } finally { 27746 showingTabsBasedOnState = false; 27747 } 27748 } 27749})(); 27750 27751/*! 27752 * justifiedGallery - v3.8.1 27753 * http://miromannino.github.io/Justified-Gallery/ 27754 * Copyright (c) 2020 Miro Mannino 27755 * Licensed under the MIT license. 27756 */ 27757(function (factory) { 27758 if (typeof define === 'function' && define.amd) { 27759 // AMD. Register as an anonymous module. 27760 define(['jquery'], factory); 27761 } else if (typeof module === 'object' && module.exports) { 27762 // Node/CommonJS 27763 module.exports = function (root, jQuery) { 27764 if (jQuery === undefined) { 27765 // require('jQuery') returns a factory that requires window to 27766 // build a jQuery instance, we normalize how we use modules 27767 // that require this pattern but the window provided is a noop 27768 // if it's defined (how jquery works) 27769 if (typeof window !== 'undefined') { 27770 jQuery = require('jquery'); 27771 } 27772 else { 27773 jQuery = require('jquery')(root); 27774 } 27775 } 27776 factory(jQuery); 27777 return jQuery; 27778 }; 27779 } else { 27780 // Browser globals 27781 factory(jQuery); 27782 } 27783}(function ($) { 27784 27785 /** 27786 * Justified Gallery controller constructor 27787 * 27788 * @param $gallery the gallery to build 27789 * @param settings the settings (the defaults are in JustifiedGallery.defaults) 27790 * @constructor 27791 */ 27792 var JustifiedGallery = function ($gallery, settings) { 27793 27794 this.settings = settings; 27795 this.checkSettings(); 27796 27797 this.imgAnalyzerTimeout = null; 27798 this.entries = null; 27799 this.buildingRow = { 27800 entriesBuff: [], 27801 width: 0, 27802 height: 0, 27803 aspectRatio: 0 27804 }; 27805 this.lastFetchedEntry = null; 27806 this.lastAnalyzedIndex = -1; 27807 this.yield = { 27808 every: 2, // do a flush every n flushes (must be greater than 1) 27809 flushed: 0 // flushed rows without a yield 27810 }; 27811 this.border = settings.border >= 0 ? settings.border : settings.margins; 27812 this.maxRowHeight = this.retrieveMaxRowHeight(); 27813 this.suffixRanges = this.retrieveSuffixRanges(); 27814 this.offY = this.border; 27815 this.rows = 0; 27816 this.spinner = { 27817 phase: 0, 27818 timeSlot: 150, 27819 $el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'), 27820 intervalId: null 27821 }; 27822 this.scrollBarOn = false; 27823 this.checkWidthIntervalId = null; 27824 this.galleryWidth = $gallery.width(); 27825 this.$gallery = $gallery; 27826 27827 }; 27828 27829 /** @returns {String} the best suffix given the width and the height */ 27830 JustifiedGallery.prototype.getSuffix = function (width, height) { 27831 var longestSide, i; 27832 longestSide = (width > height) ? width : height; 27833 for (i = 0; i < this.suffixRanges.length; i++) { 27834 if (longestSide <= this.suffixRanges[i]) { 27835 return this.settings.sizeRangeSuffixes[this.suffixRanges[i]]; 27836 } 27837 } 27838 return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]]; 27839 }; 27840 27841 /** 27842 * Remove the suffix from the string 27843 * 27844 * @returns {string} a new string without the suffix 27845 */ 27846 JustifiedGallery.prototype.removeSuffix = function (str, suffix) { 27847 return str.substring(0, str.length - suffix.length); 27848 }; 27849 27850 /** 27851 * @returns {boolean} a boolean to say if the suffix is contained in the str or not 27852 */ 27853 JustifiedGallery.prototype.endsWith = function (str, suffix) { 27854 return str.indexOf(suffix, str.length - suffix.length) !== -1; 27855 }; 27856 27857 /** 27858 * Get the used suffix of a particular url 27859 * 27860 * @param str 27861 * @returns {String} return the used suffix 27862 */ 27863 JustifiedGallery.prototype.getUsedSuffix = function (str) { 27864 for (var si in this.settings.sizeRangeSuffixes) { 27865 if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) { 27866 if (this.settings.sizeRangeSuffixes[si].length === 0) continue; 27867 if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si]; 27868 } 27869 } 27870 return ''; 27871 }; 27872 27873 /** 27874 * Given an image src, with the width and the height, returns the new image src with the 27875 * best suffix to show the best quality thumbnail. 27876 * 27877 * @returns {String} the suffix to use 27878 */ 27879 JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight, image) { 27880 var newImageSrc; 27881 27882 if (this.settings.thumbnailPath) { 27883 newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image); 27884 } else { 27885 var matchRes = imageSrc.match(this.settings.extension); 27886 var ext = (matchRes !== null) ? matchRes[0] : ''; 27887 newImageSrc = imageSrc.replace(this.settings.extension, ''); 27888 newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc)); 27889 newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext; 27890 } 27891 27892 return newImageSrc; 27893 }; 27894 27895 /** 27896 * Shows the images that is in the given entry 27897 * 27898 * @param $entry the entry 27899 * @param callback the callback that is called when the show animation is finished 27900 */ 27901 JustifiedGallery.prototype.showImg = function ($entry, callback) { 27902 if (this.settings.cssAnimation) { 27903 $entry.addClass('jg-entry-visible'); 27904 if (callback) callback(); 27905 } else { 27906 $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27907 $entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 27908 } 27909 }; 27910 27911 /** 27912 * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the 27913 * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src. 27914 * 27915 * @param $image the image to analyze 27916 * @returns {String} the extracted src 27917 */ 27918 JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) { 27919 var imageSrc = $image.data('safe-src'); 27920 var imageSrcLoc = 'data-safe-src'; 27921 // Begin Uncode edit 27922 if (typeof imageSrc === 'undefined') { 27923 var imageCurrentSrc = $image[0].currentSrc; 27924 if (imageCurrentSrc) { 27925 imageSrc = imageCurrentSrc; 27926 } else { 27927 imageSrc = $image.attr('src'); 27928 } 27929 imageSrcLoc = 'src'; 27930 } 27931 // End Uncode edit 27932 $image.data('jg.originalSrc', imageSrc); // this is saved for the destroy method 27933 $image.data('jg.src', imageSrc); // this will change overtime 27934 $image.data('jg.originalSrcLoc', imageSrcLoc); // this is saved for the destroy method 27935 return imageSrc; 27936 }; 27937 27938 /** @returns {jQuery} the image in the given entry */ 27939 JustifiedGallery.prototype.imgFromEntry = function ($entry) { 27940 var $img = $entry.find(this.settings.imgSelector); 27941 if ($img.length === 0) $img = $entry.find('.t-entry-visual-cont img');//hacked by Uncode 27942 return $img.length === 0 ? null : $img; 27943 }; 27944 27945 /** @returns {jQuery} the caption in the given entry */ 27946 JustifiedGallery.prototype.captionFromEntry = function ($entry) { 27947 var $caption = $entry.find('> .jg-caption'); 27948 return $caption.length === 0 ? null : $caption; 27949 }; 27950 27951 /** 27952 * Display the entry 27953 * 27954 * @param {jQuery} $entry the entry to display 27955 * @param {int} x the x position where the entry must be positioned 27956 * @param y the y position where the entry must be positioned 27957 * @param imgWidth the image width 27958 * @param imgHeight the image height 27959 * @param rowHeight the row height of the row that owns the entry 27960 */ 27961 JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) { 27962 $entry.width(imgWidth); 27963 $entry.height(Math.floor(rowHeight));//hacked by Uncode 27964 $entry.css('top', Math.floor(y));//hacked by Uncode 27965 $entry.css('left', x); 27966 27967 var $image = this.imgFromEntry($entry); 27968 if ($image !== null) { 27969 $image.css('width', imgWidth); 27970 $image.css('height', imgHeight); 27971 $image.css('margin-left', - imgWidth / 2); 27972 $image.css('margin-top', - imgHeight / 2); 27973 27974 // Image reloading for an high quality of thumbnails 27975 var imageSrc = $image.data('jg.src'); 27976 if (imageSrc) { 27977 imageSrc = this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]); 27978 27979 $image.one('error', function () { 27980 this.resetImgSrc($image); //revert to the original thumbnail 27981 }); 27982 27983 var loadNewImage = function () { 27984 // if (imageSrc !== newImageSrc) { 27985 $image.attr('src', imageSrc); 27986 // } 27987 }; 27988 27989 if ($entry.data('jg.loaded') === 'skipped' && imageSrc) { 27990 this.onImageEvent(imageSrc, (function() { 27991 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27992 $entry.data('jg.loaded', true); 27993 }).bind(this)); 27994 } else { 27995 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 27996 } 27997 27998 } 27999 28000 } else { 28001 this.showImg($entry); 28002 } 28003 28004 this.displayEntryCaption($entry); 28005 }; 28006 28007 /** 28008 * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt' 28009 * or the 'title' attributes. 28010 * 28011 * @param {jQuery} $entry the entry to process 28012 */ 28013 JustifiedGallery.prototype.displayEntryCaption = function ($entry) { 28014 var $image = this.imgFromEntry($entry); 28015 if ($image !== null && this.settings.captions) { 28016 var $imgCaption = this.captionFromEntry($entry); 28017 28018 // Create it if it doesn't exists 28019 if ($imgCaption === null) { 28020 var caption = $image.attr('alt'); 28021 if (!this.isValidCaption(caption)) caption = $entry.attr('title'); 28022 if (this.isValidCaption(caption)) { // Create only we found something 28023 $imgCaption = $('<div class="jg-caption">' + caption + '</div>'); 28024 $entry.append($imgCaption); 28025 $entry.data('jg.createdCaption', true); 28026 } 28027 } 28028 28029 // Create events (we check again the $imgCaption because it can be still inexistent) 28030 if ($imgCaption !== null) { 28031 if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity); 28032 this.addCaptionEventsHandlers($entry); 28033 } 28034 } else { 28035 this.removeCaptionEventsHandlers($entry); 28036 } 28037 }; 28038 28039 /** 28040 * Validates the caption 28041 * 28042 * @param caption The caption that should be validated 28043 * @return {boolean} Validation result 28044 */ 28045 JustifiedGallery.prototype.isValidCaption = function (caption) { 28046 return (typeof caption !== 'undefined' && caption.length > 0); 28047 }; 28048 28049 /** 28050 * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry. 28051 * It shows the caption using jQuery (or using CSS if it is configured so) 28052 * 28053 * @param {Event} eventObject the event object 28054 */ 28055 JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) { 28056 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 28057 if (this.settings.cssAnimation) { 28058 $caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden'); 28059 } else { 28060 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 28061 this.settings.captionSettings.visibleOpacity); 28062 } 28063 }; 28064 28065 /** 28066 * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry. 28067 * It hides the caption using jQuery (or using CSS if it is configured so) 28068 * 28069 * @param {Event} eventObject the event object 28070 */ 28071 JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) { 28072 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 28073 if (this.settings.cssAnimation) { 28074 $caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden'); 28075 } else { 28076 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 28077 this.settings.captionSettings.nonVisibleOpacity); 28078 } 28079 }; 28080 28081 /** 28082 * Add the handlers of the entry for the caption 28083 * 28084 * @param $entry the entry to modify 28085 */ 28086 JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) { 28087 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 28088 if (typeof captionMouseEvents === 'undefined') { 28089 captionMouseEvents = { 28090 mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this), 28091 mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this) 28092 }; 28093 $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter); 28094 $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave); 28095 $entry.data('jg.captionMouseEvents', captionMouseEvents); 28096 } 28097 }; 28098 28099 /** 28100 * Remove the handlers of the entry for the caption 28101 * 28102 * @param $entry the entry to modify 28103 */ 28104 JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) { 28105 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 28106 if (typeof captionMouseEvents !== 'undefined') { 28107 $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter); 28108 $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave); 28109 $entry.removeData('jg.captionMouseEvents'); 28110 } 28111 }; 28112 28113 /** 28114 * Clear the building row data to be used for a new row 28115 */ 28116 JustifiedGallery.prototype.clearBuildingRow = function () { 28117 this.buildingRow.entriesBuff = []; 28118 this.buildingRow.aspectRatio = 0; 28119 this.buildingRow.width = 0; 28120 }; 28121 28122 /** 28123 * Justify the building row, preparing it to 28124 * 28125 * @param isLastRow 28126 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 28127 * @returns a boolean to know if the row has been justified or not 28128 */ 28129 JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow, hiddenRow) { 28130 var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true; 28131 var minHeight = 0; 28132 var availableWidth = this.galleryWidth - 2 * this.border - ( 28133 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 28134 var rowHeight = Math.floor( availableWidth / this.buildingRow.aspectRatio );//hacked by Uncode 28135 var defaultRowHeight = this.settings.rowHeight; 28136 var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold; 28137 28138 //Skip the last row if we can't justify it and the lastRow == 'hide' 28139 if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) { 28140 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28141 $entry = this.buildingRow.entriesBuff[i]; 28142 if (this.settings.cssAnimation) 28143 $entry.removeClass('jg-entry-visible'); 28144 else { 28145 $entry.stop().fadeTo(0, 0.1); 28146 $entry.find('> img, > a > img').fadeTo(0, 0); 28147 } 28148 } 28149 return -1; 28150 } 28151 28152 // With lastRow = nojustify, justify if is justificable (the images will not become too big) 28153 if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') { 28154 justify = false; 28155 28156 if (this.rows > 0) { 28157 defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows; 28158 justify = defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold; 28159 } 28160 } 28161 28162 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28163 $entry = this.buildingRow.entriesBuff[i]; 28164 imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 28165 28166 if (justify) { 28167 newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio; 28168 newImgH = rowHeight; 28169 } else { 28170 newImgW = defaultRowHeight * imgAspectRatio; 28171 newImgH = defaultRowHeight; 28172 } 28173 28174 availableWidth -= Math.round(newImgW); 28175 $entry.data('jg.jwidth', Math.round(newImgW)); 28176 $entry.data('jg.jheight', Math.ceil(newImgH)); 28177 if (i === 0 || minHeight > newImgH) minHeight = newImgH; 28178 } 28179 28180 this.buildingRow.height = minHeight; 28181 return justify; 28182 }; 28183 28184 /** 28185 * Flush a row: justify it, modify the gallery height accordingly to the row height 28186 * 28187 * @param isLastRow 28188 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 28189 */ 28190 JustifiedGallery.prototype.flushRow = function (isLastRow, hiddenRow) { 28191 var settings = this.settings; 28192 var $entry, buildingRowRes, offX = this.border, i; 28193 28194 buildingRowRes = this.prepareBuildingRow(isLastRow, hiddenRow); 28195 if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1)) { 28196 this.clearBuildingRow(); 28197 return; 28198 } 28199 28200 if (this.maxRowHeight) { 28201 if (this.maxRowHeight < this.buildingRow.height) this.buildingRow.height = this.maxRowHeight; 28202 } 28203 28204 //Align last (unjustified) row 28205 if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) { 28206 var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins; 28207 28208 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 28209 $entry = this.buildingRow.entriesBuff[i]; 28210 availableWidth -= $entry.data('jg.jwidth'); 28211 } 28212 28213 if (settings.lastRow === 'center') 28214 offX += Math.round(availableWidth / 2); 28215 else if (settings.lastRow === 'right') 28216 offX += availableWidth; 28217 } 28218 28219 var lastEntryIdx = this.buildingRow.entriesBuff.length - 1; 28220 for (i = 0; i <= lastEntryIdx; i++) { 28221 $entry = this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i : i]; 28222 this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height); 28223 offX += $entry.data('jg.jwidth') + settings.margins; 28224 } 28225 28226 //Gallery Height 28227 this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border; 28228 this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight()); 28229 28230 if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) { 28231 //Ready for a new row 28232 this.offY += this.buildingRow.height + settings.margins; 28233 this.rows += 1; 28234 this.clearBuildingRow(); 28235 this.settings.triggerEvent.call(this, 'jg.rowflush'); 28236 } 28237 }; 28238 28239 28240 // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221 28241 var galleryPrevStaticHeight = 0; 28242 28243 JustifiedGallery.prototype.rememberGalleryHeight = function () { 28244 galleryPrevStaticHeight = this.$gallery.height(); 28245 this.$gallery.height(galleryPrevStaticHeight); 28246 }; 28247 28248 // grow only 28249 JustifiedGallery.prototype.setGalleryTempHeight = function (height) { 28250 galleryPrevStaticHeight = Math.max(height, galleryPrevStaticHeight); 28251 this.$gallery.height(galleryPrevStaticHeight); 28252 }; 28253 28254 JustifiedGallery.prototype.setGalleryFinalHeight = function (height) { 28255 galleryPrevStaticHeight = height; 28256 this.$gallery.height(height); 28257 }; 28258 28259 /** 28260 * Checks the width of the gallery container, to know if a new justification is needed 28261 */ 28262 JustifiedGallery.prototype.checkWidth = function () { 28263 this.checkWidthIntervalId = setInterval($.proxy(function () { 28264 28265 // if the gallery is not currently visible, abort. 28266 if (!this.$gallery.is(":visible")) return; 28267 28268 var galleryWidth = parseFloat(this.$gallery.width()); 28269 if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) { 28270 this.galleryWidth = galleryWidth; 28271 this.rewind(); 28272 28273 this.rememberGalleryHeight(); 28274 28275 // Restart to analyze 28276 this.startImgAnalyzer(true); 28277 } 28278 }, this), this.settings.refreshTime); 28279 }; 28280 28281 /** 28282 * @returns {boolean} a boolean saying if the spinner is active or not 28283 */ 28284 JustifiedGallery.prototype.isSpinnerActive = function () { 28285 return this.spinner.intervalId !== null; 28286 }; 28287 28288 /** 28289 * @returns {int} the spinner height 28290 */ 28291 JustifiedGallery.prototype.getSpinnerHeight = function () { 28292 return this.spinner.$el.innerHeight(); 28293 }; 28294 28295 /** 28296 * Stops the spinner animation and modify the gallery height to exclude the spinner 28297 */ 28298 JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () { 28299 clearInterval(this.spinner.intervalId); 28300 this.spinner.intervalId = null; 28301 this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight()); 28302 this.spinner.$el.detach(); 28303 }; 28304 28305 /** 28306 * Starts the spinner animation 28307 */ 28308 JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () { 28309 var spinnerContext = this.spinner; 28310 var $spinnerPoints = spinnerContext.$el.find('span'); 28311 clearInterval(spinnerContext.intervalId); 28312 this.$gallery.append(spinnerContext.$el); 28313 this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight()); 28314 spinnerContext.intervalId = setInterval(function () { 28315 if (spinnerContext.phase < $spinnerPoints.length) { 28316 $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1); 28317 } else { 28318 $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0); 28319 } 28320 spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2); 28321 }, spinnerContext.timeSlot); 28322 }; 28323 28324 /** 28325 * Rewind the image analysis to start from the first entry. 28326 */ 28327 JustifiedGallery.prototype.rewind = function () { 28328 this.lastFetchedEntry = null; 28329 this.lastAnalyzedIndex = -1; 28330 this.offY = this.border; 28331 this.rows = 0; 28332 this.clearBuildingRow(); 28333 }; 28334 28335 /** 28336 * @returns {String} `settings.selector` rejecting spinner element 28337 */ 28338 JustifiedGallery.prototype.getSelectorWithoutSpinner = function () { 28339 return this.settings.selector + ', div:not(.jg-spinner)'; 28340 }; 28341 28342 /** 28343 * @returns {Array} all entries matched by `settings.selector` 28344 */ 28345 JustifiedGallery.prototype.getAllEntries = function () { 28346 var selector = this.getSelectorWithoutSpinner(); 28347 return this.$gallery.children(selector).toArray(); 28348 }; 28349 28350 /** 28351 * Update the entries searching it from the justified gallery HTML element 28352 * 28353 * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered) 28354 * @returns {boolean} true if some entries has been founded 28355 */ 28356 JustifiedGallery.prototype.updateEntries = function (norewind) { 28357 var newEntries; 28358 28359 if (norewind && this.lastFetchedEntry != null) { 28360 var selector = this.getSelectorWithoutSpinner(); 28361 newEntries = $(this.lastFetchedEntry).nextAll(selector).toArray(); 28362 } else { 28363 this.entries = []; 28364 newEntries = this.getAllEntries(); 28365 } 28366 28367 if (newEntries.length > 0) { 28368 28369 // Sort or randomize 28370 if ($.isFunction(this.settings.sort)) { 28371 newEntries = this.sortArray(newEntries); 28372 } else if (this.settings.randomize) { 28373 newEntries = this.shuffleArray(newEntries); 28374 } 28375 this.lastFetchedEntry = newEntries[newEntries.length - 1]; 28376 28377 // Filter 28378 if (this.settings.filter) { 28379 newEntries = this.filterArray(newEntries); 28380 } else { 28381 this.resetFilters(newEntries); 28382 } 28383 28384 } 28385 28386 this.entries = this.entries.concat(newEntries); 28387 return true; 28388 }; 28389 28390 /** 28391 * Apply the entries order to the DOM, iterating the entries and appending the images 28392 * 28393 * @param entries the entries that has been modified and that must be re-ordered in the DOM 28394 */ 28395 JustifiedGallery.prototype.insertToGallery = function (entries) { 28396 var that = this; 28397 $.each(entries, function () { 28398 $(this).appendTo(that.$gallery); 28399 }); 28400 }; 28401 28402 /** 28403 * Shuffle the array using the Fisher-Yates shuffle algorithm 28404 * 28405 * @param a the array to shuffle 28406 * @return the shuffled array 28407 */ 28408 JustifiedGallery.prototype.shuffleArray = function (a) { 28409 var i, j, temp; 28410 for (i = a.length - 1; i > 0; i--) { 28411 j = Math.floor(Math.random() * (i + 1)); 28412 temp = a[i]; 28413 a[i] = a[j]; 28414 a[j] = temp; 28415 } 28416 this.insertToGallery(a); 28417 return a; 28418 }; 28419 28420 /** 28421 * Sort the array using settings.comparator as comparator 28422 * 28423 * @param a the array to sort (it is sorted) 28424 * @return the sorted array 28425 */ 28426 JustifiedGallery.prototype.sortArray = function (a) { 28427 a.sort(this.settings.sort); 28428 this.insertToGallery(a); 28429 return a; 28430 }; 28431 28432 /** 28433 * Reset the filters removing the 'jg-filtered' class from all the entries 28434 * 28435 * @param a the array to reset 28436 */ 28437 JustifiedGallery.prototype.resetFilters = function (a) { 28438 for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered'); 28439 }; 28440 28441 /** 28442 * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering. 28443 * 28444 * @param a the array to filter 28445 * @return the filtered array 28446 */ 28447 JustifiedGallery.prototype.filterArray = function (a) { 28448 var settings = this.settings; 28449 if ($.type(settings.filter) === 'string') { 28450 // Filter only keeping the entries passed in the string 28451 return a.filter(function (el) { 28452 var $el = $(el); 28453 if ($el.is(settings.filter)) { 28454 $el.removeClass('jg-filtered'); 28455 return true; 28456 } else { 28457 $el.addClass('jg-filtered').removeClass('jg-visible'); 28458 return false; 28459 } 28460 }); 28461 } else if ($.isFunction(settings.filter)) { 28462 // Filter using the passed function 28463 var filteredArr = a.filter(settings.filter); 28464 for (var i = 0; i < a.length; i++) { 28465 if (filteredArr.indexOf(a[i]) === -1) { 28466 $(a[i]).addClass('jg-filtered').removeClass('jg-visible'); 28467 } else { 28468 $(a[i]).removeClass('jg-filtered'); 28469 } 28470 } 28471 return filteredArr; 28472 } 28473 }; 28474 28475 /** 28476 * Revert the image src to the default value. 28477 */ 28478 JustifiedGallery.prototype.resetImgSrc = function ($img) { 28479 if ($img.data('jg.originalSrcLoc') === 'src') { 28480 $img.attr('src', $img.data('jg.originalSrc')); 28481 } else { 28482 $img.attr('src', ''); 28483 } 28484 }; 28485 28486 /** 28487 * Destroy the Justified Gallery instance. 28488 * 28489 * It clears all the css properties added in the style attributes. We doesn't backup the original 28490 * values for those css attributes, because it costs (performance) and because in general one 28491 * shouldn't use the style attribute for an uniform set of images (where we suppose the use of 28492 * classes). Creating a backup is also difficult because JG could be called multiple times and 28493 * with different style attributes. 28494 */ 28495 JustifiedGallery.prototype.destroy = function () { 28496 clearInterval(this.checkWidthIntervalId); 28497 this.stopImgAnalyzerStarter(); 28498 28499 // Get fresh entries list since filtered entries are absent in `this.entries` 28500 $.each(this.getAllEntries(), $.proxy(function (_, entry) { 28501 var $entry = $(entry); 28502 28503 // Reset entry style 28504 $entry.css('width', ''); 28505 $entry.css('height', ''); 28506 $entry.css('top', ''); 28507 $entry.css('left', ''); 28508 $entry.data('jg.loaded', undefined); 28509 $entry.removeClass('jg-entry jg-filtered jg-entry-visible'); 28510 28511 // Reset image style 28512 var $img = this.imgFromEntry($entry); 28513 if ($img) { 28514 $img.css('width', ''); 28515 $img.css('height', ''); 28516 $img.css('margin-left', ''); 28517 $img.css('margin-top', ''); 28518 this.resetImgSrc($img); 28519 $img.data('jg.originalSrc', undefined); 28520 $img.data('jg.originalSrcLoc', undefined); 28521 $img.data('jg.src', undefined); 28522 } 28523 28524 // Remove caption 28525 this.removeCaptionEventsHandlers($entry); 28526 var $caption = this.captionFromEntry($entry); 28527 if ($entry.data('jg.createdCaption')) { 28528 // remove also the caption element (if created by jg) 28529 $entry.data('jg.createdCaption', undefined); 28530 if ($caption !== null) $caption.remove(); 28531 } else { 28532 if ($caption !== null) $caption.fadeTo(0, 1); 28533 } 28534 28535 }, this)); 28536 28537 this.$gallery.css('height', ''); 28538 this.$gallery.removeClass('justified-gallery'); 28539 this.$gallery.data('jg.controller', undefined); 28540 this.settings.triggerEvent.call(this, 'jg.destroy'); 28541 }; 28542 28543 /** 28544 * Analyze the images and builds the rows. It returns if it found an image that is not loaded. 28545 * 28546 * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end 28547 */ 28548 JustifiedGallery.prototype.analyzeImages = function (isForResize) { 28549 for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) { 28550 var $entry = $(this.entries[i]); 28551 if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') { 28552 var availableWidth = this.galleryWidth - 2 * this.border - ( 28553 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 28554 var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 28555 28556 this.buildingRow.entriesBuff.push($entry); 28557 this.buildingRow.aspectRatio += imgAspectRatio; 28558 this.buildingRow.width += imgAspectRatio * this.settings.rowHeight; 28559 this.lastAnalyzedIndex = i; 28560 28561 if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) { 28562 this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 28563 28564 if (++this.yield.flushed >= this.yield.every) { 28565 this.startImgAnalyzer(isForResize); 28566 return; 28567 } 28568 } 28569 } else if ($entry.data('jg.loaded') !== 'error') { 28570 return; 28571 } 28572 } 28573 28574 // Last row flush (the row is not full) 28575 if (this.buildingRow.entriesBuff.length > 0) { 28576 this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 28577 } 28578 28579 if (this.isSpinnerActive()) { 28580 this.stopLoadingSpinnerAnimation(); 28581 } 28582 28583 /* Stop, if there is, the timeout to start the analyzeImages. 28584 This is because an image can be set loaded, and the timeout can be set, 28585 but this image can be analyzed yet. 28586 */ 28587 this.stopImgAnalyzerStarter(); 28588 28589 this.setGalleryFinalHeight(this.galleryHeightToSet); 28590 28591 //On complete callback 28592 this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete'); 28593 }; 28594 28595 /** 28596 * Stops any ImgAnalyzer starter (that has an assigned timeout) 28597 */ 28598 JustifiedGallery.prototype.stopImgAnalyzerStarter = function () { 28599 this.yield.flushed = 0; 28600 if (this.imgAnalyzerTimeout !== null) { 28601 clearTimeout(this.imgAnalyzerTimeout); 28602 this.imgAnalyzerTimeout = null; 28603 } 28604 }; 28605 28606 /** 28607 * Starts the image analyzer. It is not immediately called to let the browser to update the view 28608 * 28609 * @param isForResize specifies if the image analyzer must be called for resizing or not 28610 */ 28611 JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) { 28612 var that = this; 28613 this.stopImgAnalyzerStarter(); 28614 this.imgAnalyzerTimeout = setTimeout(function () { 28615 that.analyzeImages(isForResize); 28616 }, 0.001); // we can't start it immediately due to a IE different behaviour 28617 }; 28618 28619 /** 28620 * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property, 28621 * because some browsers, with a 404 set complete = true. 28622 * 28623 * @param imageSrc the image src to load 28624 * @param onLoad callback that is called when the image has been loaded 28625 * @param onError callback that is called in case of an error 28626 */ 28627 JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) { 28628 if (!onLoad && !onError) return; 28629 28630 var memImage = new Image(); 28631 var $memImage = $(memImage); 28632 if (onLoad) { 28633 $memImage.one('load', function () { 28634 $memImage.off('load error'); 28635 onLoad(memImage); 28636 }); 28637 } 28638 if (onError) { 28639 $memImage.one('error', function () { 28640 $memImage.off('load error'); 28641 onError(memImage); 28642 }); 28643 } 28644 memImage.src = imageSrc; 28645 }; 28646 28647 /** 28648 * Init of Justified Gallery controlled 28649 * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images) 28650 */ 28651 JustifiedGallery.prototype.init = function () { 28652 var imagesToLoad = false, skippedImages = false, that = this; 28653 $.each(this.entries, function (index, entry) { 28654 var $entry = $(entry); 28655 var $image = that.imgFromEntry($entry); 28656 28657 $entry.addClass('jg-entry'); 28658 28659 if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') { 28660 28661 // Link Rel global overwrite 28662 if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel); 28663 28664 // Link Target global overwrite 28665 if (that.settings.target !== null) $entry.attr('target', that.settings.target); 28666 28667 if ($image !== null) { 28668 28669 // Image src 28670 var imageSrc = that.extractImgSrcFromImage($image); 28671 28672 /* If we have the height and the width, we don't wait that the image is loaded, 28673 but we start directly with the justification */ 28674 if (that.settings.waitThumbnailsLoad === false || !imageSrc) { 28675 var width = parseFloat($image.attr('width')); 28676 var height = parseFloat($image.attr('height')); 28677 if ($image.prop('tagName') === 'svg') { 28678 width = parseFloat($image[0].getBBox().width); 28679 height = parseFloat($image[0].getBBox().height); 28680 } 28681 if (!isNaN(width) && !isNaN(height)) { 28682 $entry.data('jg.width', width); 28683 $entry.data('jg.height', height); 28684 $entry.data('jg.loaded', 'skipped'); 28685 skippedImages = true; 28686 that.startImgAnalyzer(false); 28687 return true; // continue 28688 } 28689 } 28690 28691 $entry.data('jg.loaded', false); 28692 imagesToLoad = true; 28693 28694 // Spinner start 28695 if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation(); 28696 28697 that.onImageEvent(imageSrc, function (loadImg) { // image loaded 28698 $entry.data('jg.width', loadImg.width); 28699 $entry.data('jg.height', loadImg.height); 28700 $entry.data('jg.loaded', true); 28701 that.startImgAnalyzer(false); 28702 }, function () { // image load error 28703 $entry.data('jg.loaded', 'error'); 28704 that.startImgAnalyzer(false); 28705 }); 28706 28707 } else { 28708 $entry.data('jg.loaded', true); 28709 $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1); 28710 $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1); 28711 } 28712 28713 } 28714 28715 }); 28716 28717 if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false); 28718 this.checkWidth(); 28719 }; 28720 28721 /** 28722 * Checks that it is a valid number. If a string is passed it is converted to a number 28723 * 28724 * @param settingContainer the object that contains the setting (to allow the conversion) 28725 * @param settingName the setting name 28726 */ 28727 JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) { 28728 if ($.type(settingContainer[settingName]) === 'string') { 28729 settingContainer[settingName] = parseFloat(settingContainer[settingName]); 28730 } 28731 28732 if ($.type(settingContainer[settingName]) === 'number') { 28733 if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName; 28734 } else { 28735 throw settingName + ' must be a number'; 28736 } 28737 }; 28738 28739 /** 28740 * Checks the sizeRangeSuffixes and, if necessary, converts 28741 * its keys from string (e.g. old settings with 'lt100') to int. 28742 */ 28743 JustifiedGallery.prototype.checkSizeRangesSuffixes = function () { 28744 if ($.type(this.settings.sizeRangeSuffixes) !== 'object') { 28745 throw 'sizeRangeSuffixes must be defined and must be an object'; 28746 } 28747 28748 var suffixRanges = []; 28749 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28750 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx); 28751 } 28752 28753 var newSizeRngSuffixes = { 0: '' }; 28754 for (var i = 0; i < suffixRanges.length; i++) { 28755 if ($.type(suffixRanges[i]) === 'string') { 28756 try { 28757 var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10); 28758 newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 28759 } catch (e) { 28760 throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')'; 28761 } 28762 } else { 28763 newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 28764 } 28765 } 28766 28767 this.settings.sizeRangeSuffixes = newSizeRngSuffixes; 28768 }; 28769 28770 /** 28771 * check and convert the maxRowHeight setting 28772 * requires rowHeight to be already set 28773 * TODO: should be always called when only rowHeight is changed 28774 * @return number or null 28775 */ 28776 JustifiedGallery.prototype.retrieveMaxRowHeight = function () { 28777 var newMaxRowHeight = null; 28778 var rowHeight = this.settings.rowHeight; 28779 28780 if ($.type(this.settings.maxRowHeight) === 'string') { 28781 if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) { 28782 newMaxRowHeight = rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100; 28783 } else { 28784 newMaxRowHeight = parseFloat(this.settings.maxRowHeight); 28785 } 28786 } else if ($.type(this.settings.maxRowHeight) === 'number') { 28787 newMaxRowHeight = this.settings.maxRowHeight; 28788 } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight == null) { 28789 return null; 28790 } else { 28791 throw 'maxRowHeight must be a number or a percentage'; 28792 } 28793 28794 // check if the converted value is not a number 28795 if (isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight'; 28796 28797 // check values, maxRowHeight must be >= rowHeight 28798 if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight; 28799 28800 return newMaxRowHeight; 28801 }; 28802 28803 /** 28804 * Checks the settings 28805 */ 28806 JustifiedGallery.prototype.checkSettings = function () { 28807 this.checkSizeRangesSuffixes(); 28808 28809 this.checkOrConvertNumber(this.settings, 'rowHeight'); 28810 this.checkOrConvertNumber(this.settings, 'margins'); 28811 this.checkOrConvertNumber(this.settings, 'border'); 28812 this.checkOrConvertNumber(this.settings, 'maxRowsCount'); 28813 28814 var lastRowModes = [ 28815 'justify', 28816 'nojustify', 28817 'left', 28818 'center', 28819 'right', 28820 'hide' 28821 ]; 28822 if (lastRowModes.indexOf(this.settings.lastRow) === -1) { 28823 throw 'lastRow must be one of: ' + lastRowModes.join(', '); 28824 } 28825 28826 this.checkOrConvertNumber(this.settings, 'justifyThreshold'); 28827 if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) { 28828 throw 'justifyThreshold must be in the interval [0,1]'; 28829 } 28830 if ($.type(this.settings.cssAnimation) !== 'boolean') { 28831 throw 'cssAnimation must be a boolean'; 28832 } 28833 28834 if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean'; 28835 this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration'); 28836 28837 this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity'); 28838 if (this.settings.captionSettings.visibleOpacity < 0 || 28839 this.settings.captionSettings.visibleOpacity > 1) { 28840 throw 'captionSettings.visibleOpacity must be in the interval [0, 1]'; 28841 } 28842 28843 this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity'); 28844 if (this.settings.captionSettings.nonVisibleOpacity < 0 || 28845 this.settings.captionSettings.nonVisibleOpacity > 1) { 28846 throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]'; 28847 } 28848 28849 this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration'); 28850 this.checkOrConvertNumber(this.settings, 'refreshTime'); 28851 this.checkOrConvertNumber(this.settings, 'refreshSensitivity'); 28852 if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean'; 28853 if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string'; 28854 28855 if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) { 28856 throw 'sort must be false or a comparison function'; 28857 } 28858 28859 if (this.settings.filter !== false && !$.isFunction(this.settings.filter) && 28860 $.type(this.settings.filter) !== 'string') { 28861 throw 'filter must be false, a string or a filter function'; 28862 } 28863 }; 28864 28865 /** 28866 * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned. 28867 * @returns {Array} sorted suffix ranges 28868 */ 28869 JustifiedGallery.prototype.retrieveSuffixRanges = function () { 28870 var suffixRanges = []; 28871 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 28872 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10)); 28873 } 28874 suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; }); 28875 return suffixRanges; 28876 }; 28877 28878 /** 28879 * Update the existing settings only changing some of them 28880 * 28881 * @param newSettings the new settings (or a subgroup of them) 28882 */ 28883 JustifiedGallery.prototype.updateSettings = function (newSettings) { 28884 // In this case Justified Gallery has been called again changing only some options 28885 this.settings = $.extend({}, this.settings, newSettings); 28886 this.checkSettings(); 28887 28888 // As reported in the settings: negative value = same as margins, 0 = disabled 28889 this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins; 28890 28891 this.maxRowHeight = this.retrieveMaxRowHeight(); 28892 this.suffixRanges = this.retrieveSuffixRanges(); 28893 }; 28894 28895 JustifiedGallery.prototype.defaults = { 28896 sizeRangeSuffixes: {}, /* e.g. Flickr configuration 28897 { 28898 100: '_t', // used when longest is less than 100px 28899 240: '_m', // used when longest is between 101px and 240px 28900 320: '_n', // ... 28901 500: '', 28902 640: '_z', 28903 1024: '_b' // used as else case because it is the last 28904 } 28905 */ 28906 thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the 28907 path relative to a specific thumbnail size. The function should accept respectively three arguments: 28908 current path, width and height */ 28909 rowHeight: 120, // required? required to be > 0? 28910 maxRowHeight: false, // false or negative value to deactivate. Positive number to express the value in pixels, 28911 // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height 28912 // can't exceed 3 * rowHeight) 28913 maxRowsCount: 0, // maximum number of rows to be displayed (0 = disabled) 28914 margins: 1, 28915 border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border 28916 28917 lastRow: 'nojustify', // ⦠which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide' 28918 28919 justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified 28920 * (i.e. lastRow setting is not considered) */ 28921 waitThumbnailsLoad: true, 28922 captions: true, 28923 cssAnimation: true, 28924 imagesAnimationDuration: 500, // ignored with css animations 28925 captionSettings: { // ignored with css animations 28926 animationDuration: 500, 28927 visibleOpacity: 0.7, 28928 nonVisibleOpacity: 0.0 28929 },
28930 rel: null, // rewrite the rel of each analyzed links 28931 target: null, // rewrite the target of all links 28932 extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image 28933 refreshTime: 200, // time interval (in ms) to check if the page changes its width 28934 refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery 28935 randomize: false, 28936 rtl: false, // right-to-left mode 28937 sort: false, /* 28938 - false: to do not sort 28939 - function: to sort them using the function as comparator (see Array.prototype.sort()) 28940 */ 28941 filter: false, /* 28942 - false, null or undefined: for a disabled filter 28943 - a string: an entry is kept if entry.is(filter string) returns true 28944 see jQuery's .is() function for further information 28945 - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise. 28946 It follows the specifications of the Array.prototype.filter() function of JavaScript. 28947 */ 28948 selector: 'a', // The selector that is used to know what are the entries of the gallery 28949 imgSelector: '> img, > a > img, > svg, > a > svg', // The selector that is used to know what are the images of each entry 28950 triggerEvent: function (event) { // This is called to trigger events, the default behavior is to call $.trigger 28951 this.$gallery.trigger(event); // Consider that 'this' is this set to the JustifiedGallery object, so it can 28952 } // access to fields such as $gallery, useful to trigger events with jQuery. 28953 }; 28954 28955 28956 /** 28957 * Justified Gallery plugin for jQuery 28958 * 28959 * Events 28960 * - jg.complete : called when all the gallery has been created 28961 * - jg.resize : called when the gallery has been resized 28962 * - jg.rowflush : when a new row appears 28963 * 28964 * @param arg the action (or the settings) passed when the plugin is called 28965 * @returns {*} the object itself 28966 */ 28967 $.fn.justifiedGallery = function (arg) { 28968 return this.each(function (index, gallery) { 28969 28970 var $gallery = $(gallery); 28971 $gallery.addClass('justified-gallery'); 28972 28973 var controller = $gallery.data('jg.controller'); 28974 if (typeof controller === 'undefined') { 28975 // Create controller and assign it to the object data 28976 if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') { 28977 if (arg === 'destroy') return; // Just a call to an unexisting object 28978 throw 'The argument must be an object'; 28979 } 28980 controller = new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg)); 28981 $gallery.data('jg.controller', controller); 28982 } else if (arg === 'norewind') { 28983 // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row 28984 // ... left to be more readable 28985 } else if (arg === 'destroy') { 28986 controller.destroy(); 28987 return; 28988 } else { 28989 // In this case Justified Gallery has been called again changing only some options 28990 controller.updateSettings(arg); 28991 controller.rewind(); 28992 } 28993 28994 // Update the entries list 28995 if (!controller.updateEntries(arg === 'norewind')) return; 28996 28997 // Init justified gallery 28998 controller.init(); 28999 29000 }); 29001 }; 29002 29003})); 29004 29005/*! 29006* Customized version of iScroll.js 0.0.1 29007* It fixes bugs affecting its integration with fullpage.js 29008*/ 29009/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */ 29010(function (window, document, Math) { 29011var rAF = window.requestAnimationFrame || 29012 window.webkitRequestAnimationFrame || 29013 window.mozRequestAnimationFrame || 29014 window.oRequestAnimationFrame || 29015 window.msRequestAnimationFrame || 29016 function (callback) { window.setTimeout(callback, 1000 / 60); }; 29017 29018var utils = (function () { 29019 var me = {}; 29020 29021 var _elementStyle = document.createElement('div').style; 29022 var _vendor = (function () { 29023 var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], 29024 transform, 29025 i = 0, 29026 l = vendors.length; 29027 29028 for ( ; i < l; i++ ) { 29029 transform = vendors[i] + 'ransform'; 29030 if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); 29031 } 29032 29033 return false;
vendor: 5,154 bytes, lines 29034-29186
29034 })(); 29035 29036 function _prefixStyle (style) { 29037 if ( _vendor === false ) return false; 29038 if ( _vendor === '' ) return style; 29039 return _vendor + style.charAt(0).toUpperCase() + style.substr(1); 29040 } 29041 29042 me.getTime = Date.now || function getTime () { return new Date().getTime(); }; 29043 29044 me.extend = function (target, obj) { 29045 for ( var i in obj ) { 29046 target[i] = obj[i]; 29047 } 29048 }; 29049 29050 me.addEvent = function (el, type, fn, capture) { 29051 el.addEventListener(type, fn, !!capture); 29052 }; 29053 29054 me.removeEvent = function (el, type, fn, capture) { 29055 el.removeEventListener(type, fn, !!capture); 29056 }; 29057 29058 me.prefixPointerEvent = function (pointerEvent) { 29059 return window.MSPointerEvent ? 29060 'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8): 29061 pointerEvent; 29062 }; 29063 29064 me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { 29065 var distance = current - start, 29066 speed = Math.abs(distance) / time, 29067 destination, 29068 duration; 29069 29070 deceleration = deceleration === undefined ? 0.0006 : deceleration; 29071 29072 destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); 29073 duration = speed / deceleration; 29074 29075 if ( destination < lowerMargin ) { 29076 destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; 29077 distance = Math.abs(destination - current); 29078 duration = distance / speed; 29079 } else if ( destination > 0 ) { 29080 destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; 29081 distance = Math.abs(current) + destination; 29082 duration = distance / speed; 29083 } 29084 29085 return { 29086 destination: Math.round(destination), 29087 duration: duration 29088 }; 29089 }; 29090 29091 var _transform = _prefixStyle('transform'); 29092 29093 me.extend(me, { 29094 hasTransform: _transform !== false, 29095 hasPerspective: _prefixStyle('perspective') in _elementStyle, 29096 hasTouch: 'ontouchstart' in window, 29097 hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed 29098 hasTransition: _prefixStyle('transition') in _elementStyle 29099 }); 29100 29101 /* 29102 This should find all Android browsers lower than build 535.19 (both stock browser and webview) 29103 - galaxy S2 is ok 29104 - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1` 29105 - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29106 - galaxy S3 is badAndroid (stock brower, webview) 29107 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29108 - galaxy S4 is badAndroid (stock brower, webview) 29109 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 29110 - galaxy S5 is OK 29111 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 29112 - galaxy S6 is OK 29113 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 29114 */ 29115 me.isBadAndroid = (function() { 29116 var appVersion = window.navigator.appVersion; 29117 // Android browser is not a chrome browser. 29118 if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) { 29119 var safariVersion = appVersion.match(/Safari\/(\d+.\d)/); 29120 if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) { 29121 return parseFloat(safariVersion[1]) < 535.19; 29122 } else { 29123 return true; 29124 } 29125 } else { 29126 return false; 29127 } 29128 })(); 29129 29130 me.extend(me.style = {}, { 29131 transform: _transform, 29132 transitionTimingFunction: _prefixStyle('transitionTimingFunction'), 29133 transitionDuration: _prefixStyle('transitionDuration'), 29134 transitionDelay: _prefixStyle('transitionDelay'), 29135 transformOrigin: _prefixStyle('transformOrigin') 29136 }); 29137 29138 me.hasClass = function (e, c) { 29139 var re = new RegExp("(^|\\s)" + c + "(\\s|$)"); 29140 return re.test(e.className); 29141 }; 29142 29143 me.addClass = function (e, c) { 29144 if ( me.hasClass(e, c) ) { 29145 return; 29146 } 29147 29148 var newclass = e.className.split(' '); 29149 newclass.push(c); 29150 e.className = newclass.join(' '); 29151 }; 29152 29153 me.removeClass = function (e, c) { 29154 if ( !me.hasClass(e, c) ) { 29155 return; 29156 } 29157 29158 var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g'); 29159 e.className = e.className.replace(re, ' '); 29160 }; 29161 29162 me.offset = function (el) { 29163 var left = -el.offsetLeft, 29164 top = -el.offsetTop; 29165 29166 // jshint -W084 29167 while (el = el.offsetParent) { 29168 left -= el.offsetLeft; 29169 top -= el.offsetTop; 29170 } 29171 // jshint +W084 29172 29173 return { 29174 left: left, 29175 top: top 29176 }; 29177 }; 29178 29179 me.preventDefaultException = function (el, exceptions) { 29180 for ( var i in exceptions ) { 29181 if ( exceptions[i].test(el[i]) ) { 29182 return true; 29183 } 29184 } 29185 29186 return false;
vendor: 5,660 bytes, lines 29187-29352
29187 }; 29188 29189 me.extend(me.eventType = {}, { 29190 touchstart: 1, 29191 touchmove: 1, 29192 touchend: 1, 29193 29194 mousedown: 2, 29195 mousemove: 2, 29196 mouseup: 2, 29197 29198 pointerdown: 3, 29199 pointermove: 3, 29200 pointerup: 3, 29201 29202 MSPointerDown: 3, 29203 MSPointerMove: 3, 29204 MSPointerUp: 3 29205 }); 29206 29207 me.extend(me.ease = {}, { 29208 quadratic: { 29209 style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', 29210 fn: function (k) { 29211 return k * ( 2 - k ); 29212 } 29213 }, 29214 circular: { 29215 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) 29216 fn: function (k) { 29217 return Math.sqrt( 1 - ( --k * k ) ); 29218 } 29219 }, 29220 back: { 29221 style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', 29222 fn: function (k) { 29223 var b = 4; 29224 return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; 29225 } 29226 }, 29227 bounce: { 29228 style: '', 29229 fn: function (k) { 29230 if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { 29231 return 7.5625 * k * k; 29232 } else if ( k < ( 2 / 2.75 ) ) { 29233 return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; 29234 } else if ( k < ( 2.5 / 2.75 ) ) { 29235 return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; 29236 } else { 29237 return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; 29238 } 29239 } 29240 }, 29241 elastic: { 29242 style: '', 29243 fn: function (k) { 29244 var f = 0.22, 29245 e = 0.4; 29246 29247 if ( k === 0 ) { return 0; } 29248 if ( k == 1 ) { return 1; } 29249 29250 return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); 29251 } 29252 } 29253 }); 29254 29255 me.tap = function (e, eventName) { 29256 var ev = document.createEvent('Event'); 29257 ev.initEvent(eventName, true, true); 29258 ev.pageX = e.pageX; 29259 ev.pageY = e.pageY; 29260 e.target.dispatchEvent(ev); 29261 }; 29262 29263 me.click = function (e) { 29264 var target = e.target, 29265 ev; 29266 29267 if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { 29268 // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent 29269 // initMouseEvent is deprecated. 29270 ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event'); 29271 ev.initEvent('click', true, true); 29272 ev.view = e.view || window; 29273 ev.detail = 1; 29274 ev.screenX = target.screenX || 0; 29275 ev.screenY = target.screenY || 0; 29276 ev.clientX = target.clientX || 0; 29277 ev.clientY = target.clientY || 0; 29278 ev.ctrlKey = !!e.ctrlKey; 29279 ev.altKey = !!e.altKey; 29280 ev.shiftKey = !!e.shiftKey; 29281 ev.metaKey = !!e.metaKey; 29282 ev.button = 0; 29283 ev.relatedTarget = null; 29284 ev._constructed = true; 29285 target.dispatchEvent(ev); 29286 } 29287 }; 29288 29289 return me; 29290})(); 29291function IScroll (el, options) { 29292 this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; 29293 this.scroller = this.wrapper.children[0]; 29294 this.scrollerStyle = this.scroller.style; // cache style for better performance 29295 29296 this.options = { 29297 29298 resizeScrollbars: true, 29299 29300 mouseWheelSpeed: 20, 29301 29302 snapThreshold: 0.334, 29303 29304// INSERT POINT: OPTIONS 29305 disablePointer : !utils.hasPointer, 29306 disableTouch : utils.hasPointer || !utils.hasTouch, 29307 disableMouse : utils.hasPointer || utils.hasTouch, 29308 startX: 0, 29309 startY: 0, 29310 scrollY: true, 29311 directionLockThreshold: 5, 29312 momentum: true, 29313 29314 bounce: true, 29315 bounceTime: 600, 29316 bounceEasing: '', 29317 29318 preventDefault: true, 29319 preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL)$/ }, 29320 29321 HWCompositing: true, 29322 useTransition: true, 29323 useTransform: true, 29324 bindToWrapper: typeof window.onmousedown === "undefined" 29325 }; 29326 29327 for ( var i in options ) { 29328 this.options[i] = options[i]; 29329 } 29330 29331 // Normalize options 29332 this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : ''; 29333 29334 this.options.useTransition = utils.hasTransition && this.options.useTransition; 29335 this.options.useTransform = utils.hasTransform && this.options.useTransform; 29336 29337 this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; 29338 this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; 29339 29340 // If you want eventPassthrough I have to lock one of the axes 29341 this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; 29342 this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; 29343 29344 // With eventPassthrough we also need lockDirection mechanism 29345 this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; 29346 this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; 29347 29348 this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; 29349 29350 this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; 29351 29352 if ( this.options.tap === true ) {
vendor: 4,893 bytes, lines 29353-29524
29353 this.options.tap = 'tap'; 29354 } 29355 29356 // https://github.com/cubiq/iscroll/issues/1029 29357 if (!this.options.useTransition && !this.options.useTransform) { 29358 if(!(/relative|absolute/i).test(this.scrollerStyle.position)) { 29359 this.scrollerStyle.position = "relative"; 29360 } 29361 } 29362 29363 if ( this.options.shrinkScrollbars == 'scale' ) { 29364 this.options.useTransition = false; 29365 } 29366 29367 this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1; 29368 29369// INSERT POINT: NORMALIZATION 29370 29371 // Some defaults 29372 this.x = 0; 29373 this.y = 0; 29374 this.directionX = 0; 29375 this.directionY = 0; 29376 this._events = {}; 29377 29378// INSERT POINT: DEFAULTS 29379 29380 this._init(); 29381 this.refresh(); 29382 29383 this.scrollTo(this.options.startX, this.options.startY); 29384 this.enable(); 29385} 29386 29387IScroll.prototype = { 29388 version: '5.2.0', 29389 29390 _init: function () { 29391 this._initEvents(); 29392 29393 if ( this.options.scrollbars || this.options.indicators ) { 29394 this._initIndicators(); 29395 } 29396 29397 if ( this.options.mouseWheel ) { 29398 this._initWheel(); 29399 } 29400 29401 if ( this.options.snap ) { 29402 this._initSnap(); 29403 } 29404 29405 if ( this.options.keyBindings ) { 29406 this._initKeys(); 29407 } 29408 29409// INSERT POINT: _init 29410 29411 }, 29412 29413 destroy: function () { 29414 this._initEvents(true); 29415 clearTimeout(this.resizeTimeout); 29416 this.resizeTimeout = null; 29417 this._execEvent('destroy'); 29418 }, 29419 29420 _transitionEnd: function (e) { 29421 if ( e.target != this.scroller || !this.isInTransition ) { 29422 return; 29423 } 29424 29425 this._transitionTime(); 29426 if ( !this.resetPosition(this.options.bounceTime) ) { 29427 this.isInTransition = false; 29428 this._execEvent('scrollEnd'); 29429 } 29430 }, 29431 29432 _start: function (e) { 29433 // React to left mouse button only 29434 if ( utils.eventType[e.type] != 1 ) { 29435 // for button property 29436 // http://unixpapa.com/js/mouse.html 29437 var button; 29438 if (!e.which) { 29439 /* IE case */ 29440 button = (e.button < 2) ? 0 : 29441 ((e.button == 4) ? 1 : 2); 29442 } else { 29443 /* All others */ 29444 button = e.button; 29445 } 29446 if ( button !== 0 ) { 29447 return; 29448 } 29449 } 29450 29451 if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { 29452 return; 29453 } 29454 29455 if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 29456 e.preventDefault(); 29457 } 29458 29459 var point = e.touches ? e.touches[0] : e, 29460 pos; 29461 29462 this.initiated = utils.eventType[e.type]; 29463 this.moved = false; 29464 this.distX = 0; 29465 this.distY = 0; 29466 this.directionX = 0; 29467 this.directionY = 0; 29468 this.directionLocked = 0; 29469 29470 this.startTime = utils.getTime(); 29471 29472 if ( this.options.useTransition && this.isInTransition ) { 29473 this._transitionTime(); 29474 this.isInTransition = false; 29475 pos = this.getComputedPosition(); 29476 this._translate(Math.round(pos.x), Math.round(pos.y)); 29477 this._execEvent('scrollEnd'); 29478 } else if ( !this.options.useTransition && this.isAnimating ) { 29479 this.isAnimating = false; 29480 this._execEvent('scrollEnd'); 29481 } 29482 29483 this.startX = this.x; 29484 this.startY = this.y; 29485 this.absStartX = this.x; 29486 this.absStartY = this.y; 29487 this.pointX = point.pageX; 29488 this.pointY = point.pageY; 29489 29490 this._execEvent('beforeScrollStart'); 29491 }, 29492 29493 _move: function (e) { 29494 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 29495 return; 29496 } 29497 29498 if ( this.options.preventDefault ) { // increases performance on Android? TODO: check! 29499 e.preventDefault(); 29500 } 29501 29502 var point = e.touches ? e.touches[0] : e, 29503 deltaX = point.pageX - this.pointX, 29504 deltaY = point.pageY - this.pointY, 29505 timestamp = utils.getTime(), 29506 newX, newY, 29507 absDistX, absDistY; 29508 29509 this.pointX = point.pageX; 29510 this.pointY = point.pageY; 29511 29512 this.distX += deltaX; 29513 this.distY += deltaY; 29514 absDistX = Math.abs(this.distX); 29515 absDistY = Math.abs(this.distY); 29516 29517 // We need to move at least 10 pixels for the scrolling to initiate 29518 if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { 29519 return; 29520 } 29521 29522 // If you are scrolling in one direction lock the other 29523 if ( !this.directionLocked && !this.options.freeScroll ) { 29524 if ( absDistX > absDistY + this.options.directionLockThreshold ) {
vendor: 6,057 bytes, lines 29525-29711
29525 this.directionLocked = 'h'; // lock horizontally 29526 } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { 29527 this.directionLocked = 'v'; // lock vertically 29528 } else { 29529 this.directionLocked = 'n'; // no lock 29530 } 29531 } 29532 29533 if ( this.directionLocked == 'h' ) { 29534 if ( this.options.eventPassthrough == 'vertical' ) { 29535 e.preventDefault(); 29536 } else if ( this.options.eventPassthrough == 'horizontal' ) { 29537 this.initiated = false; 29538 return; 29539 } 29540 29541 deltaY = 0; 29542 } else if ( this.directionLocked == 'v' ) { 29543 if ( this.options.eventPassthrough == 'horizontal' ) { 29544 e.preventDefault(); 29545 } else if ( this.options.eventPassthrough == 'vertical' ) { 29546 this.initiated = false; 29547 return; 29548 } 29549 29550 deltaX = 0; 29551 } 29552 29553 deltaX = this.hasHorizontalScroll ? deltaX : 0; 29554 deltaY = this.hasVerticalScroll ? deltaY : 0; 29555 29556 newX = this.x + deltaX; 29557 newY = this.y + deltaY; 29558 29559 // Slow down if outside of the boundaries 29560 if ( newX > 0 || newX < this.maxScrollX ) { 29561 newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; 29562 } 29563 if ( newY > 0 || newY < this.maxScrollY ) { 29564 newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; 29565 } 29566 29567 this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; 29568 this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; 29569 29570 if ( !this.moved ) { 29571 this._execEvent('scrollStart'); 29572 } 29573 29574 this.moved = true; 29575 29576 this._translate(newX, newY); 29577 29578/* REPLACE START: _move */ 29579 29580 if ( timestamp - this.startTime > 300 ) { 29581 this.startTime = timestamp; 29582 this.startX = this.x; 29583 this.startY = this.y; 29584 } 29585 29586/* REPLACE END: _move */ 29587 29588 }, 29589 29590 _end: function (e) { 29591 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 29592 return; 29593 } 29594 29595 if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 29596 e.preventDefault(); 29597 } 29598 29599 var point = e.changedTouches ? e.changedTouches[0] : e, 29600 momentumX, 29601 momentumY, 29602 duration = utils.getTime() - this.startTime, 29603 newX = Math.round(this.x), 29604 newY = Math.round(this.y), 29605 distanceX = Math.abs(newX - this.startX), 29606 distanceY = Math.abs(newY - this.startY), 29607 time = 0, 29608 easing = ''; 29609 29610 this.isInTransition = 0; 29611 this.initiated = 0; 29612 this.endTime = utils.getTime(); 29613 29614 // reset if we are outside of the boundaries 29615 if ( this.resetPosition(this.options.bounceTime) ) { 29616 return; 29617 } 29618 29619 this.scrollTo(newX, newY); // ensures that the last position is rounded 29620 29621 // we scrolled less than 10 pixels 29622 if ( !this.moved ) { 29623 if ( this.options.tap ) { 29624 utils.tap(e, this.options.tap); 29625 } 29626 29627 if ( this.options.click ) { 29628 utils.click(e); 29629 } 29630 29631 this._execEvent('scrollCancel'); 29632 return; 29633 } 29634 29635 if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) { 29636 this._execEvent('flick'); 29637 return; 29638 } 29639 29640 // start momentum animation if needed 29641 if ( this.options.momentum && duration < 300 ) { 29642 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 }; 29643 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 }; 29644 newX = momentumX.destination; 29645 newY = momentumY.destination; 29646 time = Math.max(momentumX.duration, momentumY.duration); 29647 this.isInTransition = 1; 29648 } 29649 29650 29651 if ( this.options.snap ) { 29652 var snap = this._nearestSnap(newX, newY); 29653 this.currentPage = snap; 29654 time = this.options.snapSpeed || Math.max( 29655 Math.max( 29656 Math.min(Math.abs(newX - snap.x), 1000), 29657 Math.min(Math.abs(newY - snap.y), 1000) 29658 ), 300); 29659 newX = snap.x; 29660 newY = snap.y; 29661 29662 this.directionX = 0; 29663 this.directionY = 0; 29664 easing = this.options.bounceEasing; 29665 } 29666 29667// INSERT POINT: _end 29668 29669 if ( newX != this.x || newY != this.y ) { 29670 // change easing function when scroller goes out of the boundaries 29671 if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { 29672 easing = utils.ease.quadratic; 29673 } 29674 29675 this.scrollTo(newX, newY, time, easing); 29676 return; 29677 } 29678 29679 this._execEvent('scrollEnd'); 29680 }, 29681 29682 _resize: function () { 29683 var that = this; 29684 29685 clearTimeout(this.resizeTimeout); 29686 29687 this.resizeTimeout = setTimeout(function () { 29688 that.refresh(); 29689 }, this.options.resizePolling); 29690 }, 29691 29692 resetPosition: function (time) { 29693 var x = this.x, 29694 y = this.y; 29695 29696 time = time || 0; 29697 29698 if ( !this.hasHorizontalScroll || this.x > 0 ) { 29699 x = 0; 29700 } else if ( this.x < this.maxScrollX ) { 29701 x = this.maxScrollX; 29702 } 29703 29704 if ( !this.hasVerticalScroll || this.y > 0 ) { 29705 y = 0; 29706 } else if ( this.y < this.maxScrollY ) { 29707 y = this.maxScrollY; 29708 } 29709 29710 if ( x == this.x && y == this.y ) { 29711 return false;
vendor: 5,509 bytes, lines 29712-29916
29712 } 29713 29714 this.scrollTo(x, y, time, this.options.bounceEasing); 29715 29716 return true; 29717 }, 29718 29719 disable: function () { 29720 this.enabled = false; 29721 }, 29722 29723 enable: function () { 29724 this.enabled = true; 29725 }, 29726 29727 refresh: function () { 29728 var rf = this.wrapper.offsetHeight; // Force reflow 29729 29730 this.wrapperWidth = this.wrapper.clientWidth; 29731 this.wrapperHeight = this.wrapper.clientHeight; 29732 29733/* REPLACE START: refresh */ 29734 29735 this.scrollerWidth = this.scroller.offsetWidth; 29736 this.scrollerHeight = this.scroller.offsetHeight; 29737 29738 this.maxScrollX = this.wrapperWidth - this.scrollerWidth; 29739 this.maxScrollY = this.wrapperHeight - this.scrollerHeight; 29740 29741/* REPLACE END: refresh */ 29742 29743 this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; 29744 this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; 29745 29746 if ( !this.hasHorizontalScroll ) { 29747 this.maxScrollX = 0; 29748 this.scrollerWidth = this.wrapperWidth; 29749 } 29750 29751 if ( !this.hasVerticalScroll ) { 29752 this.maxScrollY = 0; 29753 this.scrollerHeight = this.wrapperHeight; 29754 } 29755 29756 this.endTime = 0; 29757 this.directionX = 0; 29758 this.directionY = 0; 29759 29760 this.wrapperOffset = utils.offset(this.wrapper); 29761 29762 this._execEvent('refresh'); 29763 29764 this.resetPosition(); 29765 29766// INSERT POINT: _refresh 29767 29768 }, 29769 29770 29771 on: function (type, fn) { 29772 if ( !this._events[type] ) { 29773 this._events[type] = []; 29774 } 29775 29776 this._events[type].push(fn); 29777 }, 29778 29779 off: function (type, fn) { 29780 if ( !this._events[type] ) { 29781 return; 29782 } 29783 29784 var index = this._events[type].indexOf(fn); 29785 29786 if ( index > -1 ) { 29787 this._events[type].splice(index, 1); 29788 } 29789 }, 29790 29791 _execEvent: function (type) { 29792 if ( !this._events[type] ) { 29793 return; 29794 } 29795 29796 var i = 0, 29797 l = this._events[type].length; 29798 29799 if ( !l ) { 29800 return; 29801 } 29802 29803 for ( ; i < l; i++ ) { 29804 this._events[type][i].apply(this, [].slice.call(arguments, 1)); 29805 } 29806 }, 29807 29808 scrollBy: function (x, y, time, easing) { 29809 x = this.x + x; 29810 y = this.y + y; 29811 time = time || 0; 29812 29813 this.scrollTo(x, y, time, easing); 29814 }, 29815 29816 scrollTo: function (x, y, time, easing) { 29817 easing = easing || utils.ease.circular; 29818 29819 this.isInTransition = this.options.useTransition && time > 0; 29820 var transitionType = this.options.useTransition && easing.style; 29821 if ( !time || transitionType ) { 29822 if(transitionType) { 29823 this._transitionTimingFunction(easing.style); 29824 this._transitionTime(time); 29825 } 29826 this._translate(x, y); 29827 } else { 29828 this._animate(x, y, time, easing.fn); 29829 } 29830 }, 29831 29832 scrollToElement: function (el, time, offsetX, offsetY, easing) { 29833 el = el.nodeType ? el : this.scroller.querySelector(el); 29834 29835 if ( !el ) { 29836 return; 29837 } 29838 29839 var pos = utils.offset(el); 29840 29841 pos.left -= this.wrapperOffset.left; 29842 pos.top -= this.wrapperOffset.top; 29843 29844 // if offsetX/Y are true we center the element to the screen 29845 if ( offsetX === true ) { 29846 offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); 29847 } 29848 if ( offsetY === true ) { 29849 offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); 29850 } 29851 29852 pos.left -= offsetX || 0; 29853 pos.top -= offsetY || 0; 29854 29855 pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; 29856 pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; 29857 29858 time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; 29859 29860 this.scrollTo(pos.left, pos.top, time, easing); 29861 }, 29862 29863 _transitionTime: function (time) { 29864 if (!this.options.useTransition) { 29865 return; 29866 } 29867 time = time || 0; 29868 var durationProp = utils.style.transitionDuration; 29869 if(!durationProp) { 29870 return; 29871 } 29872 29873 this.scrollerStyle[durationProp] = time + 'ms'; 29874 29875 if ( !time && utils.isBadAndroid ) { 29876 this.scrollerStyle[durationProp] = '0.0001ms'; 29877 // remove 0.0001ms 29878 var self = this; 29879 rAF(function() { 29880 if(self.scrollerStyle[durationProp] === '0.0001ms') { 29881 self.scrollerStyle[durationProp] = '0s'; 29882 } 29883 }); 29884 } 29885 29886 29887 if ( this.indicators ) { 29888 for ( var i = this.indicators.length; i--; ) { 29889 this.indicators[i].transitionTime(time); 29890 } 29891 } 29892 29893 29894// INSERT POINT: _transitionTime 29895 29896 }, 29897 29898 _transitionTimingFunction: function (easing) { 29899 this.scrollerStyle[utils.style.transitionTimingFunction] = easing; 29900 29901 29902 if ( this.indicators ) { 29903 for ( var i = this.indicators.length; i--; ) { 29904 this.indicators[i].transitionTimingFunction(easing); 29905 } 29906 } 29907 29908 29909// INSERT POINT: _transitionTimingFunction 29910 29911 }, 29912 29913 _translate: function (x, y) { 29914 //Uncode addition 29915 if ( (" " + this.wrapper.className + " ").replace(/[\n\t]/g, " ").indexOf(" no-scrolloverflow ") > -1 ) 29916 return false;
vendor: 9,939 bytes, lines 29917-30228
29917 29918 if ( this.options.useTransform ) { 29919 29920/* REPLACE START: _translate */ 29921 29922 this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ; 29923 29924/* REPLACE END: _translate */ 29925 29926 } else { 29927 x = Math.round(x); 29928 y = Math.round(y); 29929 this.scrollerStyle.left = x + 'px'; 29930 this.scrollerStyle.top = y + 'px'; 29931 } 29932 29933 this.x = x; 29934 this.y = y; 29935 29936 29937 if ( this.indicators ) { 29938 for ( var i = this.indicators.length; i--; ) { 29939 this.indicators[i].updatePosition(); 29940 } 29941 } 29942 29943 //Uncode addition 29944 var uncodevent = new CustomEvent('fp-slide-scroll'); 29945 window.dispatchEvent(uncodevent); 29946 29947// INSERT POINT: _translate 29948 29949 }, 29950 29951 _initEvents: function (remove) { 29952 var eventType = remove ? utils.removeEvent : utils.addEvent, 29953 target = this.options.bindToWrapper ? this.wrapper : window; 29954 29955 eventType(window, 'orientationchange', this); 29956 eventType(window, 'resize', this); 29957 29958 if ( this.options.click ) { 29959 eventType(this.wrapper, 'click', this, true); 29960 } 29961 29962 if ( !this.options.disableMouse ) { 29963 eventType(this.wrapper, 'mousedown', this); 29964 eventType(target, 'mousemove', this); 29965 eventType(target, 'mousecancel', this); 29966 eventType(target, 'mouseup', this); 29967 } 29968 29969 if ( utils.hasPointer && !this.options.disablePointer ) { 29970 eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); 29971 eventType(target, utils.prefixPointerEvent('pointermove'), this); 29972 eventType(target, utils.prefixPointerEvent('pointercancel'), this); 29973 eventType(target, utils.prefixPointerEvent('pointerup'), this); 29974 } 29975 29976 if ( utils.hasTouch && !this.options.disableTouch ) { 29977 eventType(this.wrapper, 'touchstart', this); 29978 eventType(target, 'touchmove', this); 29979 eventType(target, 'touchcancel', this); 29980 eventType(target, 'touchend', this); 29981 } 29982 29983 eventType(this.scroller, 'transitionend', this); 29984 eventType(this.scroller, 'webkitTransitionEnd', this); 29985 eventType(this.scroller, 'oTransitionEnd', this); 29986 eventType(this.scroller, 'MSTransitionEnd', this); 29987 }, 29988 29989 getComputedPosition: function () { 29990 var matrix = window.getComputedStyle(this.scroller, null), 29991 x, y; 29992 29993 if ( this.options.useTransform ) { 29994 matrix = matrix[utils.style.transform].split(')')[0].split(', '); 29995 x = +(matrix[12] || matrix[4]); 29996 y = +(matrix[13] || matrix[5]); 29997 } else { 29998 x = +matrix.left.replace(/[^-\d.]/g, ''); 29999 y = +matrix.top.replace(/[^-\d.]/g, ''); 30000 } 30001 30002 return { x: x, y: y }; 30003 }, 30004 _initIndicators: function () { 30005 var interactive = this.options.interactiveScrollbars, 30006 customStyle = typeof this.options.scrollbars != 'string', 30007 indicators = [], 30008 indicator; 30009 30010 var that = this; 30011 30012 this.indicators = []; 30013 30014 if ( this.options.scrollbars ) { 30015 // Vertical scrollbar 30016 if ( this.options.scrollY ) { 30017 indicator = { 30018 el: createDefaultScrollbar('v', interactive, this.options.scrollbars), 30019 interactive: interactive, 30020 defaultScrollbars: true, 30021 customStyle: customStyle, 30022 resize: this.options.resizeScrollbars, 30023 shrink: this.options.shrinkScrollbars, 30024 fade: this.options.fadeScrollbars, 30025 listenX: false 30026 }; 30027 30028 this.wrapper.appendChild(indicator.el); 30029 indicators.push(indicator); 30030 } 30031 30032 // Horizontal scrollbar 30033 if ( this.options.scrollX ) { 30034 indicator = { 30035 el: createDefaultScrollbar('h', interactive, this.options.scrollbars), 30036 interactive: interactive, 30037 defaultScrollbars: true, 30038 customStyle: customStyle, 30039 resize: this.options.resizeScrollbars, 30040 shrink: this.options.shrinkScrollbars, 30041 fade: this.options.fadeScrollbars, 30042 listenY: false 30043 }; 30044 30045 this.wrapper.appendChild(indicator.el); 30046 indicators.push(indicator); 30047 } 30048 } 30049 30050 if ( this.options.indicators ) { 30051 // TODO: check concat compatibility 30052 indicators = indicators.concat(this.options.indicators); 30053 } 30054 30055 for ( var i = indicators.length; i--; ) { 30056 this.indicators.push( new Indicator(this, indicators[i]) ); 30057 } 30058 30059 // TODO: check if we can use array.map (wide compatibility and performance issues) 30060 function _indicatorsMap (fn) { 30061 if (that.indicators) { 30062 for ( var i = that.indicators.length; i--; ) { 30063 fn.call(that.indicators[i]); 30064 } 30065 } 30066 } 30067 30068 if ( this.options.fadeScrollbars ) { 30069 this.on('scrollEnd', function () { 30070 _indicatorsMap(function () { 30071 this.fade(); 30072 }); 30073 }); 30074 30075 this.on('scrollCancel', function () { 30076 _indicatorsMap(function () { 30077 this.fade(); 30078 }); 30079 }); 30080 30081 this.on('scrollStart', function () { 30082 _indicatorsMap(function () { 30083 this.fade(1); 30084 }); 30085 }); 30086 30087 this.on('beforeScrollStart', function () { 30088 _indicatorsMap(function () { 30089 this.fade(1, true); 30090 }); 30091 }); 30092 } 30093 30094 30095 this.on('refresh', function () { 30096 _indicatorsMap(function () { 30097 this.refresh(); 30098 }); 30099 }); 30100 30101 this.on('destroy', function () { 30102 _indicatorsMap(function () { 30103 this.destroy(); 30104 }); 30105 30106 delete this.indicators; 30107 }); 30108 }, 30109 30110 _initWheel: function () { 30111 utils.addEvent(this.wrapper, 'wheel', this); 30112 utils.addEvent(this.wrapper, 'mousewheel', this); 30113 utils.addEvent(this.wrapper, 'DOMMouseScroll', this); 30114 30115 this.on('destroy', function () { 30116 clearTimeout(this.wheelTimeout); 30117 this.wheelTimeout = null; 30118 utils.removeEvent(this.wrapper, 'wheel', this); 30119 utils.removeEvent(this.wrapper, 'mousewheel', this); 30120 utils.removeEvent(this.wrapper, 'DOMMouseScroll', this); 30121 }); 30122 }, 30123 30124 _wheel: function (e) { 30125 if ( !this.enabled ) { 30126 return; 30127 } 30128 30129 var wheelDeltaX, wheelDeltaY, 30130 newX, newY, 30131 that = this; 30132 30133 if ( this.wheelTimeout === undefined ) { 30134 that._execEvent('scrollStart'); 30135 } 30136 30137 // Execute the scrollEnd event after 400ms the wheel stopped scrolling 30138 clearTimeout(this.wheelTimeout); 30139 this.wheelTimeout = setTimeout(function () { 30140 if(!that.options.snap) { 30141 that._execEvent('scrollEnd'); 30142 } 30143 that.wheelTimeout = undefined; 30144 }, 400); 30145 30146 if ( 'deltaX' in e ) { 30147 if (e.deltaMode === 1) { 30148 wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed; 30149 wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed; 30150 } else { 30151 wheelDeltaX = -e.deltaX; 30152 wheelDeltaY = -e.deltaY; 30153 } 30154 } else if ( 'wheelDeltaX' in e ) { 30155 wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed; 30156 wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed; 30157 } else if ( 'wheelDelta' in e ) { 30158 wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed; 30159 } else if ( 'detail' in e ) { 30160 wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed; 30161 } else { 30162 return; 30163 } 30164 30165 wheelDeltaX *= this.options.invertWheelDirection; 30166 wheelDeltaY *= this.options.invertWheelDirection; 30167 30168 if ( !this.hasVerticalScroll ) { 30169 wheelDeltaX = wheelDeltaY; 30170 wheelDeltaY = 0; 30171 } 30172 30173 if ( this.options.snap ) { 30174 newX = this.currentPage.pageX; 30175 newY = this.currentPage.pageY; 30176 30177 if ( wheelDeltaX > 0 ) { 30178 newX--; 30179 } else if ( wheelDeltaX < 0 ) { 30180 newX++; 30181 } 30182 30183 if ( wheelDeltaY > 0 ) { 30184 newY--; 30185 } else if ( wheelDeltaY < 0 ) { 30186 newY++; 30187 } 30188 30189 this.goToPage(newX, newY); 30190 30191 return; 30192 } 30193 30194 newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0); 30195 newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0); 30196 30197 this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0; 30198 this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0; 30199 30200 if ( newX > 0 ) { 30201 newX = 0; 30202 } else if ( newX < this.maxScrollX ) { 30203 newX = this.maxScrollX; 30204 } 30205 30206 if ( newY > 0 ) { 30207 newY = 0; 30208 } else if ( newY < this.maxScrollY ) { 30209 newY = this.maxScrollY; 30210 } 30211 30212 this.scrollTo(newX, newY, 0); 30213 30214// INSERT POINT: _wheel 30215 }, 30216 30217 _initSnap: function () { 30218 this.currentPage = {}; 30219 30220 if ( typeof this.options.snap == 'string' ) { 30221 this.options.snap = this.scroller.querySelectorAll(this.options.snap); 30222 } 30223 30224 this.on('refresh', function () { 30225 var i = 0, l, 30226 m = 0, n, 30227 cx, cy, 30228 x = 0, y,
vendor: 7,339 bytes, lines 30229-30482
30229 stepX = this.options.snapStepX || this.wrapperWidth, 30230 stepY = this.options.snapStepY || this.wrapperHeight, 30231 el; 30232 30233 this.pages = []; 30234 30235 if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) { 30236 return; 30237 } 30238 30239 if ( this.options.snap === true ) { 30240 cx = Math.round( stepX / 2 ); 30241 cy = Math.round( stepY / 2 ); 30242 30243 while ( x > -this.scrollerWidth ) { 30244 this.pages[i] = []; 30245 l = 0; 30246 y = 0; 30247 30248 while ( y > -this.scrollerHeight ) { 30249 this.pages[i][l] = { 30250 x: Math.max(x, this.maxScrollX), 30251 y: Math.max(y, this.maxScrollY), 30252 width: stepX, 30253 height: stepY, 30254 cx: x - cx, 30255 cy: y - cy 30256 }; 30257 30258 y -= stepY; 30259 l++; 30260 } 30261 30262 x -= stepX; 30263 i++; 30264 } 30265 } else { 30266 el = this.options.snap; 30267 l = el.length; 30268 n = -1; 30269 30270 for ( ; i < l; i++ ) { 30271 if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) { 30272 m = 0; 30273 n++; 30274 } 30275 30276 if ( !this.pages[m] ) { 30277 this.pages[m] = []; 30278 } 30279 30280 x = Math.max(-el[i].offsetLeft, this.maxScrollX); 30281 y = Math.max(-el[i].offsetTop, this.maxScrollY); 30282 cx = x - Math.round(el[i].offsetWidth / 2); 30283 cy = y - Math.round(el[i].offsetHeight / 2); 30284 30285 this.pages[m][n] = { 30286 x: x, 30287 y: y, 30288 width: el[i].offsetWidth, 30289 height: el[i].offsetHeight, 30290 cx: cx, 30291 cy: cy 30292 }; 30293 30294 if ( x > this.maxScrollX ) { 30295 m++; 30296 } 30297 } 30298 } 30299 30300 this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0); 30301 30302 // Update snap threshold if needed 30303 if ( this.options.snapThreshold % 1 === 0 ) { 30304 this.snapThresholdX = this.options.snapThreshold; 30305 this.snapThresholdY = this.options.snapThreshold; 30306 } else { 30307 this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold); 30308 this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold); 30309 } 30310 }); 30311 30312 this.on('flick', function () { 30313 var time = this.options.snapSpeed || Math.max( 30314 Math.max( 30315 Math.min(Math.abs(this.x - this.startX), 1000), 30316 Math.min(Math.abs(this.y - this.startY), 1000) 30317 ), 300); 30318 30319 this.goToPage( 30320 this.currentPage.pageX + this.directionX, 30321 this.currentPage.pageY + this.directionY, 30322 time 30323 ); 30324 }); 30325 }, 30326 30327 _nearestSnap: function (x, y) { 30328 if ( !this.pages.length ) { 30329 return { x: 0, y: 0, pageX: 0, pageY: 0 }; 30330 } 30331 30332 var i = 0, 30333 l = this.pages.length, 30334 m = 0; 30335 30336 // Check if we exceeded the snap threshold 30337 if ( Math.abs(x - this.absStartX) < this.snapThresholdX && 30338 Math.abs(y - this.absStartY) < this.snapThresholdY ) { 30339 return this.currentPage; 30340 } 30341 30342 if ( x > 0 ) { 30343 x = 0; 30344 } else if ( x < this.maxScrollX ) { 30345 x = this.maxScrollX; 30346 } 30347 30348 if ( y > 0 ) { 30349 y = 0; 30350 } else if ( y < this.maxScrollY ) { 30351 y = this.maxScrollY; 30352 } 30353 30354 for ( ; i < l; i++ ) { 30355 if ( x >= this.pages[i][0].cx ) { 30356 x = this.pages[i][0].x; 30357 break; 30358 } 30359 } 30360 30361 l = this.pages[i].length; 30362 30363 for ( ; m < l; m++ ) { 30364 if ( y >= this.pages[0][m].cy ) { 30365 y = this.pages[0][m].y; 30366 break; 30367 } 30368 } 30369 30370 if ( i == this.currentPage.pageX ) { 30371 i += this.directionX; 30372 30373 if ( i < 0 ) { 30374 i = 0; 30375 } else if ( i >= this.pages.length ) { 30376 i = this.pages.length - 1; 30377 } 30378 30379 x = this.pages[i][0].x; 30380 } 30381 30382 if ( m == this.currentPage.pageY ) { 30383 m += this.directionY; 30384 30385 if ( m < 0 ) { 30386 m = 0; 30387 } else if ( m >= this.pages[0].length ) { 30388 m = this.pages[0].length - 1; 30389 } 30390 30391 y = this.pages[0][m].y; 30392 } 30393 30394 return { 30395 x: x, 30396 y: y, 30397 pageX: i, 30398 pageY: m 30399 }; 30400 }, 30401 30402 goToPage: function (x, y, time, easing) { 30403 easing = easing || this.options.bounceEasing; 30404 30405 if ( x >= this.pages.length ) { 30406 x = this.pages.length - 1; 30407 } else if ( x < 0 ) { 30408 x = 0; 30409 } 30410 30411 if ( y >= this.pages[x].length ) { 30412 y = this.pages[x].length - 1; 30413 } else if ( y < 0 ) { 30414 y = 0; 30415 } 30416 30417 var posX = this.pages[x][y].x, 30418 posY = this.pages[x][y].y; 30419 30420 time = time === undefined ? this.options.snapSpeed || Math.max( 30421 Math.max( 30422 Math.min(Math.abs(posX - this.x), 1000), 30423 Math.min(Math.abs(posY - this.y), 1000) 30424 ), 300) : time; 30425 30426 this.currentPage = { 30427 x: posX, 30428 y: posY, 30429 pageX: x, 30430 pageY: y 30431 }; 30432 30433 this.scrollTo(posX, posY, time, easing); 30434 }, 30435 30436 next: function (time, easing) { 30437 var x = this.currentPage.pageX, 30438 y = this.currentPage.pageY; 30439 30440 x++; 30441 30442 if ( x >= this.pages.length && this.hasVerticalScroll ) { 30443 x = 0; 30444 y++; 30445 } 30446 30447 this.goToPage(x, y, time, easing); 30448 }, 30449 30450 prev: function (time, easing) { 30451 var x = this.currentPage.pageX, 30452 y = this.currentPage.pageY; 30453 30454 x--; 30455 30456 if ( x < 0 && this.hasVerticalScroll ) { 30457 x = 0; 30458 y--; 30459 } 30460 30461 this.goToPage(x, y, time, easing); 30462 }, 30463 30464 _initKeys: function (e) { 30465 // default key bindings 30466 var keys = { 30467 pageUp: 33, 30468 pageDown: 34, 30469 end: 35, 30470 home: 36, 30471 left: 37, 30472 up: 38, 30473 right: 39, 30474 down: 40 30475 }; 30476 var i; 30477 30478 // if you give me characters I give you keycode 30479 if ( typeof this.options.keyBindings == 'object' ) { 30480 for ( i in this.options.keyBindings ) { 30481 if ( typeof this.options.keyBindings[i] == 'string' ) { 30482 this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCo
vendor: 11,097 bytes, lines 30482-30835
30482deAt(0); 30483 } 30484 } 30485 } else { 30486 this.options.keyBindings = {}; 30487 } 30488 30489 for ( i in keys ) { 30490 this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i]; 30491 } 30492 30493 utils.addEvent(window, 'keydown', this); 30494 30495 this.on('destroy', function () { 30496 utils.removeEvent(window, 'keydown', this); 30497 }); 30498 }, 30499 30500 _key: function (e) { 30501 if ( !this.enabled ) { 30502 return; 30503 } 30504 30505 var snap = this.options.snap, // we are using this alot, better to cache it 30506 newX = snap ? this.currentPage.pageX : this.x, 30507 newY = snap ? this.currentPage.pageY : this.y, 30508 now = utils.getTime(), 30509 prevTime = this.keyTime || 0, 30510 acceleration = 0.250, 30511 pos; 30512 30513 if ( this.options.useTransition && this.isInTransition ) { 30514 pos = this.getComputedPosition(); 30515 30516 this._translate(Math.round(pos.x), Math.round(pos.y)); 30517 this.isInTransition = false; 30518 } 30519 30520 this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0; 30521 30522 switch ( e.keyCode ) { 30523 case this.options.keyBindings.pageUp: 30524 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 30525 newX += snap ? 1 : this.wrapperWidth; 30526 } else { 30527 newY += snap ? 1 : this.wrapperHeight; 30528 } 30529 break; 30530 case this.options.keyBindings.pageDown: 30531 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 30532 newX -= snap ? 1 : this.wrapperWidth; 30533 } else { 30534 newY -= snap ? 1 : this.wrapperHeight; 30535 } 30536 break; 30537 case this.options.keyBindings.end: 30538 newX = snap ? this.pages.length-1 : this.maxScrollX; 30539 newY = snap ? this.pages[0].length-1 : this.maxScrollY; 30540 break; 30541 case this.options.keyBindings.home: 30542 newX = 0; 30543 newY = 0; 30544 break; 30545 case this.options.keyBindings.left: 30546 newX += snap ? -1 : 5 + this.keyAcceleration>>0; 30547 break; 30548 case this.options.keyBindings.up: 30549 newY += snap ? 1 : 5 + this.keyAcceleration>>0; 30550 break; 30551 case this.options.keyBindings.right: 30552 newX -= snap ? -1 : 5 + this.keyAcceleration>>0; 30553 break; 30554 case this.options.keyBindings.down: 30555 newY -= snap ? 1 : 5 + this.keyAcceleration>>0; 30556 break; 30557 default: 30558 return; 30559 } 30560 30561 if ( snap ) { 30562 this.goToPage(newX, newY); 30563 return; 30564 } 30565 30566 if ( newX > 0 ) { 30567 newX = 0; 30568 this.keyAcceleration = 0; 30569 } else if ( newX < this.maxScrollX ) { 30570 newX = this.maxScrollX; 30571 this.keyAcceleration = 0; 30572 } 30573 30574 if ( newY > 0 ) { 30575 newY = 0; 30576 this.keyAcceleration = 0; 30577 } else if ( newY < this.maxScrollY ) { 30578 newY = this.maxScrollY; 30579 this.keyAcceleration = 0; 30580 } 30581 30582 this.scrollTo(newX, newY, 0); 30583 30584 this.keyTime = now; 30585 }, 30586 30587 _animate: function (destX, destY, duration, easingFn) { 30588 var that = this, 30589 startX = this.x, 30590 startY = this.y, 30591 startTime = utils.getTime(), 30592 destTime = startTime + duration; 30593 30594 function step () { 30595 var now = utils.getTime(), 30596 newX, newY, 30597 easing; 30598 30599 if ( now >= destTime ) { 30600 that.isAnimating = false; 30601 that._translate(destX, destY); 30602 30603 if ( !that.resetPosition(that.options.bounceTime) ) { 30604 that._execEvent('scrollEnd'); 30605 } 30606 30607 return; 30608 } 30609 30610 now = ( now - startTime ) / duration; 30611 easing = easingFn(now); 30612 newX = ( destX - startX ) * easing + startX; 30613 newY = ( destY - startY ) * easing + startY; 30614 that._translate(newX, newY); 30615 30616 if ( that.isAnimating ) { 30617 rAF(step); 30618 } 30619 } 30620 30621 this.isAnimating = true; 30622 step(); 30623 }, 30624 handleEvent: function (e) { 30625 switch ( e.type ) { 30626 case 'touchstart': 30627 case 'pointerdown': 30628 case 'MSPointerDown': 30629 case 'mousedown': 30630 this._start(e); 30631 break; 30632 case 'touchmove': 30633 case 'pointermove': 30634 case 'MSPointerMove': 30635 case 'mousemove': 30636 this._move(e); 30637 break; 30638 case 'touchend': 30639 case 'pointerup': 30640 case 'MSPointerUp': 30641 case 'mouseup': 30642 case 'touchcancel': 30643 case 'pointercancel': 30644 case 'MSPointerCancel': 30645 case 'mousecancel': 30646 this._end(e); 30647 break; 30648 case 'orientationchange': 30649 case 'resize': 30650 this._resize(); 30651 break; 30652 case 'transitionend': 30653 case 'webkitTransitionEnd': 30654 case 'oTransitionEnd': 30655 case 'MSTransitionEnd': 30656 this._transitionEnd(e); 30657 break; 30658 case 'wheel': 30659 case 'DOMMouseScroll': 30660 case 'mousewheel': 30661 this._wheel(e); 30662 break; 30663 case 'keydown': 30664 this._key(e); 30665 break; 30666 case 'click': 30667 if ( this.enabled && !e._constructed ) { 30668 e.preventDefault(); 30669 e.stopPropagation(); 30670 } 30671 break; 30672 } 30673 } 30674}; 30675function createDefaultScrollbar (direction, interactive, type) { 30676 var scrollbar = document.createElement('div'), 30677 indicator = document.createElement('div'); 30678 30679 if ( type === true ) { 30680 scrollbar.style.cssText = 'position:absolute;z-index:9999'; 30681 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'; 30682 } 30683 30684 indicator.className = 'iScrollIndicator'; 30685 30686 if ( direction == 'h' ) { 30687 if ( type === true ) { 30688 scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0'; 30689 indicator.style.height = '100%'; 30690 } 30691 scrollbar.className = 'iScrollHorizontalScrollbar'; 30692 } else { 30693 if ( type === true ) { 30694 scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px'; 30695 indicator.style.width = '100%'; 30696 } 30697 scrollbar.className = 'iScrollVerticalScrollbar'; 30698 } 30699 30700 scrollbar.style.cssText += ';overflow:hidden'; 30701 30702 if ( !interactive ) { 30703 scrollbar.style.pointerEvents = 'none'; 30704 } 30705 30706 scrollbar.appendChild(indicator); 30707 30708 return scrollbar; 30709} 30710 30711function Indicator (scroller, options) { 30712 this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; 30713 this.wrapperStyle = this.wrapper.style; 30714 this.indicator = this.wrapper.children[0]; 30715 this.indicatorStyle = this.indicator.style; 30716 this.scroller = scroller; 30717 30718 this.options = { 30719 listenX: true, 30720 listenY: true, 30721 interactive: false, 30722 resize: true, 30723 defaultScrollbars: false, 30724 shrink: false, 30725 fade: false, 30726 speedRatioX: 0, 30727 speedRatioY: 0 30728 }; 30729 30730 for ( var i in options ) { 30731 this.options[i] = options[i]; 30732 } 30733 30734 this.sizeRatioX = 1; 30735 this.sizeRatioY = 1; 30736 this.maxPosX = 0; 30737 this.maxPosY = 0; 30738 30739 if ( this.options.interactive ) { 30740 if ( !this.options.disableTouch ) { 30741 utils.addEvent(this.indicator, 'touchstart', this); 30742 utils.addEvent(window, 'touchend', this); 30743 } 30744 if ( !this.options.disablePointer ) { 30745 utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 30746 utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this); 30747 } 30748 if ( !this.options.disableMouse ) { 30749 utils.addEvent(this.indicator, 'mousedown', this); 30750 utils.addEvent(window, 'mouseup', this); 30751 } 30752 } 30753 30754 if ( this.options.fade ) { 30755 this.wrapperStyle[utils.style.transform] = this.scroller.translateZ; 30756 var durationProp = utils.style.transitionDuration; 30757 if(!durationProp) { 30758 return; 30759 } 30760 this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms'; 30761 // remove 0.0001ms 30762 var self = this; 30763 if(utils.isBadAndroid) { 30764 rAF(function() { 30765 if(self.wrapperStyle[durationProp] === '0.0001ms') { 30766 self.wrapperStyle[durationProp] = '0s'; 30767 } 30768 }); 30769 } 30770 this.wrapperStyle.opacity = '0'; 30771 } 30772} 30773 30774Indicator.prototype = { 30775 handleEvent: function (e) { 30776 switch ( e.type ) { 30777 case 'touchstart': 30778 case 'pointerdown': 30779 case 'MSPointerDown': 30780 case 'mousedown': 30781 this._start(e); 30782 break; 30783 case 'touchmove': 30784 case 'pointermove': 30785 case 'MSPointerMove': 30786 case 'mousemove': 30787 this._move(e); 30788 break; 30789 case 'touchend': 30790 case 'pointerup': 30791 case 'MSPointerUp': 30792 case 'mouseup': 30793 case 'touchcancel': 30794 case 'pointercancel': 30795 case 'MSPointerCancel': 30796 case 'mousecancel': 30797 this._end(e); 30798 break; 30799 } 30800 }, 30801 30802 destroy: function () { 30803 if ( this.options.fadeScrollbars ) { 30804 clearTimeout(this.fadeTimeout); 30805 this.fadeTimeout = null; 30806 } 30807 if ( this.options.interactive ) { 30808 utils.removeEvent(this.indicator, 'touchstart', this); 30809 utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 30810 utils.removeEvent(this.indicator, 'mousedown', this); 30811 30812 utils.removeEvent(window, 'touchmove', this); 30813 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30814 utils.removeEvent(window, 'mousemove', this); 30815 30816 utils.removeEvent(window, 'touchend', this); 30817 utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this); 30818 utils.removeEvent(window, 'mouseup', this); 30819 } 30820 30821 if ( this.options.defaultScrollbars ) { 30822 this.wrapper.parentNode.removeChild(this.wrapper); 30823 } 30824 }, 30825 30826 _start: function (e) { 30827 var point = e.touches ? e.touches[0] : e; 30828 30829 e.preventDefault(); 30830 e.stopPropagation(); 30831 30832 this.transitionTime(); 30833 30834 this.initiated = true; 30835 this.moved = false;
vendor: 9,615 bytes, lines 30836-31094
30836 this.lastPointX = point.pageX; 30837 this.lastPointY = point.pageY; 30838 30839 this.startTime = utils.getTime(); 30840 30841 if ( !this.options.disableTouch ) { 30842 utils.addEvent(window, 'touchmove', this); 30843 } 30844 if ( !this.options.disablePointer ) { 30845 utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this); 30846 } 30847 if ( !this.options.disableMouse ) { 30848 utils.addEvent(window, 'mousemove', this); 30849 } 30850 30851 this.scroller._execEvent('beforeScrollStart'); 30852 }, 30853 30854 _move: function (e) { 30855 var point = e.touches ? e.touches[0] : e, 30856 deltaX, deltaY, 30857 newX, newY, 30858 timestamp = utils.getTime(); 30859 30860 if ( !this.moved ) { 30861 this.scroller._execEvent('scrollStart'); 30862 } 30863 30864 this.moved = true; 30865 30866 deltaX = point.pageX - this.lastPointX; 30867 this.lastPointX = point.pageX; 30868 30869 deltaY = point.pageY - this.lastPointY; 30870 this.lastPointY = point.pageY; 30871 30872 newX = this.x + deltaX; 30873 newY = this.y + deltaY; 30874 30875 this._pos(newX, newY); 30876 30877// INSERT POINT: indicator._move 30878 30879 e.preventDefault(); 30880 e.stopPropagation(); 30881 }, 30882 30883 _end: function (e) { 30884 if ( !this.initiated ) { 30885 return; 30886 } 30887 30888 this.initiated = false; 30889 30890 e.preventDefault(); 30891 e.stopPropagation(); 30892 30893 utils.removeEvent(window, 'touchmove', this); 30894 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 30895 utils.removeEvent(window, 'mousemove', this); 30896 30897 if ( this.scroller.options.snap ) { 30898 var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y); 30899 30900 var time = this.options.snapSpeed || Math.max( 30901 Math.max( 30902 Math.min(Math.abs(this.scroller.x - snap.x), 1000), 30903 Math.min(Math.abs(this.scroller.y - snap.y), 1000) 30904 ), 300); 30905 30906 if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) { 30907 this.scroller.directionX = 0; 30908 this.scroller.directionY = 0; 30909 this.scroller.currentPage = snap; 30910 this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing); 30911 } 30912 } 30913 30914 if ( this.moved ) { 30915 this.scroller._execEvent('scrollEnd'); 30916 } 30917 }, 30918 30919 transitionTime: function (time) { 30920 time = time || 0; 30921 var durationProp = utils.style.transitionDuration; 30922 if(!durationProp) { 30923 return; 30924 } 30925 30926 this.indicatorStyle[durationProp] = time + 'ms'; 30927 30928 if ( !time && utils.isBadAndroid ) { 30929 this.indicatorStyle[durationProp] = '0.0001ms'; 30930 // remove 0.0001ms 30931 var self = this; 30932 rAF(function() { 30933 if(self.indicatorStyle[durationProp] === '0.0001ms') { 30934 self.indicatorStyle[durationProp] = '0s'; 30935 } 30936 }); 30937 } 30938 }, 30939 30940 transitionTimingFunction: function (easing) { 30941 this.indicatorStyle[utils.style.transitionTimingFunction] = easing; 30942 }, 30943 30944 refresh: function () { 30945 this.transitionTime(); 30946 30947 if ( this.options.listenX && !this.options.listenY ) { 30948 this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; 30949 } else if ( this.options.listenY && !this.options.listenX ) { 30950 this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; 30951 } else { 30952 this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; 30953 } 30954 30955 if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) { 30956 utils.addClass(this.wrapper, 'iScrollBothScrollbars'); 30957 utils.removeClass(this.wrapper, 'iScrollLoneScrollbar'); 30958 30959 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30960 if ( this.options.listenX ) { 30961 this.wrapper.style.right = '8px'; 30962 } else { 30963 this.wrapper.style.bottom = '8px'; 30964 } 30965 } 30966 } else { 30967 utils.removeClass(this.wrapper, 'iScrollBothScrollbars'); 30968 utils.addClass(this.wrapper, 'iScrollLoneScrollbar'); 30969 30970 if ( this.options.defaultScrollbars && this.options.customStyle ) { 30971 if ( this.options.listenX ) { 30972 this.wrapper.style.right = '2px'; 30973 } else { 30974 this.wrapper.style.bottom = '2px'; 30975 } 30976 } 30977 } 30978 30979 var r = this.wrapper.offsetHeight; // force refresh 30980 30981 if ( this.options.listenX ) { 30982 this.wrapperWidth = this.wrapper.clientWidth; 30983 if ( this.options.resize ) { 30984 this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); 30985 this.indicatorStyle.width = this.indicatorWidth + 'px'; 30986 } else { 30987 this.indicatorWidth = this.indicator.clientWidth; 30988 } 30989 30990 this.maxPosX = this.wrapperWidth - this.indicatorWidth; 30991 30992 if ( this.options.shrink == 'clip' ) { 30993 this.minBoundaryX = -this.indicatorWidth + 8; 30994 this.maxBoundaryX = this.wrapperWidth - 8; 30995 } else { 30996 this.minBoundaryX = 0; 30997 this.maxBoundaryX = this.maxPosX; 30998 } 30999 31000 this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); 31001 } 31002 31003 if ( this.options.listenY ) { 31004 this.wrapperHeight = this.wrapper.clientHeight; 31005 if ( this.options.resize ) { 31006 this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); 31007 this.indicatorStyle.height = this.indicatorHeight + 'px'; 31008 } else { 31009 this.indicatorHeight = this.indicator.clientHeight; 31010 } 31011 31012 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 31013 31014 if ( this.options.shrink == 'clip' ) { 31015 this.minBoundaryY = -this.indicatorHeight + 8; 31016 this.maxBoundaryY = this.wrapperHeight - 8; 31017 } else { 31018 this.minBoundaryY = 0; 31019 this.maxBoundaryY = this.maxPosY; 31020 } 31021 31022 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 31023 this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); 31024 } 31025 31026 this.updatePosition(); 31027 }, 31028 31029 updatePosition: function () { 31030 var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, 31031 y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; 31032 31033 if ( !this.options.ignoreBoundaries ) { 31034 if ( x < this.minBoundaryX ) { 31035 if ( this.options.shrink == 'scale' ) { 31036 this.width = Math.max(this.indicatorWidth + x, 8); 31037 this.indicatorStyle.width = this.width + 'px'; 31038 } 31039 x = this.minBoundaryX; 31040 } else if ( x > this.maxBoundaryX ) { 31041 if ( this.options.shrink == 'scale' ) { 31042 this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); 31043 this.indicatorStyle.width = this.width + 'px'; 31044 x = this.maxPosX + this.indicatorWidth - this.width; 31045 } else { 31046 x = this.maxBoundaryX; 31047 } 31048 } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) { 31049 this.width = this.indicatorWidth; 31050 this.indicatorStyle.width = this.width + 'px'; 31051 } 31052 31053 if ( y < this.minBoundaryY ) { 31054 if ( this.options.shrink == 'scale' ) { 31055 this.height = Math.max(this.indicatorHeight + y * 3, 8); 31056 this.indicatorStyle.height = this.height + 'px'; 31057 } 31058 y = this.minBoundaryY; 31059 } else if ( y > this.maxBoundaryY ) { 31060 if ( this.options.shrink == 'scale' ) { 31061 this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); 31062 this.indicatorStyle.height = this.height + 'px'; 31063 y = this.maxPosY + this.indicatorHeight - this.height; 31064 } else { 31065 y = this.maxBoundaryY; 31066 } 31067 } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) { 31068 this.height = this.indicatorHeight; 31069 this.indicatorStyle.height = this.height + 'px'; 31070 } 31071 } 31072 31073 this.x = x; 31074 this.y = y; 31075 31076 if ( this.scroller.options.useTransform ) { 31077 this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ; 31078 } else { 31079 this.indicatorStyle.left = x + 'px'; 31080 this.indicatorStyle.top = y + 'px'; 31081 } 31082 }, 31083 31084 _pos: function (x, y) { 31085 if ( x < 0 ) { 31086 x = 0; 31087 } else if ( x > this.maxPosX ) { 31088 x = this.maxPosX; 31089 } 31090 31091 if ( y < 0 ) { 31092 y = 0; 31093 } else if ( y > this.maxPosY ) { 31094 y = this.maxPosY;
31095 } 31096 31097 x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x; 31098 y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y; 31099 31100 this.scroller.scrollTo(x, y); 31101 }, 31102 31103 fade: function (val, hold) { 31104 if ( hold && !this.visible ) { 31105 return; 31106 } 31107 31108 clearTimeout(this.fadeTimeout); 31109 this.fadeTimeout = null; 31110 31111 var time = val ? 250 : 500, 31112 delay = val ? 0 : 300; 31113 31114 val = val ? '1' : '0'; 31115 31116 this.wrapperStyle[utils.style.transitionDuration] = time + 'ms'; 31117 31118 this.fadeTimeout = setTimeout((function (val) { 31119 this.wrapperStyle.opacity = val; 31120 this.visible = +val; 31121 }).bind(this, val), delay); 31122 } 31123}; 31124 31125IScroll.utils = utils; 31126 31127if ( typeof module != 'undefined' && module.exports ) { 31128 module.exports = IScroll; 31129} else if ( typeof define == 'function' && define.amd ) { 31130 define( function () { return IScroll; } ); 31131} else { 31132 window.IScroll = IScroll; 31133} 31134 31135})(window, document, Math); 31136/*! 31137 * fullPage 2.9.4 31138 * https://github.com/alvarotrigo/fullPage.js 31139 * @license MIT licensed 31140 * 31141 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo 31142 */ 31143(function(global, factory) { 31144 'use strict'; 31145 if (typeof define === 'function' && define.amd) { 31146 define(['jquery'], function($) { 31147 return factory($, global, global.document, global.Math); 31148 }); 31149 } else if (typeof exports === "object" && exports) { 31150 module.exports = factory(require('jquery'), global, global.document, global.Math); 31151 } else { 31152 factory(jQuery, global, global.document, global.Math); 31153 } 31154})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) { 31155 'use strict'; 31156 31157 // keeping central set of classnames and selectors 31158 var WRAPPER = 'fullpage-wrapper'; 31159 var WRAPPER_SEL = '.' + WRAPPER; 31160 31161 // slimscroll 31162 var SCROLLABLE = 'fp-scrollable'; 31163 var SCROLLABLE_SEL = '.' + SCROLLABLE; 31164 31165 // util 31166 var RESPONSIVE = 'fp-responsive'; 31167 var NO_TRANSITION = 'fp-notransition'; 31168 var DESTROYED = 'fp-destroyed'; 31169 var ENABLED = 'fp-enabled'; 31170 var VIEWING_PREFIX = 'fp-viewing'; 31171 var ACTIVE = 'active'; 31172 var ACTIVE_SEL = '.' + ACTIVE; 31173 var COMPLETELY = 'fp-completely'; 31174 var COMPLETELY_SEL = '.' + COMPLETELY; 31175 31176 // section 31177 var SECTION_DEFAULT_SEL = '.section'; 31178 var SECTION = 'fp-section'; 31179 var SECTION_SEL = '.' + SECTION; 31180 var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; 31181 var SECTION_FIRST_SEL = SECTION_SEL + ':first'; 31182 var SECTION_LAST_SEL = SECTION_SEL + ':last'; 31183 var TABLE_CELL = 'fp-tableCell'; 31184 var TABLE_CELL_SEL = '.' + TABLE_CELL; 31185 var AUTO_HEIGHT = 'fp-auto-height'; 31186 var AUTO_HEIGHT_SEL = '.fp-auto-height'; 31187 var NORMAL_SCROLL = 'fp-normal-scroll'; 31188 var NORMAL_SCROLL_SEL = '.fp-normal-scroll'; 31189 31190 // section nav 31191 var SECTION_NAV = 'fp-nav'; 31192 var SECTION_NAV_SEL = '#' + SECTION_NAV; 31193 var SECTION_NAV_TOOLTIP = 'fp-tooltip'; 31194 var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP; 31195 var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; 31196 31197 // slide 31198 var SLIDE_DEFAULT_SEL = '.slide'; 31199 var SLIDE = 'fp-slide'; 31200 var SLIDE_SEL = '.' + SLIDE; 31201 var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; 31202 var SLIDES_WRAPPER = 'fp-slides'; 31203 var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; 31204 var SLIDES_CONTAINER = 'fp-slidesContainer'; 31205 var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; 31206 var TABLE = 'fp-table'; 31207 31208 // slide nav 31209 var SLIDES_NAV = 'fp-slidesNav'; 31210 var SLIDES_NAV_SEL = '.' + SLIDES_NAV; 31211 var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; 31212 var SLIDES_ARROW = 'fp-controlArrow'; 31213 var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; 31214 var SLIDES_PREV = 'fp-prev'; 31215 var SLIDES_PREV_SEL = '.' + SLIDES_PREV; 31216 var SLIDES_ARROW_PREV = SLIDES_ARROW + ' ' + SLIDES_PREV; 31217 var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; 31218 var SLIDES_NEXT = 'fp-next';
31219 var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; 31220 var SLIDES_ARROW_NEXT = SLIDES_ARROW + ' ' + SLIDES_NEXT; 31221 var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; 31222 31223 var $window = $(window); 31224 var $document = $(document); 31225 31226 // Default options for iScroll.js used when using scrollOverflow 31227 var iscrollOptions = { 31228 scrollbars: true, 31229 mouseWheel: true, 31230 hideScrollbars: false, 31231 fadeScrollbars: false, 31232 disableMouse: true, 31233 interactiveScrollbars: true, 31234 bounce: false, 31235 }; 31236 31237 $.fn.fullpage = function(options) { 31238 //only once my friend! 31239 if($('html').hasClass(ENABLED)){ displayWarnings(); return; } 31240 31241 // common jQuery objects 31242 var $htmlBody = $('html, body'); 31243 var $body = $('body'); 31244 31245 var FP = $.fn.fullpage; 31246 31247 // Creating some defaults, extending them with any options that were provided 31248 options = $.extend({ 31249 //navigation 31250 menu: false, 31251 anchors:[], 31252 lockAnchors: false, 31253 navigation: false, 31254 navigationPosition: 'right', 31255 navigationTooltips: [], 31256 showActiveTooltip: false, 31257 slidesNavigation: false, 31258 slidesNavPosition: 'bottom', 31259 scrollBar: false, 31260 hybrid: false, 31261 31262 //scrolling 31263 css3: true, 31264 scrollingSpeed: 700, 31265 autoScrolling: true, 31266 fitToSection: true, 31267 fitToSectionDelay: 1000, 31268 easing: 'easeInOutCubic', 31269 easingcss3: 'ease', 31270 loopBottom: false, 31271 loopTop: false, 31272 loopHorizontal: true, 31273 continuousVertical: false, 31274 continuousHorizontal: false, 31275 scrollHorizontally: false, 31276 interlockedSlides: false, 31277 dragAndMove: false, 31278 offsetSections: false, 31279 resetSliders: false, 31280 fadingEffect: false, 31281 normalScrollElements: null, 31282 scrollOverflow: false, 31283 scrollOverflowReset: false, 31284 scrollOverflowHandler: iscrollHandler, 31285 scrollOverflowOptions: null, 31286 touchSensitivity: 5, 31287 normalScrollElementTouchThreshold: 5, 31288 bigSectionsDestination: null, 31289 31290 //Accessibility 31291 keyboardScrolling: true, 31292 animateAnchor: true, 31293 recordHistory: true, 31294 31295 //design 31296 controlArrows: true, 31297 controlArrowColor: '#fff', 31298 verticalCentered: true, 31299 sectionsColor : [], 31300 paddingTop: 0, 31301 paddingBottom: 0, 31302 fixedElements: null, 31303 responsive: 0, //backwards compabitility with responsiveWiddth 31304 responsiveWidth: 0, 31305 responsiveHeight: 0, 31306 responsiveSlides: false, 31307 parallax: false, 31308 parallaxOptions: { 31309 type: 'reveal', 31310 percentage: 62, 31311 property: 'translate' 31312 }, 31313 31314 //Custom selectors 31315 sectionSelector: SECTION_DEFAULT_SEL, 31316 slideSelector: SLIDE_DEFAULT_SEL, 31317 31318 //events 31319 afterLoad: null, 31320 onLeave: null, 31321 afterRender: null, 31322 afterResize: null, 31323 afterReBuild: null, 31324 afterSlideLoad: null, 31325 onSlideLeave: null, 31326 afterResponsive: null, 31327 31328 lazyLoading: true 31329 }, options); 31330 31331 //flag to avoid very fast sliding for landscape sliders 31332 var slideMoving = false; 31333 31334 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 31335 var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); 31336 var container = $(this); 31337 var windowsHeight = $window.height(); 31338 var isResizing = false; 31339 var isWindowFocused = true; 31340 var lastScrolledDestiny; 31341 var lastScrolledSlide; 31342 var canScroll = true; 31343 var scrollings = []; 31344 var controlPressed; 31345 var startingSection; 31346 var isScrollAllowed = {}; 31347 isScrollAllowed.m = { 'up':true, 'down':true, 'left':true, 'right':true }; 31348 isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m); 31349 var MSPointer = getMSPointer(); 31350 var events = { 31351 touchmove: 'ontouchmove' in window ? 'touchmove' : MSPointer.move, 31352 touchstart: 'ontouchstart' in window ? 'touchstart' : MSPointer.down 31353 }; 31354 31355 //cheks for passive event support 31356 //added by Uncode from new fullPage updates 31357 var g_supportsPassive = false;
31358 try { 31359 var opts = Object.defineProperty({}, 'passive', { 31360 get: function() { 31361 g_supportsPassive = true; 31362 } 31363 }); 31364 window.addEventListener("testPassive", null, opts); 31365 window.removeEventListener("testPassive", null, opts); 31366 } catch (e) {} 31367 31368 //timeouts 31369 var resizeId; 31370 var afterSectionLoadsId; 31371 var afterSlideLoadsId; 31372 var scrollId; 31373 var scrollId2; 31374 var keydownId; 31375 var originals = $.extend(true, {}, options); //deep copy 31376 31377 //Uncode addition 31378 var $masthead = $('#masthead'); 31379 var hideMenu = !$('body').hasClass('vmenu') && $('body').hasClass('uncode-fp-menu-hide') ? true : false; 31380 var menuHeight = $masthead.hasClass('menu-transparent') || hideMenu ? 0 : UNCODE.menuHeight; 31381 var bodyBorder = UNCODE.bodyBorder; 31382 var adminBarHeight = UNCODE.adminBarHeight; 31383 31384 displayWarnings(); 31385 31386 //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783 31387 iscrollOptions.click = isTouch; // see #2035 31388 31389 //extending iScroll options with the user custom ones 31390 iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions); 31391 31392 //easeInOutCubic animation included in the plugin 31393 $.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;}}); 31394 31395 /** 31396 * Sets the autoScroll option. 31397 * It changes the scroll bar visibility and the history of the site as a result. 31398 */ 31399 function setAutoScrolling(value, type){ 31400 //removing the transformation 31401 if(!value){ 31402 silentScroll(0); 31403 } 31404 31405 setVariableState('autoScrolling', value, type); 31406 31407 var element = $(SECTION_ACTIVE_SEL); 31408 31409 if(options.autoScrolling && !options.scrollBar){ 31410 $htmlBody.css({ 31411 'overflow' : 'hidden !important', 31412 'height' : '100%' 31413 }); 31414 31415 //Uncode addition 31416 //setRecordHistory(originals.recordHistory, 'internal'); 31417 31418 //for IE touch devices 31419 container.css({ 31420 '-ms-touch-action': 'none', 31421 'touch-action': 'none' 31422 }); 31423 31424 if(element.length){ 31425 //moving the container up 31426 silentScroll(element.position().top); 31427 } 31428 31429 }else{ 31430 $htmlBody.css({ 31431 'overflow' : 'visible !important', 31432 'height' : 'initial' 31433 }); 31434 31435 //Uncode addition 31436 //setRecordHistory(false, 'internal'); 31437 31438 //for IE touch devices 31439 container.css({ 31440 '-ms-touch-action': '', 31441 'touch-action': '' 31442 }); 31443 31444 //scrolling the page to the section with no animation 31445 if (element.length) { 31446 $htmlBody.scrollTop(element.position().top); 31447 } 31448 } 31449 } 31450 31451 /** 31452 * Defines wheter to record the history for each hash change in the URL. 31453 */ 31454 function setRecordHistory(value, type){ 31455 setVariableState('recordHistory', value, type); 31456 } 31457 31458 /** 31459 * Defines the scrolling speed 31460 */ 31461 function setScrollingSpeed(value, type){ 31462 setVariableState('scrollingSpeed', value, type); 31463 } 31464 31465 /** 31466 * Sets fitToSection 31467 */ 31468 function setFitToSection(value, type){ 31469 setVariableState('fitToSection', value, type); 31470 } 31471 31472 /** 31473 * Sets lockAnchors 31474 */ 31475 function setLockAnchors(value){ 31476 options.lockAnchors = value; 31477 } 31478 31479 /** 31480 * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. 31481 */ 31482 function setMouseWheelScrolling(value){ 31483 if(value){ 31484 addMouseWheelHandler(); 31485 addMiddleWheelHandler(); 31486 }else{ 31487 removeMouseWheelHandler(); 31488 removeMiddleWheelHandler(); 31489 } 31490 } 31491 31492 /** 31493 * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures. 31494 * Optionally a second parameter can be used to specify the direction for which the action will be applied. 31495 * 31496 * @param directions string containing the direction or directions separated by comma. 31497 */ 31498 function setAllowScrolling(value, directions){ 31499 if(typeof directions !== 'undefined'){ 31500 directions = directions.replace(/ /g,'').split(','); 31501 31502 $.each(directions, function (index, direction){ 31503 setIsScrollAllowed(value, direction, 'm'); 31504 }); 31505 } 31506 else if(value){ 31507 setMouseWheelScrolling(true); 31508 addTouchHandler(); 31509 }else{ 31510 setMouseWheelScrolling(false); 31511 removeTouchHandler(); 31512 } 31513 } 31514 31515 /** 31516 * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys 31517 */ 31518 function setKeyboardScrolling(value, directions){ 31519 if(typeof directions !== 'undefined'){ 31520 directions = directions.replace(/ /g,'').split(','); 31521 31522 $.each(directions, function (index, direction){ 31523 setIsScrollAllowed(value, direction, 'k'); 31524 }); 31525 }else{ 31526 options.keyboardScrolling = value; 31527 } 31528 } 31529 31530 /** 31531 * Moves the page up one section. 31532 */ 31533 function moveSectionUp(){ 31534 var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL); 31535 31536 //looping to the bottom if there's no more sections above 31537 if (!prev.length && (options.loopTop || options.continuousVertical)) {
31538 prev = $(SECTION_SEL).last(); 31539 } 31540 31541 if (prev.length) { 31542 scrollPage(prev, null, true); 31543 } 31544 } 31545 31546 /** 31547 * Moves the page down one section. 31548 */ 31549 function moveSectionDown(){ 31550 var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL); 31551 31552 //looping to the top if there's no more sections below 31553 if(!next.length && 31554 (options.loopBottom || options.continuousVertical)){ 31555 next = $(SECTION_SEL).first(); 31556 } 31557 31558 if(next.length){ 31559 scrollPage(next, null, false); 31560 } 31561 } 31562 31563 /** 31564 * Moves the page to the given section and slide with no animation. 31565 * Anchors or index positions can be used as params. 31566 */ 31567 function silentMoveTo(sectionAnchor, slideAnchor){ 31568 setScrollingSpeed (0, 'internal'); 31569 moveTo(sectionAnchor, slideAnchor); 31570 setScrollingSpeed (originals.scrollingSpeed, 'internal'); 31571 } 31572 31573 /** 31574 * Moves the page to the given section and slide. 31575 * Anchors or index positions can be used as params. 31576 */ 31577 function moveTo(sectionAnchor, slideAnchor){ 31578 var destiny = getSectionByAnchor(sectionAnchor); 31579 31580 if (typeof slideAnchor !== 'undefined'){ 31581 scrollPageAndSlide(sectionAnchor, slideAnchor); 31582 }else if(destiny.length > 0){ 31583 scrollPage(destiny); 31584 } 31585 } 31586 31587 /** 31588 * Slides right the slider of the active section. 31589 * Optional `section` param. 31590 */ 31591 function moveSlideRight(section){ 31592 moveSlide('right', section); 31593 } 31594 31595 /** 31596 * Slides left the slider of the active section. 31597 * Optional `section` param. 31598 */ 31599 function moveSlideLeft(section){ 31600 moveSlide('left', section); 31601 } 31602 31603 /** 31604 * When resizing is finished, we adjust the slides sizes and positions 31605 */ 31606 function reBuild(resizing){ 31607 if(container.hasClass(DESTROYED)){ return; } //nothing to do if the plugin was destroyed 31608 31609 isResizing = true; 31610 31611 windowsHeight = $window.height(); //updating global var 31612 31613 $(SECTION_SEL).each(function(){ 31614 var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL); 31615 var slides = $(this).find(SLIDE_SEL); 31616 31617 //adjusting the height of the table-cell for IE and Firefox 31618 if(options.verticalCentered){ 31619 $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px'); 31620 } 31621 31622 $(this).css('height', windowsHeight + 'px'); 31623 31624 //resizing the scrolling divs 31625 if(options.scrollOverflow){ 31626 if(slides.length){ 31627 slides.each(function(){ 31628 createScrollBar($(this)); 31629 }); 31630 }else{ 31631 createScrollBar($(this)); 31632 } 31633 } 31634 31635 //adjusting the position fo the FULL WIDTH slides... 31636 if (slides.length > 1) { 31637 landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL)); 31638 } 31639 }); 31640 31641 var activeSection = $(SECTION_ACTIVE_SEL); 31642 var sectionIndex = activeSection.index(SECTION_SEL); 31643 31644 //isn't it the first section? 31645 if(sectionIndex){ 31646 //adjusting the position for the current section 31647 silentMoveTo(sectionIndex + 1); 31648 } 31649 31650 isResizing = false; 31651 // Uncode change 31652 // $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container); 31653 $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container, getTableHeight()); 31654 $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container); 31655 } 31656 31657 /** 31658 * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` 31659 * are smaller than the set limit values. 31660 */ 31661 function setResponsive(active){ 31662 var isResponsive = $body.hasClass(RESPONSIVE); 31663 31664 if(active){ 31665 if(!isResponsive){ 31666 setAutoScrolling(false, 'internal'); 31667 setFitToSection(false, 'internal'); 31668 $(SECTION_NAV_SEL).hide(); 31669 $body.addClass(RESPONSIVE); 31670 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 31671 } 31672 } 31673 else if(isResponsive){ 31674 setAutoScrolling(originals.autoScrolling, 'internal'); 31675 setFitToSection(originals.autoScrolling, 'internal'); 31676 $(SECTION_NAV_SEL).show(); 31677 $body.removeClass(RESPONSIVE); 31678 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 31679 } 31680 } 31681 31682 if($(this).length){ 31683 //public functions 31684 FP.setAutoScrolling = setAutoScrolling; 31685 FP.setRecordHistory = setRecordHistory; 31686 FP.setScrollingSpeed = setScrollingSpeed; 31687 FP.setFitToSection = setFitToSection; 31688 FP.setLockAnchors = setLockAnchors; 31689 FP.setMouseWheelScrolling = setMouseWheelScrolling; 31690 FP.setAllowScrolling = setAllowScrolling; 31691 FP.setKeyboardScrolling = setKeyboardScrolling; 31692 FP.moveSectionUp = moveSectionUp; 31693 FP.moveSectionDown = moveSectionDown; 31694 FP.silentMoveTo = silentMoveTo; 31695 FP.moveTo = moveTo; 31696 FP.moveSlideRight = moveSlideRight; 31697 FP.moveSlideLeft = moveSlideLeft; 31698 FP.fitToSection = fitToSection; 31699 FP.reBuild = reBuild; 31700 FP.setResponsive = setResponsive; 31701 FP.destroy = destroy; 31702 31703 init(); 31704 31705 bindEvents(); 31706 } 31707
31708 function init(){ 31709 //if css3 is not supported, it will use jQuery animations 31710 if(options.css3){ 31711 options.css3 = support3d(); 31712 } 31713 31714 options.scrollBar = options.scrollBar || options.hybrid; 31715 31716 setOptionsFromDOM(); 31717 prepareDom(); 31718 setAllowScrolling(true); 31719 setAutoScrolling(options.autoScrolling, 'internal'); 31720 responsive(); 31721 31722 //setting the class for the body element 31723 setBodyClass(); 31724 31725 //Uncode addition 31726 // if(document.readyState === 'complete'){ 31727 // scrollToAnchor(); 31728 // } 31729 // $window.on('load', scrollToAnchor); 31730 } 31731 31732 function bindEvents(){ 31733 $window 31734 //when scrolling... 31735 //.on('scroll', scrollHandler) 31736 31737 //detecting any change on the URL to scroll to the given anchor link 31738 //(a way to detect back history button as we play with the hashes on the URL) 31739 .on('hashchange', hashChangeHandler) 31740 31741 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 31742 .blur(blurHandler) 31743 31744 //when resizing the site, we adjust the heights of the sections, slimScroll... 31745 .resize(resizeHandler); 31746 31747 $document 31748 //Sliding with arrow keys, both, vertical and horizontal 31749 .keydown(keydownHandler) 31750 31751 //to prevent scrolling while zooming 31752 .keyup(keyUpHandler) 31753 31754 //Scrolls to the section when clicking the navigation bullet 31755 .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler) 31756 31757 //Scrolls the slider to the given slide destination for the given section 31758 .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler) 31759 31760 .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler); 31761 31762 //Scrolling horizontally when clicking on the slider controls. 31763 $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler); 31764 31765 /** 31766 * Applying normalScroll elements. 31767 * Ignoring the scrolls over the specified selectors. 31768 */ 31769 if(options.normalScrollElements){ 31770 $document.on('mouseenter', options.normalScrollElements, function () { 31771 setMouseWheelScrolling(false); 31772 }); 31773 31774 $document.on('mouseleave', options.normalScrollElements, function(){ 31775 setMouseWheelScrolling(true); 31776 }); 31777 } 31778 } 31779 31780 /** 31781 * Setting options from DOM elements if they are not provided. 31782 */ 31783 function setOptionsFromDOM(){ 31784 var sections = container.find(options.sectionSelector); 31785 31786 //no anchors option? Checking for them in the DOM attributes 31787 if(!options.anchors.length){ 31788 options.anchors = sections.filter('[data-anchor]').map(function(){ 31789 return $(this).data('anchor').toString(); 31790 }).get(); 31791 } 31792 31793 //no tooltips option? Checking for them in the DOM attributes 31794 if(!options.navigationTooltips.length){ 31795 options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){ 31796 return $(this).data('tooltip').toString(); 31797 }).get(); 31798 } 31799 } 31800 31801 /** 31802 * Works over the DOM structure to set it up for the current fullpage options. 31803 */ 31804 function prepareDom(){ 31805 container.css({ 31806 'height': '100%', 31807 'position': 'relative' 31808 }); 31809 31810 //adding a class to recognize the container internally in the code 31811 container.addClass(WRAPPER); 31812 $('html').addClass(ENABLED); 31813 31814 windowsHeight = $window.height(); 31815 31816 container.removeClass(DESTROYED); //in case it was destroyed before initializing it again 31817 31818 addInternalSelectors(); 31819 31820 //styling the sections / slides / menu 31821 $(SECTION_SEL).each(function(index){ 31822 var section = $(this); 31823 var slides = section.find(SLIDE_SEL); 31824 var numSlides = slides.length; 31825 31826 styleSection(section, index); 31827 styleMenu(section, index); 31828 31829 // if there's any slide 31830 if (numSlides > 0) { 31831 styleSlides(section, slides, numSlides); 31832 }else{ 31833 if(options.verticalCentered){ 31834 addTableClass(section); 31835 } 31836 } 31837 }); 31838 31839 //fixed elements need to be moved out of the plugin container due to problems with CSS3. 31840 if(options.fixedElements && options.css3){ 31841 $(options.fixedElements).appendTo($body); 31842 } 31843 31844 //vertical centered of the navigation + active bullet 31845 if(options.navigation){ 31846 addVerticalNavigation(); 31847 } 31848 31849 enableYoutubeAPI(); 31850 31851 if(options.scrollOverflow){ 31852 if(document.readyState === 'complete'){ 31853 createScrollBarHandler(); 31854 } 31855 //after DOM and images are loaded 31856 $window.on('load', createScrollBarHandler); 31857 }else{ 31858 afterRenderActions(); 31859 } 31860 } 31861 31862 /** 31863 * Styles the horizontal slides for a section. 31864 */ 31865 function styleSlides(section, slides, numSlides){ 31866 var sliderWidth = numSlides * 100; 31867 var slideWidth = 100 / numSlides; 31868 31869 slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />'); 31870 slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />'); 31871 31872 section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%'); 31873 31874 if(numSlides > 1){ 31875 if(options.controlArrows){ 31876 createSlideArrows(section); 31877 } 31878 31879 if(options.slidesNavigation){ 31880 addSlidesNavigation(section, numSlides); 31881 } 31882 } 31883 31884 slides.each(function(index) { 31885 $(this).css('width', slideWidth + '%'); 31886 31887 if(options.verticalCentered){ 31888 addTableClass($(this)); 31889 } 31890 }); 31891 31892 var startingSlide = section.find(SLIDE_ACTIVE_SEL); 31893 31894 //if the slide won't be an starting point, the default will be the first one 31895 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
31895ide by default. 31896 if( startingSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){ 31897 silentLandscapeScroll(startingSlide, 'internal'); 31898 }else{ 31899 slides.eq(0).addClass(ACTIVE); 31900 } 31901 } 31902 31903 /** 31904 * Styling vertical sections 31905 */ 31906 function styleSection(section, index){ 31907 //if no active section is defined, the 1st one will be the default one 31908 if(!index && $(SECTION_ACTIVE_SEL).length === 0) { 31909 section.addClass(ACTIVE); 31910 } 31911 startingSection = $(SECTION_ACTIVE_SEL); 31912 31913 section.css('height', windowsHeight + 'px'); 31914 31915 if(options.paddingTop){ 31916 section.css('padding-top', options.paddingTop); 31917 } 31918 31919 if(options.paddingBottom){ 31920 section.css('padding-bottom', options.paddingBottom); 31921 } 31922 31923 if (typeof options.sectionsColor[index] !== 'undefined') { 31924 section.css('background-color', options.sectionsColor[index]); 31925 } 31926 31927 if (typeof options.anchors[index] !== 'undefined') { 31928 section.attr('data-anchor', options.anchors[index]); 31929 } 31930 } 31931 31932 /** 31933 * Sets the data-anchor attributes to the menu elements and activates the current one. 31934 */ 31935 function styleMenu(section, index){ 31936 if (typeof options.anchors[index] !== 'undefined') { 31937 //activating the menu / nav element on load 31938 if(section.hasClass(ACTIVE)){ 31939 activateMenuAndNav(options.anchors[index], index); 31940 } 31941 } 31942 31943 //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) 31944 if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){ 31945 $(options.menu).appendTo($body); 31946 } 31947 } 31948 31949 /** 31950 * Adds internal classes to be able to provide customizable selectors 31951 * keeping the link with the style sheet. 31952 */ 31953 function addInternalSelectors(){ 31954 container.find(options.sectionSelector).addClass(SECTION); 31955 container.find(options.slideSelector).addClass(SLIDE); 31956 } 31957 31958 /** 31959 * Creates the control arrows for the given section 31960 */ 31961 function createSlideArrows(section){ 31962 section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>'); 31963 31964 if(options.controlArrowColor!='#fff'){ 31965 section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor); 31966 section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent'); 31967 } 31968 31969 if(!options.loopHorizontal){ 31970 section.find(SLIDES_ARROW_PREV_SEL).hide(); 31971 } 31972 } 31973 31974 /** 31975 * Creates a vertical navigation bar. 31976 */ 31977 function addVerticalNavigation(){ 31978 $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>'); 31979 var nav = $(SECTION_NAV_SEL); 31980 31981 nav.addClass(function() { 31982 return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition; 31983 }); 31984 31985 for (var i = 0; i < $(SECTION_SEL).length; i++) { 31986 var link = ''; 31987 if (options.anchors.length) { 31988 link = options.anchors[i]; 31989 } 31990 31991 var li = '<li><a href="#' + link + '"><span></span></a>'; 31992 31993 // Only add tooltip if needed (defined by user) 31994 var tooltip = options.navigationTooltips[i]; 31995 31996 if (typeof tooltip !== 'undefined' && tooltip !== '') { 31997 li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>'; 31998 } 31999 32000 li += '</li>'; 32001 32002 nav.find('ul').append(li); 32003 } 32004 32005 //centering it vertically 32006 $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px'); 32007 32008 //activating the current active section 32009 $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE); 32010 } 32011 32012 /** 32013 * Creates the slim scroll scrollbar for the sections and slides inside them. 32014 */ 32015 function createScrollBarHandler(){ 32016 $(SECTION_SEL).each(function(){ 32017 var slides = $(this).find(SLIDE_SEL); 32018 32019 if(slides.length){ 32020 slides.each(function(){ 32021 createScrollBar($(this)); 32022 }); 32023 }else{ 32024 createScrollBar($(this)); 32025 } 32026 32027 }); 32028 afterRenderActions(); 32029 } 32030 32031 /*
32032 * Enables the Youtube videos API so we can control their flow if necessary. 32033 */ 32034 function enableYoutubeAPI(){ 32035 container.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32036 addURLParam($(this), 'enablejsapi=1'); 32037 }); 32038 } 32039 32040 /** 32041 * Adds a new parameter and its value to the `src` of a given element 32042 */ 32043 function addURLParam(element, newParam){ 32044 var originalSrc = element.attr('src'); 32045 element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam); 32046 } 32047 32048 /* 32049 * Returns the prefix sign to use for a new parameter in an existen URL. 32050 * 32051 * @return {String} ? | & 32052 */ 32053 function getUrlParamSign(url){ 32054 return ( !/\?/.test( url ) ) ? '?' : '&'; 32055 } 32056 32057 /** 32058 * Actions and callbacks to fire afterRender 32059 */ 32060 function afterRenderActions(){ 32061 var section = $(SECTION_ACTIVE_SEL); 32062 32063 section.addClass(COMPLETELY); 32064 32065 if(options.scrollOverflowHandler.afterRender){ 32066 options.scrollOverflowHandler.afterRender(section); 32067 } 32068 lazyLoad(section); 32069 playMedia(section); 32070 options.scrollOverflowHandler.afterLoad(); 32071 32072 if(isDestinyTheStartingSection()){ 32073 $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1)); 32074 } 32075 32076 // Uncode change 32077 // $.isFunction( options.afterRender ) && options.afterRender.call(container); 32078 $.isFunction( options.afterRender ) && options.afterRender.call(container, getTableHeight()); 32079 } 32080 32081 /** 32082 * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization) 32083 */ 32084 function isDestinyTheStartingSection(){ 32085 var anchors = window.location.hash.replace('#', '').split('/'); 32086 var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0])); 32087 32088 return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index(); 32089 } 32090 32091 32092 var isScrolling = false; 32093 var lastScroll = 0; 32094 32095 //when scrolling... 32096 function scrollHandler(){ 32097 var currentSection; 32098 32099 if(!options.autoScrolling || options.scrollBar){ 32100 var currentScroll = $window.scrollTop(); 32101 var scrollDirection = getScrollDirection(currentScroll); 32102 var visibleSectionIndex = 0; 32103 var screen_mid = currentScroll + ($window.height() / 2.0); 32104 var isAtBottom = $body.height() - $window.height() === currentScroll; 32105 var sections = document.querySelectorAll(SECTION_SEL); 32106 32107 //when using `auto-height` for a small last section it won't be centered in the viewport 32108 if(isAtBottom){ 32109 visibleSectionIndex = sections.length - 1; 32110 } 32111 //is at top? when using `auto-height` for a small first section it won't be centered in the viewport 32112 else if(!currentScroll){ 32113 visibleSectionIndex = 0; 32114 } 32115 32116 //taking the section which is showing more content in the viewport 32117 else{ 32118 for (var i = 0; i < sections.length; ++i) { 32119 var section = sections[i]; 32120 32121 // Pick the the last section which passes the middle line of the screen. 32122 if (section.offsetTop <= screen_mid) 32123 { 32124 visibleSectionIndex = i; 32125 } 32126 } 32127 } 32128 32129 if(isCompletelyInViewPort(scrollDirection)){ 32130 if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){ 32131 $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 32132 } 32133 } 32134 32135 //geting the last one, the current one on the screen 32136 currentSection = $(sections).eq(visibleSectionIndex); 32137 32138 //setting the visible section as active when manually scrolling 32139 //executing only once the first time we reach the section 32140 if(!currentSection.hasClass(ACTIVE)){ 32141 isScrolling = true; 32142 var leavingSection = $(SECTION_ACTIVE_SEL); 32143 var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1; 32144 var yMovement = getYmovement(currentSection); 32145 var anchorLink = currentSection.data('anchor'); 32146 var sectionIndex = currentSection.index(SECTION_SEL) + 1; 32147 var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL); 32148 var slideIndex; 32149 var slideAnchorLink; 32150 32151 if(activeSlide.length){ 32152 slideAnchorLink = activeSlide.data('anchor'); 32153 slideIndex = activeSlide.index(); 32154 } 32155 32156 if(canScroll){ 32157 currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32158 32159 $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement); 32160 $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex); 32161 32162 stopMedia(leavingSection); 32163 lazyLoad(currentSection); 32164 playMedia(currentSection); 32165 32166 activateMenuAndNav(anchorLink, sectionIndex - 1); 32167 32168 if(options.anchors.length){ 32169 //needed to enter in hashChange event when using the menu with anchor links 32170 lastScrolledDestiny = anchorLink; 32171 } 32172 setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex); 32173 } 32174 32175 //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet 32176 clearTimeout(scrollId); 32177 scrollId = setTimeout(function(){ 32178 isScrolling = false;
32179 }, 100); 32180 } 32181 32182 if(options.fitToSection){ 32183 //for the auto adjust of the viewport to fit a whole section 32184 clearTimeout(scrollId2); 32185 32186 scrollId2 = setTimeout(function(){ 32187 //checking it again in case it changed during the delay 32188 if(options.fitToSection){ 32189 fitToSection(); 32190 } 32191 }, options.fitToSectionDelay); 32192 } 32193 } 32194 } 32195 32196 /** 32197 * Fits the site to the nearest active section 32198 */ 32199 function fitToSection(){ 32200 //checking fitToSection again in case it was set to false before the timeout delay 32201 if(canScroll){ 32202 //allows to scroll to an active section and 32203 //if the section is already active, we prevent firing callbacks 32204 isResizing = true; 32205 32206 scrollPage($(SECTION_ACTIVE_SEL)); 32207 isResizing = false; 32208 } 32209 } 32210 32211 /** 32212 * Determines whether the active section has seen in its whole or not. 32213 */ 32214 function isCompletelyInViewPort(movement){ 32215 var top = $(SECTION_ACTIVE_SEL).position().top; 32216 var bottom = top + $window.height(); 32217 32218 if(movement == 'up'){ 32219 return bottom >= ($window.scrollTop() + $window.height()); 32220 } 32221 return top <= $window.scrollTop(); 32222 } 32223 32224 /** 32225 * Gets the directon of the the scrolling fired by the scroll event. 32226 */ 32227 function getScrollDirection(currentScroll){ 32228 var direction = currentScroll > lastScroll ? 'down' : 'up'; 32229 32230 lastScroll = currentScroll; 32231 32232 //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination 32233 previousDestTop = currentScroll; 32234 32235 return direction; 32236 } 32237 32238 /** 32239 * Determines the way of scrolling up or down: 32240 * by 'automatically' scrolling a section or by using the default and normal scrolling. 32241 */ 32242 function scrolling(type, scrollable){ 32243 if (!isScrollAllowed.m[type]){ 32244 return; 32245 } 32246 var check = (type === 'down') ? 'bottom' : 'top'; 32247 var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp; 32248 32249 if(scrollable.length > 0 ){ 32250 //is the scrollbar at the start/end of the scroll? 32251 if(options.scrollOverflowHandler.isScrolled(check, scrollable)){ 32252 scrollSection(); 32253 }else{ 32254 return true; 32255 } 32256 }else{ 32257 // moved up/down 32258 scrollSection(); 32259 } 32260 } 32261 32262 /* 32263 * Preventing bouncing in iOS #2285 32264 */ 32265 function preventBouncing(event){ 32266 var e = event.originalEvent; 32267 if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e) && isScrollAllowed.m.up){ 32268 //preventing the easing on iOS devices 32269 event.preventDefault(); 32270 } 32271 } 32272 32273 var touchStartY = 0; 32274 var touchStartX = 0; 32275 var touchEndY = 0; 32276 var touchEndX = 0; 32277 32278 /* Detecting touch events 32279 32280 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 32281 * This way, the touchstart and the touch moves shows an small difference between them which is the 32282 * used one to determine the direction. 32283 */ 32284 function touchMoveHandler(event){ 32285 var e = event.originalEvent; 32286 var activeSection = $(e.target).closest(SECTION_SEL); 32287 32288 // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain 32289 if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) { 32290 32291 if(options.autoScrolling){ 32292 //preventing the easing on iOS devices 32293 event.preventDefault(); 32294 } 32295 32296 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 32297 var touchEvents = getEventsPage(e); 32298 32299 touchEndY = touchEvents.y; 32300 touchEndX = touchEvents.x; 32301 32302 //if movement in the X axys is greater than in the Y and the currect section has slides... 32303 if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) { 32304 32305 //is the movement greater than the minimum resistance to scroll? 32306 if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) { 32307 if (touchStartX > touchEndX) { 32308 if(isScrollAllowed.m.right){ 32309 moveSlideRight(activeSection); //next 32310 } 32311 } else { 32312 if(isScrollAllowed.m.left){ 32313 moveSlideLeft(activeSection); //prev 32314 } 32315 } 32316 } 32317 } 32318 32319 //vertical scrolling (only when autoScrolling is enabled) 32320 else if(options.autoScrolling && canScroll){ 32321 32322 //is the movement greater than the minimum resistance to scroll? 32323 if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) { 32324 if (touchStartY > touchEndY) { 32325 scrolling('down', scrollable); 32326 } else if (touchEndY > touchStartY) { 32327 scrolling('up', scrollable); 32328 } 32329 } 32330 } 32331 } 32332 } 32333 32334 /** 32335 * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements 32336 * Currently works well for iOS - Android might need some testing 32337 * @param {Element} el target element / jquery selector (in subsequent nodes) 32338 * @param {int} hop current hop compared to options.normalScrollElementTouchThreshold 32339 * @return {boolean} true if there is a match to options.normalScrollElements 32340 */ 32341 function checkParentForNormalScrollElement (el, hop) { 32342 hop = hop || 0; 32343 var parent = $(el).parent(); 32344 32345 if (hop < options.normalScrollElementTouchThreshold && 32346 parent.is(options.normalScrollElements) ) { 32347 return true; 32348 } else if (hop == options.normalScrollElementTouchThreshold) { 32349 return false;
32350 } else { 32351 return checkParentForNormalScrollElement(parent, ++hop); 32352 } 32353 } 32354 32355 /** 32356 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 32357 * this way we make sure that is really a touch event what IE is detecting. 32358 */ 32359 function isReallyTouch(e){ 32360 //if is not IE || IE is detecting `touch` or `pen` 32361 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 32362 } 32363 32364 /** 32365 * Handler for the touch start event. 32366 */ 32367 function touchStartHandler(event){ 32368 var e = event.originalEvent; 32369 32370 //stopping the auto scroll to adjust to a section 32371 if(options.fitToSection){ 32372 $htmlBody.stop(); 32373 } 32374 32375 if(isReallyTouch(e)){ 32376 var touchEvents = getEventsPage(e); 32377 touchStartY = touchEvents.y; 32378 touchStartX = touchEvents.x; 32379 } 32380 } 32381 32382 /** 32383 * Gets the average of the last `number` elements of the given array. 32384 */ 32385 function getAverage(elements, number){ 32386 var sum = 0; 32387 32388 //taking `number` elements from the end to make the average, if there are not enought, 1 32389 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 32390 32391 for(var i = 0; i < lastElements.length; i++){ 32392 sum = sum + lastElements[i]; 32393 } 32394 32395 return Math.ceil(sum/number); 32396 } 32397 32398 /** 32399 * Detecting mousewheel scrolling 32400 * 32401 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 32402 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 32403 */ 32404 var prevTime = new Date().getTime(); 32405 32406 function MouseWheelHandler(e) { 32407 var curTime = new Date().getTime(); 32408 var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL); 32409 32410 //autoscrolling and not zooming? 32411 if(options.autoScrolling && !controlPressed && !isNormalScroll){ 32412 // cross-browser wheel delta 32413 e = e || window.event; 32414 var value = e.wheelDelta || -e.deltaY || -e.detail; 32415 var delta = Math.max(-1, Math.min(1, value)); 32416 32417 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 32418 var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); 32419 32420 //Limiting the array to 150 (lets not waste memory!) 32421 if(scrollings.length > 149){ 32422 scrollings.shift(); 32423 } 32424 32425 //keeping record of the previous scrollings 32426 scrollings.push(Math.abs(value)); 32427 32428 //preventing to scroll the site on mouse wheel when scrollbar is present 32429 if(options.scrollBar){ 32430 e.preventDefault ? e.preventDefault() : e.returnValue = false; 32431 } 32432 32433 var activeSection = $(SECTION_ACTIVE_SEL); 32434 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 32435 32436 //time difference between the last scroll and the current one 32437 var timeDiff = curTime-prevTime; 32438 prevTime = curTime; 32439 32440 //haven't they scrolled in a while? 32441 //(enough to be consider a different scrolling action to scroll another section) 32442 if(timeDiff > 200){ 32443 //emptying the array, we dont care about old scrollings for our averages 32444 scrollings = []; 32445 } 32446 32447 if(canScroll){ 32448 var averageEnd = getAverage(scrollings, 10); 32449 var averageMiddle = getAverage(scrollings, 70); 32450 var isAccelerating = averageEnd >= averageMiddle; 32451 32452 //to avoid double swipes... 32453 if(isAccelerating && isScrollingVertically){ 32454 //scrolling down? 32455 if (delta < 0) { 32456 scrolling('down', scrollable); 32457 32458 //scrolling up? 32459 }else { 32460 scrolling('up', scrollable); 32461 } 32462 } 32463 } 32464 32465 return false;
32466 } 32467 32468 if(options.fitToSection){ 32469 //stopping the auto scroll to adjust to a section 32470 $htmlBody.stop(); 32471 } 32472 } 32473 32474 /** 32475 * Slides a slider to the given direction. 32476 * Optional `section` param. 32477 */ 32478 function moveSlide(direction, section){ 32479 var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section; 32480 var slides = activeSection.find(SLIDES_WRAPPER_SEL); 32481 var numSlides = slides.find(SLIDE_SEL).length; 32482 32483 // more than one slide needed and nothing should be sliding 32484 if (!slides.length || slideMoving || numSlides < 2) { 32485 return; 32486 } 32487 32488 var currentSlide = slides.find(SLIDE_ACTIVE_SEL); 32489 var destiny = null; 32490 32491 if(direction === 'left'){ 32492 destiny = currentSlide.prev(SLIDE_SEL); 32493 }else{ 32494 destiny = currentSlide.next(SLIDE_SEL); 32495 } 32496 32497 //isn't there a next slide in the secuence? 32498 if(!destiny.length){ 32499 //respect loopHorizontal settin 32500 if (!options.loopHorizontal) return; 32501 32502 if(direction === 'left'){ 32503 destiny = currentSlide.siblings(':last'); 32504 }else{ 32505 destiny = currentSlide.siblings(':first'); 32506 } 32507 } 32508 32509 slideMoving = true; 32510 32511 landscapeScroll(slides, destiny, direction); 32512 } 32513 32514 /** 32515 * Maintains the active slides in the viewport 32516 * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) 32517 */ 32518 function keepSlidesPosition(){ 32519 $(SLIDE_ACTIVE_SEL).each(function(){ 32520 silentLandscapeScroll($(this), 'internal'); 32521 }); 32522 } 32523 32524 var previousDestTop = 0; 32525 /** 32526 * Returns the destination Y position based on the scrolling direction and 32527 * the height of the section. 32528 */ 32529 function getDestinationPosition(element){ 32530 var elemPosition = element.position(); 32531 32532 //top of the desination will be at the top of the viewport 32533 var position = elemPosition.top; 32534 var isScrollingDown = elemPosition.top > previousDestTop; 32535 var sectionBottom = position - windowsHeight + element.outerHeight(); 32536 var bigSectionsDestination = options.bigSectionsDestination; 32537 32538 //Uncode addition 32539 var containerH = container.outerHeight(); 32540 var containerPosition = container.offset(); 32541 32542 //########### Commented by Uncode - START ########### 32543 //is the destination element bigger than the viewport? 32544 // if(element.outerHeight() > windowsHeight){ 32545 // //scrolling up? 32546 // if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){ 32547 // position = sectionBottom; 32548 // } 32549 // } 32550 32551 // //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section 32552 // else if(isScrollingDown || (isResizing && element.is(':last-child')) ){ 32553 // //The bottom of the destination will be at the bottom of the viewport 32554 // position = sectionBottom; 32555 // } 32556 //########### Commented by Uncode - END ########### 32557 32558 //Uncode addition 32559 if ( !$masthead.hasClass('menu-transparent') && $('body').hasClass('uncode-fp-menu-shrink') && !element.is(':first-child') ) 32560 position += 18; 32561 if ( ( containerH + menuHeight + bodyBorder + adminBarHeight - windowsHeight ) < position || ( isResizing && element.is(':last-child') ) ) { 32562 position = sectionBottom + menuHeight + bodyBorder*2 + adminBarHeight; 32563 } 32564 32565 /* 32566 Keeping record of the last scrolled position to determine the scrolling direction. 32567 No conventional methods can be used as the scroll bar might not be present 32568 AND the section might not be active if it is auto-height and didnt reach the middle 32569 of the viewport. 32570 */ 32571 previousDestTop = position; 32572 return position; 32573 } 32574 32575 /** 32576 * Scrolls the site to the given element and scrolls to the slide if a callback is given. 32577 */ 32578 function scrollPage(element, callback, isMovementUp){ 32579 if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function 32580 32581 var dtop = getDestinationPosition(element); 32582 var slideAnchorLink; 32583 var slideIndex; 32584 32585 //local variables 32586 var v = { 32587 element: element, 32588 callback: callback, 32589 isMovementUp: isMovementUp, 32590 dtop: dtop, 32591 yMovement: getYmovement(element), 32592 anchorLink: element.data('anchor'), 32593 sectionIndex: element.index(SECTION_SEL), 32594 activeSlide: element.find(SLIDE_ACTIVE_SEL), 32595 activeSection: $(SECTION_ACTIVE_SEL), 32596 leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1, 32597 32598 //caching the value of isResizing at the momment the function is called 32599 //because it will be checked later inside a setTimeout and the value might change 32600 localIsResizing: isResizing 32601 }; 32602 32603 //quiting when destination scroll is the same as the current one 32604 if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; } 32605 32606 if(v.activeSlide.length){ 32607 slideAnchorLink = v.activeSlide.data('anchor'); 32608 slideIndex = v.activeSlide.index(); 32609 } 32610 32611 // If continuousVertical && we need to wrap around 32612 if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" && 32613 ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or 32614 (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down 32615 32616 v = createInfiniteSections(v); 32617 } 32618 32619 //callback (onLeave) if the site is not just resizing and readjusting the slides 32620 if($.isFunction(options.onLeave) && !v.localIsResizing){ 32621 if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){ 32622 return; 32623 } 32624 } 32625 32626 //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one) 32627 if(!v.localIsResizing){ 32628 stopMedia(v.activeSection); 32629 } 32630 32631 options.scrollOverflowHandler.beforeLeave(); 32632 element.addClass(ACTIVE).siblings().removeClass(ACTIVE); 32633 lazyLoad(element); 32634 options.scrollOverflowHandler.onLeave(); 32635 32636 32637 //preventing from activating the MouseWheelHandler event 32638 //more than once if the page is scrolling 32639 canScroll = false;
32640 32641 setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex); 32642 32643 performMovement(v); 32644 32645 //flag to avoid callingn `scrollPage()` twice in case of using anchor links 32646 lastScrolledDestiny = v.anchorLink; 32647 32648 //avoid firing it twice (as it does also on scroll) 32649 activateMenuAndNav(v.anchorLink, v.sectionIndex); 32650 } 32651 32652 /** 32653 * Performs the vertical movement (by CSS3 or by jQuery) 32654 */ 32655 function performMovement(v){ 32656 // using CSS3 translate functionality 32657 if (options.css3 && options.autoScrolling && !options.scrollBar) { 32658 32659 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 32660 // that's why we round it to 0. 32661 var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)'; 32662 transformContainer(translate3d, true); 32663 32664 //even when the scrollingSpeed is 0 there's a little delay, which might cause the 32665 //scrollingSpeed to change in case of using silentMoveTo(); 32666 if(options.scrollingSpeed){ 32667 clearTimeout(afterSectionLoadsId); 32668 afterSectionLoadsId = setTimeout(function () { 32669 afterSectionLoads(v); 32670 }, options.scrollingSpeed); 32671 }else{ 32672 afterSectionLoads(v); 32673 } 32674 } 32675 32676 // using jQuery animate 32677 else{ 32678 var scrollSettings = getScrollSettings(v); 32679 32680 $(scrollSettings.element).animate( 32681 scrollSettings.options, 32682 options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating `html, body` 32683 if(options.scrollBar){ 32684 32685 /* Hack! 32686 The timeout prevents setting the most dominant section in the viewport as "active" when the user 32687 scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar. 32688 32689 When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished. 32690 */ 32691 setTimeout(function(){ 32692 afterSectionLoads(v); 32693 },30); 32694 }else{ 32695 afterSectionLoads(v); 32696 } 32697 }); 32698 } 32699 } 32700 32701 /** 32702 * Gets the scrolling settings depending on the plugin autoScrolling option 32703 */ 32704 function getScrollSettings(v){ 32705 var scroll = {}; 32706 32707 if(options.autoScrolling && !options.scrollBar){ 32708 scroll.options = { 'top': -v.dtop}; 32709 scroll.element = WRAPPER_SEL; 32710 }else{ 32711 scroll.options = { 'scrollTop': v.dtop}; 32712 scroll.element = 'html, body'; 32713 } 32714 32715 return scroll; 32716 } 32717 32718 /** 32719 * Adds sections before or after the current one to create the infinite effect. 32720 */ 32721 function createInfiniteSections(v){ 32722 // Scrolling down 32723 if (!v.isMovementUp) { 32724 // Move all previous sections to after the active section 32725 $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse()); 32726 } 32727 else { // Scrolling up 32728 // Move all next sections to before the active section 32729 $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL)); 32730 } 32731 32732 // Maintain the displayed position (now that we changed the element order) 32733 silentScroll($(SECTION_ACTIVE_SEL).position().top); 32734 32735 // Maintain the active slides visible in the viewport 32736 keepSlidesPosition(); 32737 32738 // save for later the elements that still need to be reordered 32739 v.wrapAroundElements = v.activeSection; 32740 32741 // Recalculate animation variables 32742 v.dtop = v.element.position().top; 32743 v.yMovement = getYmovement(v.element); 32744 32745 return v; 32746 } 32747 32748 /** 32749 * Fix section order after continuousVertical changes have been animated 32750 */ 32751 function continuousVerticalFixSectionOrder (v) {
32752 // If continuousVertical is in effect (and autoScrolling would also be in effect then), 32753 // finish moving the elements around so the direct navigation will function more simply 32754 if (!v.wrapAroundElements || !v.wrapAroundElements.length) { 32755 return; 32756 } 32757 32758 if (v.isMovementUp) { 32759 $(SECTION_FIRST_SEL).before(v.wrapAroundElements); 32760 } 32761 else { 32762 $(SECTION_LAST_SEL).after(v.wrapAroundElements); 32763 } 32764 32765 silentScroll($(SECTION_ACTIVE_SEL).position().top); 32766 32767 // Maintain the active slides visible in the viewport 32768 keepSlidesPosition(); 32769 } 32770 32771 32772 /** 32773 * Actions to do once the section is loaded. 32774 */ 32775 function afterSectionLoads (v){ 32776 continuousVerticalFixSectionOrder(v); 32777 32778 //callback (afterLoad) if the site is not just resizing and readjusting the slides 32779 $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1)); 32780 options.scrollOverflowHandler.afterLoad(); 32781 32782 if(!v.localIsResizing){ 32783 playMedia(v.element); 32784 } 32785 32786 v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 32787 32788 canScroll = true; 32789 32790 $.isFunction(v.callback) && v.callback.call(this); 32791 } 32792 32793 /** 32794 * Sets the value for the given attribute from the `data-` attribute with the same suffix 32795 * ie: data-srcset ==> srcset | data-src ==> src 32796 */ 32797 function setSrc(element, attribute){ 32798 element 32799 .attr(attribute, element.data(attribute)) 32800 .removeAttr('data-' + attribute); 32801 } 32802 32803 /** 32804 * Lazy loads image, video and audio elements. 32805 */ 32806 function lazyLoad(destiny){ 32807 if (!options.lazyLoading){ 32808 return; 32809 } 32810 32811 var panel = getSlideOrSection(destiny); 32812 var element; 32813 32814 panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 32815 element = $(this); 32816 32817 $.each(['src', 'srcset'], function(index, type){ 32818 var attribute = element.attr('data-' + type); 32819 if(typeof attribute !== 'undefined' && attribute){ 32820 setSrc(element, type); 32821 } 32822 }); 32823 32824 if(element.is('source')){ 32825 element.closest('video').get(0).load(); 32826 } 32827 }); 32828 } 32829 32830 /** 32831 * Plays video and audio elements. 32832 */ 32833 function playMedia(destiny){ 32834 var panel = getSlideOrSection(destiny); 32835 32836 //playing HTML5 media elements 32837 panel.find('video, audio').each(function(){ 32838 var element = $(this).get(0); 32839 32840 if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) { 32841 element.play(); 32842 } 32843 }); 32844 32845 //youtube videos 32846 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32847 var element = $(this).get(0); 32848 32849 if ( element.hasAttribute('data-autoplay') ){ 32850 playYoutube(element); 32851 } 32852 32853 //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load. 32854 element.onload = function() { 32855 if ( element.hasAttribute('data-autoplay') ){ 32856 playYoutube(element); 32857 } 32858 }; 32859 }); 32860 } 32861 32862 /** 32863 * Plays a youtube video 32864 */ 32865 function playYoutube(element){ 32866 element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); 32867 } 32868 32869 /** 32870 * Stops video and audio elements. 32871 */ 32872 function stopMedia(destiny){ 32873 var panel = getSlideOrSection(destiny); 32874 32875 //stopping HTML5 media elements 32876 panel.find('video, audio').each(function(){ 32877 var element = $(this).get(0); 32878 32879 if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) { 32880 element.pause(); 32881 } 32882 }); 32883 32884 //youtube videos 32885 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 32886 var element = $(this).get(0); 32887 32888 if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){ 32889 $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*'); 32890 } 32891 }); 32892 } 32893 32894 /** 32895 * Gets the active slide (or section) for the given section 32896 */ 32897 function getSlideOrSection(destiny){ 32898 var slide = destiny.find(SLIDE_ACTIVE_SEL); 32899 if( slide.length ) { 32900 destiny = $(slide); 32901 } 32902 32903 return destiny; 32904 } 32905 32906 /**
32907 * Scrolls to the anchor in the URL when loading the site 32908 */ 32909 function scrollToAnchor(){ 32910 //getting the anchor link in the URL and deleting the `#` 32911 var value = window.location.hash.replace('#', '').split('/'); 32912 var sectionAnchor = decodeURIComponent(value[0]); 32913 var slideAnchor = decodeURIComponent(value[1]); 32914 32915 if(sectionAnchor){ //if theres any # 32916 if(options.animateAnchor){ 32917 scrollPageAndSlide(sectionAnchor, slideAnchor); 32918 }else{ 32919 silentMoveTo(sectionAnchor, slideAnchor); 32920 } 32921 } 32922 } 32923 32924 /** 32925 * Detecting any change on the URL to scroll to the given anchor link 32926 * (a way to detect back history button as we play with the hashes on the URL) 32927 */ 32928 function hashChangeHandler(){ 32929 if(!isScrolling && !options.lockAnchors){ 32930 var value = window.location.hash.replace('#', '').split('/'); 32931 var sectionAnchor = decodeURIComponent(value[0]); 32932 var slideAnchor = decodeURIComponent(value[1]); 32933 32934 //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) 32935 var isFirstSlideMove = (typeof lastScrolledDestiny === 'undefined'); 32936 var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving); 32937 32938 32939 if(sectionAnchor.length){ 32940 /*in order to call scrollpage() only once for each destination at a time 32941 It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` 32942 event is fired on every scroll too.*/ 32943 if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor )) { 32944 scrollPageAndSlide(sectionAnchor, slideAnchor); 32945 } 32946 } 32947 } 32948 } 32949 32950 //Sliding with arrow keys, both, vertical and horizontal 32951 function keydownHandler(e) { 32952 32953 clearTimeout(keydownId); 32954 32955 var activeElement = $(':focus'); 32956 32957 if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && 32958 activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' && 32959 options.keyboardScrolling && options.autoScrolling){ 32960 var keyCode = e.which; 32961 32962 //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 32963 var keyControls = [40, 38, 32, 33, 34]; 32964 if($.inArray(keyCode, keyControls) > -1){ 32965 e.preventDefault(); 32966 } 32967 32968 controlPressed = e.ctrlKey; 32969 32970 keydownId = setTimeout(function(){ 32971 onkeydown(e); 32972 },150); 32973 } 32974 } 32975 32976 function tooltipTextHandler(){ 32977 $(this).prev().trigger('click'); 32978 } 32979 32980 //to prevent scrolling while zooming 32981 function keyUpHandler(e){ 32982 if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox 32983 controlPressed = e.ctrlKey; 32984 } 32985 } 32986 32987 //binding the mousemove when the mouse's middle button is released 32988 function mouseDownHandler(e){ 32989 //middle button 32990 if (e.which == 2){ 32991 oldPageY = e.pageY; 32992 container.on('mousemove', mouseMoveHandler); 32993 } 32994 } 32995 32996 //unbinding the mousemove when the mouse's middle button is released 32997 function mouseUpHandler(e){ 32998 //middle button 32999 if (e.which == 2){ 33000 container.off('mousemove'); 33001 } 33002 } 33003 33004 //Scrolling horizontally when clicking on the slider controls. 33005 function slideArrowHandler(){ 33006 var section = $(this).closest(SECTION_SEL); 33007 33008 if ($(this).hasClass(SLIDES_PREV)) { 33009 if(isScrollAllowed.m.left){ 33010 moveSlideLeft(section); 33011 } 33012 } else { 33013 if(isScrollAllowed.m.right){ 33014 moveSlideRight(section); 33015 } 33016 } 33017 } 33018 33019 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 33020 function blurHandler(){ 33021 isWindowFocused = false;
33022 controlPressed = false; 33023 } 33024 33025 //Scrolls to the section when clicking the navigation bullet 33026 function sectionBulletHandler(e){ 33027 e.preventDefault(); 33028 var index = $(this).parent().index(); 33029 scrollPage($(SECTION_SEL).eq(index)); 33030 } 33031 33032 //Scrolls the slider to the given slide destination for the given section 33033 function slideBulletHandler(e){ 33034 e.preventDefault(); 33035 var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL); 33036 var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index()); 33037 33038 landscapeScroll(slides, destiny); 33039 } 33040 33041 /** 33042 * Keydown event 33043 */ 33044 function onkeydown(e){ 33045 var shiftPressed = e.shiftKey; 33046 33047 //do nothing if we can not scroll or we are not using horizotnal key arrows. 33048 if(!canScroll && [37,39].indexOf(e.which) < 0){ 33049 return; 33050 } 33051 33052 switch (e.which) { 33053 //up 33054 case 38: 33055 case 33: 33056 if(isScrollAllowed.k.up){ 33057 moveSectionUp(); 33058 } 33059 break; 33060 33061 //down 33062 case 32: //spacebar 33063 if(shiftPressed && isScrollAllowed.k.up){ 33064 moveSectionUp(); 33065 break; 33066 } 33067 /* falls through */ 33068 case 40: 33069 case 34: 33070 if(isScrollAllowed.k.down){ 33071 moveSectionDown(); 33072 } 33073 break; 33074 33075 //Home 33076 case 36: 33077 if(isScrollAllowed.k.up){ 33078 moveTo(1); 33079 } 33080 break; 33081 33082 //End 33083 case 35: 33084 if(isScrollAllowed.k.down){ 33085 moveTo( $(SECTION_SEL).length ); 33086 } 33087 break; 33088 33089 //left 33090 case 37: 33091 if(isScrollAllowed.k.left){ 33092 moveSlideLeft(); 33093 } 33094 break; 33095 33096 //right 33097 case 39: 33098 if(isScrollAllowed.k.right){ 33099 moveSlideRight(); 33100 } 33101 break; 33102 33103 default: 33104 return; // exit this handler for other keys 33105 } 33106 } 33107 33108 /** 33109 * Detecting the direction of the mouse movement. 33110 * Used only for the middle button of the mouse. 33111 */ 33112 var oldPageY = 0; 33113 function mouseMoveHandler(e){ 33114 if(canScroll){ 33115 // moving up 33116 if (e.pageY < oldPageY && isScrollAllowed.m.up){ 33117 moveSectionUp(); 33118 } 33119 33120 // moving down 33121 else if(e.pageY > oldPageY && isScrollAllowed.m.down){ 33122 moveSectionDown(); 33123 } 33124 } 33125 oldPageY = e.pageY; 33126 } 33127 33128 /** 33129 * Scrolls horizontal sliders. 33130 */ 33131 function landscapeScroll(slides, destiny, direction){ 33132 var section = slides.closest(SECTION_SEL); 33133 var v = { 33134 slides: slides, 33135 destiny: destiny, 33136 direction: direction, 33137 destinyPos: destiny.position(), 33138 slideIndex: destiny.index(), 33139 section: section, 33140 sectionIndex: section.index(SECTION_SEL), 33141 anchorLink: section.data('anchor'), 33142 slidesNav: section.find(SLIDES_NAV_SEL), 33143 slideAnchor: getAnchor(destiny), 33144 prevSlide: section.find(SLIDE_ACTIVE_SEL), 33145 prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(), 33146 33147 //caching the value of isResizing at the momment the function is called 33148 //because it will be checked later inside a setTimeout and the value might change 33149 localIsResizing: isResizing 33150 }; 33151 v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex); 33152 v.direction = v.direction ? v.direction : v.xMovement; 33153 33154 //important!! Only do it when not resizing 33155 if(!v.localIsResizing){ 33156 //preventing from scrolling to the next/prev section when using scrollHorizontally 33157 canScroll = false;
33158 } 33159 33160 if(options.onSlideLeave){ 33161 33162 //if the site is not just resizing and readjusting the slides 33163 if(!v.localIsResizing && v.xMovement!=='none'){ 33164 if($.isFunction( options.onSlideLeave )){ 33165 if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){ 33166 slideMoving = false; 33167 return; 33168 } 33169 } 33170 } 33171 } 33172 33173 destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE); 33174 33175 if(!v.localIsResizing){ 33176 stopMedia(v.prevSlide); 33177 lazyLoad(destiny); 33178 } 33179 33180 if(!options.loopHorizontal && options.controlArrows){ 33181 //hidding it for the fist slide, showing for the rest 33182 section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0); 33183 33184 //hidding it for the last slide, showing for the rest 33185 section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child')); 33186 } 33187 33188 //only changing the URL if the slides are in the current section (not for resize re-adjusting) 33189 if(section.hasClass(ACTIVE) && !v.localIsResizing){ 33190 setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex); 33191 } 33192 33193 performHorizontalMove(slides, v, true); 33194 } 33195 33196 33197 function afterSlideLoads(v){ 33198 activeSlidesNavigation(v.slidesNav, v.slideIndex); 33199 33200 //if the site is not just resizing and readjusting the slides 33201 if(!v.localIsResizing){ 33202 $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex); 33203 33204 //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally 33205 //and to prevent double scroll right after a windows resize 33206 canScroll = true; 33207 33208 playMedia(v.destiny); 33209 } 33210 33211 //letting them slide again 33212 slideMoving = false; 33213 } 33214 33215 /** 33216 * Performs the horizontal movement. (CSS3 or jQuery) 33217 * 33218 * @param fireCallback {Bool} - determines whether or not to fire the callback 33219 */ 33220 function performHorizontalMove(slides, v, fireCallback){ 33221 var destinyPos = v.destinyPos; 33222 33223 if(options.css3){ 33224 var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; 33225 33226 addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d), v); 33227 33228 afterSlideLoadsId = setTimeout(function(){ 33229 fireCallback && afterSlideLoads(v); 33230 }, options.scrollingSpeed, options.easing); 33231 }else{ 33232 slides.animate({ 33233 scrollLeft : Math.round(destinyPos.left) 33234 }, options.scrollingSpeed, options.easing, function() { 33235 33236 fireCallback && afterSlideLoads(v); 33237 }); 33238 } 33239 } 33240 33241 /** 33242 * Sets the state for the horizontal bullet navigations. 33243 */ 33244 function activeSlidesNavigation(slidesNav, slideIndex){ 33245 slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE); 33246 slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE); 33247 } 33248 33249 var previousHeight = windowsHeight; 33250 33251 //when resizing the site, we adjust the heights of the sections, slimScroll... 33252 function resizeHandler(){ 33253 //checking if it needs to get responsive 33254 responsive(); 33255 33256 // rebuild immediately on touch devices 33257 if (isTouchDevice) { 33258 var activeElement = $(document.activeElement); 33259 33260 //if the keyboard is NOT visible 33261 if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { 33262 var currentHeight = $window.height(); 33263 33264 //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) 33265 if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ 33266 reBuild(true); 33267 previousHeight = currentHeight; 33268 } 33269 } 33270 }else{ 33271 //in order to call the functions only when the resize is finished 33272 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 33273 clearTimeout(resizeId); 33274 33275 resizeId = setTimeout(function(){ 33276 reBuild(true); 33277 }, 350); 33278 } 33279 } 33280 33281 /** 33282 * Checks if the site needs to get responsive and disables autoScrolling if so. 33283 * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. 33284 */ 33285 function responsive(){ 33286 var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity 33287 var heightLimit = options.responsiveHeight; 33288 33289 //only calculating what we need. Remember its called on the resize event. 33290 var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit; 33291 var isBreakingPointHeight = heightLimit && $window.height() < heightLimit; 33292 33293 if(widthLimit && heightLimit){ 33294 setResponsive(isBreakingPointWidth || isBreakingPointHeight); 33295 } 33296 else if(widthLimit){ 33297 setResponsive(isBreakingPointWidth); 33298 } 33299 else if(heightLimit){ 33300 setResponsive(isBreakingPointHeight); 33301 } 33302 } 33303 33304 /** 33305 * Adds transition animations for the given element 33306 */ 33307 function addAnimation(container, element){ 33308 var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; 33309 33310 container.removeClass(NO_TRANSITION); 33311 return container.css({
33312 '-webkit-transition': transition, 33313 'transition': transition 33314 }); 33315 } 33316 33317 /** 33318 * Remove transition animations for the given element 33319 */ 33320 function removeAnimation(element){ 33321 return element.addClass(NO_TRANSITION); 33322 } 33323 33324 /** 33325 * Activating the vertical navigation bullets according to the given slide name. 33326 */ 33327 function activateNavDots(name, sectionIndex){ 33328 if(options.navigation){ 33329 $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE); 33330 if(name){ 33331 $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE); 33332 }else{ 33333 $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE); 33334 } 33335 } 33336 } 33337 33338 /** 33339 * Activating the website main menu elements according to the given slide name. 33340 */ 33341 function activateMenuElement(name){ 33342 if(options.menu){ 33343 $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE); 33344 $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE); 33345 } 33346 } 33347 33348 /** 33349 * Sets to active the current menu and vertical nav items. 33350 */ 33351 function activateMenuAndNav(anchor, index){ 33352 activateMenuElement(anchor); 33353 activateNavDots(anchor, index); 33354 } 33355 33356 /** 33357 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 33358 * from the current section. 33359 */ 33360 function getYmovement(destiny){ 33361 var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL); 33362 var toIndex = destiny.index(SECTION_SEL); 33363 if( fromIndex == toIndex){ 33364 return 'none'; 33365 } 33366 if(fromIndex > toIndex){ 33367 return 'up'; 33368 } 33369 return 'down'; 33370 } 33371 33372 /** 33373 * Retuns `right` or `left` depending on the scrolling movement to reach its destination 33374 * from the current slide. 33375 */ 33376 function getXmovement(fromIndex, toIndex){ 33377 if( fromIndex == toIndex){ 33378 return 'none'; 33379 } 33380 if(fromIndex > toIndex){ 33381 return 'left'; 33382 } 33383 return 'right'; 33384 } 33385 33386 /** 33387 * Checks if the element needs scrollbar and if the user wants to apply it. 33388 * If so it creates it. 33389 * 33390 * @param {Object} element jQuery object of the section or slide 33391 */ 33392 function createScrollBar(element){ 33393 //User doesn't want scrollbar here? Sayonara baby! 33394 if(element.hasClass('fp-noscroll')) return; 33395 33396 //needed to make `scrollHeight` work under Opera 12 33397 element.css('overflow', 'hidden'); 33398 33399 var scrollOverflowHandler = options.scrollOverflowHandler; 33400 var wrap = scrollOverflowHandler.wrapContent(); 33401 //in case element is a slide 33402 var section = element.closest(SECTION_SEL); 33403 var scrollable = scrollOverflowHandler.scrollable(element); 33404 var contentHeight; 33405 33406 //if there was scroll, the contentHeight will be the one in the scrollable section 33407 if(scrollable.length){ 33408 contentHeight = scrollOverflowHandler.scrollHeight(element); 33409 }else{ 33410 contentHeight = element.get(0).scrollHeight; 33411 if(options.verticalCentered){ 33412 contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight; 33413 } 33414 } 33415 33416 var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top')); 33417 33418 //needs scroll? 33419 if ( contentHeight > scrollHeight) { 33420 //did we already have an scrollbar ? Updating it 33421 if(scrollable.length){ 33422 scrollOverflowHandler.update(element, scrollHeight); 33423 } 33424 //creating the scrolling 33425 else{ 33426 if(options.verticalCentered){ 33427 element.find(TABLE_CELL_SEL).wrapInner(wrap); 33428 }else{ 33429 element.wrapInner(wrap); 33430 } 33431 scrollOverflowHandler.create(element, scrollHeight); 33432 } 33433 } 33434 //removing the scrolling when it is not necessary anymore 33435 else{ 33436 scrollOverflowHandler.remove(element); 33437 } 33438 33439 //undo 33440 element.css('overflow', ''); 33441 } 33442 33443 function addTableClass(element){ 33444 //In case we are styling for the 2nd time as in with reponsiveSlides 33445 if(!element.hasClass(TABLE)){ 33446 element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />'); 33447 } 33448 } 33449 33450 function getTableHeight(element){ 33451 var sectionHeight = windowsHeight; 33452 33453 if(options.paddingTop || options.paddingBottom){ 33454 var section = element; 33455 if(!section.hasClass(SECTION)){ 33456 section = element.closest(SECTION_SEL); 33457 } 33458 33459 var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); 33460 sectionHeight = (windowsHeight - paddings); 33461 } 33462 33463 return sectionHeight; 33464 } 33465 33466 /** 33467 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 33468 */ 33469 function transformContainer(translate3d, animated){ 33470 if(animated){ 33471 addAnimation(container); 33472 }else{ 33473 removeAnimation(container); 33474 } 33475 33476 container.css(getTransforms(translate3d)); 33477 33478 //syncronously removing the class after the animation has been applied. 33479 setTimeout(function(){ 33480 container.removeClass(NO_TRANSITION); 33481 },10); 33482 } 33483 33484 /** 33485 * Gets a section by its anchor / index 33486 */ 33487 function getSectionByAnchor(sectionAnchor){ 33488 if(!sectionAnchor) return []; 33489 33490 var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]'); 33491 if(!section.length){ 33492 section = $(SECTION_SEL).eq( sectionAnchor -1); 33493 } 33494 33495 return section; 33496 } 33497 33498 /** 33499 * Gets a slide inside a given section by its anchor / index 33500 */ 33501 function getSlideByAnchor(slideAnchor, section){ 33502 var slides = section.find(SLIDES_WRAPPER_SEL); 33503 var slide = slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]'); 33504
33505 if(!slide.length){ 33506 slide = slides.find(SLIDE_SEL).eq(slideAnchor); 33507 } 33508 33509 return slide; 33510 } 33511 33512 /** 33513 * Scrolls to the given section and slide anchors 33514 */ 33515 function scrollPageAndSlide(destiny, slide){ 33516 var section = getSectionByAnchor(destiny); 33517 33518 //do nothing if there's no section with the given anchor name 33519 if(!section.length) return; 33520 33521 //default slide 33522 if (typeof slide === 'undefined') { 33523 slide = 0; 33524 } 33525 33526 //we need to scroll to the section and then to the slide 33527 if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){ 33528 scrollPage(section, function(){ 33529 scrollSlider(section, slide); 33530 }); 33531 } 33532 //if we were already in the section 33533 else{ 33534 scrollSlider(section, slide); 33535 } 33536 } 33537 33538 /** 33539 * Scrolls the slider to the given slide destination for the given section 33540 */ 33541 function scrollSlider(section, slideAnchor){ 33542 if(typeof slideAnchor !== 'undefined'){ 33543 var slides = section.find(SLIDES_WRAPPER_SEL); 33544 var destiny = getSlideByAnchor(slideAnchor, section); 33545 33546 if(destiny.length){ 33547 landscapeScroll(slides, destiny); 33548 } 33549 } 33550 } 33551 33552 /** 33553 * Creates a landscape navigation bar with dots for horizontal sliders. 33554 */ 33555 function addSlidesNavigation(section, numSlides){ 33556 section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>'); 33557 var nav = section.find(SLIDES_NAV_SEL); 33558 33559 //top or bottom 33560 nav.addClass(options.slidesNavPosition); 33561 33562 for(var i=0; i< numSlides; i++){ 33563 nav.find('ul').append('<li><a href="#"><span></span></a></li>'); 33564 } 33565 33566 //centering it 33567 nav.css('margin-left', '-' + (nav.width()/2) + 'px'); 33568 33569 nav.find('li').first().find('a').addClass(ACTIVE); 33570 } 33571 33572 33573 /** 33574 * Sets the state of the website depending on the active section/slide. 33575 * It changes the URL hash when needed and updates the body class. 33576 */ 33577 function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){ 33578 var sectionHash = ''; 33579 33580 if(options.anchors.length && !options.lockAnchors){ 33581 33582 //isn't it the first slide? 33583 if(slideIndex){ 33584 if(typeof anchorLink !== 'undefined'){ 33585 sectionHash = anchorLink; 33586 } 33587 33588 //slide without anchor link? We take the index instead. 33589 if(typeof slideAnchor === 'undefined'){ 33590 slideAnchor = slideIndex; 33591 } 33592 33593 lastScrolledSlide = slideAnchor; 33594 setUrlHash(sectionHash + '/' + slideAnchor); 33595 33596 //first slide won't have slide anchor, just the section one 33597 }else if(typeof slideIndex !== 'undefined'){ 33598 lastScrolledSlide = slideAnchor; 33599 setUrlHash(anchorLink); 33600 } 33601 33602 //section without slides 33603 else{ 33604 setUrlHash(anchorLink); 33605 } 33606 } 33607 33608 setBodyClass(); 33609 } 33610 33611 /** 33612 * Sets the URL hash. 33613 */ 33614 function setUrlHash(url){ 33615 //Uncode addition 33616 if ( typeof SiteParameters.slide_footer != 'undefined' && url == SiteParameters.slide_footer ) 33617 return false; 33618 33619 if(options.recordHistory){ 33620 location.hash = url; 33621 }else{ 33622 //Uncode addition 33623 //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) 33624 // if(isTouchDevice || isTouch){ 33625 // window.history.replaceState(undefined, undefined, '#' + url); 33626 // }else{ 33627 // var baseUrl = window.location.href.split('#')[0]; 33628 // window.location.replace( baseUrl + '#' + url ); 33629 // } 33630 return false;
33631 } 33632 } 33633 33634 /** 33635 * Gets the anchor for the given slide / section. Its index will be used if there's none. 33636 */ 33637 function getAnchor(element){ 33638 var anchor = element.data('anchor'); 33639 var index = element.index(); 33640 33641 //Slide without anchor link? We take the index instead. 33642 if(typeof anchor === 'undefined'){ 33643 anchor = index; 33644 } 33645 33646 return anchor; 33647 } 33648 33649 /** 33650 * Sets a class for the body of the page depending on the active section / slide 33651 */ 33652 function setBodyClass(){ 33653 var section = $(SECTION_ACTIVE_SEL); 33654 var slide = section.find(SLIDE_ACTIVE_SEL); 33655 33656 var sectionAnchor = getAnchor(section); 33657 var slideAnchor = getAnchor(slide); 33658 33659 var text = String(sectionAnchor); 33660 33661 if(slide.length){ 33662 text = text + '-' + slideAnchor; 33663 } 33664 33665 //changing slash for dash to make it a valid CSS style 33666 text = text.replace('/', '-').replace('#',''); 33667 33668 //removing previous anchor classes 33669 var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); 33670 $body[0].className = $body[0].className.replace(classRe, ''); 33671 33672 //adding the current anchor 33673 $body.addClass(VIEWING_PREFIX + '-' + text); 33674 } 33675 33676 /** 33677 * Checks for translate3d support 33678 * @return boolean 33679 * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support 33680 */ 33681 function support3d() { 33682 var el = document.createElement('p'), 33683 has3d, 33684 transforms = { 33685 'webkitTransform':'-webkit-transform', 33686 'OTransform':'-o-transform', 33687 'msTransform':'-ms-transform', 33688 'MozTransform':'-moz-transform', 33689 'transform':'transform' 33690 }; 33691 33692 // Add it to the body to get the computed style. 33693 document.body.insertBefore(el, null); 33694 33695 for (var t in transforms) { 33696 if (el.style[t] !== undefined) { 33697 el.style[t] = 'translate3d(1px,1px,1px)'; 33698 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 33699 } 33700 } 33701 33702 document.body.removeChild(el); 33703 33704 return (has3d !== undefined && has3d.length > 0 && has3d !== 'none'); 33705 } 33706 33707 /** 33708 * Removes the auto scrolling action fired by the mouse wheel and trackpad. 33709 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 33710 */ 33711 function removeMouseWheelHandler(){ 33712 if (document.addEventListener) { 33713 document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 33714 document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox 33715 document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox 33716 } else { 33717 document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 33718 } 33719 } 33720 33721 /** 33722 * Adds the auto scrolling action for the mouse wheel and trackpad. 33723 * After this function is called, the mousewheel and trackpad movements will scroll through sections 33724 * https://developer.mozilla.org/en-US/docs/Web/Events/wheel 33725 */ 33726 function addMouseWheelHandler(){ 33727 var prefix = ''; 33728 var _addEventListener; 33729 33730 if (window.addEventListener){ 33731 _addEventListener = "addEventListener"; 33732 }else{ 33733 _addEventListener = "attachEvent"; 33734 prefix = 'on'; 33735 } 33736 33737 // detect available wheel event 33738 var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel" 33739 document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" 33740 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox 33741 var passiveEvent = g_supportsPassive ? {passive: false }
33741: false; 33742 33743 33744 if(support == 'DOMMouseScroll'){ 33745 document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent); 33746 } 33747 33748 //handle MozMousePixelScroll in older Firefox 33749 else{ 33750 document[ _addEventListener ](prefix + support, MouseWheelHandler, passiveEvent); 33751 } 33752 } 33753 33754 /** 33755 * Binding the mousemove when the mouse's middle button is pressed 33756 */ 33757 function addMiddleWheelHandler(){ 33758 container 33759 .on('mousedown', mouseDownHandler) 33760 .on('mouseup', mouseUpHandler); 33761 } 33762 33763 /** 33764 * Unbinding the mousemove when the mouse's middle button is released 33765 */ 33766 function removeMiddleWheelHandler(){ 33767 container 33768 .off('mousedown', mouseDownHandler) 33769 .off('mouseup', mouseUpHandler); 33770 } 33771 33772 /** 33773 * Adds the possibility to auto scroll through sections on touch devices. 33774 */ 33775 function addTouchHandler(){ 33776 if(isTouchDevice || isTouch){ 33777 if(options.autoScrolling){ 33778 $body.off(events.touchmove).on(events.touchmove, preventBouncing); 33779 } 33780 33781 $(WRAPPER_SEL) 33782 .off(events.touchstart).on(events.touchstart, touchStartHandler) 33783 .off(events.touchmove).on(events.touchmove, touchMoveHandler); 33784 } 33785 } 33786 33787 /** 33788 * Removes the auto scrolling for touch devices. 33789 */ 33790 function removeTouchHandler(){ 33791 if(isTouchDevice || isTouch){ 33792 $(WRAPPER_SEL) 33793 .off(events.touchstart) 33794 .off(events.touchmove); 33795 } 33796 } 33797 33798 /* 33799 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11) 33800 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 33801 */ 33802 function getMSPointer(){ 33803 var pointer; 33804 33805 //IE >= 11 & rest of browsers 33806 if(window.PointerEvent){ 33807 pointer = { down: 'pointerdown', move: 'pointermove'}; 33808 } 33809 33810 //IE < 11 33811 else{ 33812 pointer = { down: 'MSPointerDown', move: 'MSPointerMove'}; 33813 } 33814 33815 return pointer; 33816 } 33817 33818 /** 33819 * Gets the pageX and pageY properties depending on the browser. 33820 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 33821 */ 33822 function getEventsPage(e){ 33823 var events = []; 33824 33825 events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); 33826 events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); 33827 33828 //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 33829 if(isTouch && isReallyTouch(e) && options.scrollBar){ 33830 events.y = e.touches[0].pageY; 33831 events.x = e.touches[0].pageX; 33832 } 33833 33834 return events; 33835 } 33836 33837 /** 33838 * Slides silently (with no animation) the active slider to the given slide. 33839 * @param noCallback {bool} true or defined -> no callbacks 33840 */ 33841 function silentLandscapeScroll(activeSlide, noCallbacks){ 33842 setScrollingSpeed (0, 'internal'); 33843 33844 if(typeof noCallbacks !== 'undefined'){ 33845 //preventing firing callbacks afterSlideLoad etc. 33846 isResizing = true; 33847 } 33848 33849 landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide); 33850 33851 if(typeof noCallbacks !== 'undefined'){ 33852 isResizing = false; 33853 } 33854 33855 setScrollingSpeed(originals.scrollingSpeed, 'internal'); 33856 } 33857 33858 /** 33859 * Scrolls silently (with no animation) the page to the given Y position. 33860 */ 33861 function silentScroll(top){ 33862 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 33863 // that's why we round it to 0. 33864 var roundedTop = Math.round(top); 33865 33866 if (options.css3 && options.autoScrolling && !options.scrollBar){ 33867 var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)'; 33868 transformContainer(translate3d, false); 33869 } 33870 else if(options.autoScrolling && !options.scrollBar){ 33871 container.css('top', -roundedTop); 33872 } 33873 else{ 33874 $htmlBody.scrollTop(roundedTop); 33875 } 33876 } 33877 33878 /** 33879 * Returns the cross-browser transform string. 33880 */ 33881 function getTransforms(translate3d){ 33882 return {
33883 '-webkit-transform': translate3d, 33884 '-moz-transform': translate3d, 33885 '-ms-transform':translate3d, 33886 'transform': translate3d 33887 }; 33888 } 33889 33890 /** 33891 * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) 33892 * @type m (mouse) or k (keyboard) 33893 */ 33894 function setIsScrollAllowed(value, direction, type){ 33895 switch (direction){ 33896 case 'up': isScrollAllowed[type].up = value; break; 33897 case 'down': isScrollAllowed[type].down = value; break; 33898 case 'left': isScrollAllowed[type].left = value; break; 33899 case 'right': isScrollAllowed[type].right = value; break; 33900 case 'all': 33901 if(type == 'm'){ 33902 setAllowScrolling(value); 33903 }else{ 33904 setKeyboardScrolling(value); 33905 } 33906 } 33907 } 33908 33909 /* 33910 * Destroys fullpage.js plugin events and optinally its html markup and styles 33911 */ 33912 function destroy(all){ 33913 setAutoScrolling(false, 'internal'); 33914 setAllowScrolling(false); 33915 setKeyboardScrolling(false); 33916 container.addClass(DESTROYED); 33917 33918 clearTimeout(afterSlideLoadsId); 33919 clearTimeout(afterSectionLoadsId); 33920 clearTimeout(resizeId); 33921 clearTimeout(scrollId); 33922 clearTimeout(scrollId2); 33923 33924 $window 33925 .off('scroll', scrollHandler) 33926 .off('hashchange', hashChangeHandler) 33927 .off('resize', resizeHandler); 33928 33929 $document 33930 .off('click touchstart', SECTION_NAV_SEL + ' a') 33931 .off('mouseenter', SECTION_NAV_SEL + ' li') 33932 .off('mouseleave', SECTION_NAV_SEL + ' li') 33933 .off('click touchstart', SLIDES_NAV_LINK_SEL) 33934 .off('mouseover', options.normalScrollElements) 33935 .off('mouseout', options.normalScrollElements); 33936 33937 $(SECTION_SEL) 33938 .off('click touchstart', SLIDES_ARROW_SEL); 33939 33940 clearTimeout(afterSlideLoadsId); 33941 clearTimeout(afterSectionLoadsId); 33942 33943 //lets make a mess! 33944 if(all){ 33945 destroyStructure(); 33946 } 33947 } 33948 33949 /* 33950 * Removes inline styles added by fullpage.js 33951 */ 33952 function destroyStructure(){ 33953 //reseting the `top` or `translate` properties to 0 33954 silentScroll(0); 33955 33956 //loading all the lazy load content 33957 container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 33958 setSrc($(this), 'src'); 33959 }); 33960 33961 container.find('img[data-srcset]').each(function(){ 33962 setSrc($(this), 'srcset'); 33963 }); 33964 33965 $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL).remove(); 33966 33967 //removing inline styles 33968 $(SECTION_SEL).css( { 33969 'height': '', 33970 'background-color' : '', 33971 'padding': '' 33972 }); 33973 33974 $(SLIDE_SEL).css( { 33975 'width': '' 33976 }); 33977 33978 container.css({ 33979 'height': '', 33980 'position': '', 33981 '-ms-touch-action': '', 33982 'touch-action': '' 33983 }); 33984 33985 $htmlBody.css({ 33986 'overflow': '', 33987 'height': '' 33988 }); 33989 33990 // remove .fp-enabled class 33991 $('html').removeClass(ENABLED); 33992 33993 // remove .fp-responsive class 33994 $body.removeClass(RESPONSIVE); 33995 33996 // remove all of the .fp-viewing- classes 33997 $.each($body.get(0).className.split(/\s+/), function (index, className) { 33998 if (className.indexOf(VIEWING_PREFIX) === 0) { 33999 $body.removeClass(className); 34000 } 34001 }); 34002 34003 //removing added classes 34004 $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){ 34005 options.scrollOverflowHandler.remove($(this)); 34006 $(this).removeClass(TABLE + ' ' + ACTIVE); 34007 }); 34008 34009 removeAnimation(container); 34010 34011 //Unwrapping content 34012 container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){ 34013 //unwrap not being use in case there's no child element inside and its just text 34014 $(this).replaceWith(this.childNodes); 34015 }); 34016 34017 //removing the applied transition from the fullpage wrapper 34018 container.css({
34019 '-webkit-transition': 'none', 34020 'transition': 'none' 34021 }); 34022 34023 //scrolling the page to the top with no animation 34024 $htmlBody.scrollTop(0); 34025 34026 //removing selectors 34027 var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; 34028 $.each(usedSelectors, function(index, value){ 34029 $('.' + value).removeClass(value); 34030 }); 34031 } 34032 34033 /* 34034 * Sets the state for a variable with multiple states (original, and temporal) 34035 * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. 34036 * This function is used to keep track of both states, the original and the temporal one. 34037 * If type is not 'internal', then we assume the user is globally changing the variable. 34038 */ 34039 function setVariableState(variable, value, type){ 34040 options[variable] = value; 34041 if(type !== 'internal'){ 34042 originals[variable] = value; 34043 } 34044 } 34045 34046 /** 34047 * Displays warnings 34048 */ 34049 function displayWarnings(){ 34050 var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax']; 34051 //UNCODE.addition 34052 // if($('html').hasClass(ENABLED)){ 34053 // showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); 34054 // return; 34055 // } 34056 34057 // Disable mutually exclusive settings 34058 //UNCODE.addition 34059 // if (options.continuousVertical && 34060 // (options.loopTop || options.loopBottom)) { 34061 // options.continuousVertical = false;
34062 // showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 34063 // } 34064 34065 // if(options.scrollBar && options.scrollOverflow){ 34066 // showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox'); 34067 // } 34068 34069 // if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){ 34070 // options.continuousVertical = false; 34071 // showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 34072 // } 34073 34074 //using extensions? Wrong file! 34075 $.each(extensions, function(index, extension){ 34076 //is the option set to true? 34077 if(options[extension]){ 34078 showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension); 34079 } 34080 }); 34081 34082 //anchors can not have the same value as any element ID or NAME 34083 $.each(options.anchors, function(index, name){ 34084 34085 //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) 34086 var nameAttr = $document.find('[name]').filter(function() { 34087 return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase(); 34088 }); 34089 34090 var idAttr = $document.find('[id]').filter(function() { 34091 return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase(); 34092 }); 34093 34094 if(idAttr.length || nameAttr.length ){ 34095 showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).'); 34096 idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property'); 34097 nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property'); 34098 } 34099 }); 34100 } 34101 34102 /** 34103 * Shows a message in the console of the given type. 34104 */ 34105 function showError(type, text){ 34106 console && console[type] && console[type]('fullPage: ' + text); 34107 } 34108 34109 }; //end of $.fn.fullpage 34110 34111 if(typeof IScroll !== 'undefined'){ 34112 /* 34113 * Turns iScroll `mousewheel` option off dynamically 34114 * https://github.com/cubiq/iscroll/issues/1036 34115 */ 34116 IScroll.prototype.wheelOn = function () { 34117 this.wrapper.addEventListener('wheel', this); 34118 this.wrapper.addEventListener('mousewheel', this); 34119 this.wrapper.addEventListener('DOMMouseScroll', this); 34120 }; 34121 34122 /* 34123 * Turns iScroll `mousewheel` option on dynamically 34124 * https://github.com/cubiq/iscroll/issues/1036 34125 */ 34126 IScroll.prototype.wheelOff = function () { 34127 this.wrapper.removeEventListener('wheel', this); 34128 this.wrapper.removeEventListener('mousewheel', this); 34129 this.wrapper.removeEventListener('DOMMouseScroll', this); 34130 }; 34131 } 34132 34133 /** 34134 * An object to handle overflow scrolling. 34135 * This uses jquery.slimScroll to accomplish overflow scrolling. 34136 * It is possible to pass in an alternate scrollOverflowHandler 34137 * to the fullpage.js option that implements the same functions 34138 * as this handler. 34139 * 34140 * @type {Object} 34141 */ 34142 var iscrollHandler = { 34143 refreshId: null, 34144 iScrollInstances: [], 34145 34146 // Enables or disables the mouse wheel for the active section or all slides in it 34147 toggleWheel: function(value){ 34148 var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL); 34149 scrollable.each(function(){ 34150 var iScrollInstance = $(this).data('iscrollInstance'); 34151 if(typeof iScrollInstance !== 'undefined' && iScrollInstance){ 34152 if(value){ 34153 iScrollInstance.wheelOn(); 34154 } 34155 else{ 34156 iScrollInstance.wheelOff(); 34157 } 34158 } 34159 }); 34160 }, 34161 34162 /** 34163 * Turns off iScroll for the destination section. 34164 * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
34165 * scroll the destination section/slide before the sections animations ends. 34166 */ 34167 onLeave: function(){ 34168 iscrollHandler.toggleWheel(false); 34169 }, 34170 34171 // Turns off iScroll for the leaving section 34172 beforeLeave: function(){ 34173 iscrollHandler.onLeave() 34174 }, 34175 34176 // Turns on iScroll on section load 34177 afterLoad: function(){ 34178 iscrollHandler.toggleWheel(true); 34179 }, 34180 34181 /** 34182 * Called when overflow scrolling is needed for a section. 34183 * 34184 * @param {Object} element jQuery object containing current section 34185 * @param {Number} scrollHeight Current window height in pixels 34186 */ 34187 create: function(element, scrollHeight) { 34188 var scrollable = element.find(SCROLLABLE_SEL); 34189 34190 scrollable.height(scrollHeight); 34191 scrollable.each(function() { 34192 var $this = $(this); 34193 var iScrollInstance = $this.data('iscrollInstance'); 34194 if (iScrollInstance) { 34195 $.each(iscrollHandler.iScrollInstances, function(){ 34196 $(this).destroy(); 34197 }); 34198 } 34199 34200 iScrollInstance = new IScroll($this.get(0), iscrollOptions); 34201 iscrollHandler.iScrollInstances.push(iScrollInstance); 34202 34203 //off by default until the section gets active 34204 iScrollInstance.wheelOff(); 34205 34206 $this.data('iscrollInstance', iScrollInstance); 34207 }); 34208 }, 34209 34210 /** 34211 * Return a boolean depending on whether the scrollable element is a 34212 * the end or at the start of the scrolling depending on the given type. 34213 * 34214 * @param {String} type Either 'top' or 'bottom' 34215 * @param {Object} scrollable jQuery object for the scrollable element 34216 * @return {Boolean} 34217 */ 34218 isScrolled: function(type, scrollable) { 34219 var scroller = scrollable.data('iscrollInstance'); 34220 34221 //no scroller? 34222 if (!scroller) { 34223 return true; 34224 } 34225 34226 //Uncode addition 34227 var uncode_body_borders = parseFloat($('.body-borders').attr('data-border')) || 0; 34228 //End Uncode addition 34229 34230 if (type === 'top') { 34231 return scroller.y >= 0 && !scrollable.scrollTop(); 34232 } else if (type === 'bottom') { 34233 //Uncode change 34234 // return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight; 34235 return (0 - scroller.y) + scrollable.scrollTop() + 1 + ( uncode_body_borders * 2 ) + scrollable.innerHeight() >= scrollable[0].scrollHeight; 34236 //End Uncode change 34237 } 34238 }, 34239 34240 /** 34241 * Returns the scrollable element for the given section. 34242 * If there are landscape slides, will only return a scrollable element 34243 * if it is in the active slide. 34244 * 34245 * @param {Object} activeSection jQuery object containing current section 34246 * @return {Boolean} 34247 */ 34248 scrollable: function(activeSection){ 34249 // if there are landscape slides, we check if the scrolling bar is in the current one or not 34250 if (activeSection.find(SLIDES_WRAPPER_SEL).length) { 34251 return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL); 34252 } 34253 return activeSection.find(SCROLLABLE_SEL); 34254 }, 34255 34256 /** 34257 * Returns the scroll height of the wrapped content. 34258 * If this is larger than the window height minus section padding, 34259 * overflow scrolling is needed. 34260 * 34261 * @param {Object} element jQuery object containing current section 34262 * @return {Number} 34263 */ 34264 scrollHeight: function(element) { 34265 return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight; 34266 }, 34267 34268 /** 34269 * Called when overflow scrolling is no longer needed for a section. 34270 * 34271 * @param {Object}
34271 element jQuery object containing current section 34272 */ 34273 remove: function(element) { 34274 var scrollable = element.find(SCROLLABLE_SEL); 34275 if (scrollable.length) { 34276 var iScrollInstance = scrollable.data('iscrollInstance'); 34277 iScrollInstance.destroy(); 34278 34279 scrollable.data('iscrollInstance', null); 34280 } 34281 element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap(); 34282 }, 34283 34284 /** 34285 * Called when overflow scrolling has already been setup but the 34286 * window height has potentially changed. 34287 * 34288 * @param {Object} element jQuery object containing current section 34289 * @param {Number} scrollHeight Current window height in pixels 34290 */ 34291 update: function(element, scrollHeight) { 34292 //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a 34293 //short period of time. 34294 //it also comes on handy because iScroll requires the use of timeout when using `refresh`. 34295 clearTimeout(iscrollHandler.refreshId); 34296 iscrollHandler.refreshId = setTimeout(function(){ 34297 $.each(iscrollHandler.iScrollInstances, function(){ 34298 $(this).get(0).refresh(); 34299 }); 34300 }, 150); 34301 34302 //updating the wrappers height 34303 element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px'); 34304 }, 34305 34306 /** 34307 * Called to get any additional elements needed to wrap the section 34308 * content in order to facilitate overflow scrolling. 34309 * 34310 * @return {String|Object} Can be a string containing HTML, 34311 * a DOM element, or jQuery object. 34312 */ 34313 wrapContent: function() { 34314 return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>'; 34315 } 34316 }; 34317}); 34318 34319(function (global, factory) { 34320 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 34321 typeof define === 'function' && define.amd ? define(['exports'], factory) : 34322 (global = global || self, factory(global.window = global.window || {})); 34323}(this, (function (exports) { 'use strict'; 34324 34325 /*! 34326 * ScrollTrigger 3.8.0 34327 * https://greensock.com 34328 * 34329 * @license Copyright 2008-2021, GreenSock. All rights reserved. 34330 * Subject to the terms at https://greensock.com/standard-license or for 34331 * Club GreenSock members, the agreement issued with that membership. 34332 * @author: Jack Doyle, [email protected] 34333 */ 34334 var gsap, 34335 _coreInitted, 34336 _win, 34337 _doc, 34338 _docEl, 34339 _body, 34340 _root, 34341 _resizeDelay, 34342 _raf, 34343 _request, 34344 _toArray, 34345 _clamp, 34346 _time2, 34347 _syncInterval, 34348 _refreshing, 34349 _pointerIsDown, 34350 _transformProp, 34351 _i, 34352 _prevWidth, 34353 _prevHeight, 34354 _autoRefresh, 34355 _sort, 34356 _suppressOverwrites, 34357 _ignoreResize, 34358 _limitCallbacks, 34359 _startup = 1, 34360 _proxies = [], 34361 _scrollers = [], 34362 _getTime = Date.now, 34363 _time1 = _getTime(), 34364 _lastScrollTime = 0, 34365 _enabled = 1, 34366 _passThrough = function _passThrough(v) { 34367 return v; 34368 }, 34369 _getTarget = function _getTarget(t) { 34370 return _toArray(t)[0] || (_isString(t) ? console.warn("Element not found:", t) : null); 34371 }, 34372 _round = function _round(value) { 34373 return Math.round(value * 100000) / 100000 || 0; 34374 }, 34375 _windowExists = function _windowExists() { 34376 return typeof window !== "undefined"; 34377 }, 34378 _getGSAP = function _getGSAP() { 34379 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 34380 }, 34381 _isViewport = function _isViewport(e) { 34382 return !!~_root.indexOf(e); 34383 }, 34384 _getProxyProp = function _getProxyProp(element, property) { 34385 return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property]; 34386 }, 34387 _getScrollFunc = function _getScrollFunc(element, _ref) { 34388 var s = _ref.s, 34389 sc = _ref.sc; 34390 34391 var i = _scrollers.indexOf(element), 34392 offset = sc === _vertical.sc ? 1 : 2; 34393 34394 !~i && (i = _scrollers.push(element) - 1); 34395 return _scrollers[i + offset] || (_scrollers[i + offset] = _getProxyProp(element, s) || (_isViewport(element) ? sc : function (value) { 34396 return arguments.length ? element[s] = value : element[s]; 34397 })); 34398 }, 34399 _getBoundsFunc = function _getBoundsFunc(element) { 34400 return _getProxyProp(element, "getBoundingClientRect") || (_isViewport(element) ? function () { 34401 _winOffsets.width = _win.innerWidth; 34402 _winOffsets.height = _win.innerHeight; 34403 return _winOffsets; 34404 } : function () { 34405 return _getBounds(element); 34406 }); 34407 }, 34408 _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref2) { 34409 var d = _ref2.d, 34410 d2 = _ref2.d2, 34411 a = _ref2.a; 34412 return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () { 34413 return a()[d]; 34414 } : function () { 34415 return (isViewport ? _win["inner" + d2] : scroller["client" + d2]) || 0; 34416 }; 34417 }, 34418 _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) { 34419 return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () { 34420 return _winOffsets; 34421 }; 34422 }, 34423 _maxScroll = function _maxScroll(element, _ref3) { 34424 var s = _ref3.s, 34425 d2 = _ref3.d2, 34426 d = _ref3.d, 34427 a = _ref3.a; 34428 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]; 34429 }, 34430 _iterateAutoRefresh = function _iterateAutoRefresh(func, events) { 34431 for (var i = 0; i < _autoRefresh.length; i += 3) {
vendor: 5,689 bytes, lines 34432-34636
34432 (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]); 34433 } 34434 }, 34435 _isString = function _isString(value) { 34436 return typeof value === "string"; 34437 }, 34438 _isFunction = function _isFunction(value) { 34439 return typeof value === "function"; 34440 }, 34441 _isNumber = function _isNumber(value) { 34442 return typeof value === "number"; 34443 }, 34444 _isObject = function _isObject(value) { 34445 return typeof value === "object"; 34446 }, 34447 _callIfFunc = function _callIfFunc(value) { 34448 return _isFunction(value) && value(); 34449 }, 34450 _combineFunc = function _combineFunc(f1, f2) { 34451 return function () { 34452 var result1 = _callIfFunc(f1), 34453 result2 = _callIfFunc(f2); 34454 34455 return function () { 34456 _callIfFunc(result1); 34457 34458 _callIfFunc(result2); 34459 }; 34460 }; 34461 }, 34462 _endAnimation = function _endAnimation(animation, reversed, pause) { 34463 return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause(); 34464 }, 34465 _callback = function _callback(self, func) { 34466 var result = func(self); 34467 result && result.totalTime && (self.callbackAnimation = result); 34468 }, 34469 _abs = Math.abs, 34470 _scrollLeft = "scrollLeft", 34471 _scrollTop = "scrollTop", 34472 _left = "left", 34473 _top = "top", 34474 _right = "right", 34475 _bottom = "bottom", 34476 _width = "width", 34477 _height = "height", 34478 _Right = "Right", 34479 _Left = "Left", 34480 _Top = "Top", 34481 _Bottom = "Bottom", 34482 _padding = "padding", 34483 _margin = "margin", 34484 _Width = "Width", 34485 _Height = "Height", 34486 _px = "px", 34487 _horizontal = { 34488 s: _scrollLeft, 34489 p: _left, 34490 p2: _Left, 34491 os: _right, 34492 os2: _Right, 34493 d: _width, 34494 d2: _Width, 34495 a: "x", 34496 sc: function sc(value) { 34497 return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0; 34498 } 34499 }, 34500 _vertical = { 34501 s: _scrollTop, 34502 p: _top, 34503 p2: _Top, 34504 os: _bottom, 34505 os2: _Bottom, 34506 d: _height, 34507 d2: _Height, 34508 a: "y", 34509 op: _horizontal, 34510 sc: function sc(value) { 34511 return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0; 34512 } 34513 }, 34514 _getComputedStyle = function _getComputedStyle(element) { 34515 return _win.getComputedStyle(element); 34516 }, 34517 _makePositionable = function _makePositionable(element) { 34518 var position = _getComputedStyle(element).position; 34519 34520 element.style.position = position === "absolute" || position === "fixed" ? position : "relative"; 34521 }, 34522 _setDefaults = function _setDefaults(obj, defaults) { 34523 for (var p in defaults) { 34524 p in obj || (obj[p] = defaults[p]); 34525 } 34526 34527 return obj; 34528 }, 34529 _getBounds = function _getBounds(element, withoutTransforms) { 34530 var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap.to(element, { 34531 x: 0, 34532 y: 0, 34533 xPercent: 0, 34534 yPercent: 0, 34535 rotation: 0, 34536 rotationX: 0, 34537 rotationY: 0, 34538 scale: 1, 34539 skewX: 0, 34540 skewY: 0 34541 }).progress(1), 34542 bounds = element.getBoundingClientRect(); 34543 tween && tween.progress(0).kill(); 34544 return bounds; 34545 }, 34546 _getSize = function _getSize(element, _ref4) { 34547 var d2 = _ref4.d2; 34548 return element["offset" + d2] || element["client" + d2] || 0; 34549 }, 34550 _getLabelRatioArray = function _getLabelRatioArray(timeline) { 34551 var a = [], 34552 labels = timeline.labels, 34553 duration = timeline.duration(), 34554 p; 34555 34556 for (p in labels) { 34557 a.push(labels[p] / duration); 34558 } 34559 34560 return a; 34561 }, 34562 _getClosestLabel = function _getClosestLabel(animation) { 34563 return function (value) { 34564 return gsap.utils.snap(_getLabelRatioArray(animation), value); 34565 }; 34566 }, 34567 _snapDirectional = function _snapDirectional(snapIncrementOrArray) { 34568 var snap = gsap.utils.snap(snapIncrementOrArray), 34569 a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) { 34570 return a - b; 34571 }); 34572 return a ? function (value, direction) { 34573 var i; 34574 34575 if (!direction) { 34576 return snap(value); 34577 } 34578 34579 if (direction > 0) { 34580 value -= 1e-4; 34581 34582 for (i = 0; i < a.length; i++) { 34583 if (a[i] >= value) { 34584 return a[i]; 34585 } 34586 } 34587 34588 return a[i - 1]; 34589 } else { 34590 i = a.length; 34591 value += 1e-4; 34592 34593 while (i--) { 34594 if (a[i] <= value) { 34595 return a[i]; 34596 } 34597 } 34598 } 34599 34600 return a[0]; 34601 } : function (value, direction) { 34602 var snapped = snap(value); 34603 return !direction || Math.abs(snapped - value) < 0.001 || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray); 34604 }; 34605 }, 34606 _getLabelAtDirection = function _getLabelAtDirection(timeline) { 34607 return function (value, st) { 34608 return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction); 34609 }; 34610 }, 34611 _multiListener = function _multiListener(func, element, types, callback) { 34612 return types.split(",").forEach(function (type) { 34613 return func(element, type, callback); 34614 }); 34615 }, 34616 _addListener = function _addListener(element, type, func) { 34617 return element.addEventListener(type, func, { 34618 passive: true 34619 }); 34620 }, 34621 _removeListener = function _removeListener(element, type, func) { 34622 return element.removeEventListener(type, func); 34623 }, 34624 _markerDefaults = { 34625 startColor: "green", 34626 endColor: "red", 34627 indent: 0, 34628 fontSize: "16px", 34629 fontWeight: "normal" 34630 }, 34631 _defaults = { 34632 toggleActions: "play", 34633 anticipatePin: 0 34634 }, 34635 _keywords = { 34636 top: 0,
34637 left: 0, 34638 center: 0.5, 34639 bottom: 1, 34640 right: 1 34641 }, 34642 _offsetToPx = function _offsetToPx(value, size) { 34643 if (_isString(value)) { 34644 var eqIndex = value.indexOf("="), 34645 relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0; 34646 34647 if (~eqIndex) { 34648 value.indexOf("%") > eqIndex && (relative *= size / 100); 34649 value = value.substr(0, eqIndex - 1); 34650 } 34651 34652 value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0); 34653 } 34654 34655 return value; 34656 }, 34657 _createMarker = function _createMarker(type, name, container, direction, _ref5, offset, matchWidthEl, containerAnimation) { 34658 var startColor = _ref5.startColor, 34659 endColor = _ref5.endColor, 34660 fontSize = _ref5.fontSize, 34661 indent = _ref5.indent, 34662 fontWeight = _ref5.fontWeight; 34663 34664 var e = _doc.createElement("div"), 34665 useFixedPosition = _isViewport(container) || _getProxyProp(container, "pinType") === "fixed", 34666 isScroller = type.indexOf("scroller") !== -1, 34667 parent = useFixedPosition ? _body : container, 34668 isStart = type.indexOf("start") !== -1, 34669 color = isStart ? startColor : endColor, 34670 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;"; 34671 34672 css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;"); 34673 (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;"); 34674 matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;"); 34675 e._isStart = isStart; 34676 e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : "")); 34677 e.style.cssText = css; 34678 e.innerText = name || name === 0 ? type + "-" + name : type; 34679 parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e); 34680 e._offset = e["offset" + direction.op.d2]; 34681 34682 _positionMarker(e, 0, direction, isStart); 34683 34684 return e; 34685 }, 34686 _positionMarker = function _positionMarker(marker, start, direction, flipped) { 34687 var vars = { 34688 display: "block" 34689 }, 34690 side = direction[flipped ? "os2" : "p2"], 34691 oppositeSide = direction[flipped ? "p2" : "os2"]; 34692 marker._isFlipped = flipped; 34693 vars[direction.a + "Percent"] = flipped ? -100 : 0; 34694 vars[direction.a] = flipped ? "1px" : 0; 34695 vars["border" + side + _Width] = 1; 34696 vars["border" + oppositeSide + _Width] = 0; 34697 vars[direction.p] = start + "px"; 34698 gsap.set(marker, vars); 34699 }, 34700 _triggers = [], 34701 _ids = {}, 34702 _sync = function _sync() { 34703 return _getTime() - _lastScrollTime > 20 && _updateAll(); 34704 }, 34705 _onScroll = function _onScroll() { 34706 var time = _getTime(); 34707 34708 if (_lastScrollTime !== time) { 34709 _updateAll(); 34710 34711 _lastScrollTime || _dispatch("scrollStart"); 34712 _lastScrollTime = time; 34713 } else if (!_request) { 34714 _request = _raf(_updateAll); 34715 } 34716 }, 34717 _onResize = function _onResize() { 34718 return !_refreshing && !_ignoreResize && !_doc.fullscreenElement && _resizeDelay.restart(true); 34719 }, 34720 _listeners = {}, 34721 _emptyArray = [], 34722 _media = [], 34723 _creatingMedia, 34724 _lastMediaTick, 34725 _onMediaChange = function _onMediaChange(e) { 34726 var tick = gsap.ticker.frame, 34727 matches = [], 34728 i = 0, 34729 index; 34730 34731 if (_lastMediaTick !== tick || _startup) { 34732 _revertAll(); 34733 34734 for (; i < _media.length; i += 4) { 34735 index = _win.matchMedia(_media[i]).matches; 34736 34737 if (index !== _media[i + 3]) { 34738 _media[i + 3] = index; 34739 index ? matches.push(i) : _revertAll(1, _media[i]) || _isFunction(_media[i + 2]) && _media[i + 2](); 34740 } 34741 } 34742 34743 _revertRecorded(); 34744 34745 for (i = 0; i < matches.length; i++) { 34746 index = matches[i]; 34747 _creatingMedia = _media[index]; 34748 _media[index + 2] = _media[index + 1](e); 34749 } 34750 34751 _creatingMedia = 0; 34752 _coreInitted && _refreshAll(0, 1); 34753 _lastMediaTick = tick; 34754 34755 _dispatch("matchMedia"); 34756 } 34757 }, 34758 _softRefresh = function _softRefresh() { 34759 return _removeListener(ScrollTrigger, "scrollEnd", _softRefresh) || _refreshAll(true); 34760 }, 34761 _dispatch = function _dispatch(type) { 34762 return _listeners[type] && _listeners[type].map(function (f) { 34763 return f(); 34764 }) || _emptyArray; 34765 }, 34766 _savedStyles = [], 34767 _revertRecorded = function _revertRecorded(media) { 34768 for (var i = 0; i < _savedStyles.length; i += 5) { 34769 if (!media || _savedStyles[i + 4] === media) { 34770 _savedStyles[i].style.cssText = _savedStyles[i + 1]; 34771 _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || ""); 34772 _savedStyles[i + 3].uncache = 1; 34773 } 34774 } 34775 }, 34776 _revertAll = function _revertAll(kill, media) { 34777 var trigger; 34778 34779 for (_i = 0; _i < _triggers.length; _i++) { 34780 trigger = _triggers[_i]; 34781 34782 if (!media || trigger.media === media) { 34783 if (kill) { 34784 trigger.kill(1); 34785 } else { 34786 trigger.revert(); 34787 } 34788 } 34789 } 34790 34791 media && _revertRecorded(media); 34792 media || _dispatch("revert"); 34793 }, 34794 _clearScrollMemory = function _clearScrollMemory() {
vendor: 10,266 bytes, lines 34795-35129
34795 return _scrollers.forEach(function (obj) { 34796 return typeof obj === "function" && (obj.rec = 0); 34797 }); 34798 }, 34799 _refreshingAll, 34800 _refreshAll = function _refreshAll(force, skipRevert) { 34801 if (_lastScrollTime && !force) { 34802 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 34803 34804 return; 34805 } 34806 34807 _refreshingAll = true; 34808 34809 var refreshInits = _dispatch("refreshInit"); 34810 34811 _sort && ScrollTrigger.sort(); 34812 skipRevert || _revertAll(); 34813 34814 _triggers.forEach(function (t) { 34815 return t.refresh(); 34816 }); 34817 34818 refreshInits.forEach(function (result) { 34819 return result && result.render && result.render(-1); 34820 }); 34821 34822 _clearScrollMemory(); 34823 34824 _resizeDelay.pause(); 34825 34826 _refreshingAll = false; 34827 34828 _dispatch("refresh"); 34829 }, 34830 _lastScroll = 0, 34831 _direction = 1, 34832 _updateAll = function _updateAll() { 34833 if (!_refreshingAll) { 34834 var l = _triggers.length, 34835 time = _getTime(), 34836 recordVelocity = time - _time1 >= 50, 34837 scroll = l && _triggers[0].scroll(); 34838 34839 _direction = _lastScroll > scroll ? -1 : 1; 34840 _lastScroll = scroll; 34841 34842 if (recordVelocity) { 34843 if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) { 34844 _lastScrollTime = 0; 34845 34846 _dispatch("scrollEnd"); 34847 } 34848 34849 _time2 = _time1; 34850 _time1 = time; 34851 } 34852 34853 if (_direction < 0) { 34854 _i = l; 34855 34856 while (_i-- > 0) { 34857 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34858 } 34859 34860 _direction = 1; 34861 } else { 34862 for (_i = 0; _i < l; _i++) { 34863 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 34864 } 34865 } 34866 34867 _request = 0; 34868 } 34869 }, 34870 _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"], 34871 _stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]), 34872 _swapPinOut = function _swapPinOut(pin, spacer, state) { 34873 _setState(state); 34874 34875 var cache = pin._gsap; 34876 34877 if (cache.spacerIsNative) { 34878 _setState(cache.spacerState); 34879 } else if (pin.parentNode === spacer) { 34880 var parent = spacer.parentNode; 34881 34882 if (parent) { 34883 parent.insertBefore(pin, spacer); 34884 parent.removeChild(spacer); 34885 } 34886 } 34887 }, 34888 _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) { 34889 if (pin.parentNode !== spacer) { 34890 var i = _propNamesToCopy.length, 34891 spacerStyle = spacer.style, 34892 pinStyle = pin.style, 34893 p; 34894 34895 while (i--) { 34896 p = _propNamesToCopy[i]; 34897 spacerStyle[p] = cs[p]; 34898 } 34899 34900 spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative"; 34901 cs.display === "inline" && (spacerStyle.display = "inline-block"); 34902 pinStyle[_bottom] = pinStyle[_right] = "auto"; 34903 spacerStyle.overflow = "visible"; 34904 spacerStyle.boxSizing = "border-box"; 34905 spacerStyle[_width] = _getSize(pin, _horizontal) + _px; 34906 spacerStyle[_height] = _getSize(pin, _vertical) + _px; 34907 spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0"; 34908 34909 _setState(spacerState); 34910 34911 pinStyle[_width] = pinStyle["max" + _Width] = cs[_width]; 34912 pinStyle[_height] = pinStyle["max" + _Height] = cs[_height]; 34913 pinStyle[_padding] = cs[_padding]; 34914 pin.parentNode.insertBefore(spacer, pin); 34915 spacer.appendChild(pin); 34916 } 34917 }, 34918 _capsExp = /([A-Z])/g, 34919 _setState = function _setState(state) { 34920 if (state) { 34921 var style = state.t.style, 34922 l = state.length, 34923 i = 0, 34924 p, 34925 value; 34926 (state.t._gsap || gsap.core.getCache(state.t)).uncache = 1; 34927 34928 for (; i < l; i += 2) { 34929 value = state[i + 1]; 34930 p = state[i]; 34931 34932 if (value) { 34933 style[p] = value; 34934 } else if (style[p]) { 34935 style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 34936 } 34937 } 34938 } 34939 }, 34940 _getState = function _getState(element) { 34941 var l = _stateProps.length, 34942 style = element.style, 34943 state = [], 34944 i = 0; 34945 34946 for (; i < l; i++) { 34947 state.push(_stateProps[i], style[_stateProps[i]]); 34948 } 34949 34950 state.t = element; 34951 return state; 34952 }, 34953 _copyState = function _copyState(state, override, omitOffsets) { 34954 var result = [], 34955 l = state.length, 34956 i = omitOffsets ? 8 : 0, 34957 p; 34958 34959 for (; i < l; i += 2) { 34960 p = state[i]; 34961 result.push(p, p in override ? override[p] : state[i + 1]); 34962 } 34963 34964 result.t = state.t; 34965 return result; 34966 }, 34967 _winOffsets = { 34968 left: 0, 34969 top: 0 34970 }, 34971 _parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation) { 34972 _isFunction(value) && (value = value(self)); 34973 34974 if (_isString(value) && value.substr(0, 3) === "max") { 34975 value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0); 34976 } 34977 34978 var time = containerAnimation ? containerAnimation.time() : 0, 34979 p1, 34980 p2, 34981 element; 34982 containerAnimation && containerAnimation.seek(0); 34983 34984 if (!_isNumber(value)) { 34985 _isFunction(trigger) && (trigger = trigger(self)); 34986 var offsets = value.split(" "), 34987 bounds, 34988 localOffset, 34989 globalOffset, 34990 display; 34991 element = _getTarget(trigger) || _body; 34992 bounds = _getBounds(element) || {}; 34993 34994 if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") { 34995 display = element.style.display; 34996 element.style.display = "block"; 34997 bounds = _getBounds(element); 34998 display ? element.style.display = display : element.style.removeProperty("display"); 34999 } 35000 35001 localOffset = _offsetToPx(offsets[0], bounds[direction.d]); 35002 globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize); 35003 value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset; 35004 markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20); 35005 scrollerSize -= scrollerSize - globalOffset; 35006 } else if (markerScroller) { 35007 _positionMarker(markerScroller, scrollerSize, direction, true); 35008 } 35009 35010 if (marker) { 35011 var position = value + scrollerSize, 35012 isStart = marker._isStart; 35013 p1 = "scroll" + direction.d2; 35014 35015 _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body[p1], _docEl[p1]) : marker.parentNode[p1]) <= position + 1); 35016 35017 if (useFixedPosition) { 35018 scrollerBounds = _getBounds(markerScroller); 35019 useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px); 35020 } 35021 } 35022 35023 if (containerAnimation && element) { 35024 p1 = _getBounds(element); 35025 containerAnimation.seek(scrollerMax); 35026 p2 = _getBounds(element); 35027 containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p]; 35028 value = value / containerAnimation._caScrollDist * scrollerMax; 35029 } 35030 35031 containerAnimation && containerAnimation.seek(time); 35032 return containerAnimation ? value : Math.round(value); 35033 }, 35034 _prefixExp = /(?:webkit|moz|length|cssText|inset)/i, 35035 _reparent = function _reparent(element, parent, top, left) { 35036 if (element.parentNode !== parent) { 35037 var style = element.style, 35038 p, 35039 cs; 35040 35041 if (parent === _body) { 35042 element._stOrig = style.cssText; 35043 cs = _getComputedStyle(element); 35044 35045 for (p in cs) { 35046 if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") { 35047 style[p] = cs[p]; 35048 } 35049 } 35050 35051 style.top = top; 35052 style.left = left; 35053 } else { 35054 style.cssText = element._stOrig; 35055 } 35056 35057 gsap.core.getCache(element).uncache = 1; 35058 parent.appendChild(element); 35059 } 35060 }, 35061 _getTweenCreator = function _getTweenCreator(scroller, direction) { 35062 var getScroll = _getScrollFunc(scroller, direction), 35063 prop = "_scroll" + direction.p2, 35064 lastScroll1, 35065 lastScroll2, 35066 getTween = function getTween(scrollTo, vars, initialValue, change1, change2) { 35067 var tween = getTween.tween, 35068 onComplete = vars.onComplete, 35069 modifiers = {}; 35070 tween && tween.kill(); 35071 lastScroll1 = Math.round(initialValue); 35072 vars[prop] = scrollTo; 35073 vars.modifiers = modifiers; 35074 35075 modifiers[prop] = function (value) { 35076 value = _round(getScroll()); 35077 35078 if (value !== lastScroll1 && value !== lastScroll2 && Math.abs(value - lastScroll1) > 2) { 35079 tween.kill(); 35080 getTween.tween = 0; 35081 } else { 35082 value = initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio; 35083 } 35084 35085 lastScroll2 = lastScroll1; 35086 return lastScroll1 = _round(value); 35087 }; 35088 35089 vars.onComplete = function () { 35090 getTween.tween = 0; 35091 onComplete && onComplete.call(tween); 35092 }; 35093 35094 tween = getTween.tween = gsap.to(scroller, vars); 35095 return tween; 35096 }; 35097 35098 scroller[prop] = getScroll; 35099 scroller.addEventListener("wheel", function () { 35100 return getTween.tween && getTween.tween.kill() && (getTween.tween = 0); 35101 }, { 35102 passive: true 35103 }); 35104 return getTween; 35105 }; 35106 35107 _horizontal.op = _vertical; 35108 var ScrollTrigger = function () { 35109 function ScrollTrigger(vars, animation) { 35110 _coreInitted || ScrollTrigger.register(gsap) || console.warn("Please gsap.registerPlugin(ScrollTrigger)"); 35111 this.init(vars, animation); 35112 } 35113 35114 var _proto = ScrollTrigger.prototype; 35115 35116 _proto.init = function init(vars, animation) { 35117 this.progress = this.start = 0; 35118 this.vars && this.kill(1); 35119 35120 if (!_enabled) { 35121 this.update = this.refresh = this.kill = _passThrough; 35122 return; 35123 } 35124 35125 vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? { 35126 trigger: vars 35127 } : vars, _defaults); 35128 35129 var _vars = vars,
35130 onUpdate = _vars.onUpdate, 35131 toggleClass = _vars.toggleClass, 35132 id = _vars.id, 35133 onToggle = _vars.onToggle, 35134 onRefresh = _vars.onRefresh, 35135 scrub = _vars.scrub, 35136 trigger = _vars.trigger, 35137 pin = _vars.pin, 35138 pinSpacing = _vars.pinSpacing, 35139 invalidateOnRefresh = _vars.invalidateOnRefresh, 35140 anticipatePin = _vars.anticipatePin, 35141 onScrubComplete = _vars.onScrubComplete, 35142 onSnapComplete = _vars.onSnapComplete, 35143 once = _vars.once, 35144 snap = _vars.snap, 35145 pinReparent = _vars.pinReparent, 35146 pinSpacer = _vars.pinSpacer, 35147 containerAnimation = _vars.containerAnimation, 35148 fastScrollEnd = _vars.fastScrollEnd, 35149 preventOverlaps = _vars.preventOverlaps, 35150 direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _horizontal : _vertical, 35151 isToggle = !scrub && scrub !== 0, 35152 scroller = _getTarget(vars.scroller || _win), 35153 scrollerCache = gsap.core.getCache(scroller), 35154 isViewport = _isViewport(scroller), 35155 useFixedPosition = ("pinType" in vars ? vars.pinType : _getProxyProp(scroller, "pinType") || isViewport && "fixed") === "fixed", 35156 callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack], 35157 toggleActions = isToggle && vars.toggleActions.split(" "), 35158 markers = "markers" in vars ? vars.markers : _defaults.markers, 35159 borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0, 35160 self = this, 35161 onRefreshInit = vars.onRefreshInit && function () { 35162 return vars.onRefreshInit(self); 35163 }, 35164 getScrollerSize = _getSizeFunc(scroller, isViewport, direction), 35165 getScrollerOffsets = _getOffsetsFunc(scroller, isViewport), 35166 lastSnap = 0, 35167 scrollFunc = _getScrollFunc(scroller, direction), 35168 tweenTo, 35169 pinCache, 35170 snapFunc, 35171 scroll1, 35172 scroll2, 35173 start, 35174 end, 35175 markerStart, 35176 markerEnd, 35177 markerStartTrigger, 35178 markerEndTrigger, 35179 markerVars, 35180 change, 35181 pinOriginalState, 35182 pinActiveState, 35183 pinState, 35184 spacer, 35185 offset, 35186 pinGetter, 35187 pinSetter, 35188 pinStart, 35189 pinChange, 35190 spacingStart, 35191 spacerState, 35192 markerStartSetter, 35193 markerEndSetter, 35194 cs, 35195 snap1, 35196 snap2, 35197 scrubTween, 35198 scrubSmooth, 35199 snapDurClamp, 35200 snapDelayedCall, 35201 prevProgress, 35202 prevScroll, 35203 prevAnimProgress, 35204 caMarkerSetter; 35205 35206 self.media = _creatingMedia; 35207 anticipatePin *= 45; 35208 self.scroller = scroller; 35209 self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc; 35210 scroll1 = scrollFunc(); 35211 self.vars = vars; 35212 animation = animation || vars.animation; 35213 "refreshPriority" in vars && (_sort = 1); 35214 scrollerCache.tweenScroll = scrollerCache.tweenScroll || { 35215 top: _getTweenCreator(scroller, _vertical), 35216 left: _getTweenCreator(scroller, _horizontal) 35217 }; 35218 self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p]; 35219 35220 if (animation) { 35221 animation.vars.lazy = false; 35222 animation._initted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.render(0, true, true); 35223 self.animation = animation.pause(); 35224 animation.scrollTrigger = self; 35225 scrubSmooth = _isNumber(scrub) && scrub; 35226 scrubSmooth && (scrubTween = gsap.to(animation, { 35227 ease: "power3", 35228 duration: scrubSmooth, 35229 onComplete: function onComplete() { 35230 return onScrubComplete && onScrubComplete(self); 35231 } 35232 })); 35233 snap1 = 0; 35234 id || (id = animation.vars.id); 35235 } 35236 35237 _triggers.push(self); 35238 35239 if (snap) { 35240 if (!_isObject(snap) || snap.push) { 35241 snap = { 35242 snapTo: snap 35243 }; 35244 } 35245 35246 "scrollBehavior" in _body.style && gsap.set(isViewport ? [_body, _docEl] : scroller, { 35247 scrollBehavior: "auto" 35248 }); 35249 snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) { 35250 return _snapDirectional(snap.snapTo)(value, st.direction); 35251 } : gsap.utils.snap(snap.snapTo); 35252 snapDurClamp = snap.duration || { 35253 min: 0.1, 35254 max: 2 35255 }; 35256 snapDurClamp = _isObject(snapDurClamp) ? _clamp(snapDurClamp.min, snapDurClamp.max) : _clamp(snapDurClamp, snapDurClamp); 35257 snapDelayedCall = gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () { 35258 if (Math.abs(self.getVelocity()) < 10 && !_pointerIsDown && lastSnap !== scrollFunc()) { 35259 var totalProgress = animation && !isToggle ? animation.totalProgress() : self.progress, 35260 velocity = (totalProgress - snap2) / (_getTime() - _time2) * 1000 || 0, 35261 change1 = gsap.utils.clamp(-self.progress, 1 - self.progress, _abs(velocity / 2) * velocity / 0.185), 35262 naturalEnd = self.progress + (snap.inertia === false ? 0 : change1), 35263 endValue = _clamp(0, 1, snapFunc(naturalEnd, self)), 35264 scroll = scrollFunc(), 35265 endScroll = Math.round(start + endValue * change), 35266 _snap = snap, 35267 onStart = _snap.onStart, 35268 _onInterrupt = _snap.onInterrupt, 35269 _onComplete = _snap.onComplete, 35270 tween = tweenTo.tween; 35271 35272 if (scroll <= end && scroll >= start && endScroll !== scroll) { 35273 if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) { 35274 return; 35275 } 35276 35277 if (snap.inertia === false) { 35278 change1 = endValue - self.progress; 35279 } 35280 35281 tweenTo(endScroll, { 35282 duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)), 35283 ease: snap.ease || "power3", 35284 data: _abs(endScroll - scroll), 35285 onInterrupt: function onInterrupt() { 35286 return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self); 35287 }, 35288 onComplete: function onComplete() { 35289 lastSnap = scrollFunc(); 35290 snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress; 35291 onSnapComplete && onSnapComplete(self); 35292 _onComplete && _onComplete(self); 35293 } 35294 }, scroll, change1 * change, endScroll - scroll - change1 * change); 35295 onStart && onStart(self, tweenTo.tween); 35296 } 35297 } else if (self.isActive) { 35298 snapDelayedCall.restart(true); 35299 } 35300 }).pause(); 35301 } 35302 35303 id && (_ids[id] = self); 35304 trigger = self.trigger = _getTarget(trigger || pin); 35305 pin = pin === true ? trigger : _getTarget(pin); 35306 _isString(toggleClass) && (toggleClass = { 35307 targets: trigger, 35308 className: toggleClass 35309 }); 35310 35311 if (pin) { 35312 pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding); 35313 self.pin = pin; 35314 vars.force3D !== false && gsap.set(pin, {
35315 force3D: true 35316 }); 35317 pinCache = gsap.core.getCache(pin); 35318 35319 if (!pinCache.spacer) { 35320 if (pinSpacer) { 35321 pinSpacer = _getTarget(pinSpacer); 35322 pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement); 35323 pinCache.spacerIsNative = !!pinSpacer; 35324 pinSpacer && (pinCache.spacerState = _getState(pinSpacer)); 35325 } 35326 35327 pinCache.spacer = spacer = pinSpacer || _doc.createElement("div"); 35328 spacer.classList.add("pin-spacer"); 35329 id && spacer.classList.add("pin-spacer-" + id); 35330 pinCache.pinState = pinOriginalState = _getState(pin); 35331 } else { 35332 pinOriginalState = pinCache.pinState; 35333 } 35334 35335 self.spacer = spacer = pinCache.spacer; 35336 cs = _getComputedStyle(pin); 35337 spacingStart = cs[pinSpacing + direction.os2]; 35338 pinGetter = gsap.getProperty(pin); 35339 pinSetter = gsap.quickSetter(pin, direction.a, _px); 35340 35341 _swapPinIn(pin, spacer, cs); 35342 35343 pinState = _getState(pin); 35344 } 35345 35346 if (markers) { 35347 markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults; 35348 markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0); 35349 markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger); 35350 offset = markerStartTrigger["offset" + direction.op.d2]; 35351 markerStart = _createMarker("start", id, scroller, direction, markerVars, offset, 0, containerAnimation); 35352 markerEnd = _createMarker("end", id, scroller, direction, markerVars, offset, 0, containerAnimation); 35353 containerAnimation && (caMarkerSetter = gsap.quickSetter([markerStart, markerEnd], direction.a, _px)); 35354 35355 if (!useFixedPosition && !(_proxies.length && _getProxyProp(scroller, "fixedMarkers") === true)) { 35356 _makePositionable(isViewport ? _body : scroller); 35357 35358 gsap.set([markerStartTrigger, markerEndTrigger], { 35359 force3D: true 35360 }); 35361 markerStartSetter = gsap.quickSetter(markerStartTrigger, direction.a, _px); 35362 markerEndSetter = gsap.quickSetter(markerEndTrigger, direction.a, _px); 35363 } 35364 } 35365 35366 if (containerAnimation) { 35367 var oldOnUpdate = containerAnimation.vars.onUpdate, 35368 oldParams = containerAnimation.vars.onUpdateParams; 35369 containerAnimation.eventCallback("onUpdate", function () { 35370 self.update(0, 0, 1); 35371 oldOnUpdate && oldOnUpdate.apply(oldParams || []); 35372 }); 35373 } 35374 35375 self.previous = function () { 35376 return _triggers[_triggers.indexOf(self) - 1]; 35377 }; 35378 35379 self.next = function () { 35380 return _triggers[_triggers.indexOf(self) + 1]; 35381 }; 35382 35383 self.revert = function (revert) { 35384 var r = revert !== false || !self.enabled, 35385 prevRefreshing = _refreshing; 35386 35387 if (r !== self.isReverted) { 35388 if (r) { 35389 self.scroll.rec || (self.scroll.rec = scrollFunc()); 35390 prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0); 35391 prevProgress = self.progress; 35392 prevAnimProgress = animation && animation.progress(); 35393 } 35394 35395 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35396 return m.style.display = r ? "none" : "block"; 35397 }); 35398 r && (_refreshing = 1); 35399 self.update(r); 35400 _refreshing = prevRefreshing; 35401 pin && (r ? _swapPinOut(pin, spacer, pinOriginalState) : (!pinReparent || !self.isActive) && _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState)); 35402 self.isReverted = r; 35403 } 35404 }; 35405 35406 self.refresh = function (soft, force) { 35407 if ((_refreshing || !self.enabled) && !force) { 35408 return; 35409 } 35410 35411 if (pin && soft && _lastScrollTime) { 35412 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 35413 35414 return; 35415 } 35416 35417 _refreshing = 1; 35418 scrubTween && scrubTween.pause(); 35419 invalidateOnRefresh && animation && animation.progress(0).invalidate(); 35420 self.isReverted || self.revert(); 35421 35422 var size = getScrollerSize(), 35423 scrollerBounds = getScrollerOffsets(),
35424 max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction), 35425 offset = 0, 35426 otherPinOffset = 0, 35427 parsedEnd = vars.end, 35428 parsedEndTrigger = vars.endTrigger || trigger, 35429 parsedStart = vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"), 35430 pinnedContainer = vars.pinnedContainer && _getTarget(vars.pinnedContainer), 35431 triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0, 35432 i = triggerIndex, 35433 cs, 35434 bounds, 35435 scroll, 35436 isVertical, 35437 override, 35438 curTrigger, 35439 curPin, 35440 oppositeScroll, 35441 initted, 35442 revertedPins; 35443 35444 while (i--) { 35445 curTrigger = _triggers[i]; 35446 curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = 1); 35447 curPin = curTrigger.pin; 35448 35449 if (curPin && (curPin === trigger || curPin === pin) && !curTrigger.isReverted) { 35450 revertedPins || (revertedPins = []); 35451 revertedPins.unshift(curTrigger); 35452 curTrigger.revert(); 35453 } 35454 } 35455 35456 _isFunction(parsedStart) && (parsedStart = parsedStart(self)); 35457 start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation) || (pin ? -0.001 : 0); 35458 _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self)); 35459 35460 if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) { 35461 if (~parsedEnd.indexOf(" ")) { 35462 parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd; 35463 } else { 35464 offset = _offsetToPx(parsedEnd.substr(2), size); 35465 parsedEnd = _isString(parsedStart) ? parsedStart : start + offset; 35466 parsedEndTrigger = trigger; 35467 } 35468 } 35469 35470 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; 35471 change = end - start || (start -= 0.01) && 0.001; 35472 offset = 0; 35473 i = triggerIndex; 35474 35475 while (i--) { 35476 curTrigger = _triggers[i]; 35477 curPin = curTrigger.pin; 35478 35479 if (curPin && curTrigger.start - curTrigger._pinPush < start && !containerAnimation) { 35480 cs = curTrigger.end - curTrigger.start; 35481 (curPin === trigger || curPin === pinnedContainer) && !_isNumber(parsedStart) && (offset += cs); 35482 curPin === pin && (otherPinOffset += cs); 35483 } 35484 } 35485 35486 start += offset; 35487 end += offset; 35488 self._pinPush = otherPinOffset; 35489 35490 if (markerStart && offset) { 35491 cs = {}; 35492 cs[direction.a] = "+=" + offset; 35493 pinnedContainer && (cs[direction.p] = "-=" + scrollFunc()); 35494 gsap.set([markerStart, markerEnd], cs); 35495 } 35496 35497 if (pin) { 35498 cs = _getComputedStyle(pin); 35499 isVertical = direction === _vertical; 35500 scroll = scrollFunc(); 35501 pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset; 35502 !max && end > 1 && ((isViewport ? _body : scroller).style["overflow-" + direction.a] = "scroll"); 35503 35504 _swapPinIn(pin, spacer, cs); 35505 35506 pinState = _getState(pin); 35507 bounds = _getBounds(pin, true); 35508 oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)(); 35509 35510 if (pinSpacing) { 35511 spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px]; 35512 spacerState.t = spacer; 35513 i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0; 35514 i && spacerState.push(direction.d, i + _px); 35515 35516 _setState(spacerState); 35517 35518 useFixedPosition && scrollFunc(prevScroll); 35519 } 35520 35521 if (useFixedPosition) { 35522 override = { 35523 top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px, 35524 left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px, 35525 boxSizing: "border-box", 35526 position: "fixed" 35527 }; 35528 override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px; 35529 override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px; 35530 override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0"; 35531 override[_padding] = cs[_padding]; 35532 override[_padding + _Top] = cs[_padding + _Top]; 35533 override[_padding + _Right] = cs[_padding + _Right]; 35534 override[_padding + _Bottom] = cs[_padding + _Bottom]; 35535 override[_padding + _Left] = cs[_padding + _Left]; 35536 pinActiveState = _copyState(pinOriginalState, override, pinReparent); 35537 } 35538 35539 if (animation) { 35540 initted = animation._initted; 35541 35542 _suppressOverwrites(1); 35543 35544 animation.render(animation.duration(), true, true); 35545 pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset; 35546 change !== pinChange && pinActiveState.splice(pinActiveState.length - 2, 2); 35547 animation.render(0, true, true); 35548 initted || animation.invalidate(); 35549 35550 _suppressOverwrites(0); 35551 } else { 35552 pinChange = change; 35553 } 35554 } else if (trigger && scrollFunc() && !containerAnimation) { 35555 bounds = trigger.parentNode; 35556 35557 while (bounds && bounds !== _body) { 35558 if (bounds._pinOffset) { 35559 start -= bounds._pinOffset; 35560 end -= bounds._pinOffset; 35561 } 35562 35563 bounds = bounds.parentNode; 35564 } 35565 } 35566 35567 revertedPins && revertedPins.forEach(function (t) { 35568 return t.revert(false); 35569 }); 35570 self.start = start; 35571 self.end = end; 35572 scroll1 = scroll2 = scrollFunc(); 35573 35574 if (!containerAnimation) { 35575 scroll1 < prevScroll && scrollFunc(prevScroll); 35576 self.scroll.rec = 0; 35577 } 35578 35579 self.revert(false); 35580 _refreshing = 0; 35581 animation && isToggle && animation._initted && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress, true).render(animation.time(), true, true); 35582 35583 if (prevProgress !== self.progress) { 35584 animation && !isToggle && animation.totalProgress(prevProgress, true); 35585 self.progress = prevProgress; 35586 self.update(0, 0, 1); 35587 } 35588 35589 pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange)); 35590 onRefresh && onRefresh(self); 35591 }; 35592 35593 self.getVelocity = function () { 35594 return (scrollFunc() - scroll2) / (_getTime() - _time2) * 1000 || 0; 35595 }; 35596 35597 self.endAnimation = function () {
vendor: 8,601 bytes, lines 35598-35836
35598 _endAnimation(self.callbackAnimation); 35599 35600 if (animation) { 35601 scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1); 35602 } 35603 }; 35604 35605 self.getTrailing = function (name) { 35606 var i = _triggers.indexOf(self), 35607 a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1); 35608 35609 return _isString(name) ? a.filter(function (t) { 35610 return t.vars.preventOverlaps === name; 35611 }) : a; 35612 }; 35613 35614 self.update = function (reset, recordVelocity, forceFake) { 35615 if (containerAnimation && !forceFake && !reset) { 35616 return; 35617 } 35618 35619 var scroll = self.scroll(), 35620 p = reset ? 0 : (scroll - start) / change, 35621 clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0, 35622 prevProgress = self.progress, 35623 isActive, 35624 wasActive, 35625 toggleState, 35626 action, 35627 stateChanged, 35628 toggled, 35629 isAtMax, 35630 isTakingAction; 35631 35632 if (recordVelocity) { 35633 scroll2 = scroll1; 35634 scroll1 = containerAnimation ? scrollFunc() : scroll; 35635 35636 if (snap) { 35637 snap2 = snap1; 35638 snap1 = animation && !isToggle ? animation.totalProgress() : clipped; 35639 } 35640 } 35641 35642 anticipatePin && !clipped && pin && !_refreshing && !_startup && _lastScrollTime && start < scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin && (clipped = 0.0001); 35643 35644 if (clipped !== prevProgress && self.enabled) { 35645 isActive = self.isActive = !!clipped && clipped < 1; 35646 wasActive = !!prevProgress && prevProgress < 1; 35647 toggled = isActive !== wasActive; 35648 stateChanged = toggled || !!clipped !== !!prevProgress; 35649 self.direction = clipped > prevProgress ? 1 : -1; 35650 self.progress = clipped; 35651 35652 if (stateChanged && !_refreshing) { 35653 toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3; 35654 35655 if (isToggle) { 35656 action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState]; 35657 isTakingAction = animation && (action === "complete" || action === "reset" || action in animation); 35658 } 35659 } 35660 35661 preventOverlaps && toggled && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) { 35662 return t.endAnimation(); 35663 })); 35664 35665 if (!isToggle) { 35666 if (scrubTween && !_refreshing && !_startup) { 35667 scrubTween.vars.totalProgress = clipped; 35668 scrubTween.invalidate().restart(); 35669 } else if (animation) { 35670 animation.totalProgress(clipped, !!_refreshing); 35671 } 35672 } 35673 35674 if (pin) { 35675 reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart); 35676 35677 if (!useFixedPosition) { 35678 pinSetter(pinStart + pinChange * clipped); 35679 } else if (stateChanged) { 35680 isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction); 35681 35682 if (pinReparent) { 35683 if (!reset && (isActive || isAtMax)) { 35684 var bounds = _getBounds(pin, true), 35685 _offset = scroll - start; 35686 35687 _reparent(pin, _body, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px); 35688 } else { 35689 _reparent(pin, spacer); 35690 } 35691 } 35692 35693 _setState(isActive || isAtMax ? pinActiveState : pinState); 35694 35695 pinChange !== change && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0)); 35696 } 35697 } 35698 35699 snap && !tweenTo.tween && !_refreshing && !_startup && snapDelayedCall.restart(true); 35700 toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) { 35701 return el.classList[isActive || once ? "add" : "remove"](toggleClass.className); 35702 }); 35703 onUpdate && !isToggle && !reset && onUpdate(self); 35704 35705 if (stateChanged && !_refreshing) { 35706 if (isToggle) { 35707 if (isTakingAction) { 35708 if (action === "complete") { 35709 animation.pause().totalProgress(1); 35710 } else if (action === "reset") { 35711 animation.restart(true).pause(); 35712 } else if (action === "restart") { 35713 animation.restart(true); 35714 } else { 35715 animation[action](); 35716 } 35717 } 35718 35719 onUpdate && onUpdate(self); 35720 } 35721 35722 if (toggled || !_limitCallbacks) { 35723 onToggle && toggled && _callback(self, onToggle); 35724 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 35725 once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); 35726 35727 if (!toggled) { 35728 toggleState = clipped === 1 ? 1 : 3; 35729 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 35730 } 35731 } 35732 35733 if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) { 35734 _endAnimation(self.callbackAnimation); 35735 35736 scrubTween ? scrubTween.progress(1) : _endAnimation(animation, !clipped, 1); 35737 } 35738 } else if (isToggle && onUpdate && !_refreshing) { 35739 onUpdate(self); 35740 } 35741 } 35742 35743 if (markerEndSetter) { 35744 var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll; 35745 markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0)); 35746 markerEndSetter(n); 35747 } 35748 35749 caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0)); 35750 }; 35751 35752 self.enable = function (reset, refresh) { 35753 if (!self.enabled) { 35754 self.enabled = true; 35755 35756 _addListener(scroller, "resize", _onResize); 35757 35758 _addListener(scroller, "scroll", _onScroll); 35759 35760 onRefreshInit && _addListener(ScrollTrigger, "refreshInit", onRefreshInit); 35761 35762 if (reset !== false) { 35763 self.progress = prevProgress = 0; 35764 scroll1 = scroll2 = lastSnap = scrollFunc(); 35765 } 35766 35767 refresh !== false && self.refresh(); 35768 } 35769 }; 35770 35771 self.getTween = function (snap) { 35772 return snap && tweenTo ? tweenTo.tween : scrubTween; 35773 }; 35774 35775 self.disable = function (reset, allowAnimation) { 35776 if (self.enabled) { 35777 reset !== false && self.revert(); 35778 self.enabled = self.isActive = false; 35779 allowAnimation || scrubTween && scrubTween.pause(); 35780 prevScroll = 0; 35781 pinCache && (pinCache.uncache = 1); 35782 onRefreshInit && _removeListener(ScrollTrigger, "refreshInit", onRefreshInit); 35783 35784 if (snapDelayedCall) { 35785 snapDelayedCall.pause(); 35786 tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0); 35787 } 35788 35789 if (!isViewport) { 35790 var i = _triggers.length; 35791 35792 while (i--) { 35793 if (_triggers[i].scroller === scroller && _triggers[i] !== self) { 35794 return; 35795 } 35796 } 35797 35798 _removeListener(scroller, "resize", _onResize); 35799 35800 _removeListener(scroller, "scroll", _onScroll); 35801 } 35802 } 35803 }; 35804 35805 self.kill = function (revert, allowAnimation) { 35806 self.disable(revert, allowAnimation); 35807 scrubTween && scrubTween.kill(); 35808 id && delete _ids[id]; 35809 35810 var i = _triggers.indexOf(self); 35811 35812 _triggers.splice(i, 1); 35813 35814 i === _i && _direction > 0 && _i--; 35815 i = 0; 35816 35817 _triggers.forEach(function (t) { 35818 return t.scroller === self.scroller && (i = 1); 35819 }); 35820 35821 i || (self.scroll.rec = 0); 35822 35823 if (animation) { 35824 animation.scrollTrigger = null; 35825 revert && animation.render(-1); 35826 allowAnimation || animation.kill(); 35827 } 35828 35829 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 35830 return m.parentNode && m.parentNode.removeChild(m); 35831 }); 35832 35833 if (pin) { 35834 pinCache && (pinCache.uncache = 1); 35835 i = 0; 35836
35837 _triggers.forEach(function (t) { 35838 return t.pin === pin && i++; 35839 }); 35840 35841 i || (pinCache.spacer = 0); 35842 } 35843 }; 35844 35845 self.enable(false, false); 35846 !animation || !animation.add || change ? self.refresh() : gsap.delayedCall(0.01, function () { 35847 return start || end || self.refresh(); 35848 }) && (change = 0.01) && (start = end = 0); 35849 }; 35850 35851 ScrollTrigger.register = function register(core) { 35852 if (!_coreInitted) { 35853 gsap = core || _getGSAP(); 35854 35855 if (_windowExists() && window.document) { 35856 _win = window; 35857 _doc = document; 35858 _docEl = _doc.documentElement; 35859 _body = _doc.body; 35860 } 35861 35862 if (gsap) { 35863 _toArray = gsap.utils.toArray; 35864 _clamp = gsap.utils.clamp; 35865 _suppressOverwrites = gsap.core.suppressOverwrites || _passThrough; 35866 gsap.core.globals("ScrollTrigger", ScrollTrigger); 35867 35868 if (_body) { 35869 _raf = _win.requestAnimationFrame || function (f) { 35870 return setTimeout(f, 16); 35871 }; 35872 35873 _addListener(_win, "wheel", _onScroll); 35874 35875 _root = [_win, _doc, _docEl, _body]; 35876 35877 _addListener(_doc, "scroll", _onScroll); 35878 35879 var bodyStyle = _body.style, 35880 border = bodyStyle.borderTopStyle, 35881 bounds; 35882 bodyStyle.borderTopStyle = "solid"; 35883 bounds = _getBounds(_body); 35884 _vertical.m = Math.round(bounds.top + _vertical.sc()) || 0; 35885 _horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0; 35886 border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style"); 35887 _syncInterval = setInterval(_sync, 200); 35888 gsap.delayedCall(0.5, function () { 35889 return _startup = 0; 35890 }); 35891 35892 _addListener(_doc, "touchcancel", _passThrough); 35893 35894 _addListener(_body, "touchstart", _passThrough); 35895 35896 _multiListener(_addListener, _doc, "pointerdown,touchstart,mousedown", function () { 35897 return _pointerIsDown = 1; 35898 }); 35899 35900 _multiListener(_addListener, _doc, "pointerup,touchend,mouseup", function () { 35901 return _pointerIsDown = 0; 35902 }); 35903 35904 _transformProp = gsap.utils.checkPrefix("transform"); 35905 35906 _stateProps.push(_transformProp); 35907 35908 _coreInitted = _getTime(); 35909 _resizeDelay = gsap.delayedCall(0.2, _refreshAll).pause(); 35910 _autoRefresh = [_doc, "visibilitychange", function () { 35911 var w = _win.innerWidth, 35912 h = _win.innerHeight; 35913 35914 if (_doc.hidden) { 35915 _prevWidth = w; 35916 _prevHeight = h; 35917 } else if (_prevWidth !== w || _prevHeight !== h) { 35918 _onResize(); 35919 } 35920 }, _doc, "DOMContentLoaded", _refreshAll, _win, "load", function () { 35921 return _lastScrollTime || _refreshAll(); 35922 }, _win, "resize", _onResize]; 35923 35924 _iterateAutoRefresh(_addListener); 35925 } 35926 } 35927 } 35928 35929 return _coreInitted; 35930 }; 35931 35932 ScrollTrigger.defaults = function defaults(config) { 35933 for (var p in config) { 35934 _defaults[p] = config[p]; 35935 } 35936 }; 35937 35938 ScrollTrigger.kill = function kill() { 35939 _enabled = 0; 35940 35941 _triggers.slice(0).forEach(function (trigger) { 35942 return trigger.kill(1); 35943 }); 35944 }; 35945 35946 ScrollTrigger.config = function config(vars) { 35947 "limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks); 35948 var ms = vars.syncInterval; 35949 ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms); 35950 35951 if ("autoRefreshEvents" in vars) { 35952 _iterateAutoRefresh(_removeListener) || _iterateAutoRefresh(_addListener, vars.autoRefreshEvents || "none"); 35953 _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1; 35954 } 35955 }; 35956 35957 ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) { 35958 var t = _getTarget(target), 35959 i = _scrollers.indexOf(t), 35960 isViewport = _isViewport(t); 35961 35962 if (~i) { 35963 _scrollers.splice(i, isViewport ? 6 : 2); 35964 } 35965 35966 isViewport ? _proxies.unshift(_win, vars, _body, vars, _docEl, vars) : _proxies.unshift(t, vars); 35967 }; 35968 35969 ScrollTrigger.matchMedia = function matchMedia(vars) { 35970 var mq, p, i, func, result; 35971 35972 for (p in vars) { 35973 i = _media.indexOf(p); 35974 func = vars[p]; 35975 _creatingMedia = p; 35976 35977 if (p === "all") { 35978 func(); 35979 } else { 35980 mq = _win.matchMedia(p); 35981 35982 if (mq) { 35983 mq.matches && (result = func()); 35984 35985 if (~i) { 35986 _media[i + 1] = _combineFunc(_media[i + 1], func); 35987 _media[i + 2] = _combineFunc(_media[i + 2], result); 35988 } else { 35989 i = _media.length; 35990 35991 _media.push(p, func, result); 35992 35993 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 35994 } 35995 35996 _media[i + 3] = mq.matches; 35997 } 35998 } 35999 36000 _creatingMedia = 0; 36001 } 36002 36003 return _media; 36004 }; 36005 36006 ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) { 36007 query || (_media.length = 0); 36008 query = _media.indexOf(query); 36009 query >= 0 && _media.splice(query, 4); 36010 }; 36011 36012 ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) { 36013 var bounds = (_isString(element) ? _getTarget(element) : element).getBoundingClientRect(), 36014 offset = bounds[horizontal ? _width : _height] * ratio || 0; 36015 return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win.innerHeight; 36016 }; 36017 36018 ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) { 36019 _isString(element) && (element = _getTarget(element)); 36020 var bounds = element.getBoundingClientRect(), 36021 size = bounds[horizontal ? _width : _height], 36022 offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0; 36023 return horizontal ? (bounds.left + offset) / _win.innerWidth : (bounds.top + offset) / _win.innerHeight; 36024 }; 36025 36026 return ScrollTrigger; 36027 }(); 36028 ScrollTrigger.version = "3.8.0"; 36029 36030 ScrollTrigger.saveStyles = function (targets) {
36031 return targets ? _toArray(targets).forEach(function (target) { 36032 if (target && target.style) { 36033 var i = _savedStyles.indexOf(target); 36034 36035 i >= 0 && _savedStyles.splice(i, 5); 36036 36037 _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap.core.getCache(target), _creatingMedia); 36038 } 36039 }) : _savedStyles; 36040 }; 36041 36042 ScrollTrigger.revert = function (soft, media) { 36043 return _revertAll(!soft, media); 36044 }; 36045 36046 ScrollTrigger.create = function (vars, animation) { 36047 return new ScrollTrigger(vars, animation); 36048 }; 36049 36050 ScrollTrigger.refresh = function (safe) { 36051 return safe ? _onResize() : (_coreInitted || ScrollTrigger.register()) && _refreshAll(true); 36052 }; 36053 36054 ScrollTrigger.update = _updateAll; 36055 ScrollTrigger.clearScrollMemory = _clearScrollMemory; 36056 36057 ScrollTrigger.maxScroll = function (element, horizontal) { 36058 return _maxScroll(element, horizontal ? _horizontal : _vertical); 36059 }; 36060 36061 ScrollTrigger.getScrollFunc = function (element, horizontal) { 36062 return _getScrollFunc(_getTarget(element), horizontal ? _horizontal : _vertical); 36063 }; 36064 36065 ScrollTrigger.getById = function (id) { 36066 return _ids[id]; 36067 }; 36068 36069 ScrollTrigger.getAll = function () { 36070 return _triggers.slice(0); 36071 }; 36072 36073 ScrollTrigger.isScrolling = function () { 36074 return !!_lastScrollTime; 36075 }; 36076 36077 ScrollTrigger.snapDirectional = _snapDirectional; 36078 36079 ScrollTrigger.addEventListener = function (type, callback) { 36080 var a = _listeners[type] || (_listeners[type] = []); 36081 ~a.indexOf(callback) || a.push(callback); 36082 }; 36083 36084 ScrollTrigger.removeEventListener = function (type, callback) { 36085 var a = _listeners[type], 36086 i = a && a.indexOf(callback); 36087 i >= 0 && a.splice(i, 1); 36088 }; 36089 36090 ScrollTrigger.batch = function (targets, vars) { 36091 var result = [], 36092 varsCopy = {}, 36093 interval = vars.interval || 0.016, 36094 batchMax = vars.batchMax || 1e9, 36095 proxyCallback = function proxyCallback(type, callback) { 36096 var elements = [], 36097 triggers = [], 36098 delay = gsap.delayedCall(interval, function () { 36099 callback(elements, triggers); 36100 elements = []; 36101 triggers = []; 36102 }).pause(); 36103 return function (self) { 36104 elements.length || delay.restart(true); 36105 elements.push(self.trigger); 36106 triggers.push(self); 36107 batchMax <= elements.length && delay.progress(1); 36108 }; 36109 }, 36110 p; 36111 36112 for (p in vars) { 36113 varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p]; 36114 } 36115 36116 if (_isFunction(batchMax)) { 36117 batchMax = batchMax(); 36118 36119 _addListener(ScrollTrigger, "refresh", function () { 36120 return batchMax = vars.batchMax(); 36121 }); 36122 } 36123 36124 _toArray(targets).forEach(function (target) { 36125 var config = {}; 36126 36127 for (p in varsCopy) { 36128 config[p] = varsCopy[p]; 36129 } 36130 36131 config.trigger = target; 36132 result.push(ScrollTrigger.create(config)); 36133 }); 36134 36135 return result; 36136 }; 36137 36138 ScrollTrigger.sort = function (func) { 36139 return _triggers.sort(func || function (a, b) { 36140 return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6); 36141 }); 36142 }; 36143 36144 _getGSAP() && gsap.registerPlugin(ScrollTrigger); 36145 36146 exports.ScrollTrigger = ScrollTrigger; 36147 exports.default = ScrollTrigger; 36148 36149 Object.defineProperty(exports, '__esModule', { value: true }); 36150 36151}))); 36152 36153/* ======================================================================== 36154 * Bootstrap: collapse.js v3.1.1 36155 * http://getbootstrap.com/javascript/#collapse 36156 * ======================================================================== 36157 * Copyright 2011-2014 Twitter, Inc. 36158 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36159 * ======================================================================== */ 36160 36161 36162+function ($) { 36163 'use strict'; 36164 36165 // COLLAPSE PUBLIC CLASS DEFINITION 36166 // ================================ 36167 36168 var Collapse = function (element, options) { 36169 this.$element = $(element) 36170 this.options = $.extend({}, Collapse.DEFAULTS, options) 36171 this.transitioning = null 36172 36173 if (this.options.parent) this.$parent = $(this.options.parent) 36174 if (this.options.toggle) this.toggle() 36175 } 36176 36177 Collapse.DEFAULTS = { 36178 toggle: true 36179 } 36180 36181 Collapse.prototype.dimension = function () { 36182 var hasWidth = this.$element.hasClass('width') 36183 return hasWidth ? 'width' : 'height' 36184 } 36185 36186 Collapse.prototype.show = function () { 36187 if (this.transitioning || this.$element.hasClass('in')) return 36188 36189 var startEvent = $.Event('show.bs.collapse') 36190 this.$element.trigger(startEvent) 36191 if (startEvent.isDefaultPrevented()) return 36192 36193 var actives = this.$parent && this.$parent.find('> .panel > .in') 36194 36195 if (actives && actives.length) { 36196 var hasData = actives.data('bs.collapse') 36197 if (hasData && hasData.transitioning) return 36198 //START UNCODE EDIT 36199 var parentNoToggle = this.$parent.data('no-toggle') 36200 if (!parentNoToggle) { 36201 actives.collapse('hide') 36202 } 36203 //END UNCODE EDIT 36204 hasData || actives.data('bs.collapse', null) 36205 } 36206 36207 var dimension = this.dimension() 36208 36209 this.$element 36210 .removeClass('collapse') 36211 .addClass('collapsing')[dimension](0) 36212 36213 this.transitioning = 1 36214 36215 var complete = function (e) { 36216 if (e && e.target != this.$element[0]) return 36217 this.$element 36218 .removeClass('collapsing') 36219 .addClass('collapse in')[dimension]('auto') 36220 this.transitioning = 0 36221 this.$element.trigger('shown.bs.collapse') 36222 } 36223 36224 if (!$.support.transition) return complete.call(this) 36225 36226 var scrollSize = $.camelCase(['scroll', dimension].join('-')) 36227 36228 this.$element 36229 .one($.support.transition.end, $.proxy(complete, this)) 36230 .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) 36231 } 36232 36233 Collapse.prototype.hide = function () { 36234 if (this.transitioning || !this.$element.hasClass('in')) return 36235 36236 var startEvent = $.Event('hide.bs.collapse') 36237 this.$element.trigger(startEvent) 36238 if (startEvent.isDefaultPrevented()) return 36239 36240 var dimension = this.dimension() 36241 36242 this.$element[dimension](this.$element[dimension]())[0].offsetHeight 36243 36244 this.$element 36245 .addClass('collapsing') 36246 .removeClass('collapse') 36247 .removeClass('in') 36248 36249 this.transitioning = 1 36250 36251 var complete = function (e) { 36252 if (e && e.target != this.$element[0]) return 36253 this.transitioning = 0 36254 this.$element 36255 .trigger('hidden.bs.collapse') 36256 .removeClass('collapsing') 36257 .addClass('collapse') 36258 } 36259 36260 if (!$.support.transition) return complete.call(this) 36261 36262 this.$element 36263 [dimension](0) 36264 .one($.support.transition.end, $.proxy(complete, this)) 36265 .emulateTransitionEnd(350) 36266 } 36267 36268 Collapse.prototype.toggle = function () { 36269 this[this.$element.hasClass('in') ? 'hide' : 'show']() 36270 } 36271 36272 36273 // COLLAPSE PLUGIN DEFINITION 36274 // ========================== 36275 36276 var old = $.fn.collapse 36277 36278 $.fn.collapse = function (option) { 36279 return this.each(function () { 36280 var $this = $(this) 36281 var data = $this.data('bs.collapse') 36282 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 36283 36284 if (!data && options.toggle && option == 'show') option = !option 36285 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 36286 if (typeof option == 'string') data[option]() 36287 }) 36288 } 36289 36290 $.fn.collapse.Constructor = Collapse 36291 36292 36293 // COLLAPSE NO CONFLICT 36294 // ==================== 36295 36296 $.fn.collapse.noConflict = function () { 36297 $.fn.collapse = old 36298 return this 36299 } 36300 36301 36302 // COLLAPSE DATA-API 36303 // ================= 36304 36305 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 36306 var $this = $(this), href 36307 var target = $this.attr('data-target') 36308 || e.preventDefault() 36309 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 36310 //Edited by Uncode to replace ID in panel [START] 36311 var _target = href.replace(/^#/, ""); 36312 if ( $('[data-id="' + _target + '"]').length ) { 36313 var $target = $('[data-id="' + _target + '"]') 36314 } else { 36315 var $target = $(target) 36316 } 36317 //Edited by Uncode to replace ID in panel [END] 36318 var data = $target.data('bs.collapse') 36319 var option = data ? 'toggle' : $this.data() 36320 var parent = $this.attr('data-parent') 36321 var $parent = parent && $(parent) 36322 36323 if (!data || !data.transitioning) { 36324 if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') 36325 $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 36326 } 36327 36328 $target.collapse(option) 36329 }) 36330 36331}(jQuery); 36332 36333/* ======================================================================== 36334 * Bootstrap: tab.js v3.1.1 36335 * http://getbootstrap.com/javascript/#tabs 36336 * ======================================================================== 36337 * Copyright 2011-2014 Twitter, Inc. 36338 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36339 * ======================================================================== */ 36340 36341 36342+function ($) { 36343 'use strict'; 36344 36345 // TAB CLASS DEFINITION 36346 // ==================== 36347 36348 var Tab = function (element) { 36349 this.element = $(element) 36350 } 36351 36352 Tab.prototype.show = function () { 36353 var $this = this.element 36354 var $ul = $this.closest('ul:not(.dropdown-menu)') 36355 var selector = $this.data('target') 36356 36357 if (!selector) { 36358 selector = $this.attr('href') 36359 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 36360 } 36361 36362 if ($this.parent('li').hasClass('active')) return 36363 36364 var previous = $ul.find('.active:last a')[0] 36365 var e = $.Event('show.bs.tab', { 36366 relatedTarget: previous 36367 }) 36368 36369 $this.trigger(e) 36370 36371 if (e.isDefaultPrevented()) return 36372 36373 //Edited by Uncode to replace ID in panel [START] 36374 var _target = selector.replace(/^#/, ""); 36375 if ( $('[data-id="' + _target + '"]').length ) 36376 var $target = $('[data-id="' + _target + '"]') 36377 else 36378 var $target = $(selector) 36379 //Edited by Uncode to replace ID in panel [END] 36380 36381 this.activate($this.parent('li'), $ul) 36382 this.activate($target, $target.parent(), function () { 36383 $this.trigger({ 36384 type: 'shown.bs.tab', 36385 relatedTarget: previous 36386 }) 36387 }) 36388 } 36389 36390 Tab.prototype.activate = function (element, container, callback) { 36391 var $active = container.find('> .active').add(container.find('> .active > .active')) 36392 var transition = callback 36393 && $.support.transition 36394 && $active.hasClass('fade') 36395 36396 function next() { 36397 $active 36398 .removeClass('active') 36399 .find('> .dropdown-menu > .active') 36400 .removeClass('active') 36401 36402 $active 36403 .find('.tab-excerpt').slideUp(); 36404 36405 element.addClass('active') 36406 $('.tab-excerpt', element).slideDown(); 36407 36408 //if (transition) { 36409 element[0].offsetWidth // reflow for transition 36410 element.add($active).addClass('in') 36411 /*} else { 36412 element.removeClass('fade') 36413 }*/ 36414 36415 if (element.parent('.dropdown-menu')) { 36416 element.closest('li.dropdown').addClass('active') 36417 } 36418 36419 if ( ! element.is('li') ) { 36420 element.closest('.tab-content').find('> .active').not(element).removeClass('active'); 36421 } 36422 36423 callback && callback() 36424 } 36425 36426 transition ? 36427 $active 36428 .one($.support.transition.end, next) 36429 .emulateTransitionEnd(150) : 36430 next() 36431 36432 $active.removeClass('in') 36433 } 36434 36435 36436 // TAB PLUGIN DEFINITION 36437 // ===================== 36438 36439 var old = $.fn.tab 36440 36441 $.fn.tab = function ( option ) { 36442 return this.each(function () { 36443 var $this = $(this) 36444 var data = $this.data('bs.tab') 36445 36446 if (!data) $this.data('bs.tab', (data = new Tab(this))) 36447 if (typeof option == 'string') data[option]() 36448 }) 36449 } 36450 36451 $.fn.tab.Constructor = Tab 36452 36453 36454 // TAB NO CONFLICT 36455 // =============== 36456 36457 $.fn.tab.noConflict = function () { 36458 $.fn.tab = old 36459 return this 36460 } 36461 36462 36463 // TAB DATA-API 36464 // ============ 36465 36466 $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 36467 e.preventDefault() 36468 $(this).tab('show') 36469 }) 36470 36471}(jQuery); 36472 36473/* ======================================================================== 36474 * Bootstrap: tooltip.js v3.1.1 36475 * http://getbootstrap.com/javascript/#tooltip 36476 * Inspired by the original jQuery.tipsy by Jason Frame 36477 * ======================================================================== 36478 * Copyright 2011-2014 Twitter, Inc. 36479 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36480 * ======================================================================== */ 36481 36482 36483+function ($) { 36484 'use strict'; 36485 36486 // TOOLTIP PUBLIC CLASS DEFINITION 36487 // =============================== 36488 36489 var Tooltip = function (element, options) { 36490 this.type = 36491 this.options = 36492 this.enabled = 36493 this.timeout = 36494 this.hoverState = 36495 this.$element = null 36496 36497 this.init('tooltip', element, options) 36498 } 36499 36500 Tooltip.DEFAULTS = { 36501 animation: true, 36502 placement: 'top', 36503 selector: false, 36504 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 36505 trigger: 'hover focus', 36506 title: '', 36507 delay: 0, 36508 html: false, 36509 container: false, 36510 viewport: { 36511 selector: 'body', 36512 padding: 0 36513 } 36514 } 36515 36516 Tooltip.prototype.init = function (type, element, options) { 36517 this.enabled = true 36518 this.type = type 36519 this.$element = $(element) 36520 this.options = this.getOptions(options) 36521 this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) 36522 36523 var triggers = this.options.trigger.split(' ') 36524 36525 for (var i = triggers.length; i--;) { 36526 var trigger = triggers[i] 36527 36528 if (trigger == 'click') { 36529 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 36530 } else if (trigger != 'manual') { 36531 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 36532 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 36533 36534 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 36535 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 36536 } 36537 } 36538 36539 this.options.selector ? 36540 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 36541 this.fixTitle() 36542 } 36543 36544 Tooltip.prototype.getDefaults = function () { 36545 return Tooltip.DEFAULTS 36546 } 36547 36548 Tooltip.prototype.getOptions = function (options) { 36549 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 36550 36551 if (options.delay && typeof options.delay == 'number') { 36552 options.delay = { 36553 show: options.delay, 36554 hide: options.delay 36555 } 36556 } 36557 36558 return options 36559 } 36560 36561 Tooltip.prototype.getDelegateOptions = function () { 36562 var options = {} 36563 var defaults = this.getDefaults() 36564 36565 this._options && $.each(this._options, function (key, value) { 36566 if (defaults[key] != value) options[key] = value 36567 }) 36568 36569 return options 36570 } 36571 36572 Tooltip.prototype.enter = function (obj) { 36573 var self = obj instanceof this.constructor ? 36574 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 36575 36576 clearTimeout(self.timeout) 36577 36578 self.hoverState = 'in' 36579 36580 if (!self.options.delay || !self.options.delay.show) return self.show() 36581 36582 self.timeout = setTimeout(function () { 36583 if (self.hoverState == 'in') self.show() 36584 }, self.options.delay.show) 36585 } 36586 36587 Tooltip.prototype.leave = function (obj) { 36588 var self = obj instanceof this.constructor ? 36589 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 36590 36591 clearTimeout(self.timeout) 36592 36593 self.hoverState = 'out' 36594 36595 if (!self.options.delay || !self.options.delay.hide) return self.hide() 36596 36597 self.timeout = setTimeout(function () { 36598 if (self.hoverState == 'out') self.hide() 36599 }, self.options.delay.hide) 36600 } 36601 36602 Tooltip.prototype.show = function () { 36603 var e = $.Event('show.bs.' + this.type) 36604 36605 if (this.hasContent() && this.enabled) { 36606 this.$element.trigger(e) 36607 36608 if (e.isDefaultPrevented()) return 36609 var that = this; 36610 36611 var $tip = this.tip() 36612 36613 this.setContent() 36614 36615 if (this.options.animation) $tip.addClass('fade') 36616 36617 var placement = typeof this.options.placement == 'function' ? 36618 this.options.placement.call(this, $tip[0], this.$element[0]) : 36619 this.options.placement 36620 36621 var autoToken = /\s?auto?\s?/i 36622 var autoPlace = autoT
36622oken.test(placement) 36623 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 36624 36625 $tip 36626 .detach() 36627 .css({ top: 0, left: 0, display: 'block' }) 36628 .addClass(placement) 36629 36630 this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) 36631 36632 var pos = this.getPosition() 36633 var actualWidth = $tip[0].offsetWidth 36634 var actualHeight = $tip[0].offsetHeight 36635 36636 if (autoPlace) { 36637 var orgPlacement = placement 36638 var $parent = this.$element.parent() 36639 var parentDim = this.getPosition($parent) 36640 36641 placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' : 36642 placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' : 36643 placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' : 36644 placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' : 36645 placement 36646 36647 $tip 36648 .removeClass(orgPlacement) 36649 .addClass(placement) 36650 } 36651 36652 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 36653 36654 this.applyPlacement(calculatedOffset, placement) 36655 this.hoverState = null 36656 36657 var complete = function() { 36658 that.$element.trigger('shown.bs.' + that.type) 36659 } 36660 36661 $.support.transition && this.$tip.hasClass('fade') ? 36662 $tip 36663 .one($.support.transition.end, complete) 36664 .emulateTransitionEnd(150) : 36665 complete() 36666 } 36667 } 36668 36669 Tooltip.prototype.applyPlacement = function (offset, placement) { 36670 var $tip = this.tip() 36671 var width = $tip[0].offsetWidth 36672 var height = $tip[0].offsetHeight 36673 36674 // manually read margins because getBoundingClientRect includes difference 36675 var marginTop = parseInt($tip.css('margin-top'), 10) 36676 var marginLeft = parseInt($tip.css('margin-left'), 10) 36677 36678 // we must check for NaN for ie 8/9 36679 if (isNaN(marginTop)) marginTop = 0 36680 if (isNaN(marginLeft)) marginLeft = 0 36681 36682 offset.top = offset.top + marginTop 36683 offset.left = offset.left + marginLeft 36684 36685 // $.fn.offset doesn't round pixel values 36686 // so we use setOffset directly with our own function B-0 36687 $.offset.setOffset($tip[0], $.extend({ 36688 using: function (props) { 36689 $tip.css({ 36690 top: Math.round(props.top), 36691 left: Math.round(props.left) 36692 }) 36693 } 36694 }, offset), 0) 36695 36696 $tip.addClass('in') 36697 36698 // check to see if placing tip in new offset caused the tip to resize itself 36699 var actualWidth = $tip[0].offsetWidth 36700 var actualHeight = $tip[0].offsetHeight 36701 36702 if (placement == 'top' && actualHeight != height) { 36703 offset.top = offset.top + height - actualHeight 36704 } 36705 36706 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 36707 36708 if (delta.left) offset.left += delta.left 36709 else offset.top += delta.top 36710 36711 var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 36712 var arrowPosition = delta.left ? 'left' : 'top' 36713 var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' 36714 36715 $tip.offset(offset) 36716 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) 36717 } 36718 36719 Tooltip.prototype.replaceArrow = function (delta, dimension, position) { 36720 this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '') 36721 } 36722 36723 Tooltip.prototype.setContent = function () { 36724 var $tip = this.tip() 36725 var title = this.getTitle() 36726 36727 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 36728 $tip.removeClass('fade in top bottom left right') 36729 } 36730 36731 Tooltip.prototype.hide = function () { 36732 var that = this 36733 var $tip = this.tip() 36734 var e = $.Event('hide.bs.' + this.type) 36735 36736 function complete() { 36737 if (that.hoverState != 'in') $tip.detach() 36738 that.$element.trigger('hidden.bs.' + that.type) 36739 } 36740 36741 this.$element.trigger(e) 36742 36743 if (e.isDefaultPrevented()) return 36744 36745 $tip.removeClass('in') 36746 36747 $.support.transition && this.$tip.hasClass('fade') ? 36748 $tip 36749 .one($.support.transition.end, complete) 36750 .emulateTransitionEnd(150) : 36751 complete() 36752 36753 this.hoverState = null 36754 36755 return this 36756 } 36757 36758 Tooltip.prototype.fixTitle = function () { 36759 var $e = this.$element 36760 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { 36761 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 36762 } 36763 } 36764 36765 Tooltip.prototype.hasContent = function () { 36766 return this.getTitle() 36767 } 36768 36769 Tooltip.prototype.getPosition = function ($element) { 36770 $element = $element || this.$element 36771 var el = $element[0] 36772 var isBody = el.tagName == 'BODY' 36773 return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, { 36774 scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(), 36775 width: isBody ? $(window).width() : $element.outerWidth(), 36776 height: isBody ? $(window).height() : $element.outerHeight() 36777 }, isBody ? {top: 0, left: 0} : $element.offset()) 36778 } 36779 36780 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 36781 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36782 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 36783 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 36784 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 36785 36786 } 36787 36788 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 36789 var delta = { top: 0, left: 0 } 36790 if (!this.$viewport) return delta 36791 36792 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 36793 var viewportDimensions = this.getPosition(this.$viewport) 36794 36795 if (/right|left/.test(placement)) { 36796 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 36797 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 36798 if (topEdgeOffset < viewportDimensions.top) { // top overflow 36799 delta.top = viewportDimensions.top - topEdgeOffset 36800 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 36801 delta.top = viewportDimensions.top + viewportDimensions.height - bottom
36801EdgeOffset 36802 } 36803 } else { 36804 var leftEdgeOffset = pos.left - viewportPadding 36805 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 36806 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 36807 delta.left = viewportDimensions.left - leftEdgeOffset 36808 } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow 36809 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 36810 } 36811 } 36812 36813 return delta 36814 } 36815 36816 Tooltip.prototype.getTitle = function () { 36817 var title 36818 var $e = this.$element 36819 var o = this.options 36820 36821 title = $e.attr('data-original-title') 36822 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 36823 36824 return title 36825 } 36826 36827 Tooltip.prototype.tip = function () { 36828 return this.$tip = this.$tip || $(this.options.template) 36829 } 36830 36831 Tooltip.prototype.arrow = function () { 36832 return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow') 36833 } 36834 36835 Tooltip.prototype.validate = function () { 36836 if (!this.$element[0].parentNode) { 36837 this.hide() 36838 this.$element = null 36839 this.options = null 36840 } 36841 } 36842 36843 Tooltip.prototype.enable = function () { 36844 this.enabled = true 36845 } 36846 36847 Tooltip.prototype.disable = function () { 36848 this.enabled = false 36849 } 36850 36851 Tooltip.prototype.toggleEnabled = function () { 36852 this.enabled = !this.enabled 36853 } 36854 36855 Tooltip.prototype.toggle = function (e) { 36856 var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this 36857 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 36858 } 36859 36860 Tooltip.prototype.destroy = function () { 36861 clearTimeout(this.timeout) 36862 this.hide().$element.off('.' + this.type).removeData('bs.' + this.type) 36863 } 36864 36865 36866 // TOOLTIP PLUGIN DEFINITION 36867 // ========================= 36868 36869 var old = $.fn.tooltip 36870 36871 $.fn.tooltip = function (option) { 36872 return this.each(function () { 36873 var $this = $(this) 36874 var data = $this.data('bs.tooltip') 36875 var options = typeof option == 'object' && option 36876 36877 if (!data && option == 'destroy') return 36878 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 36879 if (typeof option == 'string') data[option]() 36880 }) 36881 } 36882 36883 $.fn.tooltip.Constructor = Tooltip 36884 36885 36886 // TOOLTIP NO CONFLICT 36887 // =================== 36888 36889 $.fn.tooltip.noConflict = function () { 36890 $.fn.tooltip = old 36891 return this 36892 } 36893 36894}(jQuery); 36895 36896/* ======================================================================== 36897 * Bootstrap: transition.js v3.1.1 36898 * http://getbootstrap.com/javascript/#transitions 36899 * ======================================================================== 36900 * Copyright 2011-2014 Twitter, Inc. 36901 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 36902 * ======================================================================== */ 36903 36904 36905+function ($) { 36906 'use strict'; 36907 36908 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 36909 // ============================================================ 36910 36911 function transitionEnd() { 36912 var el = document.createElement('bootstrap') 36913 36914 var transEndEventNames = { 36915 WebkitTransition : 'webkitTransitionEnd', 36916 MozTransition : 'transitionend', 36917 OTransition : 'oTransitionEnd otransitionend', 36918 transition : 'transitionend' 36919 } 36920 36921 for (var name in transEndEventNames) { 36922 if (el.style[name] !== undefined) { 36923 return { end: transEndEventNames[name] } 36924 } 36925 } 36926 36927 return false // explicit for ie8 ( ._.) 36928 } 36929 36930 // http://blog.alexmaccaw.com/css-transitions 36931 $.fn.emulateTransitionEnd = function (duration) { 36932 var called = false, $el = this 36933 $(this).one($.support.transition.end, function () { called = true }) 36934 var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 36935 setTimeout(callback, duration) 36936 return this 36937 } 36938 36939 $(function () { 36940 $.support.transition = transitionEnd() 36941 }) 36942 36943}(jQuery); 36944 36945 36946// ------------------------------------------ 36947// Rellax.js 36948// Buttery smooth parallax library 36949// Copyright (c) 2016 Moe Amaya (@moeamaya) 36950// MIT license 36951// 36952// Thanks to Paraxify.js and Jaime Cabllero 36953// for parallax concepts 36954// ------------------------------------------ 36955 36956(function (root, factory) { 36957 if (typeof define === 'function' && define.amd) { 36958 // AMD. Register as an anonymous module. 36959 define([], factory); 36960 } else if (typeof module === 'object' && module.exports) { 36961 // Node. Does not work with strict CommonJS, but 36962 // only CommonJS-like environments that support module.exports, 36963 // like Node. 36964 module.exports = factory(); 36965 } else { 36966 // Browser globals (root is window) 36967 root.Rellax = factory(); 36968 } 36969}(typeof window !== "undefined" ? window : global, function () { 36970 var Rellax = function(el, options){ 36971 "use strict"; 36972 36973 var self = Object.create(Rellax.prototype); 36974 36975 var posY = 0; 36976 var screenY = 0; 36977 var posX = 0; 36978 var screenX = 0; 36979 var blocks = []; 36980 var pause = true; 36981 36982 // check what requestAnimationFrame to use, and if 36983 // it's not supported, use the onscroll event 36984 var loop = window.requestAnimationFrame || 36985 window.webkitRequestAnimationFrame || 36986 window.mozRequestAnimationFrame || 36987 window.msRequestAnimationFrame || 36988 window.oRequestAnimationFrame || 36989 function(callback){ return setTimeout(callback, 1000 / 60); }; 36990 36991 // store the id for later use 36992 var loopId = null; 36993 36994 // Test via a getter in the options object to see if the passive property is accessed 36995 var supportsPassive = false;
vendor: 10,724 bytes, lines 36996-37297
36996 try { 36997 var opts = Object.defineProperty({}, 'passive', { 36998 get: function() { 36999 supportsPassive = true; 37000 } 37001 }); 37002 window.addEventListener("testPassive", null, opts); 37003 window.removeEventListener("testPassive", null, opts); 37004 } catch (e) {} 37005 37006 // check what cancelAnimation method to use 37007 var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout; 37008 37009 // check which transform property to use 37010 var transformProp = window.transformProp || (function(){ 37011 var testEl = document.createElement('div'); 37012 if (testEl.style.transform === null) { 37013 var vendors = ['Webkit', 'Moz', 'ms']; 37014 for (var vendor in vendors) { 37015 if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) { 37016 return vendors[vendor] + 'Transform'; 37017 } 37018 } 37019 } 37020 return 'transform'; 37021 })(); 37022 37023 // Default Settings 37024 self.options = { 37025 speed: -2, 37026 verticalSpeed: null, 37027 horizontalSpeed: null, 37028 breakpoints: [576, 768, 1201], 37029 center: false, 37030 wrapper: null, 37031 relativeToWrapper: false, 37032 round: true, 37033 vertical: true, 37034 horizontal: false, 37035 verticalScrollAxis: "y", 37036 horizontalScrollAxis: "x", 37037 callback: function() {}, 37038 }; 37039 37040 // User defined options (might have more in the future) 37041 if (options){ 37042 Object.keys(options).forEach(function(key){ 37043 self.options[key] = options[key]; 37044 }); 37045 } 37046 37047 function validateCustomBreakpoints () { 37048 if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) { 37049 var isAscending = true; 37050 var isNumerical = true; 37051 var lastVal; 37052 self.options.breakpoints.forEach(function (i) { 37053 if (typeof i !== 'number') isNumerical = false; 37054 if (lastVal !== null) { 37055 if (i < lastVal) isAscending = false; 37056 } 37057 lastVal = i; 37058 }); 37059 if (isAscending && isNumerical) return; 37060 } 37061 // revert defaults if set incorrectly 37062 self.options.breakpoints = [576, 768, 1201]; 37063 console.warn("Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted"); 37064 } 37065 37066 if (options && options.breakpoints) { 37067 validateCustomBreakpoints(); 37068 } 37069 37070 // By default, rellax class 37071 if (!el) { 37072 el = '.rellax'; 37073 } 37074 37075 // check if el is a className or a node 37076 var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el]; 37077 37078 // Now query selector 37079 if (elements.length > 0) { 37080 self.elems = elements; 37081 } 37082 37083 // The elements don't exist 37084 else { 37085 console.warn("Rellax: The elements you're trying to select don't exist."); 37086 return; 37087 } 37088 37089 // Has a wrapper and it exists 37090 if (self.options.wrapper) { 37091 if (!self.options.wrapper.nodeType) { 37092 var wrapper = document.querySelector(self.options.wrapper); 37093 37094 if (wrapper) { 37095 self.options.wrapper = wrapper; 37096 } else { 37097 console.warn("Rellax: The wrapper you're trying to use doesn't exist."); 37098 return; 37099 } 37100 } 37101 } 37102 37103 // set a placeholder for the current breakpoint 37104 var currentBreakpoint; 37105 37106 // helper to determine current breakpoint 37107 var getCurrentBreakpoint = function (w) { 37108 var bp = self.options.breakpoints; 37109 if (w < bp[0]) return 'xs'; 37110 if (w >= bp[0] && w < bp[1]) return 'sm'; 37111 if (w >= bp[1] && w < bp[2]) return 'md'; 37112 return 'lg'; 37113 }; 37114 37115 // Get and cache initial position of all elements 37116 var cacheBlocks = function() { 37117 for (var i = 0; i < self.elems.length; i++){ 37118 var block = createBlock(self.elems[i]); 37119 blocks.push(block); 37120 } 37121 }; 37122 37123 37124 // Let's kick this script off 37125 // Build array for cached element values 37126 var init = function() { 37127 for (var i = 0; i < blocks.length; i++){ 37128 self.elems[i].style.cssText = blocks[i].style; 37129 } 37130 37131 blocks = []; 37132 37133 screenY = window.innerHeight; 37134 screenX = window.innerWidth; 37135 currentBreakpoint = getCurrentBreakpoint(screenX); 37136 37137 setPosition(); 37138 37139 cacheBlocks(); 37140 37141 animate(); 37142 37143 // If paused, unpause and set listener for window resizing events 37144 if (pause) { 37145 window.addEventListener('resize', init); 37146 pause = false; 37147 // Start the loop 37148 update(); 37149 } 37150 }; 37151 37152 // We want to cache the parallax blocks' 37153 // values: base, top, height, speed 37154 // el: is dom object, return: el cache values 37155 var createBlock = function(el) { 37156 var dataPercentage = el.getAttribute( 'data-rellax-percentage' ); 37157 var dataSpeed = el.getAttribute( 'data-rellax-speed' ); 37158 var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' ); 37159 var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' ); 37160 var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' ); 37161 var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' ); 37162 var dataVerticalSpeed = el.getAttribute('data-rellax-vertical-speed'); 37163 var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed'); 37164 var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis'); 37165 var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis'); 37166 var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0; 37167 var dataMin = el.getAttribute( 'data-rellax-min' ); 37168 var dataMax = el.getAttribute( 'data-rellax-max' ); 37169 var dataMinX = el.getAttribute('data-rellax-min-x'); 37170 var dataMaxX = el.getAttribute('data-rellax-max-x'); 37171 var dataMinY = el.getAttribute('data-rellax-min-y'); 37172 var dataMaxY = el.getAttribute('data-rellax-max-y'); 37173 var mapBreakpoints; 37174 var breakpoints = true; 37175 37176 if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) { 37177 breakpoints = false; 37178 } else { 37179 mapBreakpoints = { 37180 'xs': dataXsSpeed, 37181 'sm': dataMobileSpeed, 37182 'md': dataTabletSpeed, 37183 'lg': dataDesktopSpeed 37184 }; 37185 } 37186 37187 // initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser) 37188 // ensures elements are positioned based on HTML layout. 37189 // 37190 // If the element has the percentage attribute, the posY and posX needs to be 37191 // the current scroll position's value, so that the elements are still positioned based on HTML layout 37192 var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 37193 // If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll. 37194 if (self.options.relativeToWrapper) { 37195 var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 37196 wrapperPosY = scrollPosY - self.options.wrapper.offsetTop; 37197 } 37198 var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0; 37199 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; 37200 37201 var blockTop = posY + el.getBoundingClientRect().top; 37202 var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight; 37203 37204 var blockLeft = posX + el.getBoundingClientRect().left; 37205 var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth; 37206 37207 // apparently parallax equation everyone uses 37208 var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY); 37209 var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX); 37210 if(self.options.center){ percentageX = 0.5; percentageY = 0.5; } 37211 37212 // Optional individual block speed as data attr, otherwise global speed 37213 var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed); 37214 var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed; 37215 var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed; 37216 37217 // Optional individual block movement axis direction as data attr, otherwise global movement direction 37218 var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis; 37219 var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis; 37220 37221 var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed); 37222 37223 // ~~Store non-translate3d transforms~~ 37224 // Store inline styles and extract transforms 37225 var style = el.style.cssText; 37226 var transform = ''; 37227 37228 // Check if there's an inline styled transform 37229 var searchResult = /transform\s*:/i.exec(style); 37230 if (searchResult) { 37231 // Get the index of the transform 37232 var index = searchResult.index; 37233 37234 // Trim the style to the transform point and get the following semi-colon index 37235 var trimmedStyle = style.slice(index); 37236 var delimiter = trimmedStyle.indexOf(';'); 37237 37238 // Remove "transform" string and save the attribute 37239 if (delimiter) { 37240 transform = " " + trimmedStyle.slice(11, delimiter).replace(/\s/g,''); 37241 } else { 37242 transform = " " + trimmedStyle.slice(11).replace(/\s/g,''); 37243 } 37244 } 37245 37246 return { 37247 baseX: bases.x, 37248 baseY: bases.y, 37249 top: blockTop, 37250 left: blockLeft, 37251 height: blockHeight, 37252 width: blockWidth, 37253 speed: speed, 37254 verticalSpeed: verticalSpeed, 37255 horizontalSpeed: horizontalSpeed, 37256 verticalScrollAxis: verticalScrollAxis, 37257 horizontalScrollAxis: horizontalScrollAxis, 37258 style: style, 37259 transform: transform, 37260 zindex: dataZindex, 37261 min: dataMin, 37262 max: dataMax, 37263 minX: dataMinX, 37264 maxX: dataMaxX, 37265 minY: dataMinY, 37266 maxY: dataMaxY 37267 }; 37268 }; 37269 37270 // set scroll position (posY, posX) 37271 // side effect method is not ideal, but okay for now 37272 // returns true if the scroll changed, false if nothing happened 37273 var setPosition = function() { 37274 var oldY = posY; 37275 var oldX = posX; 37276 37277 posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 37278 posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset; 37279 // If option relativeToWrapper is true, use relative wrapper value instead. 37280 if (self.options.relativeToWrapper) { 37281 var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 37282 posY = scrollPosY - self.options.wrapper.offsetTop; 37283 } 37284 37285 37286 if (oldY != posY && self.options.vertical) { 37287 // scroll changed, return true 37288 return true; 37289 } 37290 37291 if (oldX != posX && self.options.horizontal) { 37292 // scroll changed, return true 37293 return true; 37294 } 37295 37296 // scroll did not change 37297 return false;
37298 }; 37299 37300 // Ahh a pure function, gets new transform value 37301 // based on scrollPosition and speed 37302 // Allow for decimal pixel values 37303 var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) { 37304 var result = {}; 37305 var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX))); 37306 var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY))); 37307 37308 result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100; 37309 result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100; 37310 37311 return result; 37312 }; 37313 37314 // Remove event listeners and loop again 37315 var deferredUpdate = function() { 37316 window.removeEventListener('resize', deferredUpdate); 37317 window.removeEventListener('orientationchange', deferredUpdate); 37318 (self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate); 37319 (self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate); 37320 37321 // loop again 37322 loopId = loop(update); 37323 }; 37324 37325 // Loop 37326 var update = function() { 37327 if (setPosition() && pause === false) { 37328 animate(); 37329 37330 // loop again 37331 loopId = loop(update); 37332 } else { 37333 loopId = null; 37334 37335 // Don't animate until we get a position updating event 37336 window.addEventListener('resize', deferredUpdate); 37337 window.addEventListener('orientationchange', deferredUpdate); 37338 (self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false); 37339 (self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false); 37340 } 37341 }; 37342 37343 // Transform3d on parallax element 37344 var animate = function() { 37345 var positions; 37346 for (var i = 0; i < self.elems.length; i++){ 37347 // Determine relevant movement directions 37348 var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase(); 37349 var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase(); 37350 var verticalScrollX = verticalScrollAxis.indexOf("x") != -1 ? posY : 0; 37351 var verticalScrollY = verticalScrollAxis.indexOf("y") != -1 ? posY : 0; 37352 var horizontalScrollX = horizontalScrollAxis.indexOf("x") != -1 ? posX : 0; 37353 var horizontalScrollY = horizontalScrollAxis.indexOf("y") != -1 ? posX : 0; 37354 37355 var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY)); 37356 var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX)); 37357 37358 // Subtracting initialize value, so element stays in same spot as HTML 37359 positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed); 37360 var positionY = positions.y - blocks[i].baseY; 37361 var positionX = positions.x - blocks[i].baseX; 37362 37363 // The next two "if" blocks go like this: 37364 // Check if a limit is defined (first "min", then "max"); 37365 // Check if we need to change the Y or the X 37366 // (Currently working only if just one of the axes is enabled) 37367 // Then, check if the new position is inside the allowed limit 37368 // If so, use new position. If not, set position to limit. 37369 37370 // Check if a min limit is defined 37371 if (blocks[i].min !== null) { 37372 if (self.options.vertical && !self.options.horizontal) { 37373 positionY = positionY <= blocks[i].min ? blocks[i].min : positionY; 37374 } 37375 if (self.options.horizontal && !self.options.vertical) { 37376 positionX = positionX <= blocks[i].min ? blocks[i].min : positionX; 37377 } 37378 } 37379 37380 // Check if directional min limits are defined 37381 if (blocks[i].minY != null) { 37382 positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY; 37383 } 37384 if (blocks[i].minX != null) { 37385 positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX; 37386 } 37387 37388 // Check if a max limit is defined 37389 if (blocks[i].max !== null) { 37390 if (self.options.vertical && !self.options.horizontal) { 37391 positionY = positionY >= blocks[i].max ? blocks[i].max : positionY; 37392 } 37393 if (self.options.horizontal && !self.options.vertical) { 37394 positionX = positionX >= blocks[i].max ? blocks[i].max : positionX; 37395 } 37396 } 37397 37398 // Check if directional max limits are defined 37399 if (blocks[i].maxY != null) { 37400 positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY; 37401 } 37402 if (blocks[i].maxX != null) { 37403 positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX; 37404 } 37405 37406 var zindex = blocks[i].zindex; 37407 37408 // Move that element 37409 // (Set the new translation and append initial inline transforms.) 37410 var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform; 37411 self.elems[i].style[transformProp] = translate; 37412 } 37413 self.options.callback(positions); 37414 }; 37415 37416 self.destroy = function() { 37417 for (var i = 0; i < self.elems.length; i++){ 37418 self.elems[i].style.cssText = blocks[i].style; 37419 } 37420 37421 // Remove resize event listener if not pause, and pause 37422 if (!pause) { 37423 window.removeEventListener('resize', init); 37424 pause = true; 37425 } 37426 37427 // Clear the animation loop to prevent possible memory leak 37428 clearLoop(loopId); 37429 loopId = null; 37430 }; 37431 37432 // Init 37433 init(); 37434 37435 // Allow to recalculate the initial values whenever we want 37436 self.refresh = init; 37437 37438 return self; 37439 }; 37440 return Rellax; 37441})); 37442 37443/* 37444 * OKVideo by OKFocus v2.3.2 37445 * http://okfoc.us 37446 * 37447 * Copyright 2014, OKFocus 37448 * Licensed under the MIT license. 37449 * 37450 */ 37451var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array(); 37452// youtube player ready 37453function onYouTubeIframeAPIReady() { 37454 YTplayers = new Array(); 37455 jQuery('.uncode-video-container.video').each(function() { 37456 var playerY; 37457 if (jQuery(this).attr('data-provider') == 'youtube') { 37458 var id = jQuery(this).attr('data-id'), 37459 start = jQuery(this).attr('data-start'), 37460 end = jQuery(this).attr('data-end'); 37461 start = typeof start && start !== null ? start : 0; 37462 end = typeof end && end !== null ? end : 0; 37463 options = jQuery(window).data('okoptions-' + id); 37464 if ( typeof options === 'undefined' ) { 37465 return true; 37466 } 37467 options.time = jQuery(this).attr('data-t'); 37468 playerY = new YT.Player('okplayer-' + id, { 37469 videoId: options.video ? options.video.id : null, 37470 playerVars: { 37471 'autohide': 1, 37472 'autoplay': jQuery(this).hasClass('is-no-control') ? options.autoplay : 0, //options.autoplay, 37473 'disablekb': 1, 37474 'cc_load_policy': options.captions, 37475 'controls': 0, 37476 'enablejsapi': 1, 37477 'fs': 0, 37478 'modestbranding': 1, 37479 'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname), 37480 'iv_load_policy': options.annotations, 37481 'loop': options.loop, 37482 'showinfo': 0, 37483 'rel': 0, 37484 'wmode': 'opaque', 37485 'hd': options.hd, 37486 'mute': 1, 37487 'start': start, 37488 'end': end 37489 }, 37490 events: { 37491 'onReady': OKEvents.yt.ready, 37492 'onStateChange': OKEvents.yt.onStateChange, 37493 'onError': OKEvents.yt.error 37494 } 37495 }); 37496 YTplayers[id] = playerY; 37497 playerY.videoId = id; 37498 } 37499 37500 }); 37501} 37502// vimeo player ready 37503function vimeoPlayerReady(id) { 37504 options = jQuery(window).data('okoptions-' + id); 37505 if ( typeof options === 'undefined' ) { 37506 return true; 37507 }
37508 var jIframe = options.jobject, 37509 iframe = jIframe[0]; 37510 37511 jIframe.attr('src', jIframe.data('src')); 37512 var playerV = new Vimeo.Player(iframe); 37513 // hide player until Vimeo hides controls... 37514 playerV.on('loaded', function(e) { 37515 OKEvents.v.onReady(iframe); 37516 var carouselContainer = jQuery(iframe).closest('.owl-carousel'); 37517 if (carouselContainer.length) { 37518 UNCODE.owlPlayVideo(carouselContainer); 37519 } 37520 // "Do not try to add listeners or call functions before receiving this event." 37521 if (OKEvents.utils.isMobile()) { 37522 // mobile devices cannot listen for play event 37523 OKEvents.v.onPlay(playerV); 37524 } else { 37525 playerV.on('play', function(){ 37526 OKEvents.v.onPlay(playerV); 37527 jQuery(window).trigger('okevents.v.play', [playerV]); 37528 }); 37529 playerV.on('pause', function(){ 37530 OKEvents.v.onPause; 37531 jQuery(window).trigger('okevents.v.pause', [playerV]); 37532 }); 37533 playerV.on('ended', function(){ 37534 OKEvents.v.onFinish 37535 jQuery(window).trigger('okevents.v.ended', [playerV]); 37536 }); 37537 } 37538 if (options.time != null) { 37539 var optsTimeStr = (options.time).replace('t=', ''), 37540 timeV = ''; 37541 37542 if ( /[a-zA-Z]/g.test(optsTimeStr) ) { 37543 var timeArr = optsTimeStr.split(/([^\d.-])/); 37544 for ( var i = 0; i < timeArr.length; i++ ) { 37545 if ( timeArr[i] === 'h' ) { 37546 timeV += parseFloat(timeArr[i-1]) * 3600; 37547 } else if ( timeArr[i] === 'm' ) { 37548 timeV += parseFloat(timeArr[i-1]) * 60; 37549 } else if ( timeArr[i] === 's' ) { 37550 timeV += parseFloat(timeArr[i-1]); 37551 } 37552 } 37553 } else { 37554 timeV = optsTimeStr; 37555 } 37556 37557 playerV.setCurrentTime(timeV); 37558 } 37559 37560 playerV.setVolume(0); 37561 playerV.play(); 37562 jQuery(iframe).css({ 37563 visibility: 'visible', 37564 opacity: 1 37565 }); 37566 jQuery(iframe).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37567 jQuery(iframe).closest('#page-header').addClass('video-started'); 37568 jQuery(iframe).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37569 37570 jQuery(window).trigger('okevents.v.loaded', [playerV]); 37571 }); 37572} 37573OKEvents = { 37574 yt: { 37575 ready: function(event) { 37576 var id = event.target.videoId, 37577 $video = jQuery('#okplayer-' + id), 37578 options = jQuery(window).data('okoptions-' + id); 37579 if ( typeof options === 'undefined' ) { 37580 return true; 37581 } 37582 youtubePlayers[id] = event.target; 37583 event.target.setVolume(options.volume); 37584 if (options.autoplay === 1) { 37585 if (options.playlist.list) { 37586 player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality); 37587 } else { 37588 var inCarousel = $video.closest('.owl-item'); 37589 if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) { 37590 if (options.time != null) { 37591 event.target.seekTo(parseInt(options.time)); 37592 } 37593 event.target.playVideo(); 37594 } else { 37595 event.target.pauseVideo(); 37596 } 37597 } 37598 } 37599 OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target); 37600 37601 $video.closest('[data-provider]').on('uncode-resume', function(){ 37602 if (options.time != null) { 37603 event.target.seekTo(parseInt(options.time)).playVideo(); 37604 } else { 37605 event.target.seekTo(0).playVideo(); 37606 } 37607 }); 37608 37609 $video.closest('[data-provider]').on('uncode-pause', function(){ 37610 if (options.time != null) { 37611 event.target.seekTo(parseInt(options.time)).pauseVideo(); 37612 } else { 37613 event.target.seekTo(0).pauseVideo(); 37614 } 37615 }); 37616 jQuery(window).trigger('okevents.y.loaded', [event]); 37617 }, 37618 onStateChange: function(event) { 37619 var id = event.target.videoId, 37620 $video = jQuery('#okplayer-' + id), 37621 options = jQuery(window).data('okoptions-' + id); 37622 if ( typeof options === 'undefined' ) { 37623 return true; 37624 } 37625 youtubePlayers[id] = event.target; 37626 event.target.setVolume(options.volume); 37627 var $fluid = $video.closest('.fluid-object'), 37628 $tmb = $video.closest('.tmb'), 37629 setTime; 37630 switch (event.data) { 37631 case -1: 37632 OKEvents.utils.isFunction(options.unstarted) && options.unstarted(); 37633 break; 37634 case 0: 37635 OKEvents.utils.isFunction(options.onFinished) && options.onFinished(); 37636 options.loop && event.target.playVideo(); 37637 break; 37638 case 1: 37639 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 37640 setTimeout(function() { 37641 UNCODE.initVideoComponent(document.body, '.uncode-video-container.video:not(.drop-move), .uncode-video-container.self-video:not(.drop-move)'); 37642 jQuery('#okplayer-' + id).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37643 jQuery('#okplayer-' + id).closest('#page-header').addClass('video-started'); 37644 jQuery('#okplayer-' + id).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37645 }, 300); 37646 break; 37647 case 2: 37648 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 37649 break; 37650 case 3: 37651 OKEvents.utils.isFunction(options.buffering) && options.buffering(); 37652 break; 37653 case 5: 37654 OKEvents.utils.isFunction(options.cued) && options.cued(); 37655 break; 37656 default:
37657 throw "OKVideo: received invalid data from YT player."; 37658 } 37659 37660 jQuery(window).trigger('okevents.y.change', [event]); 37661 }, 37662 error: function(event) { 37663 throw event; 37664 } 37665 }, 37666 v: { 37667 onReady: function(target) { 37668 if ( typeof options === 'undefined' ) { 37669 return true; 37670 } 37671 OKEvents.utils.isFunction(options.onReady) && options.onReady(target); 37672 }, 37673 onPlay: function(player) { 37674 if ( typeof options === 'undefined' ) { 37675 return true; 37676 } 37677 if (!OKEvents.utils.isMobile()) player.setVolume(options.volume); 37678 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 37679 jQuery(player.element).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 37680 jQuery(player.element).closest('#page-header').addClass('video-started'); 37681 jQuery(player.element).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 37682 }, 37683 onPause: function() { 37684 if ( typeof options === 'undefined' ) { 37685 return true; 37686 } 37687 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 37688 }, 37689 onFinish: function() { 37690 if ( typeof options === 'undefined' ) { 37691 return true; 37692 } 37693 OKEvents.utils.isFunction(options.onFinish) && options.onFinish(); 37694 } 37695 }, 37696 utils: { 37697 isFunction: function(func) { 37698 if (typeof func === 'function') { 37699 return true; 37700 } else { 37701 return false; 37702 } 37703 }, 37704 isMobile: function() { 37705 if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) { 37706 return true; 37707 } else { 37708 return false; 37709 } 37710 } 37711 } 37712}; 37713 37714/** 37715 * vivus - JavaScript library to make drawing animation on SVG 37716 * @version v0.4.4 37717 * @link https://github.com/maxwellito/vivus 37718 * @license MIT 37719 */ 37720 37721'use strict'; 37722 37723(function () { 37724 37725 'use strict'; 37726 37727/** 37728 * Pathformer 37729 * Beta version 37730 * 37731 * Take any SVG version 1.1 and transform 37732 * child elements to 'path' elements 37733 * 37734 * This code is purely forked from 37735 * https://github.com/Waest/SVGPathConverter 37736 */ 37737 37738/** 37739 * Class constructor 37740 * 37741 * @param {DOM|String} element Dom element of the SVG or id of it 37742 */ 37743function Pathformer(element) { 37744 // Test params 37745 if (typeof element === 'undefined') { 37746 throw new Error('Pathformer [constructor]: "element" parameter is required'); 37747 } 37748 37749 // Set the element 37750 if (element.constructor === String) { 37751 element = document.getElementById(element); 37752 if (!element) { 37753 throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID'); 37754 } 37755 } 37756 if (element instanceof window.SVGElement || 37757 element instanceof window.SVGGElement || 37758 /^svg$/i.test(element.nodeName)) { 37759 this.el = element; 37760 } else { 37761 throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'); 37762 } 37763 37764 // Start 37765 this.scan(element); 37766} 37767 37768/** 37769 * List of tags which can be transformed 37770 * to path elements 37771 * 37772 * @type {Array} 37773 */ 37774Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect']; 37775 37776/** 37777 * List of attribute names which contain 37778 * data. This array list them to check if 37779 * they contain bad values, like percentage. 37780 * 37781 * @type {Array} 37782 */ 37783Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', '
vendor: 24,640 bytes, lines 37783-38581
37783y1', 'y2']; 37784 37785/** 37786 * Finds the elements compatible for transform 37787 * and apply the liked method 37788 * 37789 * @param {object} options Object from the constructor 37790 */ 37791Pathformer.prototype.scan = function (svg) { 37792 var fn, element, pathData, pathDom, 37793 elements = svg.querySelectorAll(this.TYPES.join(',')); 37794 37795 for (var i = 0; i < elements.length; i++) { 37796 element = elements[i]; 37797 fn = this[element.tagName.toLowerCase() + 'ToPath']; 37798 pathData = fn(this.parseAttr(element.attributes)); 37799 pathDom = this.pathMaker(element, pathData); 37800 element.parentNode.replaceChild(pathDom, element); 37801 } 37802}; 37803 37804 37805/** 37806 * Read `line` element to extract and transform 37807 * data, to make it ready for a `path` object. 37808 * 37809 * @param {DOMelement} element Line element to transform 37810 * @return {object} Data for a `path` element 37811 */ 37812Pathformer.prototype.lineToPath = function (element) { 37813 var newElement = {}, 37814 x1 = element.x1 || 0, 37815 y1 = element.y1 || 0, 37816 x2 = element.x2 || 0, 37817 y2 = element.y2 || 0; 37818 37819 newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2; 37820 return newElement; 37821}; 37822 37823/** 37824 * Read `rect` element to extract and transform 37825 * data, to make it ready for a `path` object. 37826 * The radius-border is not taken in charge yet. 37827 * (your help is more than welcomed) 37828 * 37829 * @param {DOMelement} element Rect element to transform 37830 * @return {object} Data for a `path` element 37831 */ 37832Pathformer.prototype.rectToPath = function (element) { 37833 var newElement = {}, 37834 x = parseFloat(element.x) || 0, 37835 y = parseFloat(element.y) || 0, 37836 width = parseFloat(element.width) || 0, 37837 height = parseFloat(element.height) || 0; 37838 37839 if (element.rx || element.ry) { 37840 var rx = parseInt(element.rx, 10) || -1, 37841 ry = parseInt(element.ry, 10) || -1; 37842 rx = Math.min(Math.max(rx < 0 ? ry : rx, 0), width/2); 37843 ry = Math.min(Math.max(ry < 0 ? rx : ry, 0), height/2); 37844 37845 newElement.d = 'M ' + (x + rx) + ',' + y + ' ' + 37846 'L ' + (x + width - rx) + ',' + y + ' ' + 37847 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width) + ',' + (y + ry) + ' ' + 37848 'L ' + (x + width) + ',' + (y + height - ry) + ' ' + 37849 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width - rx) + ',' + (y + height) + ' ' + 37850 'L ' + (x + rx) + ',' + (y + height) + ' ' + 37851 'A ' + rx + ',' + ry + ',0,0,1,' + x + ',' + (y + height - ry) + ' ' + 37852 'L ' + x + ',' + (y + ry) + ' ' + 37853 'A ' + rx + ',' + ry + ',0,0,1,' + (x + rx) + ',' + y; 37854 } 37855 else { 37856 newElement.d = 'M' + x + ' ' + y + ' ' + 37857 'L' + (x + width) + ' ' + y + ' ' + 37858 'L' + (x + width) + ' ' + (y + height) + ' ' + 37859 'L' + x + ' ' + (y + height) + ' Z'; 37860 } 37861 return newElement; 37862}; 37863 37864/** 37865 * Read `polyline` element to extract and transform 37866 * data, to make it ready for a `path` object. 37867 * 37868 * @param {DOMelement} element Polyline element to transform 37869 * @return {object} Data for a `path` element 37870 */ 37871Pathformer.prototype.polylineToPath = function (element) { 37872 var newElement = {}, 37873 points = element.points.trim().split(' '), 37874 i, path; 37875 37876 // Reformatting if points are defined without commas 37877 if (element.points.indexOf(',') === -1) { 37878 var formattedPoints = []; 37879 for (i = 0; i < points.length; i+=2) { 37880 formattedPoints.push(points[i] + ',' + points[i+1]); 37881 } 37882 points = formattedPoints; 37883 } 37884 37885 // Generate the path.d value 37886 path = 'M' + points[0]; 37887 for(i = 1; i < points.length; i++) { 37888 if (points[i].indexOf(',') !== -1) { 37889 path += 'L' + points[i]; 37890 } 37891 } 37892 newElement.d = path; 37893 return newElement; 37894}; 37895 37896/** 37897 * Read `polygon` element to extract and transform 37898 * data, to make it ready for a `path` object. 37899 * This method rely on polylineToPath, because the 37900 * logic is similar. The path created is just closed, 37901 * so it needs an 'Z' at the end. 37902 * 37903 * @param {DOMelement} element Polygon element to transform 37904 * @return {object} Data for a `path` element 37905 */ 37906Pathformer.prototype.polygonToPath = function (element) { 37907 var newElement = Pathformer.prototype.polylineToPath(element); 37908 37909 newElement.d += 'Z'; 37910 return newElement; 37911}; 37912 37913/** 37914 * Read `ellipse` element to extract and transform 37915 * data, to make it ready for a `path` object. 37916 * 37917 * @param {DOMelement} element ellipse element to transform 37918 * @return {object} Data for a `path` element 37919 */ 37920Pathformer.prototype.ellipseToPath = function (element) { 37921 var newElement = {}, 37922 rx = parseFloat(element.rx) || 0, 37923 ry = parseFloat(element.ry) || 0, 37924 cx = parseFloat(element.cx) || 0, 37925 cy = parseFloat(element.cy) || 0, 37926 startX = cx - rx, 37927 startY = cy, 37928 endX = parseFloat(cx) + parseFloat(rx), 37929 endY = cy; 37930 37931 newElement.d = 'M' + startX + ',' + startY + 37932 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY + 37933 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY; 37934 return newElement; 37935}; 37936 37937/** 37938 * Read `circle` element to extract and transform 37939 * data, to make it ready for a `path` object. 37940 * 37941 * @param {DOMelement} element Circle element to transform 37942 * @return {object} Data for a `path` element 37943 */ 37944Pathformer.prototype.circleToPath = function (element) { 37945 var newElement = {}, 37946 r = parseFloat(element.r) || 0, 37947 cx = parseFloat(element.cx) || 0, 37948 cy = parseFloat(element.cy) || 0, 37949 startX = cx - r, 37950 startY = cy, 37951 endX = parseFloat(cx) + parseFloat(r), 37952 endY = cy; 37953 37954 newElement.d = 'M' + startX + ',' + startY + 37955 'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY + 37956 'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY; 37957 return newElement; 37958}; 37959 37960/** 37961 * Create `path` elements form original element 37962 * and prepared objects 37963 * 37964 * @param {DOMelement} element Original element to transform 37965 * @param {object} pathData Path data (from `toPath` methods) 37966 * @return {DOMelement} Path element 37967 */ 37968Pathformer.prototype.pathMaker = function (element, pathData) { 37969 var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path'); 37970 for(i = 0; i < element.attributes.length; i++) { 37971 attr = element.attributes[i]; 37972 if (this.ATTR_WATCH.indexOf(attr.name) === -1) { 37973 pathTag.setAttribute(attr.name, attr.value); 37974 } 37975 } 37976 for(i in pathData) { 37977 pathTag.setAttribute(i, pathData[i]); 37978 } 37979 return pathTag; 37980}; 37981 37982/** 37983 * Parse attributes of a DOM element to 37984 * get an object of attribute => value 37985 * 37986 * @param {NamedNodeMap} attributes Attributes object from DOM element to parse 37987 * @return {object} Object of attributes 37988 */ 37989Pathformer.prototype.parseAttr = function (element) { 37990 var attr, output = {}; 37991 for (var i = 0; i < element.length; i++) { 37992 attr = element[i]; 37993 // Check if no data attribute contains '%', or the transformation is impossible 37994 if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) { 37995 throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.'); 37996 } 37997 output[attr.name] = attr.value; 37998 } 37999 return output; 38000}; 38001 38002 'use strict'; 38003 38004var setupEnv, requestAnimFrame, cancelAnimFrame, parsePositiveInt; 38005 38006/** 38007 * Vivus 38008 * Beta version 38009 * 38010 * Take any SVG and make the animation 38011 * to give give the impression of live drawing 38012 * 38013 * This in more than just inspired from codrops 38014 * At that point, it's a pure fork. 38015 */ 38016 38017/** 38018 * Class constructor 38019 * option structure 38020 * type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed) 38021 * duration: <int> (in frames) 38022 * start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport) 38023 * delay: <int> (delay between the drawing of first and last path) 38024 * dashGap <integer> whitespace extra margin between dashes 38025 * pathTimingFunction <function> timing animation function for each path element of the SVG 38026 * animTimingFunction <function> timing animation function for the complete SVG 38027 * forceRender <boolean> force the browser to re-render all updated path items 38028 * selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original 38029 * 38030 * The attribute 'type' is by default on 'delayed'. 38031 * - 'delayed' 38032 * all paths are draw at the same time but with a 38033 * little delay between them before start 38034 * - 'sync' 38035 * all path are start and finish at the same time 38036 * - 'oneByOne' 38037 * only one path is draw at the time 38038 * the end of the first one will trigger the draw 38039 * of the next one 38040 * 38041 * All these values can be overwritten individually 38042 * for each path item in the SVG 38043 * The value of frames will always take the advantage of 38044 * the duration value. 38045 * If you fail somewhere, an error will be thrown. 38046 * Good luck. 38047 * 38048 * @constructor 38049 * @this {Vivus} 38050 * @param {DOM|String} element Dom element of the SVG or id of it 38051 * @param {Object} options Options about the animation 38052 * @param {Function} callback Callback for the end of the animation 38053 */ 38054function Vivus (element, options, callback) { 38055 38056 setupEnv(); 38057 38058 // Setup 38059 this.isReady = false; 38060 this.setElement(element, options); 38061 this.setOptions(options); 38062 this.setCallback(callback); 38063 38064 if (this.isReady) { 38065 this.init(); 38066 } 38067} 38068 38069/** 38070 * Timing functions 38071 ************************************** 38072 * 38073 * Default functions to help developers. 38074 * It always take a number as parameter (between 0 to 1) then 38075 * return a number (between 0 and 1) 38076 */ 38077Vivus.LINEAR = function (x) {return x;}; 38078Vivus.EASE = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;}; 38079Vivus.EASE_OUT = function (x) {return 1 - Math.pow(1-x, 3);}; 38080Vivus.EASE_IN = function (x) {return Math.pow(x, 3);}; 38081Vivus.EASE_OUT_BOUNCE = function (x) { 38082 var base = -Math.cos(x * (0.5 * Math.PI)) + 1, 38083 rate = Math.pow(base,1.5), 38084 rateR = Math.pow(1 - x, 2), 38085 progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1; 38086 return (1- rateR) + (progress * rateR); 38087}; 38088 38089 38090/** 38091 * Setters 38092 ************************************** 38093 */ 38094 38095/** 38096 * Check and set the element in the instance 38097 * The method will not return anything, but will throw an 38098 * error if the parameter is invalid 38099 * 38100 * @param {DOM|String} element SVG Dom element or id of it 38101 */ 38102Vivus.prototype.setElement = function (element, options) { 38103 var onLoad, self; 38104 38105 // Basic check 38106 if (typeof element === 'undefined') { 38107 throw new Error('Vivus [constructor]: "element" parameter is required'); 38108 } 38109 38110 // Set the element 38111 if (element.constructor === String) { 38112 element = document.getElementById(element); 38113 if (!element) { 38114 throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID'); 38115 } 38116 } 38117 this.parentEl = element; 38118 38119 // Load the SVG with XMLHttpRequest and extract the SVG 38120 if (options && options.file) { 38121 var self = this; 38122 onLoad = function (e) { 38123 var domSandbox = document.createElement('div'); 38124 domSandbox.innerHTML = this.responseText; 38125 38126 var svgTag = domSandbox.querySelector('svg'); 38127 if (!svgTag) { 38128 throw new Error('Vivus [load]: Cannot find the SVG in the loaded file : ' + options.file); 38129 } 38130 38131 self.el = svgTag 38132 self.el.setAttribute('width', '100%'); 38133 self.el.setAttribute('height', '100%'); 38134 self.parentEl.appendChild(self.el) 38135 self.isReady = true; 38136 self.init(); 38137 self = null; 38138 } 38139 38140 var oReq = new window.XMLHttpRequest(); 38141 oReq.addEventListener('load', onLoad); 38142 oReq.open('GET', options.file); 38143 oReq.send(); 38144 return; 38145 } 38146 38147 switch (element.constructor) { 38148 case window.SVGSVGElement: 38149 case window.SVGElement: 38150 case window.SVGGElement: 38151 this.el = element; 38152 this.isReady = true; 38153 break; 38154 38155 case window.HTMLObjectElement: 38156 self = this; 38157 onLoad = function (e) { 38158 if (self.isReady) { 38159 return; 38160 } 38161 self.el = element.contentDocument && element.contentDocument.querySelector('svg'); 38162 if (!self.el && e) { 38163 throw new Error('Vivus [constructor]: object loaded does not contain any SVG'); 38164 } 38165 else if (self.el) { 38166 if (element.getAttribute('built-by-vivus')) { 38167 self.parentEl.insertBefore(self.el, element); 38168 self.parentEl.removeChild(element); 38169 self.el.setAttribute('width', '100%'); 38170 self.el.setAttribute('height', '100%'); 38171 } 38172 self.isReady = true; 38173 self.init(); 38174 self = null; 38175 } 38176 }; 38177 38178 if (!onLoad()) { 38179 element.addEventListener('load', onLoad); 38180 } 38181 break; 38182 38183 default: 38184 throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'); 38185 } 38186}; 38187 38188/** 38189 * Set up user option to the instance 38190 * The method will not return anything, but will throw an 38191 * error if the parameter is invalid 38192 * 38193 * @param {object} options Object from the constructor 38194 */ 38195Vivus.prototype.setOptions = function (options) { 38196 var allowedTypes = ['delayed', 'sync', 'async', 'nsync', 'oneByOne', 'scenario', 'scenario-sync']; 38197 var allowedStarts = ['inViewport', 'manual', 'autostart']; 38198 38199 // Basic check 38200 if (options !== undefined && options.constructor !== Object) { 38201 throw new Error('Vivus [constructor]: "options" parameter must be an object'); 38202 } 38203 else { 38204 options = options || {}; 38205 } 38206 38207 // Set the animation type 38208 if (options.type && allowedTypes.indexOf(options.type) === -1) { 38209 throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`'); 38210 } 38211 else { 38212 this.type = options.type || allowedTypes[0]; 38213 } 38214 38215 // Set the start type 38216 if (options.start && allowedStarts.indexOf(options.start) === -1) { 38217 throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option'); 38218 } 38219 else { 38220 this.start = options.start || allowedStarts[0]; 38221 } 38222 38223 this.isIE = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 ); 38224 this.duration = parsePositiveInt(options.duration, 120); 38225 this.delay = parsePositiveInt(options.delay, null); 38226 //Uncode addition 38227 this.delayStart = parsePositiveInt(options.delayStart, null); 38228 //#END 38229 this.dashGap = parsePositiveInt(options.dashGap, 1); 38230 this.forceRender = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE; 38231 this.reverseStack = !!options.reverseStack; 38232 this.selfDestroy = !!options.selfDestroy; 38233 this.onReady = options.onReady; 38234 this.map = []; 38235 this.frameLength = this.currentFrame = this.delayUnit = this.speed = this.handle = null; 38236 38237 this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false; 38238 38239 this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR; 38240 this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR; 38241 38242 if (this.delay >= this.duration) { 38243 throw new Error('Vivus [constructor]: delay must be shorter than duration'); 38244 } 38245}; 38246 38247/** 38248 * Set up callback to the instance 38249 * The method will not return enything, but will throw an 38250 * error if the parameter is invalid 38251 * 38252 * @param {Function} callback Callback for the animation end 38253 */ 38254Vivus.prototype.setCallback = function (callback) { 38255 // Basic check 38256 if (!!callback && callback.constructor !== Function) { 38257 throw new Error('Vivus [constructor]: "callback" parameter must be a function'); 38258 } 38259 this.callback = callback || function () {}; 38260}; 38261 38262 38263/** 38264 * Core 38265 ************************************** 38266 */ 38267 38268/** 38269 * Map the svg, path by path. 38270 * The method return nothing, it just fill the 38271 * `map` array. Each item in this array represent 38272 * a path element from the SVG, with informations for 38273 * the animation. 38274 * 38275 * ``` 38276 * [ 38277 * { 38278 * el: <DOMobj> the path element 38279 * length: <number> length of the path line 38280 * startAt: <number> time start of the path animation (in frames) 38281 * duration: <number> path animation duration (in frames) 38282 * }, 38283 * ... 38284 * ] 38285 * ``` 38286 * 38287 */ 38288Vivus.prototype.mapping = function () { 38289 var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint; 38290 timePoint = totalLength = lengthMeter = 0; 38291 paths = this.el.querySelectorAll('path'); 38292 38293 for (i = 0; i < paths.length; i++) { 38294 path = paths[i]; 38295 if (this.isInvisible(path)) { 38296 continue; 38297 } 38298 pathObj = { 38299 el: path, 38300 length: Math.ceil(path.getTotalLength()) 38301 }; 38302 // Test if the path length is correct 38303 if (isNaN(pathObj.length)) { 38304 if (window.console && console.warn) { 38305 console.warn('Vivus [mapping]: cannot retrieve a path element length', path); 38306 } 38307 continue; 38308 } 38309 this.map.push(pathObj); 38310 path.style.strokeDasharray = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2); 38311 path.style.strokeDashoffset = pathObj.length + this.dashGap; 38312 pathObj.length += this.dashGap; 38313 totalLength += pathObj.length; 38314 38315 this.renderPath(i); 38316 } 38317 38318 totalLength = totalLength === 0 ? 1 : totalLength; 38319 this.delay = this.delay === null ? this.duration / 3 : this.delay; 38320 this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1); 38321 38322 // Reverse stack if asked 38323 if (this.reverseStack) { 38324 this.map.reverse(); 38325 } 38326 38327 for (i = 0; i < this.map.length; i++) { 38328 pathObj = this.map[i]; 38329 38330 switch (this.type) { 38331 case 'delayed': 38332 pathObj.startAt = this.delayUnit * i; 38333 pathObj.duration = this.duration - this.delay; 38334 break; 38335 38336 case 'oneByOne': 38337 pathObj.startAt = lengthMeter / totalLength * this.duration; 38338 pathObj.duration = pathObj.length / totalLength * this.duration; 38339 break; 38340 38341 case 'sync': 38342 case 'async': 38343 case 'nsync': 38344 pathObj.startAt = 0; 38345 pathObj.duration = this.duration; 38346 break; 38347 38348 case 'scenario-sync': 38349 path = pathObj.el; 38350 pAttrs = this.parseAttr(path); 38351 pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0); 38352 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 38353 timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration; 38354 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 38355 break; 38356 38357 case 'scenario': 38358 path = pathObj.el; 38359 pAttrs = this.parseAttr(path); 38360 pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0; 38361 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 38362 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 38363 break; 38364 } 38365 lengthMeter += pathObj.length; 38366 this.frameLength = this.frameLength || this.duration; 38367 } 38368}; 38369 38370/** 38371 * Interval method to draw the SVG from current 38372 * position of the animation. It update the value of 38373 * `currentFrame` and re-trace the SVG. 38374 * 38375 * It use this.handle to store the requestAnimationFrame 38376 * and clear it one the animation is stopped. So this 38377 * attribute can be used to know if the animation is 38378 * playing. 38379 * 38380 * Once the animation at the end, this method will 38381 * trigger the Vivus callback. 38382 * 38383 */ 38384Vivus.prototype.drawer = function () { 38385 var self = this; 38386 this.currentFrame += this.speed; 38387 38388 if (this.currentFrame <= 0) { 38389 this.stop(); 38390 this.reset(); 38391 } else if (this.currentFrame >= this.frameLength) { 38392 this.stop(); 38393 this.currentFrame = this.frameLength; 38394 this.trace(); 38395 if (this.selfDestroy) { 38396 this.destroy(); 38397 } 38398 } else { 38399 this.trace(); 38400 this.handle = requestAnimFrame(function () { 38401 self.drawer(); 38402 }); 38403 return; 38404 } 38405 38406 this.callback(this); 38407 if (this.instanceCallback) { 38408 this.instanceCallback(this); 38409 this.instanceCallback = null; 38410 } 38411}; 38412 38413/** 38414 * Draw the SVG at the current instant from the 38415 * `currentFrame` value. Here is where most of the magic is. 38416 * The trick is to use the `strokeDashoffset` style property. 38417 * 38418 * For optimisation reasons, a new property called `progress` 38419 * is added in each item of `map`. This one contain the current 38420 * progress of the path element. Only if the new value is different 38421 * the new value will be applied to the DOM element. This 38422 * method save a lot of resources to re-render the SVG. And could 38423 * be improved if the animation couldn't be played forward. 38424 * 38425 */ 38426Vivus.prototype.trace = function () { 38427 var i, progress, path, currentFrame; 38428 currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength; 38429 for (i = 0; i < this.map.length; i++) { 38430 path = this.map[i]; 38431 progress = (currentFrame - path.startAt) / path.duration; 38432 progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress))); 38433 if (path.progress !== progress) { 38434 path.progress = progress; 38435 path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress)); 38436 this.renderPath(i); 38437 } 38438 } 38439}; 38440 38441/** 38442 * Method forcing the browser to re-render a path element 38443 * from it's index in the map. Depending on the `forceRender` 38444 * value. 38445 * The trick is to replace the path element by it's clone. 38446 * This practice is not recommended because it's asking more 38447 * ressources, too much DOM manupulation.. 38448 * but it's the only way to let the magic happen on IE. 38449 * By default, this fallback is only applied on IE. 38450 * 38451 * @param {Number} index Path index 38452 */ 38453Vivus.prototype.renderPath = function (index) { 38454 if (this.forceRender && this.map && this.map[index]) { 38455 var pathObj = this.map[index], 38456 newPath = pathObj.el.cloneNode(true); 38457 pathObj.el.parentNode.replaceChild(newPath, pathObj.el); 38458 pathObj.el = newPath; 38459 } 38460}; 38461 38462/** 38463 * When the SVG object is loaded and ready, 38464 * this method will continue the initialisation. 38465 * 38466 * This this mainly due to the case of passing an 38467 * object tag in the constructor. It will wait 38468 * the end of the loading to initialise. 38469 * 38470 */ 38471Vivus.prototype.init = function () { 38472 // Set object variables 38473 this.frameLength = 0; 38474 this.currentFrame = 0; 38475 this.map = []; 38476 38477 // Start 38478 new Pathformer(this.el); 38479 this.mapping(); 38480 this.starter(); 38481 38482 if (this.onReady) { 38483 this.onReady(this); 38484 } 38485}; 38486 38487/** 38488 * Trigger to start of the animation. 38489 * Depending on the `start` value, a different script 38490 * will be applied. 38491 * 38492 * If the `start` value is not valid, an error will be thrown. 38493 * Even if technically, this is impossible. 38494 * 38495 */ 38496Vivus.prototype.starter = function () { 38497 switch (this.start) { 38498 case 'manual': 38499 return; 38500 38501 case 'autostart': 38502 this.play(); 38503 break; 38504 38505 case 'inViewport': 38506 var self = this, 38507 listener = function () { 38508 if (self.isInViewport(self.parentEl, 1)) { 38509 self.play(); 38510 window.removeEventListener('scroll', listener); 38511 //Uncode addition 38512 window.removeEventListener('fp-slide-changed', listener); 38513 window.removeEventListener('fp-slide-scroll', listener); 38514 //#END 38515 } 38516 }; 38517 window.addEventListener('scroll', listener); 38518 //Uncode addition 38519 window.addEventListener('fp-slide-changed', listener); 38520 window.addEventListener('fp-slide-scroll', listener); 38521 //#END 38522 listener(); 38523 break; 38524 } 38525}; 38526 38527 38528/** 38529 * Controls 38530 ************************************** 38531 */ 38532 38533/** 38534 * Get the current status of the animation between 38535 * three different states: 'start', 'progress', 'end'. 38536 * @return {string} Instance status 38537 */ 38538Vivus.prototype.getStatus = function () { 38539 return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress'; 38540}; 38541 38542/** 38543 * Reset the instance to the initial state : undraw 38544 * Be careful, it just reset the animation, if you're 38545 * playing the animation, this won't stop it. But just 38546 * make it start from start. 38547 * 38548 */ 38549Vivus.prototype.reset = function () { 38550 return this.setFrameProgress(0); 38551}; 38552 38553/** 38554 * Set the instance to the final state : drawn 38555 * Be careful, it just set the animation, if you're 38556 * playing the animation on rewind, this won't stop it. 38557 * But just make it start from the end. 38558 * 38559 */ 38560Vivus.prototype.finish = function () { 38561 return this.setFrameProgress(1); 38562}; 38563 38564/** 38565 * Set the level of progress of the drawing. 38566 * 38567 * @param {number} progress Level of progress to set 38568 */ 38569Vivus.prototype.setFrameProgress = function (progress) { 38570 progress = Math.min(1, Math.max(0, progress)); 38571 this.currentFrame = Math.round(this.frameLength * progress); 38572 this.trace(); 38573 return this; 38574}; 38575 38576/** 38577 * Play the animation at the desired speed. 38578 * Speed must be a valid number (no zero). 38579 * By default, the speed value is 1. 38580 * But a negative value is accepted to go forward. 38581 *
38582 * And works with float too. 38583 * But don't forget we are in JavaScript, se be nice 38584 * with him and give him a 1/2^x value. 38585 * 38586 * @param {number} speed Animation speed [optional] 38587 */ 38588Vivus.prototype.play = function (speed, callback) { 38589 this.instanceCallback = null; 38590 38591 if (speed && typeof speed === 'function') { 38592 this.instanceCallback = speed; // first parameter is actually the callback function 38593 speed = null; 38594 } 38595 else if (speed && typeof speed !== 'number') { 38596 throw new Error('Vivus [play]: invalid speed'); 38597 } 38598 // if the first parameter wasn't the callback, check if the seconds was 38599 if (callback && typeof(callback) === 'function' && !this.instanceCallback) { 38600 this.instanceCallback = callback; 38601 } 38602 38603 38604 this.speed = speed || 1; 38605 //Uncode addition 38606 if (!this.handle) { 38607 var $this = this, 38608 delay = (this.delayStart != null) ? this.delayStart : 0; 38609 setTimeout(function() { 38610 $this.drawer(); 38611 }, delay); 38612 } 38613 //#END 38614 return this; 38615}; 38616 38617/** 38618 * Stop the current animation, if on progress. 38619 * Should not trigger any error. 38620 * 38621 */ 38622Vivus.prototype.stop = function () { 38623 if (this.handle) { 38624 cancelAnimFrame(this.handle); 38625 this.handle = null; 38626 } 38627 return this; 38628}; 38629 38630/** 38631 * Destroy the instance. 38632 * Remove all bad styling attributes on all 38633 * path tags 38634 * 38635 */ 38636Vivus.prototype.destroy = function () { 38637 this.stop(); 38638 var i, path; 38639 for (i = 0; i < this.map.length; i++) { 38640 path = this.map[i]; 38641 path.el.style.strokeDashoffset = null; 38642 path.el.style.strokeDasharray = null; 38643 this.renderPath(i); 38644 } 38645}; 38646 38647 38648/** 38649 * Utils methods 38650 * include methods from Codrops 38651 ************************************** 38652 */ 38653 38654/** 38655 * Method to best guess if a path should added into 38656 * the animation or not. 38657 * 38658 * 1. Use the `data-vivus-ignore` attribute if set 38659 * 2. Check if the instance must ignore invisible paths 38660 * 3. Check if the path is visible 38661 * 38662 * For now the visibility checking is unstable. 38663 * It will be used for a beta phase. 38664 * 38665 * Other improvments are planned. Like detecting 38666 * is the path got a stroke or a valid opacity. 38667 */ 38668Vivus.prototype.isInvisible = function (el) { 38669 var rect, 38670 ignoreAttr = el.getAttribute('data-ignore'); 38671 38672 if (ignoreAttr !== null) { 38673 return ignoreAttr !== 'false'; 38674 } 38675 38676 if (this.ignoreInvisible) { 38677 rect = el.getBoundingClientRect(); 38678 return !rect.width && !rect.height; 38679 } 38680 else { 38681 return false; 38682 } 38683}; 38684 38685/** 38686 * Parse attributes of a DOM element to 38687 * get an object of {attributeName => attributeValue} 38688 * 38689 * @param {object} element DOM element to parse 38690 * @return {object} Object of attributes 38691 */ 38692Vivus.prototype.parseAttr = function (element) { 38693 var attr, output = {}; 38694 if (element && element.attributes) { 38695 for (var i = 0; i < element.attributes.length; i++) { 38696 attr = element.attributes[i]; 38697 output[attr.name] = attr.value; 38698 } 38699 } 38700 return output; 38701}; 38702 38703/** 38704 * Reply if an element is in the page viewport 38705 * 38706 * @param {object} el Element to observe 38707 * @param {number} h Percentage of height 38708 * @return {boolean} 38709 */ 38710Vivus.prototype.isInViewport = function (el, h) { 38711 var scrolled = this.scrollY(), 38712 viewed = scrolled + this.getViewportH(), 38713 elBCR = el.getBoundingClientRect(), 38714 elHeight = elBCR.height, 38715 elTop = scrolled + elBCR.top, 38716 elBottom = elTop + elHeight; 38717 38718 // if 0, the element is considered in the viewport as soon as it enters. 38719 // if 1, the element is considered in the viewport only when it's fully inside 38720 // value in percentage (1 >= h >= 0) 38721 h = h || 0; 38722 38723 return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled; 38724}; 38725 38726 38727/** 38728 * Get the viewport height in pixels 38729 * 38730 * @return {integer} Viewport height 38731 */ 38732Vivus.prototype.getViewportH = function () { 38733 var client = this.docElem.clientHeight, 38734 inner = window.innerHeight; 38735 38736 if (client < inner) { 38737 return inner; 38738 } 38739 else { 38740 return client; 38741 } 38742}; 38743 38744/** 38745 * Get the page Y offset 38746 * 38747 * @return {integer} Page Y offset 38748 */ 38749Vivus.prototype.scrollY = function () { 38750 return window.pageYOffset || this.docElem.scrollTop; 38751}; 38752 38753setupEnv = function () { 38754 38755 if (Vivus.prototype.docElem) { 38756 return; 38757 } 38758 38759 /** 38760 * Alias for document element 38761 * 38762 * @type {DOMelement} 38763 */ 38764 Vivus.prototype.docElem = window.document.documentElement; 38765 38766 /** 38767 * Alias for `requestAnimationFrame` or 38768 * `setTimeout` function for deprecated browsers. 38769 * 38770 */ 38771 requestAnimFrame = (function () { 38772 return ( 38773 window.requestAnimationFrame || 38774 window.webkitRequestAnimationFrame || 38775 window.mozRequestAnimationFrame || 38776 window.oRequestAnimationFrame || 38777 window.msRequestAnimationFrame || 38778 function(/* function */ callback){ 38779 return window.setTimeout(callback, 1000 / 60); 38780 } 38781 ); 38782 })(); 38783 38784 /** 38785 * Alias for `cancelAnimationFrame` or 38786 * `cancelTimeout` function for deprecated browsers. 38787 * 38788 */ 38789 cancelAnimFrame = (function () { 38790 return ( 38791 window.cancelAnimationFrame || 38792 window.webkitCancelAnimationFrame || 38793 window.mozCancelAnimationFrame || 38794 window.oCancelAnimationFrame || 38795 window.msCancelAnimationFrame || 38796 function(id){ 38797 return window.clearTimeout(id); 38798 } 38799 ); 38800 })(); 38801}; 38802 38803/** 38804 * Parse string to integer. 38805 * If the number is not positive or null 38806 * the method will return the default value 38807 * or 0 if undefined 38808 * 38809 * @param {string} value String to parse 38810 * @param {*}
38810 defaultValue Value to return if the result parsed is invalid 38811 * @return {number} 38812 * 38813 */ 38814parsePositiveInt = function (value, defaultValue) { 38815 var output = parseInt(value, 10); 38816 return (output >= 0) ? output : defaultValue; 38817}; 38818 38819 38820 if (typeof define === 'function' && define.amd) { 38821 // AMD. Register as an anonymous module. 38822 define([], function() { 38823 return Vivus; 38824 }); 38825 } else if (typeof exports === 'object') { 38826 // Node. Does not work with strict CommonJS, but 38827 // only CommonJS-like environments that support module.exports, 38828 // like Node. 38829 module.exports = Vivus; 38830 } else { 38831 // Browser globals 38832 window.Vivus = Vivus; 38833 } 38834 38835}()); 38836 38837//Noise.js 38838!function(){"use strict";var r=.5*(Math.sqrt(3)-1),e=(3-Math.sqrt(3))/6,t=1/6,a=(Math.sqrt(5)-1)/4,o=(5-Math.sqrt(5))/20;function i(r){var e;e="function"==typeof r?r:r?function(){var r=0,e=0,t=0,a=1,o=(i=4022871197,function(r){r=r.toString();for(var e=0;e<r.length;e++){var t=.02519603282416938*(i+=r.charCodeAt(e));t-=i=t>>>0,i=(t*=i)>>>0,i+=4294967296*(t-=i)}return 2.3283064365386963e-10*(i>>>0)});var i;r=o(" "),e=o(" "),t=o(" ");for(var n=0;n<arguments.length;n++)(r-=o(arguments[n]))<0&&(r+=1),(e-=o(arguments[n]))<0&&(e+=1),(t-=o(arguments[n]))<0&&(t+=1);return o=null,function(){var o=2091639*r+2.3283064365386963e-10*a;return r=e,e=t,t=o-(a=0|o)}}(r):Math.random,this.p=n(e),this.perm=new Uint8Array(512),this.permMod12=new Uint8Array(512);for(var t=0;t<512;t++)this.perm[t]=this.p[255&t],this.permMod12[t]=this.perm[t]%12}function n(r){var e,t=new Uint8Array(256);for(e=0;e<256;e++)t[e]=e;for(e=0;e<255;e++){var a=e+~~(r()*(256-e)),o=t[e];t[e]=t[a],t[a]=o}return t}i.prototype={grad3:new Float32Array([1,1,0,-1,1,0,1,-1,0,-1,-1,0,1,0,1,-1,0,1,1,0,-1,-1,0,-1,0,1,1,0,-1,1,0,1,-1,0,-1,-1]),grad4:new Float32Array([0,1,1,1,0,1,1,-1,0,1,-1,1,0,1,-1,-1,0,-1,1,1,0,-1,1,-1,0,-1,-1,1,0,-1,-1,-1,1,0,1,1,1,0,1,-1,1,0,-1,1,1,0,-1,-1,-1,0,1,1,-1,0,1,-1,-1,0,-1,1,-1,0,-1,-1,1,1,0,1,1,1,0,-1,1,-1,0,1,1,-1,0,-1,-1,1,0,1,-1,1,0,-1,-1,-1,0,1,-1,-1,0,-1,1,1,1,0,1,1,-1,0,1,-1,1,0,1,-1,-1,0,-1,1,1,0,-1,1,-1,0,-1,-1,1,0,-1,-1,-1,0]),noise2D:function(t,a){var o,i,n=this.permMod12,f=this.perm,s=this.grad3,v=0,h=0,l=0,u=(t+a)*r,d=Math.floor(t+u),p=Math.floor(a+u),M=(d+p)*e,m=t-(d-M),c=a-(p-M);m>c?(o=1,i=0):(o=0,i=1);var y=m-o+e,w=c-i+e,g=m-1+2*e,A=c-1+2*e,x=255&d,q=255&p,D=.5-m*m-c*c;if(D>=0){var S=3*n[x+f[q]];v=(D*=D)*D*(s[S]*m+s[S+1]*c)}var U=.5-y*y-w*w;if(U>=0){var b=3*n[x+o+f[q+i]];h=(U*=U)*U*(s[b]*y+s[b+1]*w)}var F=.5-g*g-A*A;if(F>=0){var N=3*n[x+1+f[q+1]];l=(F*=F)*F*(s[N]*g+s[N+1]*A)}return 70*(v+h+l)},noise3D:function(r,e,a){var o,i,n,f,s,v,h,l,u,d,p=this.permMod12,M=this.perm,m=this.grad3,c=(r+e+a)*(1/3),y=Math.floor(r+c),w=Math.floor(e+c),g=Math.floor(a+c),A=(y+w+g)*t,x=r-(y-A),q=e-(w-A),D=a-(g-A);x>=q?q>=D?(s=1,v=0,h=0,l=1,u=1,d=0):x>=D?(s=1,v=0,h=0,l=1,u=0,d=1):(s=0,v=0,h=1,l=1,u=0,d=1):q<D?(s=0,v=0,h=1,l=0,u=1,d=1):x<D?(s=0,v=1,h=0,l=0,u=1,d=1):(s=0,v=1,h=0,l=1,u=1,d=0);var S=x-s+t,U=q-v+t,b=D-h+t,F=x-l+2*t,N=q-u+2*t,C=D-d+2*t,P=x-1+.5,T=q-1+.5,_=D-1+.5,j=255&y,k=255&w,z=255&g,B=.6-x*x-q*q-D*D;if(B<0)o=0;else{var E=3*p[j+M[k+M[z]]];o=(B*=B)*B*(m[E]*x+m[E+1]*q+m[E+2]*D)}var G=.6-S*S-U*U-b*b;if(G<0)i=0;else{var H=3*p[j+s+M[k+v+M[z+h]]];i=(G*=G)*G*(m[H]*S+m[H+1]*U+m[H+2]*b)}var I=.6-F*F-N*N-C*C;if(I<0)n=0;else{var J=3*p[j+l+M[k+u+M[z+d]]];n=(I*=I)*I*(m[J]*F+m[J+1]*N+m[J+2]*C)}var K=.6-P*P-T*T-_*_;if(K<0)f=0;else{var L=3*p[j+1+M[k+1+M[z+1]]];f=(K*=K)*K*(m[L]*P+m[L+1]*T+m[L+2]*_)}return 32*(o+i+n+f)},noise4D:function(r,e,t,i){var n,f,s,v,h,l,u,d,p,M,m,c,y,w,g,A,x,q=this.perm,D=this.grad4,S=(r+e+t+i)*a,U=Math.floor(r+S),b=Math.floor(e+S),F=Math.floor(t+S),N=Math.floor(i+S),C=(U+b+F+N)*o,P=r-(U-C),T=e-(b-C),_=t-(F-C),j=i-(N-C),k=0,z=0,B=0,E=0;P>T?k++:z++,P>_?k++:B++,P>j?k++:E++,T>_?z++:B++,T>j?z++:E++,_>j?B++:E++;var G=P-(l=k>=3?1:0)+o,H=T-(u=z>=3?1:0)+o,I=_-(d=B>=3?1:0)+o,J=j-(p=E>=3?1:0)+o,K=P-(M=k>=2?1:0)+2*o,L=T-(m=z>=2?1:0)+2*o,O=_-(c=B>=2?1:0)+2*o,Q=j-(y=E>=2?1:0)+2*o,R=P-(w=k>=1?1:0)+3*o,V=T-(g=z>=1?1:0)+3*o,W=_-(A=B>=1?1:0)+3*o,X=j-(x=E>=1?1:0)+3*o,Y=P-1+4*o,Z=T-1+4*o,$=_-1+4*o,rr=j-1+4*o,er=255&U,tr=255&b,ar=255&F,or=255&N,ir=.6-P*P-T*T-_*_-j*j;if(ir<0)n=0;else{var nr=q[er+q[tr+q[ar+q[or]]]]%32*4;n=(ir*=ir)*ir*(D[nr]*P+D[nr+1]*T+D[nr+2]*_+D[nr+3]*j)}var fr=.6-G*G-H*H-I*I-J*J;if(fr<0)f=0;else{var sr=q[er+l+q[tr+u+q[ar+d+q[or+p]]]]%32*4;f=(fr*=fr)*fr*(D[sr]*G+D[sr+1]*H+D[sr+2]*I+D[sr+3]*J)}var vr=.6-K*K-L*L-O*O-Q*Q;if(vr<0)s=0;else{var hr=q[er+M+q[tr+m+q[ar+c+q[or+y]]]]%32*4;s=(vr*=vr)*vr*(D[hr]*K+D[hr+1]*L+D[hr+2]*O+D[hr+3]*Q)}
38838var lr=.6-R*R-V*V-W*W-X*X;if(lr<0)v=0;else{var ur=q[er+w+q[tr+g+q[ar+A+q[or+x]]]]%32*4;v=(lr*=lr)*lr*(D[ur]*R+D[ur+1]*V+D[ur+2]*W+D[ur+3]*X)}var dr=.6-Y*Y-Z*Z-$*$-rr*rr;if(dr<0)h=0;else{var pr=q[er+1+q[tr+1+q[ar+1+q[or+1]]]]%32*4;h=(dr*=dr)*dr*(D[pr]*Y+D[pr+1]*Z+D[pr+2]*$+D[pr+3]*rr)}return 27*(n+f+s+v+h)}},i._buildPermutationTable=n,"undefined"!=typeof define&&define.amd&&define(function(){return i}),"undefined"!=typeof exports?exports.SimplexNoise=i:"undefined"!=typeof window&&(window.SimplexNoise=i),"undefined"!=typeof module&&(module.exports=i)}();
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.