vendor: 4,970 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.12.5 27 * https://gsap.com 28 * 29 * @license Copyright 2008-2024, GreenSock. All rights reserved. 30 * Subject to the terms at https://gsap.com/standard-license or for 31 * Club GSAP 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: 6,338 bytes, lines 162-371
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 && !_reverting && _lazyRender(); 201 animation.render(time, suppressEvents, force || _reverting && time < 0 && (animation._initted || animation._startAt)); 202 _lazyTweens.length && !_reverting && _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.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
vendor: 17,487 bytes, lines 371-839
371); 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._dur && child._initted || child._start < timeline._time && (child._dur || !child.add)) { 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 < l && wrapAt--; 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-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(
vendor: 531 bytes, lines 839-855
839value) { 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
vendor: 14,290 bytes, lines 855-1371
855); 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 }, 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 _registerPluginQueue = [], 970 _createPlugin = function _createPlugin(config) { 971 if (!config) return; 972 config = !config.name && config["default"] || config; 973 974 if (_windowExists() || config.headless) { 975 var name = config.name, 976 isFunc = _isFunction(config), 977 Plugin = name && !isFunc && config.init ? function () { 978 this._props = []; 979 } : config, 980 instanceDefaults = { 981 init: _emptyFunc, 982 render: _renderPropTweens, 983 add: _addPropTween, 984 kill: _killPropTweensOf, 985 modifier: _addPluginModifier, 986 rawVars: 0 987 }, 988 statics = { 989 targetTest: 0, 990 get: 0, 991 getSetter: _getSetter, 992 aliases: {}, 993 register: 0 994 }; 995 996 _wake(); 997 998 if (config !== Plugin) { 999 if (_plugins[name]) { 1000 return; 1001 } 1002 1003 _setDefaults(Plugin, _setDefaults(_copyExcluding(config, instanceDefaults), statics)); 1004 1005 _merge(Plugin.prototype, _merge(instanceDefaults, _copyExcluding(config, statics))); 1006 1007 _plugins[Plugin.prop = name] = Plugin; 1008 1009 if (config.targetTest) { 1010 _harnessPlugins.push(Plugin); 1011 1012 _reservedProps[name] = 1; 1013 } 1014 1015 name = (name === "css" ? "CSS" : name.charAt(0).toUpperCase() + name.substr(1)) + "Plugin"; 1016 } 1017 1018 _addGlobal(name, Plugin); 1019 1020 config.register && config.register(gsap, Plugin, PropTween); 1021 } else { 1022 _registerPluginQueue.push(config); 1023 } 1024 }, 1025 _255 = 255, 1026 _colorLookup = { 1027 aqua: [0, _255, _255], 1028 lime: [0, _255, 0], 1029 silver: [192, 192, 192], 1030 black: [0, 0, 0], 1031 maroon: [128, 0, 0], 1032 teal: [0, 128, 128], 1033 blue: [0, 0, _255], 1034 navy: [0, 0, 128], 1035 white: [_255, _255, _255], 1036 olive: [128, 128, 0], 1037 yellow: [_255, _255, 0], 1038 orange: [_255, 165, 0], 1039 gray: [128, 128, 128], 1040 purple: [128, 0, 128], 1041 green: [0, 128, 0], 1042 red: [_255, 0, 0], 1043 pink: [_255, 192, 203], 1044 cyan: [0, _255, _255], 1045 transparent: [_255, _255, _255, 0] 1046 }, 1047 _hue = function _hue(h, m1, m2) { 1048 h += h < 0 ? 1 : h > 1 ? -1 : 0; 1049 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; 1050 }, 1051 splitColor = function splitColor(v, toHSL, forceAlpha) { 1052 var a = !v ? _colorLookup.black : _isNumber(v) ? [v >> 16, v >> 8 & _255, v & _255] : 0, 1053 r, 1054 g, 1055 b, 1056 h, 1057 s, 1058 l, 1059 max, 1060 min, 1061 d, 1062 wasHSL; 1063 1064 if (!a) { 1065 if (v.substr(-1) === ",") { 1066 v = v.substr(0, v.length - 1); 1067 } 1068 1069 if (_colorLookup[v]) { 1070 a = _colorLookup[v]; 1071 } else if (v.charAt(0) === "#") { 1072 if (v.length < 6) { 1073 r = v.charAt(1); 1074 g = v.charAt(2); 1075 b = v.charAt(3); 1076 v = "#" + r + r + g + g + b + b + (v.length === 5 ? v.charAt(4) + v.charAt(4) : ""); 1077 } 1078 1079 if (v.length === 9) { 1080 a = parseInt(v.substr(1, 6), 16); 1081 return [a >> 16, a >> 8 & _255, a & _255, parseInt(v.substr(7), 16) / 255]; 1082 } 1083 1084 v = parseInt(v.substr(1), 16); 1085 a = [v >> 16, v >> 8 & _255, v & _255]; 1086 } else if (v.substr(0, 3) === "hsl") { 1087 a = wasHSL = v.match(_strictNumExp); 1088 1089 if (!toHSL) { 1090 h = +a[0] % 360 / 360; 1091 s = +a[1] / 100; 1092 l = +a[2] / 100; 1093 g = l <= .5 ? l * (s + 1) : l + s - l * s; 1094 r = l * 2 - g; 1095 a.length > 3 && (a[3] *= 1); 1096 a[0] = _hue(h + 1 / 3, r, g); 1097 a[1] = _hue(h, r, g); 1098 a[2] = _hue(h - 1 / 3, r, g); 1099 } else if (~v.indexOf("=")) { 1100 a = v.match(_numExp); 1101 forceAlpha && a.length < 4 && (a[3] = 1); 1102 return a; 1103 } 1104 } else { 1105 a = v.match(_strictNumExp) || _colorLookup.transparent; 1106 } 1107 1108 a = a.map(Number); 1109 } 1110 1111 if (toHSL && !wasHSL) { 1112 r = a[0] / _255; 1113 g = a[1] / _255; 1114 b = a[2] / _255; 1115 max = Math.max(r, g, b); 1116 min = Math.min(r, g, b); 1117 l = (max + min) / 2; 1118 1119 if (max === min) { 1120 h = s = 0; 1121 } else { 1122 d = max - min; 1123 s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 1124 h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4; 1125 h *= 60; 1126 } 1127 1128 a[0] = ~~(h + .5); 1129 a[1] = ~~(s * 100 + .5); 1130 a[2] = ~~(l * 100 + .5); 1131 } 1132 1133 forceAlpha && a.length < 4 && (a[3] = 1); 1134 return a; 1135 }, 1136 _colorOrderData = function _colorOrderData(v) { 1137 var values = [], 1138 c = [], 1139 i = -1; 1140 v.split(_colorExp).forEach(function (v) { 1141 var a = v.match(_numWithUnitExp) || []; 1142 values.push.apply(values, a); 1143 c.push(i += a.length + 1); 1144 }); 1145 values.c = c; 1146 return values; 1147 }, 1148 _formatColors = function _formatColors(s, toHSL, orderMatchData) { 1149 var result = "", 1150 colors = (s + result).match(_colorExp), 1151 type = toHSL ? "hsla(" : "rgba(", 1152 i = 0, 1153 c, 1154 shell, 1155 d, 1156 l; 1157 1158 if (!colors) { 1159 return s; 1160 } 1161 1162 colors = colors.map(function (color) { 1163 return (color = splitColor(color, toHSL, 1)) && type + (toHSL ? color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : color.join(",")) + ")"; 1164 }); 1165 1166 if (orderMatchData) { 1167 d = _colorOrderData(s); 1168 c = orderMatchData.c; 1169 1170 if (c.join(result) !== d.c.join(result)) { 1171 shell = s.replace(_colorExp, "1").split(_numWithUnitExp); 1172 l = shell.length - 1; 1173 1174 for (; i < l; i++) { 1175 result += shell[i] + (~c.indexOf(i) ? colors.shift() || type + "0,0,0,0)" : (d.length ? d : colors.length ? colors : orderMatchData).shift()); 1176 } 1177 } 1178 } 1179 1180 if (!shell) { 1181 shell = s.split(_colorExp); 1182 l = shell.length - 1; 1183 1184 for (; i < l; i++) { 1185 result += shell[i] + colors[i]; 1186 } 1187 } 1188 1189 return result + shell[l]; 1190 }, 1191 _colorExp = function () { 1192 var s = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3,4}){1,2}\\b", 1193 p; 1194 1195 for (p in _colorLookup) { 1196 s += "|" + p + "\\b"; 1197 } 1198 1199 return new RegExp(s + ")", "gi"); 1200 }(), 1201 _hslExp = /hsl[a]?\(/, 1202 _colorStringFilter = function _colorStringFilter(a) { 1203 var combined = a.join(" "), 1204 toHSL; 1205 _colorExp.lastIndex = 0; 1206 1207 if (_colorExp.test(combined)) { 1208 toHSL = _hslExp.test(combined); 1209 a[1] = _formatColors(a[1], toHSL); 1210 a[0] = _formatColors(a[0], toHSL, _colorOrderData(a[1])); 1211 return true; 1212 } 1213 }, 1214 _tickerActive, 1215 _ticker = function () { 1216 var _getTime = Date.now, 1217 _lagThreshold = 500, 1218 _adjustedLag = 33, 1219 _startTime = _getTime(), 1220 _lastUpdate = _startTime, 1221 _gap = 1000 / 240, 1222 _nextTime = _gap, 1223 _listeners = [], 1224 _id, 1225 _req, 1226 _raf, 1227 _self, 1228 _delta, 1229 _i, 1230 _tick = function _tick(v) { 1231 var elapsed = _getTime() - _lastUpdate, 1232 manual = v === true, 1233 overlap, 1234 dispatch, 1235 time, 1236 frame; 1237 1238 (elapsed > _lagThreshold || elapsed < 0) && (_startTime += elapsed - _adjustedLag); 1239 _lastUpdate += elapsed; 1240 time = _lastUpdate - _startTime; 1241 overlap = time - _nextTime; 1242 1243 if (overlap > 0 || manual) { 1244 frame = ++_self.frame; 1245 _delta = time - _self.time * 1000; 1246 _self.time = time = time / 1000; 1247 _nextTime += overlap + (overlap >= _gap ? 4 : _gap - overlap); 1248 dispatch = 1; 1249 } 1250 1251 manual || (_id = _req(_tick)); 1252 1253 if (dispatch) { 1254 for (_i = 0; _i < _listeners.length; _i++) { 1255 _listeners[_i](time, _delta, frame, v); 1256 } 1257 } 1258 }; 1259 1260 _self = { 1261 time: 0, 1262 frame: 0, 1263 tick: function tick() { 1264 _tick(true); 1265 }, 1266 deltaRatio: function deltaRatio(fps) { 1267 return _delta / (1000 / (fps || 60)); 1268 }, 1269 wake: function wake() { 1270 if (_coreReady) { 1271 if (!_coreInitted && _windowExists()) { 1272 _win = _coreInitted = window; 1273 _doc = _win.document || {}; 1274 _globals.gsap = gsap; 1275 (_win.gsapVersions || (_win.gsapVersions = [])).push(gsap.version); 1276 1277 _install(_installScope || _win.GreenSockGlobals || !_win.gsap && _win || {}); 1278 1279 _registerPluginQueue.forEach(_createPlugin); 1280 } 1281 1282 _raf = typeof requestAnimationFrame !== "undefined" && requestAnimationFrame; 1283 _id && _self.sleep(); 1284 1285 _req = _raf || function (f) { 1286 return setTimeout(f, _nextTime - _self.time * 1000 + 1 | 0); 1287 }; 1288 1289 _tickerActive = 1; 1290 1291 _tick(2); 1292 } 1293 }, 1294 sleep: function sleep() { 1295 (_raf ? cancelAnimationFrame : clearTimeout)(_id); 1296 _tickerActive = 0; 1297 _req = _emptyFunc; 1298 }, 1299 lagSmoothing: function lagSmoothing(threshold, adjustedLag) { 1300 _lagThreshold = threshold || Infinity; 1301 _adjustedLag = Math.min(adjustedLag || 33, _lagThreshold); 1302 }, 1303 fps: function fps(_fps) { 1304 _gap = 1000 / (_fps || 240); 1305 _nextTime = _self.time * 1000 + _gap; 1306 }, 1307 add: function add(callback, once, prioritize) { 1308 var func = once ? function (t, d, f, v) { 1309 callback(t, d, f, v); 1310 1311 _self.remove(func); 1312 } : callback; 1313 1314 _self.remove(callback); 1315 1316 _listeners[prioritize ? "unshift" : "push"](func); 1317 1318 _wake(); 1319 1320 return func; 1321 }, 1322 remove: function remove(callback, i) { 1323 ~(i = _listeners.indexOf(callback)) && _listeners.splice(i, 1) && _i >= i && _i--; 1324 }, 1325 _listeners: _listeners 1326 }; 1327 return _self; 1328 }(), 1329 _wake = function _wake() { 1330 return !_tickerActive && _ticker.wake(); 1331 }, 1332 _easeMap = {}, 1333 _customEaseExp = /^[\d.\-M][\d.\-,\s]/, 1334 _quotesExp = /["']/g, 1335 _parseObjectInString = function _parseObjectInString(value) { 1336 var obj = {}, 1337 split = value.substr(1, value.length - 3).split(":"), 1338 key = split[0], 1339 i = 1, 1340 l = split.length, 1341 index, 1342 val, 1343 parsedVal; 1344 1345 for (; i < l; i++) { 1346 val = split[i]; 1347 index = i !== l - 1 ? val.lastIndexOf(",") : val.length; 1348 parsedVal = val.substr(0, index); 1349 obj[key] = isNaN(parsedVal) ? parsedVal.replace(_quotesExp, "").trim() : +parsedVal; 1350 key = val.substr(index + 1).trim(); 1351 } 1352 1353 return obj; 1354 }, 1355 _valueInParentheses = function _valueInParentheses(value) { 1356 var open = value.indexOf("(") + 1, 1357 close = value.indexOf(")"), 1358 nested = value.indexOf("(", open); 1359 return value.substring(open, ~nested && nested < close ? value.indexOf(")", close + 1) : close); 1360 }, 1361 _configEaseFromString = function _configEaseFromString(name) { 1362 var split = (name + "").split("("), 1363 ease = _easeMap[split[0]]; 1364 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; 1365 }, 1366 _invertEase = function _invertEase(ease) { 1367 return function (p) { 1368 return 1 - ease(1 - p); 1369 }; 1370 }, 1371 _p
1371ropagateYoyoEase = function _propagateYoyoEase(timeline, isYoyo) { 1372 var child = timeline._first, 1373 ease; 1374 1375 while (child) { 1376 if (child instanceof Timeline) { 1377 _propagateYoyoEase(child, isYoyo); 1378 } else if (child.vars.yoyoEase && (!child._yoyo || !child._repeat) && child._yoyo !== isYoyo) { 1379 if (child.timeline) { 1380 _propagateYoyoEase(child.timeline, isYoyo); 1381 } else { 1382 ease = child._ease; 1383 child._ease = child._yEase; 1384 child._yEase = ease; 1385 child._yoyo = isYoyo; 1386 } 1387 } 1388 1389 child = child._next; 1390 }
vendor: 3,445 bytes, lines 1390-1501
1390 1391 }, 1392 _parseEase = function _parseEase(ease, defaultEase) { 1393 return !ease ? defaultEase : (_isFunction(ease) ? ease : _easeMap[ease] || _configEaseFromString(ease)) || defaultEase; 1394 }, 1395 _insertEase = function _insertEase(names, easeIn, easeOut, easeInOut) { 1396 if (easeOut === void 0) { 1397 easeOut = function easeOut(p) { 1398 return 1 - easeIn(1 - p); 1399 }; 1400 } 1401 1402 if (easeInOut === void 0) { 1403 easeInOut = function easeInOut(p) { 1404 return p < .5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2; 1405 }; 1406 } 1407 1408 var ease = { 1409 easeIn: easeIn, 1410 easeOut: easeOut, 1411 easeInOut: easeInOut 1412 }, 1413 lowercaseName; 1414 1415 _forEachName(names, function (name) { 1416 _easeMap[name] = _globals[name] = ease; 1417 _easeMap[lowercaseName = name.toLowerCase()] = easeOut; 1418 1419 for (var p in ease) { 1420 _easeMap[lowercaseName + (p === "easeIn" ? ".in" : p === "easeOut" ? ".out" : ".inOut")] = _easeMap[name + "." + p] = ease[p]; 1421 } 1422 }); 1423 1424 return ease; 1425 }, 1426 _easeInOutFromOut = function _easeInOutFromOut(easeOut) { 1427 return function (p) { 1428 return p < .5 ? (1 - easeOut(1 - p * 2)) / 2 : .5 + easeOut((p - .5) * 2) / 2; 1429 }; 1430 }, 1431 _configElastic = function _configElastic(type, amplitude, period) { 1432 var p1 = amplitude >= 1 ? amplitude : 1, 1433 p2 = (period || (type ? .3 : .45)) / (amplitude < 1 ? amplitude : 1), 1434 p3 = p2 / _2PI * (Math.asin(1 / p1) || 0), 1435 easeOut = function easeOut(p) { 1436 return p === 1 ? 1 : p1 * Math.pow(2, -10 * p) * _sin((p - p3) * p2) + 1; 1437 }, 1438 ease = type === "out" ? easeOut : type === "in" ? function (p) { 1439 return 1 - easeOut(1 - p); 1440 } : _easeInOutFromOut(easeOut); 1441 1442 p2 = _2PI / p2; 1443 1444 ease.config = function (amplitude, period) { 1445 return _configElastic(type, amplitude, period); 1446 }; 1447 1448 return ease; 1449 }, 1450 _configBack = function _configBack(type, overshoot) { 1451 if (overshoot === void 0) { 1452 overshoot = 1.70158; 1453 } 1454 1455 var easeOut = function easeOut(p) { 1456 return p ? --p * p * ((overshoot + 1) * p + overshoot) + 1 : 0; 1457 }, 1458 ease = type === "out" ? easeOut : type === "in" ? function (p) { 1459 return 1 - easeOut(1 - p); 1460 } : _easeInOutFromOut(easeOut); 1461 1462 ease.config = function (overshoot) { 1463 return _configBack(type, overshoot); 1464 }; 1465 1466 return ease; 1467 }; 1468 1469 _forEachName("Linear,Quad,Cubic,Quart,Quint,Strong", function (name, i) { 1470 var power = i < 5 ? i + 1 : i; 1471 1472 _insertEase(name + ",Power" + (power - 1), i ? function (p) { 1473 return Math.pow(p, power); 1474 } : function (p) { 1475 return p; 1476 }, function (p) { 1477 return 1 - Math.pow(1 - p, power); 1478 }, function (p) { 1479 return p < .5 ? Math.pow(p * 2, power) / 2 : 1 - Math.pow((1 - p) * 2, power) / 2; 1480 }); 1481 }); 1482 1483 _easeMap.Linear.easeNone = _easeMap.none = _easeMap.Linear.easeIn; 1484 1485 _insertEase("Elastic", _configElastic("in"), _configElastic("out"), _configElastic()); 1486 1487 (function (n, c) { 1488 var n1 = 1 / c, 1489 n2 = 2 * n1, 1490 n3 = 2.5 * n1, 1491 easeOut = function easeOut(p) { 1492 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; 1493 }; 1494 1495 _insertEase("Bounce", function (p) { 1496 return 1 - easeOut(1 - p); 1497 }, easeOut); 1498 })(7.5625, 2.75); 1499 1500 _insertEase("Expo", function (p) { 1501 return
vendor: 18,509 bytes, lines 1501-2076
1501p ? Math.pow(2, 10 * (p - 1)) : 0; 1502 }); 1503 1504 _insertEase("Circ", function (p) { 1505 return -(_sqrt(1 - p * p) - 1); 1506 }); 1507 1508 _insertEase("Sine", function (p) { 1509 return p === 1 ? 1 : -_cos(p * _HALF_PI) + 1; 1510 }); 1511 1512 _insertEase("Back", _configBack("in"), _configBack("out"), _configBack()); 1513 1514 _easeMap.SteppedEase = _easeMap.steps = _globals.SteppedEase = { 1515 config: function config(steps, immediateStart) { 1516 if (steps === void 0) { 1517 steps = 1; 1518 } 1519 1520 var p1 = 1 / steps, 1521 p2 = steps + (immediateStart ? 0 : 1), 1522 p3 = immediateStart ? 1 : 0, 1523 max = 1 - _tinyNum; 1524 return function (p) { 1525 return ((p2 * _clamp(0, max, p) | 0) + p3) * p1; 1526 }; 1527 } 1528 }; 1529 _defaults.ease = _easeMap["quad.out"]; 1530 1531 _forEachName("onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt", function (name) { 1532 return _callbackNames += name + "," + name + "Params,"; 1533 }); 1534 1535 var GSCache = function GSCache(target, harness) { 1536 this.id = _gsID++; 1537 target._gsap = this; 1538 this.target = target; 1539 this.harness = harness; 1540 this.get = harness ? harness.get : _getProperty; 1541 this.set = harness ? harness.getSetter : _getSetter; 1542 }; 1543 var Animation = function () { 1544 function Animation(vars) { 1545 this.vars = vars; 1546 this._delay = +vars.delay || 0; 1547 1548 if (this._repeat = vars.repeat === Infinity ? -2 : vars.repeat || 0) { 1549 this._rDelay = vars.repeatDelay || 0; 1550 this._yoyo = !!vars.yoyo || !!vars.yoyoEase; 1551 } 1552 1553 this._ts = 1; 1554 1555 _setDuration(this, +vars.duration, 1, 1); 1556 1557 this.data = vars.data; 1558 1559 if (_context) { 1560 this._ctx = _context; 1561 1562 _context.data.push(this); 1563 } 1564 1565 _tickerActive || _ticker.wake(); 1566 } 1567 1568 var _proto = Animation.prototype; 1569 1570 _proto.delay = function delay(value) { 1571 if (value || value === 0) { 1572 this.parent && this.parent.smoothChildTiming && this.startTime(this._start + value - this._delay); 1573 this._delay = value; 1574 return this; 1575 } 1576 1577 return this._delay; 1578 }; 1579 1580 _proto.duration = function duration(value) { 1581 return arguments.length ? this.totalDuration(this._repeat > 0 ? value + (value + this._rDelay) * this._repeat : value) : this.totalDuration() && this._dur; 1582 }; 1583 1584 _proto.totalDuration = function totalDuration(value) { 1585 if (!arguments.length) { 1586 return this._tDur; 1587 } 1588 1589 this._dirty = 0; 1590 return _setDuration(this, this._repeat < 0 ? value : (value - this._repeat * this._rDelay) / (this._repeat + 1)); 1591 }; 1592 1593 _proto.totalTime = function totalTime(_totalTime, suppressEvents) { 1594 _wake(); 1595 1596 if (!arguments.length) { 1597 return this._tTime; 1598 } 1599 1600 var parent = this._dp; 1601 1602 if (parent && parent.smoothChildTiming && this._ts) { 1603 _alignPlayhead(this, _totalTime); 1604 1605 !parent._dp || parent.parent || _postAddChecks(parent, this); 1606 1607 while (parent && parent.parent) { 1608 if (parent.parent._time !== parent._start + (parent._ts >= 0 ? parent._tTime / parent._ts : (parent.totalDuration() - parent._tTime) / -parent._ts)) { 1609 parent.totalTime(parent._tTime, true); 1610 } 1611 1612 parent = parent.parent; 1613 } 1614 1615 if (!this.parent && this._dp.autoRemoveChildren && (this._ts > 0 && _totalTime < this._tDur || this._ts < 0 && _totalTime > 0 || !this._tDur && !_totalTime)) { 1616 _addToTimeline(this._dp, this, this._start - this._delay); 1617 } 1618 } 1619 1620 if (this._tTime !== _totalTime || !this._dur && !suppressEvents || this._initted && Math.abs(this._zTime) === _tinyNum || !_totalTime && !this._initted && (this.add || this._ptLookup)) { 1621 this._ts || (this._pTime = _totalTime); 1622 1623 _lazySafeRender(this, _totalTime, suppressEvents); 1624 } 1625 1626 return this; 1627 }; 1628 1629 _proto.time = function time(value, suppressEvents) { 1630 return arguments.length ? this.totalTime(Math.min(this.totalDuration(), value + _elapsedCycleDuration(this)) % (this._dur + this._rDelay) || (value ? this._dur : 0), suppressEvents) : this._time; 1631 }; 1632 1633 _proto.totalProgress = function totalProgress(value, suppressEvents) { 1634 return arguments.length ? this.totalTime(this.totalDuration() * value, suppressEvents) : this.totalDuration() ? Math.min(1, this._tTime / this._tDur) : this.rawTime() > 0 ? 1 : 0; 1635 }; 1636 1637 _proto.progress = function progress(value, suppressEvents) { 1638 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.rawTime() > 0 ? 1 : 0; 1639 }; 1640 1641 _proto.iteration = function iteration(value, suppressEvents) { 1642 var cycleDuration = this.duration() + this._rDelay; 1643 1644 return arguments.length ? this.totalTime(this._time + (value - 1) * cycleDuration, suppressEvents) : this._repeat ? _animationCycle(this._tTime, cycleDuration) + 1 : 1; 1645 }; 1646 1647 _proto.timeScale = function timeScale(value, suppressEvents) { 1648 if (!arguments.length) { 1649 return this._rts === -_tinyNum ? 0 : this._rts; 1650 } 1651 1652 if (this._rts === value) { 1653 return this; 1654 } 1655 1656 var tTime = this.parent && this._ts ? _parentToChildTotalTime(this.parent._time, this) : this._tTime; 1657 this._rts = +value || 0; 1658 this._ts = this._ps || value === -_tinyNum ? 0 : this._rts; 1659 this.totalTime(_clamp(-Math.abs(this._delay), this._tDur, tTime), suppressEvents !== false); 1660 1661 _setEnd(this); 1662 1663 return _recacheAncestors(this); 1664 }; 1665 1666 _proto.paused = function paused(value) { 1667 if (!arguments.length) { 1668 return this._ps; 1669 } 1670 1671 if (this._ps !== value) { 1672 this._ps = value; 1673 1674 if (value) { 1675 this._pTime = this._tTime || Math.max(-this._delay, this.rawTime()); 1676 this._ts = this._act = 0; 1677 } else { 1678 _wake(); 1679 1680 this._ts = this._rts; 1681 this.totalTime(this.parent && !this.parent.smoothChildTiming ? this.rawTime() : this._tTime || this._pTime, this.progress() === 1 && Math.abs(this._zTime) !== _tinyNum && (this._tTime -= _tinyNum)); 1682 } 1683 } 1684 1685 return this; 1686 }; 1687 1688 _proto.startTime = function startTime(value) { 1689 if (arguments.length) { 1690 this._start = value; 1691 var parent = this.parent || this._dp; 1692 parent && (parent._sort || !this.parent) && _addToTimeline(parent, this, value - this._delay); 1693 return this; 1694 } 1695 1696 return this._start; 1697 }; 1698 1699 _proto.endTime = function endTime(includeRepeats) { 1700 return this._start + (_isNotFalse(includeRepeats) ? this.totalDuration() : this.duration()) / Math.abs(this._ts || 1); 1701 }; 1702 1703 _proto.rawTime = function rawTime(wrapRepeats) { 1704 var parent = this.parent || this._dp; 1705 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); 1706 }; 1707 1708 _proto.revert = function revert(config) { 1709 if (config === void 0) { 1710 config = _revertConfig; 1711 } 1712 1713 var prevIsReverting = _reverting; 1714 _reverting = config; 1715 1716 if (this._initted || this._startAt) { 1717 this.timeline && this.timeline.revert(config); 1718 this.totalTime(-0.01, config.suppressEvents); 1719 } 1720 1721 this.data !== "nested" && config.kill !== false && this.kill(); 1722 _reverting = prevIsReverting; 1723 return this; 1724 }; 1725 1726 _proto.globalTime = function globalTime(rawTime) { 1727 var animation = this, 1728 time = arguments.length ? rawTime : animation.rawTime(); 1729 1730 while (animation) { 1731 time = animation._start + time / (Math.abs(animation._ts) || 1); 1732 animation = animation._dp; 1733 } 1734 1735 return !this.parent && this._sat ? this._sat.globalTime(rawTime) : time; 1736 }; 1737 1738 _proto.repeat = function repeat(value) { 1739 if (arguments.length) { 1740 this._repeat = value === Infinity ? -2 : value; 1741 return _onUpdateTotalDuration(this); 1742 } 1743 1744 return this._repeat === -2 ? Infinity : this._repeat; 1745 }; 1746 1747 _proto.repeatDelay = function repeatDelay(value) { 1748 if (arguments.length) { 1749 var time = this._time; 1750 this._rDelay = value; 1751 1752 _onUpdateTotalDuration(this); 1753 1754 return time ? this.time(time) : this; 1755 } 1756 1757 return this._rDelay; 1758 }; 1759 1760 _proto.yoyo = function yoyo(value) { 1761 if (arguments.length) { 1762 this._yoyo = value; 1763 return this; 1764 } 1765 1766 return this._yoyo; 1767 }; 1768 1769 _proto.seek = function seek(position, suppressEvents) { 1770 return this.totalTime(_parsePosition(this, position), _isNotFalse(suppressEvents)); 1771 }; 1772 1773 _proto.restart = function restart(includeDelay, suppressEvents) { 1774 return this.play().totalTime(includeDelay ? -this._delay : 0, _isNotFalse(suppressEvents)); 1775 }; 1776 1777 _proto.play = function play(from, suppressEvents) { 1778 from != null && this.seek(from, suppressEvents); 1779 return this.reversed(false).paused(false); 1780 }; 1781 1782 _proto.reverse = function reverse(from, suppressEvents) { 1783 from != null && this.seek(from || this.totalDuration(), suppressEvents); 1784 return this.reversed(true).paused(false); 1785 }; 1786 1787 _proto.pause = function pause(atTime, suppressEvents) { 1788 atTime != null && this.seek(atTime, suppressEvents); 1789 return this.paused(true); 1790 }; 1791 1792 _proto.resume = function resume() { 1793 return this.paused(false); 1794 }; 1795 1796 _proto.reversed = function reversed(value) { 1797 if (arguments.length) { 1798 !!value !== this.reversed() && this.timeScale(-this._rts || (value ? -_tinyNum : 0)); 1799 return this; 1800 } 1801 1802 return this._rts < 0; 1803 }; 1804 1805 _proto.invalidate = function invalidate() { 1806 this._initted = this._act = 0; 1807 this._zTime = -_tinyNum; 1808 return this; 1809 }; 1810 1811 _proto.isActive = function isActive() { 1812 var parent = this.parent || this._dp, 1813 start = this._start, 1814 rawTime; 1815 return !!(!parent || this._ts && this._initted && parent.isActive() && (rawTime = parent.rawTime(true)) >= start && rawTime < this.endTime(true) - _tinyNum); 1816 }; 1817 1818 _proto.eventCallback = function eventCallback(type, callback, params) { 1819 var vars = this.vars; 1820 1821 if (arguments.length > 1) { 1822 if (!callback) { 1823 delete vars[type]; 1824 } else { 1825 vars[type] = callback; 1826 params && (vars[type + "Params"] = params); 1827 type === "onUpdate" && (this._onUpdate = callback); 1828 } 1829 1830 return this; 1831 } 1832 1833 return vars[type]; 1834 }; 1835 1836 _proto.then = function then(onFulfilled) { 1837 var self = this; 1838 return new Promise(function (resolve) { 1839 var f = _isFunction(onFulfilled) ? onFulfilled : _passThrough, 1840 _resolve = function _resolve() { 1841 var _then = self.then; 1842 self.then = null; 1843 _isFunction(f) && (f = f(self)) && (f.then || f === self) && (self.then = _then); 1844 resolve(f); 1845 self.then = _then; 1846 }; 1847 1848 if (self._initted && self.totalProgress() === 1 && self._ts >= 0 || !self._tTime && self._ts < 0) { 1849 _resolve(); 1850 } else { 1851 self._prom = _resolve; 1852 } 1853 }); 1854 }; 1855 1856 _proto.kill = function kill() { 1857 _interrupt(this); 1858 }; 1859 1860 return Animation; 1861 }(); 1862 1863 _setDefaults(Animation.prototype, { 1864 _time: 0, 1865 _start: 0, 1866 _end: 0, 1867 _tTime: 0, 1868 _tDur: 0, 1869 _dirty: 0, 1870 _repeat: 0, 1871 _yoyo: false, 1872 parent: null, 1873 _initted: false, 1874 _rDelay: 0, 1875 _ts: 1, 1876 _dp: 0, 1877 ratio: 0, 1878 _zTime: -_tinyNum, 1879 _prom: 0, 1880 _ps: false, 1881 _rts: 1 1882 }); 1883 1884 var Timeline = function (_Animation) { 1885 _inheritsLoose(Timeline, _Animation); 1886 1887 function Timeline(vars, position) { 1888 var _this; 1889 1890 if (vars === void 0) { 1891 vars = {}; 1892 } 1893 1894 _this = _Animation.call(this, vars) || this; 1895 _this.labels = {}; 1896 _this.smoothChildTiming = !!vars.smoothChildTiming; 1897 _this.autoRemoveChildren = !!vars.autoRemoveChildren; 1898 _this._sort = _isNotFalse(vars.sortChildren); 1899 _globalTimeline && _addToTimeline(vars.parent || _globalTimeline, _assertThisInitialized(_this), position); 1900 vars.reversed && _this.reverse(); 1901 vars.paused && _this.paused(true); 1902 vars.scrollTrigger && _scrollTrigger(_assertThisInitialized(_this), vars.scrollTrigger); 1903 return _this; 1904 } 1905 1906 var _proto2 = Timeline.prototype; 1907 1908 _proto2.to = function to(targets, vars, position) { 1909 _createTweenType(0, arguments, this); 1910 1911 return this; 1912 }; 1913 1914 _proto2.from = function from(targets, vars, position) { 1915 _createTweenType(1, arguments, this); 1916 1917 return this; 1918 }; 1919 1920 _proto2.fromTo = function fromTo(targets, fromVars, toVars, position) { 1921 _createTweenType(2, arguments, this); 1922 1923 return this; 1924 }; 1925 1926 _proto2.set = function set(targets, vars, position) { 1927 vars.duration = 0; 1928 vars.parent = this; 1929 _inheritDefaults(vars).repeatDelay || (vars.repeat = 0); 1930 vars.immediateRender = !!vars.immediateRender; 1931 new Tween(targets, vars, _parsePosition(this, position), 1); 1932 return this; 1933 }; 1934 1935 _proto2.call = function call(callback, params, position) { 1936 return _addToTimeline(this, Tween.delayedCall(0, callback, params), position); 1937 }; 1938 1939 _proto2.staggerTo = function staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 1940 vars.duration = duration; 1941 vars.stagger = vars.stagger || stagger; 1942 vars.onComplete = onCompleteAll; 1943 vars.onCompleteParams = onCompleteAllParams; 1944 vars.parent = this; 1945 new Tween(targets, vars, _parsePosition(this, position)); 1946 return this; 1947 }; 1948 1949 _proto2.staggerFrom = function staggerFrom(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 1950 vars.runBackwards = 1; 1951 _inheritDefaults(vars).immediateRender = _isNotFalse(vars.immediateRender); 1952 return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams); 1953 }; 1954 1955 _proto2.staggerFromTo = function staggerFromTo(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams) { 1956 toVars.startAt = fromVars; 1957 _inheritDefaults(toVars).immediateRender = _isNotFalse(toVars.immediateRender); 1958 return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams); 1959 }; 1960 1961 _proto2.render = function render(totalTime, suppressEvents, force) { 1962 var prevTime = this._time, 1963 tDur = this._dirty ? this.totalDuration() : this._tDur, 1964 dur = this._dur, 1965 tTime = totalTime <= 0 ? 0 : _roundPrecise(totalTime), 1966 crossingStart = this._zTime < 0 !== totalTime < 0 && (this._initted || !dur), 1967 time, 1968 child, 1969 next, 1970 iteration, 1971 cycleDuration, 1972 prevPaused, 1973 pauseTween, 1974 timeScale, 1975 prevStart, 1976 prevIteration, 1977 yoyo, 1978 isYoyo; 1979 this !== _globalTimeline && tTime > tDur && totalTime >= 0 && (tTime = tDur); 1980 1981 if (tTime !== this._tTime || force || crossingStart) { 1982 if (prevTime !== this._time && dur) { 1983 tTime += this._time - prevTime; 1984 totalTime += this._time - prevTime; 1985 } 1986 1987 time = tTime; 1988 prevStart = this._start; 1989 timeScale = this._ts; 1990 prevPaused = !timeScale; 1991 1992 if (crossingStart) { 1993 dur || (prevTime = this._zTime); 1994 (totalTime || !suppressEvents) && (this._zTime = totalTime); 1995 } 1996 1997 if (this._repeat) { 1998 yoyo = this._yoyo; 1999 cycleDuration = dur + this._rDelay; 2000 2001 if (this._repeat < -1 && totalTime < 0) { 2002 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 2003 } 2004 2005 time = _roundPrecise(tTime % cycleDuration); 2006 2007 if (tTime === tDur) { 2008 iteration = this._repeat; 2009 time = dur; 2010 } else { 2011 iteration = ~~(tTime / cycleDuration); 2012 2013 if (iteration && iteration === tTime / cycleDuration) { 2014 time = dur; 2015 iteration--; 2016 } 2017 2018 time > dur && (time = dur); 2019 } 2020 2021 prevIteration = _animationCycle(this._tTime, cycleDuration); 2022 !prevTime && this._tTime && prevIteration !== iteration && this._tTime - prevIteration * cycleDuration - this._dur <= 0 && (prevIteration = iteration); 2023 2024 if (yoyo && iteration & 1) { 2025 time = dur - time; 2026 isYoyo = 1; 2027 } 2028 2029 if (iteration !== prevIteration && !this._lock) { 2030 var rewinding = yoyo && prevIteration & 1, 2031 doesWrap = rewinding === (yoyo && iteration & 1); 2032 iteration < prevIteration && (rewinding = !rewinding); 2033 prevTime = rewinding ? 0 : tTime % dur ? dur : tTime; 2034 this._lock = 1; 2035 this.render(prevTime || (isYoyo ? 0 : _roundPrecise(iteration * cycleDuration)), suppressEvents, !dur)._lock = 0; 2036 this._tTime = tTime; 2037 !suppressEvents && this.parent && _callback(this, "onRepeat"); 2038 this.vars.repeatRefresh && !isYoyo && (this.invalidate()._lock = 1); 2039 2040 if (prevTime && prevTime !== this._time || prevPaused !== !this._ts || this.vars.onRepeat && !this.parent && !this._act) { 2041 return this; 2042 } 2043 2044 dur = this._dur; 2045 tDur = this._tDur; 2046 2047 if (doesWrap) { 2048 this._lock = 2; 2049 prevTime = rewinding ? dur : -0.0001; 2050 this.render(prevTime, true); 2051 this.vars.repeatRefresh && !isYoyo && this.invalidate(); 2052 } 2053 2054 this._lock = 0; 2055 2056 if (!this._ts && !prevPaused) { 2057 return this; 2058 } 2059 2060 _propagateYoyoEase(this, isYoyo); 2061 } 2062 } 2063 2064 if (this._hasPause && !this._forcing && this._lock < 2) { 2065 pauseTween = _findNextPauseTween(this, _roundPrecise(prevTime), _roundPrecise(time)); 2066 2067 if (pauseTween) { 2068 tTime -= time - (time = pauseTween._start); 2069 } 2070 } 2071 2072 this._tTime = tTime; 2073 this._time = time; 2074 this._act = !timeScale; 2075 2076 if (!this._initted) {
vendor: 30,026 bytes, lines 2077-3039
2077 this._onUpdate = this.vars.onUpdate; 2078 this._initted = 1; 2079 this._zTime = totalTime; 2080 prevTime = 0; 2081 } 2082 2083 if (!prevTime && time && !suppressEvents && !iteration) { 2084 _callback(this, "onStart"); 2085 2086 if (this._tTime !== tTime) { 2087 return this; 2088 } 2089 } 2090 2091 if (time >= prevTime && totalTime >= 0) { 2092 child = this._first; 2093 2094 while (child) { 2095 next = child._next; 2096 2097 if ((child._act || time >= child._start) && child._ts && pauseTween !== child) { 2098 if (child.parent !== this) { 2099 return this.render(totalTime, suppressEvents, force); 2100 } 2101 2102 child.render(child._ts > 0 ? (time - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (time - child._start) * child._ts, suppressEvents, force); 2103 2104 if (time !== this._time || !this._ts && !prevPaused) { 2105 pauseTween = 0; 2106 next && (tTime += this._zTime = -_tinyNum); 2107 break; 2108 } 2109 } 2110 2111 child = next; 2112 } 2113 } else { 2114 child = this._last; 2115 var adjustedTime = totalTime < 0 ? totalTime : time; 2116 2117 while (child) { 2118 next = child._prev; 2119 2120 if ((child._act || adjustedTime <= child._end) && child._ts && pauseTween !== child) { 2121 if (child.parent !== this) { 2122 return this.render(totalTime, suppressEvents, force); 2123 } 2124 2125 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)); 2126 2127 if (time !== this._time || !this._ts && !prevPaused) { 2128 pauseTween = 0; 2129 next && (tTime += this._zTime = adjustedTime ? -_tinyNum : _tinyNum); 2130 break; 2131 } 2132 } 2133 2134 child = next; 2135 } 2136 } 2137 2138 if (pauseTween && !suppressEvents) { 2139 this.pause(); 2140 pauseTween.render(time >= prevTime ? 0 : -_tinyNum)._zTime = time >= prevTime ? 1 : -1; 2141 2142 if (this._ts) { 2143 this._start = prevStart; 2144 2145 _setEnd(this); 2146 2147 return this.render(totalTime, suppressEvents, force); 2148 } 2149 } 2150 2151 this._onUpdate && !suppressEvents && _callback(this, "onUpdate", true); 2152 if (tTime === tDur && this._tTime >= this.totalDuration() || !tTime && prevTime) if (prevStart === this._start || Math.abs(timeScale) !== Math.abs(this._ts)) if (!this._lock) { 2153 (totalTime || !dur) && (tTime === tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); 2154 2155 if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime || !tDur)) { 2156 _callback(this, tTime === tDur && totalTime >= 0 ? "onComplete" : "onReverseComplete", true); 2157 2158 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 2159 } 2160 } 2161 } 2162 2163 return this; 2164 }; 2165 2166 _proto2.add = function add(child, position) { 2167 var _this2 = this; 2168 2169 _isNumber(position) || (position = _parsePosition(this, position, child)); 2170 2171 if (!(child instanceof Animation)) { 2172 if (_isArray(child)) { 2173 child.forEach(function (obj) { 2174 return _this2.add(obj, position); 2175 }); 2176 return this; 2177 } 2178 2179 if (_isString(child)) { 2180 return this.addLabel(child, position); 2181 } 2182 2183 if (_isFunction(child)) { 2184 child = Tween.delayedCall(0, child); 2185 } else { 2186 return this; 2187 } 2188 } 2189 2190 return this !== child ? _addToTimeline(this, child, position) : this; 2191 }; 2192 2193 _proto2.getChildren = function getChildren(nested, tweens, timelines, ignoreBeforeTime) { 2194 if (nested === void 0) { 2195 nested = true; 2196 } 2197 2198 if (tweens === void 0) { 2199 tweens = true; 2200 } 2201 2202 if (timelines === void 0) { 2203 timelines = true; 2204 } 2205 2206 if (ignoreBeforeTime === void 0) { 2207 ignoreBeforeTime = -_bigNum; 2208 } 2209 2210 var a = [], 2211 child = this._first; 2212 2213 while (child) { 2214 if (child._start >= ignoreBeforeTime) { 2215 if (child instanceof Tween) { 2216 tweens && a.push(child); 2217 } else { 2218 timelines && a.push(child); 2219 nested && a.push.apply(a, child.getChildren(true, tweens, timelines)); 2220 } 2221 } 2222 2223 child = child._next; 2224 } 2225 2226 return a; 2227 }; 2228 2229 _proto2.getById = function getById(id) { 2230 var animations = this.getChildren(1, 1, 1), 2231 i = animations.length; 2232 2233 while (i--) { 2234 if (animations[i].vars.id === id) { 2235 return animations[i]; 2236 } 2237 } 2238 }; 2239 2240 _proto2.remove = function remove(child) { 2241 if (_isString(child)) { 2242 return this.removeLabel(child); 2243 } 2244 2245 if (_isFunction(child)) { 2246 return this.killTweensOf(child); 2247 } 2248 2249 _removeLinkedListItem(this, child); 2250 2251 if (child === this._recent) { 2252 this._recent = this._last; 2253 } 2254 2255 return _uncache(this); 2256 }; 2257 2258 _proto2.totalTime = function totalTime(_totalTime2, suppressEvents) { 2259 if (!arguments.length) { 2260 return this._tTime; 2261 } 2262 2263 this._forcing = 1; 2264 2265 if (!this._dp && this._ts) { 2266 this._start = _roundPrecise(_ticker.time - (this._ts > 0 ? _totalTime2 / this._ts : (this.totalDuration() - _totalTime2) / -this._ts)); 2267 } 2268 2269 _Animation.prototype.totalTime.call(this, _totalTime2, suppressEvents); 2270 2271 this._forcing = 0; 2272 return this; 2273 }; 2274 2275 _proto2.addLabel = function addLabel(label, position) { 2276 this.labels[label] = _parsePosition(this, position); 2277 return this; 2278 }; 2279 2280 _proto2.removeLabel = function removeLabel(label) { 2281 delete this.labels[label]; 2282 return this; 2283 }; 2284 2285 _proto2.addPause = function addPause(position, callback, params) { 2286 var t = Tween.delayedCall(0, callback || _emptyFunc, params); 2287 t.data = "isPause"; 2288 this._hasPause = 1; 2289 return _addToTimeline(this, t, _parsePosition(this, position)); 2290 }; 2291 2292 _proto2.removePause = function removePause(position) { 2293 var child = this._first; 2294 position = _parsePosition(this, position); 2295 2296 while (child) { 2297 if (child._start === position && child.data === "isPause") { 2298 _removeFromParent(child); 2299 } 2300 2301 child = child._next; 2302 } 2303 }; 2304 2305 _proto2.killTweensOf = function killTweensOf(targets, props, onlyActive) { 2306 var tweens = this.getTweensOf(targets, onlyActive), 2307 i = tweens.length; 2308 2309 while (i--) { 2310 _overwritingTween !== tweens[i] && tweens[i].kill(targets, props); 2311 } 2312 2313 return this; 2314 }; 2315 2316 _proto2.getTweensOf = function getTweensOf(targets, onlyActive) { 2317 var a = [], 2318 parsedTargets = toArray(targets), 2319 child = this._first, 2320 isGlobalTime = _isNumber(onlyActive), 2321 children; 2322 2323 while (child) { 2324 if (child instanceof Tween) { 2325 if (_arrayContainsAny(child._targets, parsedTargets) && (isGlobalTime ? (!_overwritingTween || child._initted && child._ts) && child.globalTime(0) <= onlyActive && child.globalTime(child.totalDuration()) > onlyActive : !onlyActive || child.isActive())) { 2326 a.push(child); 2327 } 2328 } else if ((children = child.getTweensOf(parsedTargets, onlyActive)).length) { 2329 a.push.apply(a, children); 2330 } 2331 2332 child = child._next; 2333 } 2334 2335 return a; 2336 }; 2337 2338 _proto2.tweenTo = function tweenTo(position, vars) { 2339 vars = vars || {}; 2340 2341 var tl = this, 2342 endTime = _parsePosition(tl, position), 2343 _vars = vars, 2344 startAt = _vars.startAt, 2345 _onStart = _vars.onStart, 2346 onStartParams = _vars.onStartParams, 2347 immediateRender = _vars.immediateRender, 2348 initted, 2349 tween = Tween.to(tl, _setDefaults({ 2350 ease: vars.ease || "none", 2351 lazy: false, 2352 immediateRender: false, 2353 time: endTime, 2354 overwrite: "auto", 2355 duration: vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()) || _tinyNum, 2356 onStart: function onStart() { 2357 tl.pause(); 2358 2359 if (!initted) { 2360 var duration = vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()); 2361 tween._dur !== duration && _setDuration(tween, duration, 0, 1).render(tween._time, true, true); 2362 initted = 1; 2363 } 2364 2365 _onStart && _onStart.apply(tween, onStartParams || []); 2366 } 2367 }, vars)); 2368 2369 return immediateRender ? tween.render(0) : tween; 2370 }; 2371 2372 _proto2.tweenFromTo = function tweenFromTo(fromPosition, toPosition, vars) { 2373 return this.tweenTo(toPosition, _setDefaults({ 2374 startAt: { 2375 time: _parsePosition(this, fromPosition) 2376 } 2377 }, vars)); 2378 }; 2379 2380 _proto2.recent = function recent() { 2381 return this._recent; 2382 }; 2383 2384 _proto2.nextLabel = function nextLabel(afterTime) { 2385 if (afterTime === void 0) { 2386 afterTime = this._time; 2387 } 2388 2389 return _getLabelInDirection(this, _parsePosition(this, afterTime)); 2390 }; 2391 2392 _proto2.previousLabel = function previousLabel(beforeTime) { 2393 if (beforeTime === void 0) { 2394 beforeTime = this._time; 2395 } 2396 2397 return _getLabelInDirection(this, _parsePosition(this, beforeTime), 1); 2398 }; 2399 2400 _proto2.currentLabel = function currentLabel(value) { 2401 return arguments.length ? this.seek(value, true) : this.previousLabel(this._time + _tinyNum); 2402 }; 2403 2404 _proto2.shiftChildren = function shiftChildren(amount, adjustLabels, ignoreBeforeTime) { 2405 if (ignoreBeforeTime === void 0) { 2406 ignoreBeforeTime = 0; 2407 } 2408 2409 var child = this._first, 2410 labels = this.labels, 2411 p; 2412 2413 while (child) { 2414 if (child._start >= ignoreBeforeTime) { 2415 child._start += amount; 2416 child._end += amount; 2417 } 2418 2419 child = child._next; 2420 } 2421 2422 if (adjustLabels) { 2423 for (p in labels) { 2424 if (labels[p] >= ignoreBeforeTime) { 2425 labels[p] += amount; 2426 } 2427 } 2428 } 2429 2430 return _uncache(this); 2431 }; 2432 2433 _proto2.invalidate = function invalidate(soft) { 2434 var child = this._first; 2435 this._lock = 0; 2436 2437 while (child) { 2438 child.invalidate(soft); 2439 child = child._next; 2440 } 2441 2442 return _Animation.prototype.invalidate.call(this, soft); 2443 }; 2444 2445 _proto2.clear = function clear(includeLabels) { 2446 if (includeLabels === void 0) { 2447 includeLabels = true; 2448 } 2449 2450 var child = this._first, 2451 next; 2452 2453 while (child) { 2454 next = child._next; 2455 this.remove(child); 2456 child = next; 2457 } 2458 2459 this._dp && (this._time = this._tTime = this._pTime = 0); 2460 includeLabels && (this.labels = {}); 2461 return _uncache(this); 2462 }; 2463 2464 _proto2.totalDuration = function totalDuration(value) { 2465 var max = 0, 2466 self = this, 2467 child = self._last, 2468 prevStart = _bigNum, 2469 prev, 2470 start, 2471 parent; 2472 2473 if (arguments.length) { 2474 return self.timeScale((self._repeat < 0 ? self.duration() : self.totalDuration()) / (self.reversed() ? -value : value)); 2475 } 2476 2477 if (self._dirty) { 2478 parent = self.parent; 2479 2480 while (child) { 2481 prev = child._prev; 2482 child._dirty && child.totalDuration(); 2483 start = child._start; 2484 2485 if (start > prevStart && self._sort && child._ts && !self._lock) { 2486 self._lock = 1; 2487 _addToTimeline(self, child, start - child._delay, 1)._lock = 0; 2488 } else { 2489 prevStart = start; 2490 } 2491 2492 if (start < 0 && child._ts) { 2493 max -= start; 2494 2495 if (!parent && !self._dp || parent && parent.smoothChildTiming) { 2496 self._start += start / self._ts; 2497 self._time -= start; 2498 self._tTime -= start; 2499 } 2500 2501 self.shiftChildren(-start, false, -1e999); 2502 prevStart = 0; 2503 } 2504 2505 child._end > max && child._ts && (max = child._end); 2506 child = prev; 2507 } 2508 2509 _setDuration(self, self === _globalTimeline && self._time > max ? self._time : max, 1, 1); 2510 2511 self._dirty = 0; 2512 } 2513 2514 return self._tDur; 2515 }; 2516 2517 Timeline.updateRoot = function updateRoot(time) { 2518 if (_globalTimeline._ts) { 2519 _lazySafeRender(_globalTimeline, _parentToChildTotalTime(time, _globalTimeline)); 2520 2521 _lastRenderedFrame = _ticker.frame; 2522 } 2523 2524 if (_ticker.frame >= _nextGCFrame) { 2525 _nextGCFrame += _config.autoSleep || 120; 2526 var child = _globalTimeline._first; 2527 if (!child || !child._ts) if (_config.autoSleep && _ticker._listeners.length < 2) { 2528 while (child && !child._ts) { 2529 child = child._next; 2530 } 2531 2532 child || _ticker.sleep(); 2533 } 2534 } 2535 }; 2536 2537 return Timeline; 2538 }(Animation); 2539 2540 _setDefaults(Timeline.prototype, { 2541 _lock: 0, 2542 _hasPause: 0, 2543 _forcing: 0 2544 }); 2545 2546 var _addComplexStringPropTween = function _addComplexStringPropTween(target, prop, start, end, setter, stringFilter, funcParam) { 2547 var pt = new PropTween(this._pt, target, prop, 0, 1, _renderComplexString, null, setter), 2548 index = 0, 2549 matchIndex = 0, 2550 result, 2551 startNums, 2552 color, 2553 endNum, 2554 chunk, 2555 startNum, 2556 hasRandom, 2557 a; 2558 pt.b = start; 2559 pt.e = end; 2560 start += ""; 2561 end += ""; 2562 2563 if (hasRandom = ~end.indexOf("random(")) { 2564 end = _replaceRandom(end); 2565 } 2566 2567 if (stringFilter) { 2568 a = [start, end]; 2569 stringFilter(a, target, prop); 2570 start = a[0]; 2571 end = a[1]; 2572 } 2573 2574 startNums = start.match(_complexStringNumExp) || []; 2575 2576 while (result = _complexStringNumExp.exec(end)) { 2577 endNum = result[0]; 2578 chunk = end.substring(index, result.index); 2579 2580 if (color) { 2581 color = (color + 1) % 5; 2582 } else if (chunk.substr(-5) === "rgba(") { 2583 color = 1; 2584 } 2585 2586 if (endNum !== startNums[matchIndex++]) { 2587 startNum = parseFloat(startNums[matchIndex - 1]) || 0; 2588 pt._pt = { 2589 _next: pt._pt, 2590 p: chunk || matchIndex === 1 ? chunk : ",", 2591 s: startNum, 2592 c: endNum.charAt(1) === "=" ? _parseRelative(startNum, endNum) - startNum : parseFloat(endNum) - startNum, 2593 m: color && color < 4 ? Math.round : 0 2594 }; 2595 index = _complexStringNumExp.lastIndex; 2596 } 2597 } 2598 2599 pt.c = index < end.length ? end.substring(index, end.length) : ""; 2600 pt.fp = funcParam; 2601 2602 if (_relExp.test(end) || hasRandom) { 2603 pt.e = 0; 2604 } 2605 2606 this._pt = pt; 2607 return pt; 2608 }, 2609 _addPropTween = function _addPropTween(target, prop, start, end, index, targets, modifier, stringFilter, funcParam, optional) { 2610 _isFunction(end) && (end = end(index || 0, target, targets)); 2611 var currentValue = target[prop], 2612 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](), 2613 setter = !_isFunction(currentValue) ? _setterPlain : funcParam ? _setterFuncWithParam : _setterFunc, 2614 pt; 2615 2616 if (_isString(end)) { 2617 if (~end.indexOf("random(")) { 2618 end = _replaceRandom(end); 2619 } 2620 2621 if (end.charAt(1) === "=") { 2622 pt = _parseRelative(parsedStart, end) + (getUnit(parsedStart) || 0); 2623 2624 if (pt || pt === 0) { 2625 end = pt; 2626 } 2627 } 2628 } 2629 2630 if (!optional || parsedStart !== end || _forceAllPropTweens) { 2631 if (!isNaN(parsedStart * end) && end !== "") { 2632 pt = new PropTween(this._pt, target, prop, +parsedStart || 0, end - (parsedStart || 0), typeof currentValue === "boolean" ? _renderBoolean : _renderPlain, 0, setter); 2633 funcParam && (pt.fp = funcParam); 2634 modifier && pt.modifier(modifier, this, target); 2635 return this._pt = pt; 2636 } 2637 2638 !currentValue && !(prop in target) && _missingPlugin(prop, end); 2639 return _addComplexStringPropTween.call(this, target, prop, parsedStart, end, setter, stringFilter || _config.stringFilter, funcParam); 2640 } 2641 }, 2642 _processVars = function _processVars(vars, index, target, targets, tween) { 2643 _isFunction(vars) && (vars = _parseFuncOrString(vars, tween, index, target, targets)); 2644 2645 if (!_isObject(vars) || vars.style && vars.nodeType || _isArray(vars) || _isTypedArray(vars)) { 2646 return _isString(vars) ? _parseFuncOrString(vars, tween, index, target, targets) : vars; 2647 } 2648 2649 var copy = {}, 2650 p; 2651 2652 for (p in vars) { 2653 copy[p] = _parseFuncOrString(vars[p], tween, index, target, targets); 2654 } 2655 2656 return copy; 2657 }, 2658 _checkPlugin = function _checkPlugin(property, vars, tween, index, target, targets) { 2659 var plugin, pt, ptLookup, i; 2660 2661 if (_plugins[property] && (plugin = new _plugins[property]()).init(target, plugin.rawVars ? vars[property] : _processVars(vars[property], index, target, targets, tween), tween, index, targets) !== false) { 2662 tween._pt = pt = new PropTween(tween._pt, target, property, 0, 1, plugin.render, plugin, 0, plugin.priority); 2663 2664 if (tween !== _quickTween) { 2665 ptLookup = tween._ptLookup[tween._targets.indexOf(target)]; 2666 i = plugin._props.length; 2667 2668 while (i--) { 2669 ptLookup[plugin._props[i]] = pt; 2670 } 2671 } 2672 } 2673 2674 return plugin; 2675 }, 2676 _overwritingTween, 2677 _forceAllPropTweens, 2678 _initTween = function _initTween(tween, time, tTime) { 2679 var vars = tween.vars, 2680 ease = vars.ease, 2681 startAt = vars.startAt, 2682 immediateRender = vars.immediateRender, 2683 lazy = vars.lazy, 2684 onUpdate = vars.onUpdate, 2685 runBackwards = vars.runBackwards, 2686 yoyoEase = vars.yoyoEase, 2687 keyframes = vars.keyframes, 2688 autoRevert = vars.autoRevert, 2689 dur = tween._dur, 2690 prevStartAt = tween._startAt, 2691 targets = tween._targets, 2692 parent = tween.parent, 2693 fullTargets = parent && parent.data === "nested" ? parent.vars.targets : targets, 2694 autoOverwrite = tween._overwrite === "auto" && !_suppressOverwrites, 2695 tl = tween.timeline, 2696 cleanVars, 2697 i, 2698 p, 2699 pt, 2700 target, 2701 hasPriority, 2702 gsData, 2703 harness, 2704 plugin, 2705 ptLookup, 2706 index, 2707 harnessVars, 2708 overwritten; 2709 tl && (!keyframes || !ease) && (ease = "none"); 2710 tween._ease = _parseEase(ease, _defaults.ease); 2711 tween._yEase = yoyoEase ? _invertEase(_parseEase(yoyoEase === true ? ease : yoyoEase, _defaults.ease)) : 0; 2712 2713 if (yoyoEase && tween._yoyo && !tween._repeat) { 2714 yoyoEase = tween._yEase; 2715 tween._yEase = tween._ease; 2716 tween._ease = yoyoEase; 2717 } 2718 2719 tween._from = !tl && !!vars.runBackwards; 2720 2721 if (!tl || keyframes && !vars.stagger) { 2722 harness = targets[0] ? _getCache(targets[0]).harness : 0; 2723 harnessVars = harness && vars[harness.prop]; 2724 cleanVars = _copyExcluding(vars, _reservedProps); 2725 2726 if (prevStartAt) { 2727 prevStartAt._zTime < 0 && prevStartAt.progress(1); 2728 time < 0 && runBackwards && immediateRender && !autoRevert ? prevStartAt.render(-1, true) : prevStartAt.revert(runBackwards && dur ? _revertConfigNoKill : _startAtRevertConfig); 2729 prevStartAt._lazy = 0; 2730 } 2731 2732 if (startAt) { 2733 _removeFromParent(tween._startAt = Tween.set(targets, _setDefaults({ 2734 data: "isStart", 2735 overwrite: false, 2736 parent: parent, 2737 immediateRender: true, 2738 lazy: !prevStartAt && _isNotFalse(lazy), 2739 startAt: null, 2740 delay: 0, 2741 onUpdate: onUpdate && function () { 2742 return _callback(tween, "onUpdate"); 2743 }, 2744 stagger: 0 2745 }, startAt))); 2746 2747 tween._startAt._dp = 0; 2748 tween._startAt._sat = tween; 2749 time < 0 && (_reverting || !immediateRender && !autoRevert) && tween._startAt.revert(_revertConfigNoKill); 2750 2751 if (immediateRender) { 2752 if (dur && time <= 0 && tTime <= 0) { 2753 time && (tween._zTime = time); 2754 return; 2755 } 2756 } 2757 } else if (runBackwards && dur) { 2758 if (!prevStartAt) { 2759 time && (immediateRender = false); 2760 p = _setDefaults({ 2761 overwrite: false, 2762 data: "isFromStart", 2763 lazy: immediateRender && !prevStartAt && _isNotFalse(lazy), 2764 immediateRender: immediateRender, 2765 stagger: 0, 2766 parent: parent 2767 }, cleanVars); 2768 harnessVars && (p[harness.prop] = harnessVars); 2769 2770 _removeFromParent(tween._startAt = Tween.set(targets, p)); 2771 2772 tween._startAt._dp = 0; 2773 tween._startAt._sat = tween; 2774 time < 0 && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween._startAt.render(-1, true)); 2775 tween._zTime = time; 2776 2777 if (!immediateRender) { 2778 _initTween(tween._startAt, _tinyNum, _tinyNum); 2779 } else if (!time) { 2780 return; 2781 } 2782 } 2783 } 2784 2785 tween._pt = tween._ptCache = 0; 2786 lazy = dur && _isNotFalse(lazy) || lazy && !dur; 2787 2788 for (i = 0; i < targets.length; i++) { 2789 target = targets[i]; 2790 gsData = target._gsap || _harness(targets)[i]._gsap; 2791 tween._ptLookup[i] = ptLookup = {}; 2792 _lazyLookup[gsData.id] && _lazyTweens.length && _lazyRender(); 2793 index = fullTargets === targets ? i : fullTargets.indexOf(target); 2794 2795 if (harness && (plugin = new harness()).init(target, harnessVars || cleanVars, tween, index, fullTargets) !== false) { 2796 tween._pt = pt = new PropTween(tween._pt, target, plugin.name, 0, 1, plugin.render, plugin, 0, plugin.priority); 2797 2798 plugin._props.forEach(function (name) { 2799 ptLookup[name] = pt; 2800 }); 2801 2802 plugin.priority && (hasPriority = 1); 2803 } 2804 2805 if (!harness || harnessVars) { 2806 for (p in cleanVars) { 2807 if (_plugins[p] && (plugin = _checkPlugin(p, cleanVars, tween, index, target, fullTargets))) { 2808 plugin.priority && (hasPriority = 1); 2809 } else { 2810 ptLookup[p] = pt = _addPropTween.call(tween, target, p, "get", cleanVars[p], index, fullTargets, 0, vars.stringFilter); 2811 } 2812 } 2813 } 2814 2815 tween._op && tween._op[i] && tween.kill(target, tween._op[i]); 2816 2817 if (autoOverwrite && tween._pt) { 2818 _overwritingTween = tween; 2819 2820 _globalTimeline.killTweensOf(target, ptLookup, tween.globalTime(time)); 2821 2822 overwritten = !tween.parent; 2823 _overwritingTween = 0; 2824 } 2825 2826 tween._pt && lazy && (_lazyLookup[gsData.id] = 1); 2827 } 2828 2829 hasPriority && _sortPropTweensByPriority(tween); 2830 tween._onInit && tween._onInit(tween); 2831 } 2832 2833 tween._onUpdate = onUpdate; 2834 tween._initted = (!tween._op || tween._pt) && !overwritten; 2835 keyframes && time <= 0 && tl.render(_bigNum, true, true); 2836 }, 2837 _updatePropTweens = function _updatePropTweens(tween, property, value, start, startIsRelative, ratio, time, skipRecursion) { 2838 var ptCache = (tween._pt && tween._ptCache || (tween._ptCache = {}))[property], 2839 pt, 2840 rootPT, 2841 lookup, 2842 i; 2843 2844 if (!ptCache) { 2845 ptCache = tween._ptCache[property] = []; 2846 lookup = tween._ptLookup; 2847 i = tween._targets.length; 2848 2849 while (i--) { 2850 pt = lookup[i][property]; 2851 2852 if (pt && pt.d && pt.d._pt) { 2853 pt = pt.d._pt; 2854 2855 while (pt && pt.p !== property && pt.fp !== property) { 2856 pt = pt._next; 2857 } 2858 } 2859 2860 if (!pt) { 2861 _forceAllPropTweens = 1; 2862 tween.vars[property] = "+=0"; 2863 2864 _initTween(tween, time); 2865 2866 _forceAllPropTweens = 0; 2867 return skipRecursion ? _warn(property + " not eligible for reset") : 1; 2868 } 2869 2870 ptCache.push(pt); 2871 } 2872 } 2873 2874 i = ptCache.length; 2875 2876 while (i--) { 2877 rootPT = ptCache[i]; 2878 pt = rootPT._pt || rootPT; 2879 pt.s = (start || start === 0) && !startIsRelative ? start : pt.s + (start || 0) + ratio * pt.c; 2880 pt.c = value - pt.s; 2881 rootPT.e && (rootPT.e = _round(value) + getUnit(rootPT.e)); 2882 rootPT.b && (rootPT.b = pt.s + getUnit(rootPT.b)); 2883 } 2884 }, 2885 _addAliasesToVars = function _addAliasesToVars(targets, vars) { 2886 var harness = targets[0] ? _getCache(targets[0]).harness : 0, 2887 propertyAliases = harness && harness.aliases, 2888 copy, 2889 p, 2890 i, 2891 aliases; 2892 2893 if (!propertyAliases) { 2894 return vars; 2895 } 2896 2897 copy = _merge({}, vars); 2898 2899 for (p in propertyAliases) { 2900 if (p in copy) { 2901 aliases = propertyAliases[p].split(","); 2902 i = aliases.length; 2903 2904 while (i--) { 2905 copy[aliases[i]] = copy[p]; 2906 } 2907 } 2908 } 2909 2910 return copy; 2911 }, 2912 _parseKeyframe = function _parseKeyframe(prop, obj, allProps, easeEach) { 2913 var ease = obj.ease || easeEach || "power1.inOut", 2914 p, 2915 a; 2916 2917 if (_isArray(obj)) { 2918 a = allProps[prop] || (allProps[prop] = []); 2919 obj.forEach(function (value, i) { 2920 return a.push({ 2921 t: i / (obj.length - 1) * 100, 2922 v: value, 2923 e: ease 2924 }); 2925 }); 2926 } else { 2927 for (p in obj) { 2928 a = allProps[p] || (allProps[p] = []); 2929 p === "ease" || a.push({ 2930 t: parseFloat(prop), 2931 v: obj[p], 2932 e: ease 2933 }); 2934 } 2935 } 2936 }, 2937 _parseFuncOrString = function _parseFuncOrString(value, tween, i, target, targets) { 2938 return _isFunction(value) ? value.call(tween, i, target, targets) : _isString(value) && ~value.indexOf("random(") ? _replaceRandom(value) : value; 2939 }, 2940 _staggerTweenProps = _callbackNames + "repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,autoRevert", 2941 _staggerPropsToSkip = {}; 2942 2943 _forEachName(_staggerTweenProps + ",id,stagger,delay,duration,paused,scrollTrigger", function (name) { 2944 return _staggerPropsToSkip[name] = 1; 2945 }); 2946 2947 var Tween = function (_Animation2) { 2948 _inheritsLoose(Tween, _Animation2); 2949 2950 function Tween(targets, vars, position, skipInherit) { 2951 var _this3; 2952 2953 if (typeof vars === "number") { 2954 position.duration = vars; 2955 vars = position; 2956 position = null; 2957 } 2958 2959 _this3 = _Animation2.call(this, skipInherit ? vars : _inheritDefaults(vars)) || this; 2960 var _this3$vars = _this3.vars, 2961 duration = _this3$vars.duration, 2962 delay = _this3$vars.delay, 2963 immediateRender = _this3$vars.immediateRender, 2964 stagger = _this3$vars.stagger, 2965 overwrite = _this3$vars.overwrite, 2966 keyframes = _this3$vars.keyframes, 2967 defaults = _this3$vars.defaults, 2968 scrollTrigger = _this3$vars.scrollTrigger, 2969 yoyoEase = _this3$vars.yoyoEase, 2970 parent = vars.parent || _globalTimeline, 2971 parsedTargets = (_isArray(targets) || _isTypedArray(targets) ? _isNumber(targets[0]) : "length" in vars) ? [targets] : toArray(targets), 2972 tl, 2973 i, 2974 copy, 2975 l, 2976 p, 2977 curTarget, 2978 staggerFunc, 2979 staggerVarsToMerge; 2980 _this3._targets = parsedTargets.length ? _harness(parsedTargets) : _warn("GSAP target " + targets + " not found. https://gsap.com", !_config.nullTargetWarn) || []; 2981 _this3._ptLookup = []; 2982 _this3._overwrite = overwrite; 2983 2984 if (keyframes || stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) { 2985 vars = _this3.vars; 2986 tl = _this3.timeline = new Timeline({ 2987 data: "nested", 2988 defaults: defaults || {}, 2989 targets: parent && parent.data === "nested" ? parent.vars.targets : parsedTargets 2990 }); 2991 tl.kill(); 2992 tl.parent = tl._dp = _assertThisInitialized(_this3); 2993 tl._start = 0; 2994 2995 if (stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) { 2996 l = parsedTargets.length; 2997 staggerFunc = stagger && distribute(stagger); 2998 2999 if (_isObject(stagger)) { 3000 for (p in stagger) { 3001 if (~_staggerTweenProps.indexOf(p)) { 3002 staggerVarsToMerge || (staggerVarsToMerge = {}); 3003 staggerVarsToMerge[p] = stagger[p]; 3004 } 3005 } 3006 } 3007 3008 for (i = 0; i < l; i++) { 3009 copy = _copyExcluding(vars, _staggerPropsToSkip); 3010 copy.stagger = 0; 3011 yoyoEase && (copy.yoyoEase = yoyoEase); 3012 staggerVarsToMerge && _merge(copy, staggerVarsToMerge); 3013 curTarget = parsedTargets[i]; 3014 copy.duration = +_parseFuncOrString(duration, _assertThisInitialized(_this3), i, curTarget, parsedTargets); 3015 copy.delay = (+_parseFuncOrString(delay, _assertThisInitialized(_this3), i, curTarget, parsedTargets) || 0) - _this3._delay; 3016 3017 if (!stagger && l === 1 && copy.delay) { 3018 _this3._delay = delay = copy.delay; 3019 _this3._start += delay; 3020 copy.delay = 0; 3021 } 3022 3023 tl.to(curTarget, copy, staggerFunc ? staggerFunc(i, curTarget, parsedTargets) : 0); 3024 tl._ease = _easeMap.none; 3025 } 3026 3027 tl.duration() ? duration = delay = 0 : _this3.timeline = 0; 3028 } else if (keyframes) { 3029 _inheritDefaults(_setDefaults(tl.vars.defaults, { 3030 ease: "none" 3031 })); 3032 3033 tl._ease = _parseEase(keyframes.ease || vars.ease || "none"); 3034 var time = 0, 3035 a, 3036 kf, 3037 v; 3038 3039 if (_isArray(keyframes)) {
vendor: 6,477 bytes, lines 3040-3246
3040 keyframes.forEach(function (frame) { 3041 return tl.to(parsedTargets, frame, ">"); 3042 }); 3043 tl.duration(); 3044 } else { 3045 copy = {}; 3046 3047 for (p in keyframes) { 3048 p === "ease" || p === "easeEach" || _parseKeyframe(p, keyframes[p], copy, keyframes.easeEach); 3049 } 3050 3051 for (p in copy) { 3052 a = copy[p].sort(function (a, b) { 3053 return a.t - b.t; 3054 }); 3055 time = 0; 3056 3057 for (i = 0; i < a.length; i++) { 3058 kf = a[i]; 3059 v = { 3060 ease: kf.e, 3061 duration: (kf.t - (i ? a[i - 1].t : 0)) / 100 * duration 3062 }; 3063 v[p] = kf.v; 3064 tl.to(parsedTargets, v, time); 3065 time += v.duration; 3066 } 3067 } 3068 3069 tl.duration() < duration && tl.to({}, { 3070 duration: duration - tl.duration() 3071 }); 3072 } 3073 } 3074 3075 duration || _this3.duration(duration = tl.duration()); 3076 } else { 3077 _this3.timeline = 0; 3078 } 3079 3080 if (overwrite === true && !_suppressOverwrites) { 3081 _overwritingTween = _assertThisInitialized(_this3); 3082 3083 _globalTimeline.killTweensOf(parsedTargets); 3084 3085 _overwritingTween = 0; 3086 } 3087 3088 _addToTimeline(parent, _assertThisInitialized(_this3), position); 3089 3090 vars.reversed && _this3.reverse(); 3091 vars.paused && _this3.paused(true); 3092 3093 if (immediateRender || !duration && !keyframes && _this3._start === _roundPrecise(parent._time) && _isNotFalse(immediateRender) && _hasNoPausedAncestors(_assertThisInitialized(_this3)) && parent.data !== "nested") { 3094 _this3._tTime = -_tinyNum; 3095 3096 _this3.render(Math.max(0, -delay) || 0); 3097 } 3098 3099 scrollTrigger && _scrollTrigger(_assertThisInitialized(_this3), scrollTrigger); 3100 return _this3; 3101 } 3102 3103 var _proto3 = Tween.prototype; 3104 3105 _proto3.render = function render(totalTime, suppressEvents, force) { 3106 var prevTime = this._time, 3107 tDur = this._tDur, 3108 dur = this._dur, 3109 isNegative = totalTime < 0, 3110 tTime = totalTime > tDur - _tinyNum && !isNegative ? tDur : totalTime < _tinyNum ? 0 : totalTime, 3111 time, 3112 pt, 3113 iteration, 3114 cycleDuration, 3115 prevIteration, 3116 isYoyo, 3117 ratio, 3118 timeline, 3119 yoyoEase; 3120 3121 if (!dur) { 3122 _renderZeroDurationTween(this, totalTime, suppressEvents, force); 3123 } else if (tTime !== this._tTime || !totalTime || force || !this._initted && this._tTime || this._startAt && this._zTime < 0 !== isNegative) { 3124 time = tTime; 3125 timeline = this.timeline; 3126 3127 if (this._repeat) { 3128 cycleDuration = dur + this._rDelay; 3129 3130 if (this._repeat < -1 && isNegative) { 3131 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 3132 } 3133 3134 time = _roundPrecise(tTime % cycleDuration); 3135 3136 if (tTime === tDur) { 3137 iteration = this._repeat; 3138 time = dur; 3139 } else { 3140 iteration = ~~(tTime / cycleDuration); 3141 3142 if (iteration && iteration === _roundPrecise(tTime / cycleDuration)) { 3143 time = dur; 3144 iteration--; 3145 } 3146 3147 time > dur && (time = dur); 3148 } 3149 3150 isYoyo = this._yoyo && iteration & 1; 3151 3152 if (isYoyo) { 3153 yoyoEase = this._yEase; 3154 time = dur - time; 3155 } 3156 3157 prevIteration = _animationCycle(this._tTime, cycleDuration); 3158 3159 if (time === prevTime && !force && this._initted && iteration === prevIteration) { 3160 this._tTime = tTime; 3161 return this; 3162 } 3163 3164 if (iteration !== prevIteration) { 3165 timeline && this._yEase && _propagateYoyoEase(timeline, isYoyo); 3166 3167 if (this.vars.repeatRefresh && !isYoyo && !this._lock && this._time !== cycleDuration && this._initted) { 3168 this._lock = force = 1; 3169 this.render(_roundPrecise(cycleDuration * iteration), true).invalidate()._lock = 0; 3170 } 3171 } 3172 } 3173 3174 if (!this._initted) { 3175 if (_attemptInitTween(this, isNegative ? totalTime : time, force, suppressEvents, tTime)) { 3176 this._tTime = 0; 3177 return this; 3178 } 3179 3180 if (prevTime !== this._time && !(force && this.vars.repeatRefresh && iteration !== prevIteration)) { 3181 return this; 3182 } 3183 3184 if (dur !== this._dur) { 3185 return this.render(totalTime, suppressEvents, force); 3186 } 3187 } 3188 3189 this._tTime = tTime; 3190 this._time = time; 3191 3192 if (!this._act && this._ts) { 3193 this._act = 1; 3194 this._lazy = 0; 3195 } 3196 3197 this.ratio = ratio = (yoyoEase || this._ease)(time / dur); 3198 3199 if (this._from) { 3200 this.ratio = ratio = 1 - ratio; 3201 } 3202 3203 if (time && !prevTime && !suppressEvents && !iteration) { 3204 _callback(this, "onStart"); 3205 3206 if (this._tTime !== tTime) { 3207 return this; 3208 } 3209 } 3210 3211 pt = this._pt; 3212 3213 while (pt) { 3214 pt.r(ratio, pt.d); 3215 pt = pt._next; 3216 } 3217 3218 timeline && timeline.render(totalTime < 0 ? totalTime : timeline._dur * timeline._ease(time / this._dur), suppressEvents, force) || this._startAt && (this._zTime = totalTime); 3219 3220 if (this._onUpdate && !suppressEvents) { 3221 isNegative && _rewindStartAt(this, totalTime, suppressEvents, force); 3222 3223 _callback(this, "onUpdate"); 3224 } 3225 3226 this._repeat && iteration !== prevIteration && this.vars.onRepeat && !suppressEvents && this.parent && _callback(this, "onRepeat"); 3227 3228 if ((tTime === this._tDur || !tTime) && this._tTime === tTime) { 3229 isNegative && !this._onUpdate && _rewindStartAt(this, totalTime, true, true); 3230 (totalTime || !dur) && (tTime === this._tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); 3231 3232 if (!suppressEvents && !(isNegative && !prevTime) && (tTime || prevTime || isYoyo)) { 3233 _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true); 3234 3235 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 3236 } 3237 } 3238 } 3239 3240 return this; 3241 }; 3242 3243 _proto3.targets = function targets() { 3244 return this._targets; 3245 }; 3246
vendor: 1,310 bytes, lines 3247-3280
3247 _proto3.invalidate = function invalidate(soft) { 3248 (!soft || !this.vars.runBackwards) && (this._startAt = 0); 3249 this._pt = this._op = this._onUpdate = this._lazy = this.ratio = 0; 3250 this._ptLookup = []; 3251 this.timeline && this.timeline.invalidate(soft); 3252 return _Animation2.prototype.invalidate.call(this, soft); 3253 }; 3254 3255 _proto3.resetTo = function resetTo(property, value, start, startIsRelative, skipRecursion) { 3256 _tickerActive || _ticker.wake(); 3257 this._ts || this.play(); 3258 var time = Math.min(this._dur, (this._dp._time - this._start) * this._ts), 3259 ratio; 3260 this._initted || _initTween(this, time); 3261 ratio = this._ease(time / this._dur); 3262 3263 if (_updatePropTweens(this, property, value, start, startIsRelative, ratio, time, skipRecursion)) { 3264 return this.resetTo(property, value, start, startIsRelative, 1); 3265 } 3266 3267 _alignPlayhead(this, 0); 3268 3269 this.parent || _addLinkedListItem(this._dp, this, "_first", "_last", this._dp._sort ? "_start" : 0); 3270 return this.render(0); 3271 }; 3272 3273 _proto3.kill = function kill(targets, vars) { 3274 if (vars === void 0) { 3275 vars = "all"; 3276 } 3277 3278 if (!targets && (!vars || vars === "all")) { 3279 this._lazy = this._pt = 0; 3280 return this.parent ? _interrupt(this) :
vendor: 16,527 bytes, lines 3280-3882
3280 this; 3281 } 3282 3283 if (this.timeline) { 3284 var tDur = this.timeline.totalDuration(); 3285 this.timeline.killTweensOf(targets, vars, _overwritingTween && _overwritingTween.vars.overwrite !== true)._first || _interrupt(this); 3286 this.parent && tDur !== this.timeline.totalDuration() && _setDuration(this, this._dur * this.timeline._tDur / tDur, 0, 1); 3287 return this; 3288 } 3289 3290 var parsedTargets = this._targets, 3291 killingTargets = targets ? toArray(targets) : parsedTargets, 3292 propTweenLookup = this._ptLookup, 3293 firstPT = this._pt, 3294 overwrittenProps, 3295 curLookup, 3296 curOverwriteProps, 3297 props, 3298 p, 3299 pt, 3300 i; 3301 3302 if ((!vars || vars === "all") && _arraysMatch(parsedTargets, killingTargets)) { 3303 vars === "all" && (this._pt = 0); 3304 return _interrupt(this); 3305 } 3306 3307 overwrittenProps = this._op = this._op || []; 3308 3309 if (vars !== "all") { 3310 if (_isString(vars)) { 3311 p = {}; 3312 3313 _forEachName(vars, function (name) { 3314 return p[name] = 1; 3315 }); 3316 3317 vars = p; 3318 } 3319 3320 vars = _addAliasesToVars(parsedTargets, vars); 3321 } 3322 3323 i = parsedTargets.length; 3324 3325 while (i--) { 3326 if (~killingTargets.indexOf(parsedTargets[i])) { 3327 curLookup = propTweenLookup[i]; 3328 3329 if (vars === "all") { 3330 overwrittenProps[i] = vars; 3331 props = curLookup; 3332 curOverwriteProps = {}; 3333 } else { 3334 curOverwriteProps = overwrittenProps[i] = overwrittenProps[i] || {}; 3335 props = vars; 3336 } 3337 3338 for (p in props) { 3339 pt = curLookup && curLookup[p]; 3340 3341 if (pt) { 3342 if (!("kill" in pt.d) || pt.d.kill(p) === true) { 3343 _removeLinkedListItem(this, pt, "_pt"); 3344 } 3345 3346 delete curLookup[p]; 3347 } 3348 3349 if (curOverwriteProps !== "all") { 3350 curOverwriteProps[p] = 1; 3351 } 3352 } 3353 } 3354 } 3355 3356 this._initted && !this._pt && firstPT && _interrupt(this); 3357 return this; 3358 }; 3359 3360 Tween.to = function to(targets, vars) { 3361 return new Tween(targets, vars, arguments[2]); 3362 }; 3363 3364 Tween.from = function from(targets, vars) { 3365 return _createTweenType(1, arguments); 3366 }; 3367 3368 Tween.delayedCall = function delayedCall(delay, callback, params, scope) { 3369 return new Tween(callback, 0, { 3370 immediateRender: false, 3371 lazy: false, 3372 overwrite: false, 3373 delay: delay, 3374 onComplete: callback, 3375 onReverseComplete: callback, 3376 onCompleteParams: params, 3377 onReverseCompleteParams: params, 3378 callbackScope: scope 3379 }); 3380 }; 3381 3382 Tween.fromTo = function fromTo(targets, fromVars, toVars) { 3383 return _createTweenType(2, arguments); 3384 }; 3385 3386 Tween.set = function set(targets, vars) { 3387 vars.duration = 0; 3388 vars.repeatDelay || (vars.repeat = 0); 3389 return new Tween(targets, vars); 3390 }; 3391 3392 Tween.killTweensOf = function killTweensOf(targets, props, onlyActive) { 3393 return _globalTimeline.killTweensOf(targets, props, onlyActive); 3394 }; 3395 3396 return Tween; 3397 }(Animation); 3398 3399 _setDefaults(Tween.prototype, { 3400 _targets: [], 3401 _lazy: 0, 3402 _startAt: 0, 3403 _op: 0, 3404 _onInit: 0 3405 }); 3406 3407 _forEachName("staggerTo,staggerFrom,staggerFromTo", function (name) { 3408 Tween[name] = function () { 3409 var tl = new Timeline(), 3410 params = _slice.call(arguments, 0); 3411 3412 params.splice(name === "staggerFromTo" ? 5 : 4, 0, 0); 3413 return tl[name].apply(tl, params); 3414 }; 3415 }); 3416 3417 var _setterPlain = function _setterPlain(target, property, value) { 3418 return target[property] = value; 3419 }, 3420 _setterFunc = function _setterFunc(target, property, value) { 3421 return target[property](value); 3422 }, 3423 _setterFuncWithParam = function _setterFuncWithParam(target, property, value, data) { 3424 return target[property](data.fp, value); 3425 }, 3426 _setterAttribute = function _setterAttribute(target, property, value) { 3427 return target.setAttribute(property, value); 3428 }, 3429 _getSetter = function _getSetter(target, property) { 3430 return _isFunction(target[property]) ? _setterFunc : _isUndefined(target[property]) && target.setAttribute ? _setterAttribute : _setterPlain; 3431 }, 3432 _renderPlain = function _renderPlain(ratio, data) { 3433 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 1000000) / 1000000, data); 3434 }, 3435 _renderBoolean = function _renderBoolean(ratio, data) { 3436 return data.set(data.t, data.p, !!(data.s + data.c * ratio), data); 3437 }, 3438 _renderComplexString = function _renderComplexString(ratio, data) { 3439 var pt = data._pt, 3440 s = ""; 3441 3442 if (!ratio && data.b) { 3443 s = data.b; 3444 } else if (ratio === 1 && data.e) { 3445 s = data.e; 3446 } else { 3447 while (pt) { 3448 s = pt.p + (pt.m ? pt.m(pt.s + pt.c * ratio) : Math.round((pt.s + pt.c * ratio) * 10000) / 10000) + s; 3449 pt = pt._next; 3450 } 3451 3452 s += data.c; 3453 } 3454 3455 data.set(data.t, data.p, s, data); 3456 }, 3457 _renderPropTweens = function _renderPropTweens(ratio, data) { 3458 var pt = data._pt; 3459 3460 while (pt) { 3461 pt.r(ratio, pt.d); 3462 pt = pt._next; 3463 } 3464 }, 3465 _addPluginModifier = function _addPluginModifier(modifier, tween, target, property) { 3466 var pt = this._pt, 3467 next; 3468 3469 while (pt) { 3470 next = pt._next; 3471 pt.p === property && pt.modifier(modifier, tween, target); 3472 pt = next; 3473 } 3474 }, 3475 _killPropTweensOf = function _killPropTweensOf(property) { 3476 var pt = this._pt, 3477 hasNonDependentRemaining, 3478 next; 3479 3480 while (pt) { 3481 next = pt._next; 3482 3483 if (pt.p === property && !pt.op || pt.op === property) { 3484 _removeLinkedListItem(this, pt, "_pt"); 3485 } else if (!pt.dep) { 3486 hasNonDependentRemaining = 1; 3487 } 3488 3489 pt = next; 3490 } 3491 3492 return !hasNonDependentRemaining; 3493 }, 3494 _setterWithModifier = function _setterWithModifier(target, property, value, data) { 3495 data.mSet(target, property, data.m.call(data.tween, value, data.mt), data); 3496 }, 3497 _sortPropTweensByPriority = function _sortPropTweensByPriority(parent) { 3498 var pt = parent._pt, 3499 next, 3500 pt2, 3501 first, 3502 last; 3503 3504 while (pt) { 3505 next = pt._next; 3506 pt2 = first; 3507 3508 while (pt2 && pt2.pr > pt.pr) { 3509 pt2 = pt2._next; 3510 } 3511 3512 if (pt._prev = pt2 ? pt2._prev : last) { 3513 pt._prev._next = pt; 3514 } else { 3515 first = pt; 3516 } 3517 3518 if (pt._next = pt2) { 3519 pt2._prev = pt; 3520 } else { 3521 last = pt; 3522 } 3523 3524 pt = next; 3525 } 3526 3527 parent._pt = first; 3528 }; 3529 3530 var PropTween = function () { 3531 function PropTween(next, target, prop, start, change, renderer, data, setter, priority) { 3532 this.t = target; 3533 this.s = start; 3534 this.c = change; 3535 this.p = prop; 3536 this.r = renderer || _renderPlain; 3537 this.d = data || this; 3538 this.set = setter || _setterPlain; 3539 this.pr = priority || 0; 3540 this._next = next; 3541 3542 if (next) { 3543 next._prev = this; 3544 } 3545 } 3546 3547 var _proto4 = PropTween.prototype; 3548 3549 _proto4.modifier = function modifier(func, tween, target) { 3550 this.mSet = this.mSet || this.set; 3551 this.set = _setterWithModifier; 3552 this.m = func; 3553 this.mt = target; 3554 this.tween = tween; 3555 }; 3556 3557 return PropTween; 3558 }(); 3559 3560 _forEachName(_callbackNames + "parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger", function (name) { 3561 return _reservedProps[name] = 1; 3562 }); 3563 3564 _globals.TweenMax = _globals.TweenLite = Tween; 3565 _globals.TimelineLite = _globals.TimelineMax = Timeline; 3566 _globalTimeline = new Timeline({ 3567 sortChildren: false, 3568 defaults: _defaults, 3569 autoRemoveChildren: true, 3570 id: "root", 3571 smoothChildTiming: true 3572 }); 3573 _config.stringFilter = _colorStringFilter; 3574 3575 var _media = [], 3576 _listeners = {}, 3577 _emptyArray = [], 3578 _lastMediaTime = 0, 3579 _contextID = 0, 3580 _dispatch = function _dispatch(type) { 3581 return (_listeners[type] || _emptyArray).map(function (f) { 3582 return f(); 3583 }); 3584 }, 3585 _onMediaChange = function _onMediaChange() { 3586 var time = Date.now(), 3587 matches = []; 3588 3589 if (time - _lastMediaTime > 2) { 3590 _dispatch("matchMediaInit"); 3591 3592 _media.forEach(function (c) { 3593 var queries = c.queries, 3594 conditions = c.conditions, 3595 match, 3596 p, 3597 anyMatch, 3598 toggled; 3599 3600 for (p in queries) { 3601 match = _win.matchMedia(queries[p]).matches; 3602 match && (anyMatch = 1); 3603 3604 if (match !== conditions[p]) { 3605 conditions[p] = match; 3606 toggled = 1; 3607 } 3608 } 3609 3610 if (toggled) { 3611 c.revert(); 3612 anyMatch && matches.push(c); 3613 } 3614 }); 3615 3616 _dispatch("matchMediaRevert"); 3617 3618 matches.forEach(function (c) { 3619 return c.onMatch(c, function (func) { 3620 return c.add(null, func); 3621 }); 3622 }); 3623 _lastMediaTime = time; 3624 3625 _dispatch("matchMedia"); 3626 } 3627 }; 3628 3629 var Context = function () { 3630 function Context(func, scope) { 3631 this.selector = scope && selector(scope); 3632 this.data = []; 3633 this._r = []; 3634 this.isReverted = false; 3635 this.id = _contextID++; 3636 func && this.add(func); 3637 } 3638 3639 var _proto5 = Context.prototype; 3640 3641 _proto5.add = function add(name, func, scope) { 3642 if (_isFunction(name)) { 3643 scope = func; 3644 func = name; 3645 name = _isFunction; 3646 } 3647 3648 var self = this, 3649 f = function f() { 3650 var prev = _context, 3651 prevSelector = self.selector, 3652 result; 3653 prev && prev !== self && prev.data.push(self); 3654 scope && (self.selector = selector(scope)); 3655 _context = self; 3656 result = func.apply(self, arguments); 3657 _isFunction(result) && self._r.push(result); 3658 _context = prev; 3659 self.selector = prevSelector; 3660 self.isReverted = false; 3661 return result; 3662 }; 3663 3664 self.last = f; 3665 return name === _isFunction ? f(self, function (func) { 3666 return self.add(null, func); 3667 }) : name ? self[name] = f : f; 3668 }; 3669 3670 _proto5.ignore = function ignore(func) { 3671 var prev = _context; 3672 _context = null; 3673 func(this); 3674 _context = prev; 3675 }; 3676 3677 _proto5.getTweens = function getTweens() { 3678 var a = []; 3679 this.data.forEach(function (e) { 3680 return e instanceof Context ? a.push.apply(a, e.getTweens()) : e instanceof Tween && !(e.parent && e.parent.data === "nested") && a.push(e); 3681 }); 3682 return a; 3683 }; 3684 3685 _proto5.clear = function clear() { 3686 this._r.length = this.data.length = 0; 3687 }; 3688 3689 _proto5.kill = function kill(revert, matchMedia) { 3690 var _this4 = this; 3691 3692 if (revert) { 3693 (function () { 3694 var tweens = _this4.getTweens(), 3695 i = _this4.data.length, 3696 t; 3697 3698 while (i--) { 3699 t = _this4.data[i]; 3700 3701 if (t.data === "isFlip") { 3702 t.revert(); 3703 t.getChildren(true, true, false).forEach(function (tween) { 3704 return tweens.splice(tweens.indexOf(tween), 1); 3705 }); 3706 } 3707 } 3708 3709 tweens.map(function (t) { 3710 return { 3711 g: t._dur || t._delay || t._sat && !t._sat.vars.immediateRender ? t.globalTime(0) : -Infinity, 3712 t: t 3713 }; 3714 }).sort(function (a, b) { 3715 return b.g - a.g || -Infinity; 3716 }).forEach(function (o) { 3717 return o.t.revert(revert); 3718 }); 3719 i = _this4.data.length; 3720 3721 while (i--) { 3722 t = _this4.data[i]; 3723 3724 if (t instanceof Timeline) { 3725 if (t.data !== "nested") { 3726 t.scrollTrigger && t.scrollTrigger.revert(); 3727 t.kill(); 3728 } 3729 } else { 3730 !(t instanceof Tween) && t.revert && t.revert(revert); 3731 } 3732 } 3733 3734 _this4._r.forEach(function (f) { 3735 return f(revert, _this4); 3736 }); 3737 3738 _this4.isReverted = true; 3739 })(); 3740 } else { 3741 this.data.forEach(function (e) { 3742 return e.kill && e.kill(); 3743 }); 3744 } 3745 3746 this.clear(); 3747 3748 if (matchMedia) { 3749 var i = _media.length; 3750 3751 while (i--) { 3752 _media[i].id === this.id && _media.splice(i, 1); 3753 } 3754 } 3755 }; 3756 3757 _proto5.revert = function revert(config) { 3758 this.kill(config || {}); 3759 }; 3760 3761 return Context; 3762 }(); 3763 3764 var MatchMedia = function () { 3765 function MatchMedia(scope) { 3766 this.contexts = []; 3767 this.scope = scope; 3768 _context && _context.data.push(this); 3769 } 3770 3771 var _proto6 = MatchMedia.prototype; 3772 3773 _proto6.add = function add(conditions, func, scope) { 3774 _isObject(conditions) || (conditions = { 3775 matches: conditions 3776 }); 3777 var context = new Context(0, scope || this.scope), 3778 cond = context.conditions = {}, 3779 mq, 3780 p, 3781 active; 3782 _context && !context.selector && (context.selector = _context.selector); 3783 this.contexts.push(context); 3784 func = context.add("onMatch", func); 3785 context.queries = conditions; 3786 3787 for (p in conditions) { 3788 if (p === "all") { 3789 active = 1; 3790 } else { 3791 mq = _win.matchMedia(conditions[p]); 3792 3793 if (mq) { 3794 _media.indexOf(context) < 0 && _media.push(context); 3795 (cond[p] = mq.matches) && (active = 1); 3796 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 3797 } 3798 } 3799 } 3800 3801 active && func(context, function (f) { 3802 return context.add(null, f); 3803 }); 3804 return this; 3805 }; 3806 3807 _proto6.revert = function revert(config) { 3808 this.kill(config || {}); 3809 }; 3810 3811 _proto6.kill = function kill(revert) { 3812 this.contexts.forEach(function (c) { 3813 return c.kill(revert, true); 3814 }); 3815 }; 3816 3817 return MatchMedia; 3818 }(); 3819 3820 var _gsap = { 3821 registerPlugin: function registerPlugin() { 3822 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 3823 args[_key2] = arguments[_key2]; 3824 } 3825 3826 args.forEach(function (config) { 3827 return _createPlugin(config); 3828 }); 3829 }, 3830 timeline: function timeline(vars) { 3831 return new Timeline(vars); 3832 }, 3833 getTweensOf: function getTweensOf(targets, onlyActive) { 3834 return _globalTimeline.getTweensOf(targets, onlyActive); 3835 }, 3836 getProperty: function getProperty(target, property, unit, uncache) { 3837 _isString(target) && (target = toArray(target)[0]); 3838 3839 var getter = _getCache(target || {}).get, 3840 format = unit ? _passThrough : _numericIfPossible; 3841 3842 unit === "native" && (unit = ""); 3843 return !target ? target : !property ? function (property, unit, uncache) { 3844 return format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 3845 } : format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 3846 }, 3847 quickSetter: function quickSetter(target, property, unit) { 3848 target = toArray(target); 3849 3850 if (target.length > 1) { 3851 var setters = target.map(function (t) { 3852 return gsap.quickSetter(t, property, unit); 3853 }), 3854 l = setters.length; 3855 return function (value) { 3856 var i = l; 3857 3858 while (i--) { 3859 setters[i](value); 3860 } 3861 }; 3862 } 3863 3864 target = target[0] || {}; 3865 3866 var Plugin = _plugins[property], 3867 cache = _getCache(target), 3868 p = cache.harness && (cache.harness.aliases || {})[property] || property, 3869 setter = Plugin ? function (value) { 3870 var p = new Plugin(); 3871 _quickTween._pt = 0; 3872 p.init(target, unit ? value + unit : value, _quickTween, 0, [target]); 3873 p.render(1, p); 3874 _quickTween._pt && _renderPropTweens(1, _quickTween); 3875 } : cache.set(target, p); 3876 3877 return Plugin ? setter : function (value) { 3878 return setter(target, p, unit ? value + unit : value, cache, 1); 3879 }; 3880 }, 3881 quickTo: function quickTo(target, property, vars) { 3882 var _
3882merge2; 3883 3884 var tween = gsap.to(target, _merge((_merge2 = {}, _merge2[property] = "+=0.1", _merge2.paused = true, _merge
vendor: 5,649 bytes, lines 3884-4086
38842), vars || {})), 3885 func = function func(value, start, startIsRelative) { 3886 return tween.resetTo(property, value, start, startIsRelative); 3887 }; 3888 3889 func.tween = tween; 3890 return func; 3891 }, 3892 isTweening: function isTweening(targets) { 3893 return _globalTimeline.getTweensOf(targets, true).length > 0; 3894 }, 3895 defaults: function defaults(value) { 3896 value && value.ease && (value.ease = _parseEase(value.ease, _defaults.ease)); 3897 return _mergeDeep(_defaults, value || {}); 3898 }, 3899 config: function config(value) { 3900 return _mergeDeep(_config, value || {}); 3901 }, 3902 registerEffect: function registerEffect(_ref3) { 3903 var name = _ref3.name, 3904 effect = _ref3.effect, 3905 plugins = _ref3.plugins, 3906 defaults = _ref3.defaults, 3907 extendTimeline = _ref3.extendTimeline; 3908 (plugins || "").split(",").forEach(function (pluginName) { 3909 return pluginName && !_plugins[pluginName] && !_globals[pluginName] && _warn(name + " effect requires " + pluginName + " plugin."); 3910 }); 3911 3912 _effects[name] = function (targets, vars, tl) { 3913 return effect(toArray(targets), _setDefaults(vars || {}, defaults), tl); 3914 }; 3915 3916 if (extendTimeline) { 3917 Timeline.prototype[name] = function (targets, vars, position) { 3918 return this.add(_effects[name](targets, _isObject(vars) ? vars : (position = vars) && {}, this), position); 3919 }; 3920 } 3921 }, 3922 registerEase: function registerEase(name, ease) { 3923 _easeMap[name] = _parseEase(ease); 3924 }, 3925 parseEase: function parseEase(ease, defaultEase) { 3926 return arguments.length ? _parseEase(ease, defaultEase) : _easeMap; 3927 }, 3928 getById: function getById(id) { 3929 return _globalTimeline.getById(id); 3930 }, 3931 exportRoot: function exportRoot(vars, includeDelayedCalls) { 3932 if (vars === void 0) { 3933 vars = {}; 3934 } 3935 3936 var tl = new Timeline(vars), 3937 child, 3938 next; 3939 tl.smoothChildTiming = _isNotFalse(vars.smoothChildTiming); 3940 3941 _globalTimeline.remove(tl); 3942 3943 tl._dp = 0; 3944 tl._time = tl._tTime = _globalTimeline._time; 3945 child = _globalTimeline._first; 3946 3947 while (child) { 3948 next = child._next; 3949 3950 if (includeDelayedCalls || !(!child._dur && child instanceof Tween && child.vars.onComplete === child._targets[0])) { 3951 _addToTimeline(tl, child, child._start - child._delay); 3952 } 3953 3954 child = next; 3955 } 3956 3957 _addToTimeline(_globalTimeline, tl, 0); 3958 3959 return tl; 3960 }, 3961 context: function context(func, scope) { 3962 return func ? new Context(func, scope) : _context; 3963 }, 3964 matchMedia: function matchMedia(scope) { 3965 return new MatchMedia(scope); 3966 }, 3967 matchMediaRefresh: function matchMediaRefresh() { 3968 return _media.forEach(function (c) { 3969 var cond = c.conditions, 3970 found, 3971 p; 3972 3973 for (p in cond) { 3974 if (cond[p]) { 3975 cond[p] = false; 3976 found = 1; 3977 } 3978 } 3979 3980 found && c.revert(); 3981 }) || _onMediaChange(); 3982 }, 3983 addEventListener: function addEventListener(type, callback) { 3984 var a = _listeners[type] || (_listeners[type] = []); 3985 ~a.indexOf(callback) || a.push(callback); 3986 }, 3987 removeEventListener: function removeEventListener(type, callback) { 3988 var a = _listeners[type], 3989 i = a && a.indexOf(callback); 3990 i >= 0 && a.splice(i, 1); 3991 }, 3992 utils: { 3993 wrap: wrap, 3994 wrapYoyo: wrapYoyo, 3995 distribute: distribute, 3996 random: random, 3997 snap: snap, 3998 normalize: normalize, 3999 getUnit: getUnit, 4000 clamp: clamp, 4001 splitColor: splitColor, 4002 toArray: toArray, 4003 selector: selector, 4004 mapRange: mapRange, 4005 pipe: pipe, 4006 unitize: unitize, 4007 interpolate: interpolate, 4008 shuffle: shuffle 4009 }, 4010 install: _install, 4011 effects: _effects, 4012 ticker: _ticker, 4013 updateRoot: Timeline.updateRoot, 4014 plugins: _plugins, 4015 globalTimeline: _globalTimeline, 4016 core: { 4017 PropTween: PropTween, 4018 globals: _addGlobal, 4019 Tween: Tween, 4020 Timeline: Timeline, 4021 Animation: Animation, 4022 getCache: _getCache, 4023 _removeLinkedListItem: _removeLinkedListItem, 4024 reverting: function reverting() { 4025 return _reverting; 4026 }, 4027 context: function context(toAdd) { 4028 if (toAdd && _context) { 4029 _context.data.push(toAdd); 4030 4031 toAdd._ctx = _context; 4032 } 4033 4034 return _context; 4035 }, 4036 suppressOverwrites: function suppressOverwrites(value) { 4037 return _suppressOverwrites = value; 4038 } 4039 } 4040 }; 4041 4042 _forEachName("to,from,fromTo,delayedCall,set,killTweensOf", function (name) { 4043 return _gsap[name] = Tween[name]; 4044 }); 4045 4046 _ticker.add(Timeline.updateRoot); 4047 4048 _quickTween = _gsap.to({}, { 4049 duration: 0 4050 }); 4051 4052 var _getPluginPropTween = function _getPluginPropTween(plugin, prop) { 4053 var pt = plugin._pt; 4054 4055 while (pt && pt.p !== prop && pt.op !== prop && pt.fp !== prop) { 4056 pt = pt._next; 4057 } 4058 4059 return pt; 4060 }, 4061 _addModifiers = function _addModifiers(tween, modifiers) { 4062 var targets = tween._targets, 4063 p, 4064 i, 4065 pt; 4066 4067 for (p in modifiers) { 4068 i = targets.length; 4069 4070 while (i--) { 4071 pt = tween._ptLookup[i][p]; 4072 4073 if (pt && (pt = pt.d)) { 4074 if (pt._pt) { 4075 pt = _getPluginPropTween(pt, p); 4076 } 4077 4078 pt && pt.modifier && pt.modifier(modifiers[p], tween, targets[i], p); 4079 } 4080 } 4081 } 4082 }, 4083 _buildModifierPlugin = function _buildModifierPlugin(name, modifier) { 4084 return { 4085 name: name, 4086
vendor: 21,125 bytes, lines 4086-4737
4086rawVars: 1, 4087 init: function init(target, vars, tween) { 4088 tween._onInit = function (tween) { 4089 var temp, p; 4090 4091 if (_isString(vars)) { 4092 temp = {}; 4093 4094 _forEachName(vars, function (name) { 4095 return temp[name] = 1; 4096 }); 4097 4098 vars = temp; 4099 } 4100 4101 if (modifier) { 4102 temp = {}; 4103 4104 for (p in vars) { 4105 temp[p] = modifier(vars[p]); 4106 } 4107 4108 vars = temp; 4109 } 4110 4111 _addModifiers(tween, vars); 4112 }; 4113 } 4114 }; 4115 }; 4116 4117 var gsap = _gsap.registerPlugin({ 4118 name: "attr", 4119 init: function init(target, vars, tween, index, targets) { 4120 var p, pt, v; 4121 this.tween = tween; 4122 4123 for (p in vars) { 4124 v = target.getAttribute(p) || ""; 4125 pt = this.add(target, "setAttribute", (v || 0) + "", vars[p], index, targets, 0, 0, p); 4126 pt.op = p; 4127 pt.b = v; 4128 4129 this._props.push(p); 4130 } 4131 }, 4132 render: function render(ratio, data) { 4133 var pt = data._pt; 4134 4135 while (pt) { 4136 _reverting ? pt.set(pt.t, pt.p, pt.b, pt) : pt.r(ratio, pt.d); 4137 pt = pt._next; 4138 } 4139 } 4140 }, { 4141 name: "endArray", 4142 init: function init(target, value) { 4143 var i = value.length; 4144 4145 while (i--) { 4146 this.add(target, i, target[i] || 0, value[i], 0, 0, 0, 0, 0, 1); 4147 } 4148 } 4149 }, _buildModifierPlugin("roundProps", _roundModifier), _buildModifierPlugin("modifiers"), _buildModifierPlugin("snap", snap)) || _gsap; 4150 Tween.version = Timeline.version = gsap.version = "3.12.5"; 4151 _coreReady = 1; 4152 _windowExists() && _wake(); 4153 var Power0 = _easeMap.Power0, 4154 Power1 = _easeMap.Power1, 4155 Power2 = _easeMap.Power2, 4156 Power3 = _easeMap.Power3, 4157 Power4 = _easeMap.Power4, 4158 Linear = _easeMap.Linear, 4159 Quad = _easeMap.Quad, 4160 Cubic = _easeMap.Cubic, 4161 Quart = _easeMap.Quart, 4162 Quint = _easeMap.Quint, 4163 Strong = _easeMap.Strong, 4164 Elastic = _easeMap.Elastic, 4165 Back = _easeMap.Back, 4166 SteppedEase = _easeMap.SteppedEase, 4167 Bounce = _easeMap.Bounce, 4168 Sine = _easeMap.Sine, 4169 Expo = _easeMap.Expo, 4170 Circ = _easeMap.Circ; 4171 4172 var _win$1, 4173 _doc$1, 4174 _docElement, 4175 _pluginInitted, 4176 _tempDiv, 4177 _tempDivStyler, 4178 _recentSetterPlugin, 4179 _reverting$1, 4180 _windowExists$1 = function _windowExists() { 4181 return typeof window !== "undefined"; 4182 }, 4183 _transformProps = {}, 4184 _RAD2DEG = 180 / Math.PI, 4185 _DEG2RAD = Math.PI / 180, 4186 _atan2 = Math.atan2, 4187 _bigNum$1 = 1e8, 4188 _capsExp = /([A-Z])/g, 4189 _horizontalExp = /(left|right|width|margin|padding|x)/i, 4190 _complexExp = /[\s,\(]\S/, 4191 _propertyAliases = { 4192 autoAlpha: "opacity,visibility", 4193 scale: "scaleX,scaleY", 4194 alpha: "opacity" 4195 }, 4196 _renderCSSProp = function _renderCSSProp(ratio, data) { 4197 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 4198 }, 4199 _renderPropWithEnd = function _renderPropWithEnd(ratio, data) { 4200 return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 4201 }, 4202 _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) { 4203 return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data); 4204 }, 4205 _renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) { 4206 var value = data.s + data.c * ratio; 4207 data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data); 4208 }, 4209 _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) { 4210 return data.set(data.t, data.p, ratio ? data.e : data.b, data); 4211 }, 4212 _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) { 4213 return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data); 4214 }, 4215 _setterCSSStyle = function _setterCSSStyle(target, property, value) { 4216 return target.style[property] = value; 4217 }, 4218 _setterCSSProp = function _setterCSSProp(target, property, value) { 4219 return target.style.setProperty(property, value); 4220 }, 4221 _setterTransform = function _setterTransform(target, property, value) { 4222 return target._gsap[property] = value; 4223 }, 4224 _setterScale = function _setterScale(target, property, value) { 4225 return target._gsap.scaleX = target._gsap.scaleY = value; 4226 }, 4227 _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) { 4228 var cache = target._gsap; 4229 cache.scaleX = cache.scaleY = value; 4230 cache.renderTransform(ratio, cache); 4231 }, 4232 _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) { 4233 var cache = target._gsap; 4234 cache[property] = value; 4235 cache.renderTransform(ratio, cache); 4236 }, 4237 _transformProp = "transform", 4238 _transformOriginProp = _transformProp + "Origin", 4239 _saveStyle = function _saveStyle(property, isNotCSS) { 4240 var _this = this; 4241 4242 var target = this.target, 4243 style = target.style, 4244 cache = target._gsap; 4245 4246 if (property in _transformProps && style) { 4247 this.tfm = this.tfm || {}; 4248 4249 if (property !== "transform") { 4250 property = _propertyAliases[property] || property; 4251 ~property.indexOf(",") ? property.split(",").forEach(function (a) { 4252 return _this.tfm[a] = _get(target, a); 4253 }) : this.tfm[property] = cache.x ? cache[property] : _get(target, property); 4254 property === _transformOriginProp && (this.tfm.zOrigin = cache.zOrigin); 4255 } else { 4256 return _propertyAliases.transform.split(",").forEach(function (p) { 4257 return _saveStyle.call(_this, p, isNotCSS); 4258 }); 4259 } 4260 4261 if (this.props.indexOf(_transformProp) >= 0) { 4262 return; 4263 } 4264 4265 if (cache.svg) { 4266 this.svgo = target.getAttribute("data-svg-origin"); 4267 this.props.push(_transformOriginProp, isNotCSS, ""); 4268 } 4269 4270 property = _transformProp; 4271 } 4272 4273 (style || isNotCSS) && this.props.push(property, isNotCSS, style[property]); 4274 }, 4275 _removeIndependentTransforms = function _removeIndependentTransforms(style) { 4276 if (style.translate) { 4277 style.removeProperty("translate"); 4278 style.removeProperty("scale"); 4279 style.removeProperty("rotate"); 4280 } 4281 }, 4282 _revertStyle = function _revertStyle() { 4283 var props = this.props, 4284 target = this.target, 4285 style = target.style, 4286 cache = target._gsap, 4287 i, 4288 p; 4289 4290 for (i = 0; i < props.length; i += 3) { 4291 props[i + 1] ? target[props[i]] = props[i + 2] : props[i + 2] ? style[props[i]] = props[i + 2] : style.removeProperty(props[i].substr(0, 2) === "--" ? props[i] : props[i].replace(_capsExp, "-$1").toLowerCase()); 4292 } 4293 4294 if (this.tfm) { 4295 for (p in this.tfm) { 4296 cache[p] = this.tfm[p]; 4297 } 4298 4299 if (cache.svg) { 4300 cache.renderTransform(); 4301 target.setAttribute("data-svg-origin", this.svgo || ""); 4302 } 4303 4304 i = _reverting$1(); 4305 4306 if ((!i || !i.isStart) && !style[_transformProp]) { 4307 _removeIndependentTransforms(style); 4308 4309 if (cache.zOrigin && style[_transformOriginProp]) { 4310 style[_transformOriginProp] += " " + cache.zOrigin + "px"; 4311 cache.zOrigin = 0; 4312 cache.renderTransform(); 4313 } 4314 4315 cache.uncache = 1; 4316 } 4317 } 4318 }, 4319 _getStyleSaver = function _getStyleSaver(target, properties) { 4320 var saver = { 4321 target: target, 4322 props: [], 4323 revert: _revertStyle, 4324 save: _saveStyle 4325 }; 4326 target._gsap || gsap.core.getCache(target); 4327 properties && properties.split(",").forEach(function (p) { 4328 return saver.save(p); 4329 }); 4330 return saver; 4331 }, 4332 _supports3D, 4333 _createElement = function _createElement(type, ns) { 4334 var e = _doc$1.createElementNS ? _doc$1.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc$1.createElement(type); 4335 return e && e.style ? e : _doc$1.createElement(type); 4336 }, 4337 _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) { 4338 var cs = getComputedStyle(target); 4339 return cs[property] || cs.getPropertyValue(property.replace(_capsExp, "-$1").toLowerCase()) || cs.getPropertyValue(property) || !skipPrefixFallback && _getComputedProperty(target, _checkPropPrefix(property) || property, 1) || ""; 4340 }, 4341 _prefixes = "O,Moz,ms,Ms,Webkit".split(","), 4342 _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) { 4343 var e = element || _tempDiv, 4344 s = e.style, 4345 i = 5; 4346 4347 if (property in s && !preferPrefix) { 4348 return property; 4349 } 4350 4351 property = property.charAt(0).toUpperCase() + property.substr(1); 4352 4353 while (i-- && !(_prefixes[i] + property in s)) {} 4354 4355 return i < 0 ? null : (i === 3 ? "ms" : i >= 0 ? _prefixes[i] : "") + property; 4356 }, 4357 _initCore = function _initCore() { 4358 if (_windowExists$1() && window.document) { 4359 _win$1 = window; 4360 _doc$1 = _win$1.document; 4361 _docElement = _doc$1.documentElement; 4362 _tempDiv = _createElement("div") || { 4363 style: {} 4364 }; 4365 _tempDivStyler = _createElement("div"); 4366 _transformProp = _checkPropPrefix(_transformProp); 4367 _transformOriginProp = _transformProp + "Origin"; 4368 _tempDiv.style.cssText = "border-width:0;line-height:0;position:absolute;padding:0"; 4369 _supports3D = !!_checkPropPrefix("perspective"); 4370 _reverting$1 = gsap.core.reverting; 4371 _pluginInitted = 1; 4372 } 4373 }, 4374 _getBBoxHack = function _getBBoxHack(swapIfPossible) { 4375 var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"), 4376 oldParent = this.parentNode, 4377 oldSibling = this.nextSibling, 4378 oldCSS = this.style.cssText, 4379 bbox; 4380 4381 _docElement.appendChild(svg); 4382 4383 svg.appendChild(this); 4384 this.style.display = "block"; 4385 4386 if (swapIfPossible) { 4387 try { 4388 bbox = this.getBBox(); 4389 this._gsapBBox = this.getBBox; 4390 this.getBBox = _getBBoxHack; 4391 } catch (e) {} 4392 } else if (this._gsapBBox) { 4393 bbox = this._gsapBBox(); 4394 } 4395 4396 if (oldParent) { 4397 if (oldSibling) { 4398 oldParent.insertBefore(this, oldSibling); 4399 } else { 4400 oldParent.appendChild(this); 4401 } 4402 } 4403 4404 _docElement.removeChild(svg); 4405 4406 this.style.cssText = oldCSS; 4407 return bbox; 4408 }, 4409 _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) { 4410 var i = attributesArray.length; 4411 4412 while (i--) { 4413 if (target.hasAttribute(attributesArray[i])) { 4414 return target.getAttribute(attributesArray[i]); 4415 } 4416 } 4417 }, 4418 _getBBox = function _getBBox(target) { 4419 var bounds; 4420 4421 try { 4422 bounds = target.getBBox(); 4423 } catch (error) { 4424 bounds = _getBBoxHack.call(target, true); 4425 } 4426 4427 bounds && (bounds.width || bounds.height) || target.getBBox === _getBBoxHack || (bounds = _getBBoxHack.call(target, true)); 4428 return bounds && !bounds.width && !bounds.x && !bounds.y ? { 4429 x: +_getAttributeFallbacks(target, ["x", "cx", "x1"]) || 0, 4430 y: +_getAttributeFallbacks(target, ["y", "cy", "y1"]) || 0, 4431 width: 0, 4432 height: 0 4433 } : bounds; 4434 }, 4435 _isSVG = function _isSVG(e) { 4436 return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e)); 4437 }, 4438 _removeProperty = function _removeProperty(target, property) { 4439 if (property) { 4440 var style = target.style, 4441 first2Chars; 4442 4443 if (property in _transformProps && property !== _transformOriginProp) { 4444 property = _transformProp; 4445 } 4446 4447 if (style.removeProperty) { 4448 first2Chars = property.substr(0, 2); 4449 4450 if (first2Chars === "ms" || property.substr(0, 6) === "webkit") { 4451 property = "-" + property; 4452 } 4453 4454 style.removeProperty(first2Chars === "--" ? property : property.replace(_capsExp, "-$1").toLowerCase()); 4455 } else { 4456 style.removeAttribute(property); 4457 } 4458 } 4459 }, 4460 _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) { 4461 var pt = new PropTween(plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue); 4462 plugin._pt = pt; 4463 pt.b = beginning; 4464 pt.e = end; 4465 4466 plugin._props.push(property); 4467 4468 return pt; 4469 }, 4470 _nonConvertibleUnits = { 4471 deg: 1, 4472 rad: 1, 4473 turn: 1 4474 }, 4475 _nonStandardLayouts = { 4476 grid: 1, 4477 flex: 1 4478 }, 4479 _convertToUnit = function _convertToUnit(target, property, value, unit) { 4480 var curValue = parseFloat(value) || 0, 4481 curUnit = (value + "").trim().substr((curValue + "").length) || "px", 4482 style = _tempDiv.style, 4483 horizontal = _horizontalExp.test(property), 4484 isRootSVG = target.tagName.toLowerCase() === "svg", 4485 measureProperty = (isRootSVG ? "client" : "offset") + (horizontal ? "Width" : "Height"), 4486 amount = 100, 4487 toPixels = unit === "px", 4488 toPercent = unit === "%", 4489 px, 4490 parent, 4491 cache, 4492 isSVG; 4493 4494 if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) { 4495 return curValue; 4496 } 4497 4498 curUnit !== "px" && !toPixels && (curValue = _convertToUnit(target, property, value, "px")); 4499 isSVG = target.getCTM && _isSVG(target); 4500 4501 if ((toPercent || curUnit === "%") && (_transformProps[property] || ~property.indexOf("adius"))) { 4502 px = isSVG ? target.getBBox()[horizontal ? "width" : "height"] : target[measureProperty]; 4503 return _round(toPercent ? curValue / px * amount : curValue / 100 * px); 4504 } 4505 4506 style[horizontal ? "width" : "height"] = amount + (toPixels ? curUnit : unit); 4507 parent = ~property.indexOf("adius") || unit === "em" && target.appendChild && !isRootSVG ? target : target.parentNode; 4508 4509 if (isSVG) { 4510 parent = (target.ownerSVGElement || {}).parentNode; 4511 } 4512 4513 if (!parent || parent === _doc$1 || !parent.appendChild) { 4514 parent = _doc$1.body; 4515 } 4516 4517 cache = parent._gsap; 4518 4519 if (cache && toPercent && cache.width && horizontal && cache.time === _ticker.time && !cache.uncache) { 4520 return _round(curValue / cache.width * amount); 4521 } else { 4522 if (toPercent && (property === "height" || property === "width")) { 4523 var v = target.style[property]; 4524 target.style[property] = amount + unit; 4525 px = target[measureProperty]; 4526 v ? target.style[property] = v : _removeProperty(target, property); 4527 } else { 4528 (toPercent || curUnit === "%") && !_nonStandardLayouts[_getComputedProperty(parent, "display")] && (style.position = _getComputedProperty(target, "position")); 4529 parent === target && (style.position = "static"); 4530 parent.appendChild(_tempDiv); 4531 px = _tempDiv[measureProperty]; 4532 parent.removeChild(_tempDiv); 4533 style.position = "absolute"; 4534 } 4535 4536 if (horizontal && toPercent) { 4537 cache = _getCache(parent); 4538 cache.time = _ticker.time; 4539 cache.width = parent[measureProperty]; 4540 } 4541 } 4542 4543 return _round(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0); 4544 }, 4545 _get = function _get(target, property, unit, uncache) { 4546 var value; 4547 _pluginInitted || _initCore(); 4548 4549 if (property in _propertyAliases && property !== "transform") { 4550 property = _propertyAliases[property]; 4551 4552 if (~property.indexOf(",")) { 4553 property = property.split(",")[0]; 4554 } 4555 } 4556 4557 if (_transformProps[property] && property !== "transform") { 4558 value = _parseTransform(target, uncache); 4559 value = property !== "transformOrigin" ? value[property] : value.svg ? value.origin : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + " " + value.zOrigin + "px"; 4560 } else { 4561 value = target.style[property]; 4562 4563 if (!value || value === "auto" || uncache || ~(value + "").indexOf("calc(")) { 4564 value = _specialProps[property] && _specialProps[property](target, property, unit) || _getComputedProperty(target, property) || _getProperty(target, property) || (property === "opacity" ? 1 : 0); 4565 } 4566 } 4567 4568 return unit && !~(value + "").trim().indexOf(" ") ? _convertToUnit(target, property, value, unit) + unit : value; 4569 }, 4570 _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) { 4571 if (!start || start === "none") { 4572 var p = _checkPropPrefix(prop, target, 1), 4573 s = p && _getComputedProperty(target, p, 1); 4574 4575 if (s && s !== start) { 4576 prop = p; 4577 start = s; 4578 } else if (prop === "borderColor") { 4579 start = _getComputedProperty(target, "borderTopColor"); 4580 } 4581 } 4582 4583 var pt = new PropTween(this._pt, target.style, prop, 0, 1, _renderComplexString), 4584 index = 0, 4585 matchIndex = 0, 4586 a, 4587 result, 4588 startValues, 4589 startNum, 4590 color, 4591 startValue, 4592 endValue, 4593 endNum, 4594 chunk, 4595 endUnit, 4596 startUnit, 4597 endValues; 4598 pt.b = start; 4599 pt.e = end; 4600 start += ""; 4601 end += ""; 4602 4603 if (end === "auto") { 4604 startValue = target.style[prop]; 4605 target.style[prop] = end; 4606 end = _getComputedProperty(target, prop) || end; 4607 startValue ? target.style[prop] = startValue : _removeProperty(target, prop); 4608 } 4609 4610 a = [start, end]; 4611 4612 _colorStringFilter(a); 4613 4614 start = a[0]; 4615 end = a[1]; 4616 startValues = start.match(_numWithUnitExp) || []; 4617 endValues = end.match(_numWithUnitExp) || []; 4618 4619 if (endValues.length) { 4620 while (result = _numWithUnitExp.exec(end)) { 4621 endValue = result[0]; 4622 chunk = end.substring(index, result.index); 4623 4624 if (color) { 4625 color = (color + 1) % 5; 4626 } else if (chunk.substr(-5) === "rgba(" || chunk.substr(-5) === "hsla(") { 4627 color = 1; 4628 } 4629 4630 if (endValue !== (startValue = startValues[matchIndex++] || "")) { 4631 startNum = parseFloat(startValue) || 0; 4632 startUnit = startValue.substr((startNum + "").length); 4633 endValue.charAt(1) === "=" && (endValue = _parseRelative(startNum, endValue) + startUnit); 4634 endNum = parseFloat(endValue); 4635 endUnit = endValue.substr((endNum + "").length); 4636 index = _numWithUnitExp.lastIndex - endUnit.length; 4637 4638 if (!endUnit) { 4639 endUnit = endUnit || _config.units[prop] || startUnit; 4640 4641 if (index === end.length) { 4642 end += endUnit; 4643 pt.e += endUnit; 4644 } 4645 } 4646 4647 if (startUnit !== endUnit) { 4648 startNum = _convertToUnit(target, prop, startValue, endUnit) || 0; 4649 } 4650 4651 pt._pt = { 4652 _next: pt._pt, 4653 p: chunk || matchIndex === 1 ? chunk : ",", 4654 s: startNum, 4655 c: endNum - startNum, 4656 m: color && color < 4 || prop === "zIndex" ? Math.round : 0 4657 }; 4658 } 4659 } 4660 4661 pt.c = index < end.length ? end.substring(index, end.length) : ""; 4662 } else { 4663 pt.r = prop === "display" && end === "none" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue; 4664 } 4665 4666 _relExp.test(end) && (pt.e = 0); 4667 this._pt = pt; 4668 return pt; 4669 }, 4670 _keywordToPercent = { 4671 top: "0%", 4672 bottom: "100%", 4673 left: "0%", 4674 right: "100%", 4675 center: "50%" 4676 }, 4677 _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) { 4678 var split = value.split(" "), 4679 x = split[0], 4680 y = split[1] || "50%"; 4681 4682 if (x === "top" || x === "bottom" || y === "left" || y === "right") { 4683 value = x; 4684 x = y; 4685 y = value; 4686 } 4687 4688 split[0] = _keywordToPercent[x] || x; 4689 split[1] = _keywordToPercent[y] || y; 4690 return split.join(" "); 4691 }, 4692 _renderClearProps = function _renderClearProps(ratio, data) { 4693 if (data.tween && data.tween._time === data.tween._dur) { 4694 var target = data.t, 4695 style = target.style, 4696 props = data.u, 4697 cache = target._gsap, 4698 prop, 4699 clearTransforms, 4700 i; 4701 4702 if (props === "all" || props === true) { 4703 style.cssText = ""; 4704 clearTransforms = 1; 4705 } else { 4706 props = props.split(","); 4707 i = props.length; 4708 4709 while (--i > -1) { 4710 prop = props[i]; 4711 4712 if (_transformProps[prop]) { 4713 clearTransforms = 1; 4714 prop = prop === "transformOrigin" ? _transformOriginProp : _transformProp; 4715 } 4716 4717 _removeProperty(target, prop); 4718 } 4719 } 4720 4721 if (clearTransforms) { 4722 _removeProperty(target, _transformProp); 4723 4724 if (cache) { 4725 cache.svg && target.removeAttribute("transform"); 4726 4727 _parseTransform(target, 1); 4728 4729 cache.uncache = 1; 4730 4731 _removeIndependentTransforms(style); 4732 } 4733 } 4734 } 4735 }, 4736 _specialProps = { 4737 clearProps: function clearProps(plugin, target, property, endValue, tween) {
vendor: 1,580 bytes, lines 4738-4778
4738 if (tween.data !== "isFromStart") { 4739 var pt = plugin._pt = new PropTween(plugin._pt, target, property, 0, 0, _renderClearProps); 4740 pt.u = endValue; 4741 pt.pr = -10; 4742 pt.tween = tween; 4743 4744 plugin._props.push(property); 4745 4746 return 1; 4747 } 4748 } 4749 }, 4750 _identity2DMatrix = [1, 0, 0, 1, 0, 0], 4751 _rotationalProperties = {}, 4752 _isNullTransform = function _isNullTransform(value) { 4753 return value === "matrix(1, 0, 0, 1, 0, 0)" || value === "none" || !value; 4754 }, 4755 _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) { 4756 var matrixString = _getComputedProperty(target, _transformProp); 4757 4758 return _isNullTransform(matrixString) ? _identity2DMatrix : matrixString.substr(7).match(_numExp).map(_round); 4759 }, 4760 _getMatrix = function _getMatrix(target, force2D) { 4761 var cache = target._gsap || _getCache(target), 4762 style = target.style, 4763 matrix = _getComputedTransformMatrixAsArray(target), 4764 parent, 4765 nextSibling, 4766 temp, 4767 addedToDOM; 4768 4769 if (cache.svg && target.getAttribute("transform")) { 4770 temp = target.transform.baseVal.consolidate().matrix; 4771 matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f]; 4772 return matrix.join(",") === "1,0,0,1,0,0" ? _identity2DMatrix : matrix; 4773 } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) { 4774 temp = style.display; 4775 style.display = "block"; 4776 parent = target.parentNode; 4777 4778 if (!parent || !target.offsetParent
vendor: 18,926 bytes, lines 4778-5375
4778) { 4779 addedToDOM = 1; 4780 nextSibling = target.nextElementSibling; 4781 4782 _docElement.appendChild(target); 4783 } 4784 4785 matrix = _getComputedTransformMatrixAsArray(target); 4786 temp ? style.display = temp : _removeProperty(target, "display"); 4787 4788 if (addedToDOM) { 4789 nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target); 4790 } 4791 } 4792 4793 return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix; 4794 }, 4795 _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) { 4796 var cache = target._gsap, 4797 matrix = matrixArray || _getMatrix(target, true), 4798 xOriginOld = cache.xOrigin || 0, 4799 yOriginOld = cache.yOrigin || 0, 4800 xOffsetOld = cache.xOffset || 0, 4801 yOffsetOld = cache.yOffset || 0, 4802 a = matrix[0], 4803 b = matrix[1], 4804 c = matrix[2], 4805 d = matrix[3], 4806 tx = matrix[4], 4807 ty = matrix[5], 4808 originSplit = origin.split(" "), 4809 xOrigin = parseFloat(originSplit[0]) || 0, 4810 yOrigin = parseFloat(originSplit[1]) || 0, 4811 bounds, 4812 determinant, 4813 x, 4814 y; 4815 4816 if (!originIsAbsolute) { 4817 bounds = _getBBox(target); 4818 xOrigin = bounds.x + (~originSplit[0].indexOf("%") ? xOrigin / 100 * bounds.width : xOrigin); 4819 yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf("%") ? yOrigin / 100 * bounds.height : yOrigin); 4820 } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) { 4821 x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant; 4822 y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant; 4823 xOrigin = x; 4824 yOrigin = y; 4825 } 4826 4827 if (smooth || smooth !== false && cache.smooth) { 4828 tx = xOrigin - xOriginOld; 4829 ty = yOrigin - yOriginOld; 4830 cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx; 4831 cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty; 4832 } else { 4833 cache.xOffset = cache.yOffset = 0; 4834 } 4835 4836 cache.xOrigin = xOrigin; 4837 cache.yOrigin = yOrigin; 4838 cache.smooth = !!smooth; 4839 cache.origin = origin; 4840 cache.originIsAbsolute = !!originIsAbsolute; 4841 target.style[_transformOriginProp] = "0px 0px"; 4842 4843 if (pluginToAddPropTweensTo) { 4844 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOrigin", xOriginOld, xOrigin); 4845 4846 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOrigin", yOriginOld, yOrigin); 4847 4848 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOffset", xOffsetOld, cache.xOffset); 4849 4850 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOffset", yOffsetOld, cache.yOffset); 4851 } 4852 4853 target.setAttribute("data-svg-origin", xOrigin + " " + yOrigin); 4854 }, 4855 _parseTransform = function _parseTransform(target, uncache) { 4856 var cache = target._gsap || new GSCache(target); 4857 4858 if ("x" in cache && !uncache && !cache.uncache) { 4859 return cache; 4860 } 4861 4862 var style = target.style, 4863 invertedScaleX = cache.scaleX < 0, 4864 px = "px", 4865 deg = "deg", 4866 cs = getComputedStyle(target), 4867 origin = _getComputedProperty(target, _transformOriginProp) || "0", 4868 x, 4869 y, 4870 z, 4871 scaleX, 4872 scaleY, 4873 rotation, 4874 rotationX, 4875 rotationY, 4876 skewX, 4877 skewY, 4878 perspective, 4879 xOrigin, 4880 yOrigin, 4881 matrix, 4882 angle, 4883 cos, 4884 sin, 4885 a, 4886 b, 4887 c, 4888 d, 4889 a12, 4890 a22, 4891 t1, 4892 t2, 4893 t3, 4894 a13, 4895 a23, 4896 a33, 4897 a42, 4898 a43, 4899 a32; 4900 x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0; 4901 scaleX = scaleY = 1; 4902 cache.svg = !!(target.getCTM && _isSVG(target)); 4903 4904 if (cs.translate) { 4905 if (cs.translate !== "none" || cs.scale !== "none" || cs.rotate !== "none") { 4906 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] : ""); 4907 } 4908 4909 style.scale = style.rotate = style.translate = "none"; 4910 } 4911 4912 matrix = _getMatrix(target, cache.svg); 4913 4914 if (cache.svg) { 4915 if (cache.uncache) { 4916 t2 = target.getBBox(); 4917 origin = cache.xOrigin - t2.x + "px " + (cache.yOrigin - t2.y) + "px"; 4918 t1 = ""; 4919 } else { 4920 t1 = !uncache && target.getAttribute("data-svg-origin"); 4921 } 4922 4923 _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix); 4924 } 4925 4926 xOrigin = cache.xOrigin || 0; 4927 yOrigin = cache.yOrigin || 0; 4928 4929 if (matrix !== _identity2DMatrix) { 4930 a = matrix[0]; 4931 b = matrix[1]; 4932 c = matrix[2]; 4933 d = matrix[3]; 4934 x = a12 = matrix[4]; 4935 y = a22 = matrix[5]; 4936 4937 if (matrix.length === 6) { 4938 scaleX = Math.sqrt(a * a + b * b); 4939 scaleY = Math.sqrt(d * d + c * c); 4940 rotation = a || b ? _atan2(b, a) * _RAD2DEG : 0; 4941 skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0; 4942 skewX && (scaleY *= Math.abs(Math.cos(skewX * _DEG2RAD))); 4943 4944 if (cache.svg) { 4945 x -= xOrigin - (xOrigin * a + yOrigin * c); 4946 y -= yOrigin - (xOrigin * b + yOrigin * d); 4947 } 4948 } else { 4949 a32 = matrix[6]; 4950 a42 = matrix[7]; 4951 a13 = matrix[8]; 4952 a23 = matrix[9]; 4953 a33 = matrix[10]; 4954 a43 = matrix[11]; 4955 x = matrix[12]; 4956 y = matrix[13]; 4957 z = matrix[14]; 4958 angle = _atan2(a32, a33); 4959 rotationX = angle * _RAD2DEG; 4960 4961 if (angle) { 4962 cos = Math.cos(-angle); 4963 sin = Math.sin(-angle); 4964 t1 = a12 * cos + a13 * sin; 4965 t2 = a22 * cos + a23 * sin; 4966 t3 = a32 * cos + a33 * sin; 4967 a13 = a12 * -sin + a13 * cos; 4968 a23 = a22 * -sin + a23 * cos; 4969 a33 = a32 * -sin + a33 * cos; 4970 a43 = a42 * -sin + a43 * cos; 4971 a12 = t1; 4972 a22 = t2; 4973 a32 = t3; 4974 } 4975 4976 angle = _atan2(-c, a33); 4977 rotationY = angle * _RAD2DEG; 4978 4979 if (angle) { 4980 cos = Math.cos(-angle); 4981 sin = Math.sin(-angle); 4982 t1 = a * cos - a13 * sin; 4983 t2 = b * cos - a23 * sin; 4984 t3 = c * cos - a33 * sin; 4985 a43 = d * sin + a43 * cos; 4986 a = t1; 4987 b = t2; 4988 c = t3; 4989 } 4990 4991 angle = _atan2(b, a); 4992 rotation = angle * _RAD2DEG; 4993 4994 if (angle) { 4995 cos = Math.cos(angle); 4996 sin = Math.sin(angle); 4997 t1 = a * cos + b * sin; 4998 t2 = a12 * cos + a22 * sin; 4999 b = b * cos - a * sin; 5000 a22 = a22 * cos - a12 * sin; 5001 a = t1; 5002 a12 = t2; 5003 } 5004 5005 if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) { 5006 rotationX = rotation = 0; 5007 rotationY = 180 - rotationY; 5008 } 5009 5010 scaleX = _round(Math.sqrt(a * a + b * b + c * c)); 5011 scaleY = _round(Math.sqrt(a22 * a22 + a32 * a32)); 5012 angle = _atan2(a12, a22); 5013 skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0; 5014 perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0; 5015 } 5016 5017 if (cache.svg) { 5018 t1 = target.getAttribute("transform"); 5019 cache.forceCSS = target.setAttribute("transform", "") || !_isNullTransform(_getComputedProperty(target, _transformProp)); 5020 t1 && target.setAttribute("transform", t1); 5021 } 5022 } 5023 5024 if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) { 5025 if (invertedScaleX) { 5026 scaleX *= -1; 5027 skewX += rotation <= 0 ? 180 : -180; 5028 rotation += rotation <= 0 ? 180 : -180; 5029 } else { 5030 scaleY *= -1; 5031 skewX += skewX <= 0 ? 180 : -180; 5032 } 5033 } 5034 5035 uncache = uncache || cache.uncache; 5036 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; 5037 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; 5038 cache.z = z + px; 5039 cache.scaleX = _round(scaleX); 5040 cache.scaleY = _round(scaleY); 5041 cache.rotation = _round(rotation) + deg; 5042 cache.rotationX = _round(rotationX) + deg; 5043 cache.rotationY = _round(rotationY) + deg; 5044 cache.skewX = skewX + deg; 5045 cache.skewY = skewY + deg; 5046 cache.transformPerspective = perspective + px; 5047 5048 if (cache.zOrigin = parseFloat(origin.split(" ")[2]) || !uncache && cache.zOrigin || 0) { 5049 style[_transformOriginProp] = _firstTwoOnly(origin); 5050 } 5051 5052 cache.xOffset = cache.yOffset = 0; 5053 cache.force3D = _config.force3D; 5054 cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms; 5055 cache.uncache = 0; 5056 return cache; 5057 }, 5058 _firstTwoOnly = function _firstTwoOnly(value) { 5059 return (value = value.split(" "))[0] + " " + value[1]; 5060 }, 5061 _addPxTranslate = function _addPxTranslate(target, start, value) { 5062 var unit = getUnit(start); 5063 return _round(parseFloat(start) + parseFloat(_convertToUnit(target, "x", value + "px", unit))) + unit; 5064 }, 5065 _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) { 5066 cache.z = "0px"; 5067 cache.rotationY = cache.rotationX = "0deg"; 5068 cache.force3D = 0; 5069 5070 _renderCSSTransforms(ratio, cache); 5071 }, 5072 _zeroDeg = "0deg", 5073 _zeroPx = "0px", 5074 _endParenthesis = ") ", 5075 _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) { 5076 var _ref = cache || this, 5077 xPercent = _ref.xPercent, 5078 yPercent = _ref.yPercent, 5079 x = _ref.x, 5080 y = _ref.y, 5081 z = _ref.z, 5082 rotation = _ref.rotation, 5083 rotationY = _ref.rotationY, 5084 rotationX = _ref.rotationX, 5085 skewX = _ref.skewX, 5086 skewY = _ref.skewY, 5087 scaleX = _ref.scaleX, 5088 scaleY = _ref.scaleY, 5089 transformPerspective = _ref.transformPerspective, 5090 force3D = _ref.force3D, 5091 target = _ref.target, 5092 zOrigin = _ref.zOrigin, 5093 transforms = "", 5094 use3D = force3D === "auto" && ratio && ratio !== 1 || force3D === true; 5095 5096 if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) { 5097 var angle = parseFloat(rotationY) * _DEG2RAD, 5098 a13 = Math.sin(angle), 5099 a33 = Math.cos(angle), 5100 cos; 5101 5102 angle = parseFloat(rotationX) * _DEG2RAD; 5103 cos = Math.cos(angle); 5104 x = _addPxTranslate(target, x, a13 * cos * -zOrigin); 5105 y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin); 5106 z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin); 5107 } 5108 5109 if (transformPerspective !== _zeroPx) { 5110 transforms += "perspective(" + transformPerspective + _endParenthesis; 5111 } 5112 5113 if (xPercent || yPercent) { 5114 transforms += "translate(" + xPercent + "%, " + yPercent + "%) "; 5115 } 5116 5117 if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) { 5118 transforms += z !== _zeroPx || use3D ? "translate3d(" + x + ", " + y + ", " + z + ") " : "translate(" + x + ", " + y + _endParenthesis; 5119 } 5120 5121 if (rotation !== _zeroDeg) { 5122 transforms += "rotate(" + rotation + _endParenthesis; 5123 } 5124 5125 if (rotationY !== _zeroDeg) { 5126 transforms += "rotateY(" + rotationY + _endParenthesis; 5127 } 5128 5129 if (rotationX !== _zeroDeg) { 5130 transforms += "rotateX(" + rotationX + _endParenthesis; 5131 } 5132 5133 if (skewX !== _zeroDeg || skewY !== _zeroDeg) { 5134 transforms += "skew(" + skewX + ", " + skewY + _endParenthesis; 5135 } 5136 5137 if (scaleX !== 1 || scaleY !== 1) { 5138 transforms += "scale(" + scaleX + ", " + scaleY + _endParenthesis; 5139 } 5140 5141 target.style[_transformProp] = transforms || "translate(0, 0)"; 5142 }, 5143 _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) { 5144 var _ref2 = cache || this, 5145 xPercent = _ref2.xPercent, 5146 yPercent = _ref2.yPercent, 5147 x = _ref2.x, 5148 y = _ref2.y, 5149 rotation = _ref2.rotation, 5150 skewX = _ref2.skewX, 5151 skewY = _ref2.skewY, 5152 scaleX = _ref2.scaleX, 5153 scaleY = _ref2.scaleY, 5154 target = _ref2.target, 5155 xOrigin = _ref2.xOrigin, 5156 yOrigin = _ref2.yOrigin, 5157 xOffset = _ref2.xOffset, 5158 yOffset = _ref2.yOffset, 5159 forceCSS = _ref2.forceCSS, 5160 tx = parseFloat(x), 5161 ty = parseFloat(y), 5162 a11, 5163 a21, 5164 a12, 5165 a22, 5166 temp; 5167 5168 rotation = parseFloat(rotation); 5169 skewX = parseFloat(skewX); 5170 skewY = parseFloat(skewY); 5171 5172 if (skewY) { 5173 skewY = parseFloat(skewY); 5174 skewX += skewY; 5175 rotation += skewY; 5176 } 5177 5178 if (rotation || skewX) { 5179 rotation *= _DEG2RAD; 5180 skewX *= _DEG2RAD; 5181 a11 = Math.cos(rotation) * scaleX; 5182 a21 = Math.sin(rotation) * scaleX; 5183 a12 = Math.sin(rotation - skewX) * -scaleY; 5184 a22 = Math.cos(rotation - skewX) * scaleY; 5185 5186 if (skewX) { 5187 skewY *= _DEG2RAD; 5188 temp = Math.tan(skewX - skewY); 5189 temp = Math.sqrt(1 + temp * temp); 5190 a12 *= temp; 5191 a22 *= temp; 5192 5193 if (skewY) { 5194 temp = Math.tan(skewY); 5195 temp = Math.sqrt(1 + temp * temp); 5196 a11 *= temp; 5197 a21 *= temp; 5198 } 5199 } 5200 5201 a11 = _round(a11); 5202 a21 = _round(a21); 5203 a12 = _round(a12); 5204 a22 = _round(a22); 5205 } else { 5206 a11 = scaleX; 5207 a22 = scaleY; 5208 a21 = a12 = 0; 5209 } 5210 5211 if (tx && !~(x + "").indexOf("px") || ty && !~(y + "").indexOf("px")) { 5212 tx = _convertToUnit(target, "x", x, "px"); 5213 ty = _convertToUnit(target, "y", y, "px"); 5214 } 5215 5216 if (xOrigin || yOrigin || xOffset || yOffset) { 5217 tx = _round(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset); 5218 ty = _round(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset); 5219 } 5220 5221 if (xPercent || yPercent) { 5222 temp = target.getBBox(); 5223 tx = _round(tx + xPercent / 100 * temp.width); 5224 ty = _round(ty + yPercent / 100 * temp.height); 5225 } 5226 5227 temp = "matrix(" + a11 + "," + a21 + "," + a12 + "," + a22 + "," + tx + "," + ty + ")"; 5228 target.setAttribute("transform", temp); 5229 forceCSS && (target.style[_transformProp] = temp); 5230 }, 5231 _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue) { 5232 var cap = 360, 5233 isString = _isString(endValue), 5234 endNum = parseFloat(endValue) * (isString && ~endValue.indexOf("rad") ? _RAD2DEG : 1), 5235 change = endNum - startNum, 5236 finalValue = startNum + change + "deg", 5237 direction, 5238 pt; 5239 5240 if (isString) { 5241 direction = endValue.split("_")[1]; 5242 5243 if (direction === "short") { 5244 change %= cap; 5245 5246 if (change !== change % (cap / 2)) { 5247 change += change < 0 ? cap : -cap; 5248 } 5249 } 5250 5251 if (direction === "cw" && change < 0) { 5252 change = (change + cap * _bigNum$1) % cap - ~~(change / cap) * cap; 5253 } else if (direction === "ccw" && change > 0) { 5254 change = (change - cap * _bigNum$1) % cap - ~~(change / cap) * cap; 5255 } 5256 } 5257 5258 plugin._pt = pt = new PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd); 5259 pt.e = finalValue; 5260 pt.u = "deg"; 5261 5262 plugin._props.push(property); 5263 5264 return pt; 5265 }, 5266 _assign = function _assign(target, source) { 5267 for (var p in source) { 5268 target[p] = source[p]; 5269 } 5270 5271 return target; 5272 }, 5273 _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) { 5274 var startCache = _assign({}, target._gsap), 5275 exclude = "perspective,force3D,transformOrigin,svgOrigin", 5276 style = target.style, 5277 endCache, 5278 p, 5279 startValue, 5280 endValue, 5281 startNum, 5282 endNum, 5283 startUnit, 5284 endUnit; 5285 5286 if (startCache.svg) { 5287 startValue = target.getAttribute("transform"); 5288 target.setAttribute("transform", ""); 5289 style[_transformProp] = transforms; 5290 endCache = _parseTransform(target, 1); 5291 5292 _removeProperty(target, _transformProp); 5293 5294 target.setAttribute("transform", startValue); 5295 } else { 5296 startValue = getComputedStyle(target)[_transformProp]; 5297 style[_transformProp] = transforms; 5298 endCache = _parseTransform(target, 1); 5299 style[_transformProp] = startValue; 5300 } 5301 5302 for (p in _transformProps) { 5303 startValue = startCache[p]; 5304 endValue = endCache[p]; 5305 5306 if (startValue !== endValue && exclude.indexOf(p) < 0) { 5307 startUnit = getUnit(startValue); 5308 endUnit = getUnit(endValue); 5309 startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue); 5310 endNum = parseFloat(endValue); 5311 plugin._pt = new PropTween(plugin._pt, endCache, p, startNum, endNum - startNum, _renderCSSProp); 5312 plugin._pt.u = endUnit || 0; 5313 5314 plugin._props.push(p); 5315 } 5316 } 5317 5318 _assign(endCache, startCache); 5319 }; 5320 5321 _forEachName("padding,margin,Width,Radius", function (name, index) { 5322 var t = "Top", 5323 r = "Right", 5324 b = "Bottom", 5325 l = "Left", 5326 props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) { 5327 return index < 2 ? name + side : "border" + side + name; 5328 }); 5329 5330 _specialProps[index > 1 ? "border" + name : name] = function (plugin, target, property, endValue, tween) { 5331 var a, vars; 5332 5333 if (arguments.length < 4) { 5334 a = props.map(function (prop) { 5335 return _get(plugin, prop, property); 5336 }); 5337 vars = a.join(" "); 5338 return vars.split(a[0]).length === 5 ? a[0] : vars; 5339 } 5340 5341 a = (endValue + "").split(" "); 5342 vars = {}; 5343 props.forEach(function (prop, i) { 5344 return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0]; 5345 }); 5346 plugin.init(target, vars, tween); 5347 }; 5348 }); 5349 5350 var CSSPlugin = { 5351 name: "css", 5352 register: _initCore, 5353 targetTest: function targetTest(target) { 5354 return target.style && target.nodeType; 5355 }, 5356 init: function init(target, vars, tween, index, targets) { 5357 var props = this._props, 5358 style = target.style, 5359 startAt = tween.vars.startAt, 5360 startValue, 5361 endValue, 5362 endNum, 5363 startNum, 5364 type, 5365 specialProp, 5366 p, 5367 startUnit, 5368 endUnit, 5369 relative, 5370 isTransformRelated, 5371 transformPropTween, 5372 cache, 5373 smooth, 5374 hasPriority, 5375 inlineProps
vendor: 8,025 bytes, lines 5375-5562
5375; 5376 _pluginInitted || _initCore(); 5377 this.styles = this.styles || _getStyleSaver(target); 5378 inlineProps = this.styles.props; 5379 this.tween = tween; 5380 5381 for (p in vars) { 5382 if (p === "autoRound") { 5383 continue; 5384 } 5385 5386 endValue = vars[p]; 5387 5388 if (_plugins[p] && _checkPlugin(p, vars, tween, index, target, targets)) { 5389 continue; 5390 } 5391 5392 type = typeof endValue; 5393 specialProp = _specialProps[p]; 5394 5395 if (type === "function") { 5396 endValue = endValue.call(tween, index, target, targets); 5397 type = typeof endValue; 5398 } 5399 5400 if (type === "string" && ~endValue.indexOf("random(")) { 5401 endValue = _replaceRandom(endValue); 5402 } 5403 5404 if (specialProp) { 5405 specialProp(this, target, p, endValue, tween) && (hasPriority = 1); 5406 } else if (p.substr(0, 2) === "--") { 5407 startValue = (getComputedStyle(target).getPropertyValue(p) + "").trim(); 5408 endValue += ""; 5409 _colorExp.lastIndex = 0; 5410 5411 if (!_colorExp.test(startValue)) { 5412 startUnit = getUnit(startValue); 5413 endUnit = getUnit(endValue); 5414 } 5415 5416 endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit); 5417 this.add(style, "setProperty", startValue, endValue, index, targets, 0, 0, p); 5418 props.push(p); 5419 inlineProps.push(p, 0, style[p]); 5420 } else if (type !== "undefined") { 5421 if (startAt && p in startAt) { 5422 startValue = typeof startAt[p] === "function" ? startAt[p].call(tween, index, target, targets) : startAt[p]; 5423 _isString(startValue) && ~startValue.indexOf("random(") && (startValue = _replaceRandom(startValue)); 5424 getUnit(startValue + "") || startValue === "auto" || (startValue += _config.units[p] || getUnit(_get(target, p)) || ""); 5425 (startValue + "").charAt(1) === "=" && (startValue = _get(target, p)); 5426 } else { 5427 startValue = _get(target, p); 5428 } 5429 5430 startNum = parseFloat(startValue); 5431 relative = type === "string" && endValue.charAt(1) === "=" && endValue.substr(0, 2); 5432 relative && (endValue = endValue.substr(2)); 5433 endNum = parseFloat(endValue); 5434 5435 if (p in _propertyAliases) { 5436 if (p === "autoAlpha") { 5437 if (startNum === 1 && _get(target, "visibility") === "hidden" && endNum) { 5438 startNum = 0; 5439 } 5440 5441 inlineProps.push("visibility", 0, style.visibility); 5442 5443 _addNonTweeningPT(this, style, "visibility", startNum ? "inherit" : "hidden", endNum ? "inherit" : "hidden", !endNum); 5444 } 5445 5446 if (p !== "scale" && p !== "transform") { 5447 p = _propertyAliases[p]; 5448 ~p.indexOf(",") && (p = p.split(",")[0]); 5449 } 5450 } 5451 5452 isTransformRelated = p in _transformProps; 5453 5454 if (isTransformRelated) { 5455 this.styles.save(p); 5456 5457 if (!transformPropTween) { 5458 cache = target._gsap; 5459 cache.renderTransform && !vars.parseTransform || _parseTransform(target, vars.parseTransform); 5460 smooth = vars.smoothOrigin !== false && cache.smooth; 5461 transformPropTween = this._pt = new PropTween(this._pt, style, _transformProp, 0, 1, cache.renderTransform, cache, 0, -1); 5462 transformPropTween.dep = 1; 5463 } 5464 5465 if (p === "scale") { 5466 this._pt = new PropTween(this._pt, cache, "scaleY", cache.scaleY, (relative ? _parseRelative(cache.scaleY, relative + endNum) : endNum) - cache.scaleY || 0, _renderCSSProp); 5467 this._pt.u = 0; 5468 props.push("scaleY", p); 5469 p += "X"; 5470 } else if (p === "transformOrigin") { 5471 inlineProps.push(_transformOriginProp, 0, style[_transformOriginProp]); 5472 endValue = _convertKeywordsToPercentages(endValue); 5473 5474 if (cache.svg) { 5475 _applySVGOrigin(target, endValue, 0, smooth, 0, this); 5476 } else { 5477 endUnit = parseFloat(endValue.split(" ")[2]) || 0; 5478 endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, "zOrigin", cache.zOrigin, endUnit); 5479 5480 _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue)); 5481 } 5482 5483 continue; 5484 } else if (p === "svgOrigin") { 5485 _applySVGOrigin(target, endValue, 1, smooth, 0, this); 5486 5487 continue; 5488 } else if (p in _rotationalProperties) { 5489 _addRotationalPropTween(this, cache, p, startNum, relative ? _parseRelative(startNum, relative + endValue) : endValue); 5490 5491 continue; 5492 } else if (p === "smoothOrigin") { 5493 _addNonTweeningPT(this, cache, "smooth", cache.smooth, endValue); 5494 5495 continue; 5496 } else if (p === "force3D") { 5497 cache[p] = endValue; 5498 continue; 5499 } else if (p === "transform") { 5500 _addRawTransformPTs(this, endValue, target); 5501 5502 continue; 5503 } 5504 } else if (!(p in style)) { 5505 p = _checkPropPrefix(p) || p; 5506 } 5507 5508 if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) { 5509 startUnit = (startValue + "").substr((startNum + "").length); 5510 endNum || (endNum = 0); 5511 endUnit = getUnit(endValue) || (p in _config.units ? _config.units[p] : startUnit); 5512 startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit)); 5513 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); 5514 this._pt.u = endUnit || 0; 5515 5516 if (startUnit !== endUnit && endUnit !== "%") { 5517 this._pt.b = startValue; 5518 this._pt.r = _renderCSSPropWithBeginning; 5519 } 5520 } else if (!(p in style)) { 5521 if (p in target) { 5522 this.add(target, p, startValue || target[p], relative ? relative + endValue : endValue, index, targets); 5523 } else if (p !== "parseTransform") { 5524 _missingPlugin(p, endValue); 5525 5526 continue; 5527 } 5528 } else { 5529 _tweenComplexCSSString.call(this, target, p, startValue, relative ? relative + endValue : endValue); 5530 } 5531 5532 isTransformRelated || (p in style ? inlineProps.push(p, 0, style[p]) : inlineProps.push(p, 1, startValue || target[p])); 5533 props.push(p); 5534 } 5535 } 5536 5537 hasPriority && _sortPropTweensByPriority(this); 5538 }, 5539 render: function render(ratio, data) { 5540 if (data.tween._time || !_reverting$1()) { 5541 var pt = data._pt; 5542 5543 while (pt) { 5544 pt.r(ratio, pt.d); 5545 pt = pt._next; 5546 } 5547 } else { 5548 data.styles.revert(); 5549 } 5550 }, 5551 get: _get, 5552 aliases: _propertyAliases, 5553 getSetter: function getSetter(target, property, plugin) { 5554 var p = _propertyAliases[property]; 5555 p && p.indexOf(",") < 0 && (property = p); 5556 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); 5557 }, 5558 core: { 5559 _removeProperty: _removeProperty, 5560 _getMatrix: _getMatrix 5561 } 5562 };
5563 gsap.utils.checkPrefix = _checkPropPrefix; 5564 gsap.core.getStyleSaver = _getStyleSaver; 5565 5566 (function (positionAndScale, rotation, others, aliases) { 5567 var all = _forEachName(positionAndScale + "," + rotation + "," + others, function (name) { 5568 _transformProps[name] = 1; 5569 }); 5570 5571 _forEachName(rotation, function (name) { 5572 _config.units[name] = "deg"; 5573 _rotationalProperties[name] = 1; 5574 }); 5575 5576 _propertyAliases[all[13]] = positionAndScale + "," + rotation; 5577 5578 _forEachName(aliases, function (name) { 5579 var split = name.split(":"); 5580 _propertyAliases[split[1]] = all[split[0]]; 5581 }); 5582 })("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"); 5583 5584 _forEachName("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective", function (name) { 5585 _config.units[name] = "px"; 5586 }); 5587 5588 gsap.registerPlugin(CSSPlugin); 5589 5590 var gsapWithCSS = gsap.registerPlugin(CSSPlugin) || gsap, 5591 TweenMaxWithCSS = gsapWithCSS.core.Tween; 5592 5593 exports.Back = Back; 5594 exports.Bounce = Bounce; 5595 exports.CSSPlugin = CSSPlugin; 5596 exports.Circ = Circ; 5597 exports.Cubic = Cubic; 5598 exports.Elastic = Elastic; 5599 exports.Expo = Expo; 5600 exports.Linear = Linear; 5601 exports.Power0 = Power0; 5602 exports.Power1 = Power1; 5603 exports.Power2 = Power2; 5604 exports.Power3 = Power3; 5605 exports.Power4 = Power4; 5606 exports.Quad = Quad; 5607 exports.Quart = Quart; 5608 exports.Quint = Quint; 5609 exports.Sine = Sine; 5610 exports.SteppedEase = SteppedEase; 5611 exports.Strong = Strong; 5612 exports.TimelineLite = Timeline; 5613 exports.TimelineMax = Timeline; 5614 exports.TweenLite = Tween; 5615 exports.TweenMax = TweenMaxWithCSS; 5616 exports.default = gsapWithCSS; 5617 exports.gsap = gsapWithCSS; 5618 5619 if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;} 5620 5621}))); 5622"use strict"; 5623 5624function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 5625function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } 5626function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } 5627function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } 5628function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } 5629function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } 5630(function (global, factory) { 5631 (typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Lenis = factory()); 5632})(void 0, function () { 5633 'use strict'; 5634 5635 var version = "1.1.9"; 5636 5637 // Clamp a value between a minimum and maximum value 5638 function clamp(min, input, max) { 5639 return Math.max(min, Math.min(input, max)); 5640 } 5641 5642 // Linearly interpolate between two values using an amount (0 <= t <= 1) 5643 function lerp(x, y, t) { 5644 return (1 - t) * x + t * y; 5645 } 5646 5647 // http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/ 5648 function damp(x, y, lambda, dt) { 5649 return lerp(x, y, 1 - Math.exp(-lambda * dt)); 5650 } 5651 5652 // Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor 5653 // https://anguscroll.com/just/just-modulo 5654 function modulo(n, d) { 5655 return (n % d + d) % d; 5656 } 5657 var Animate = /*#__PURE__*/function () { 5658 function Animate() { 5659 _classCallCheck(this, Animate); 5660 this.isRunning = false;
5661 this.value = 0; 5662 this.from = 0; 5663 this.to = 0; 5664 this.duration = 0; 5665 this.currentTime = 0; 5666 } 5667 _createClass(Animate, [{ 5668 key: "advance", 5669 value: function advance(deltaTime) { 5670 var _a; 5671 if (!this.isRunning) return; 5672 var completed = false; 5673 if (this.duration && this.easing) { 5674 this.currentTime += deltaTime; 5675 var linearProgress = clamp(0, this.currentTime / this.duration, 1); 5676 completed = linearProgress >= 1; 5677 var easedProgress = completed ? 1 : this.easing(linearProgress); 5678 this.value = this.from + (this.to - this.from) * easedProgress; 5679 } else if (this.lerp) { 5680 this.value = damp(this.value, this.to, this.lerp * 60, deltaTime); 5681 if (Math.round(this.value) === this.to) { 5682 this.value = this.to; 5683 completed = true; 5684 } 5685 } else { 5686 this.value = this.to; 5687 completed = true; 5688 } 5689 if (completed) { 5690 this.stop(); 5691 } 5692 (_a = this.onUpdate) === null || _a === void 0 ? void 0 : _a.call(this, this.value, completed); 5693 } 5694 }, { 5695 key: "stop", 5696 value: function stop() { 5697 this.isRunning = false; 5698 } 5699 }, { 5700 key: "fromTo", 5701 value: function fromTo(from, to, _ref) { 5702 var lerp = _ref.lerp, 5703 duration = _ref.duration, 5704 easing = _ref.easing, 5705 onStart = _ref.onStart, 5706 onUpdate = _ref.onUpdate; 5707 this.from = this.value = from; 5708 this.to = to; 5709 this.lerp = lerp; 5710 this.duration = duration; 5711 this.easing = easing; 5712 this.currentTime = 0; 5713 this.isRunning = true; 5714 onStart === null || onStart === void 0 ? void 0 : onStart(); 5715 this.onUpdate = onUpdate; 5716 } 5717 }]); 5718 return Animate; 5719 }(); 5720 function debounce(callback, delay) { 5721 var timer; 5722 return function () { 5723 var args = arguments; 5724 var context = this; 5725 clearTimeout(timer); 5726 timer = setTimeout(function () { 5727 callback.apply(context, args); 5728 }, delay); 5729 }; 5730 } 5731 var Dimensions = /*#__PURE__*/function () { 5732 function Dimensions() { 5733 var _this = this; 5734 var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, 5735 wrapper = _ref2.wrapper, 5736 content = _ref2.content, 5737 _ref2$autoResize = _ref2.autoResize, 5738 autoResize = _ref2$autoResize === void 0 ? true : _ref2$autoResize, 5739 _ref2$debounce = _ref2.debounce, 5740 debounceValue = _ref2$debounce === void 0 ? 250 : _ref2$debounce; 5741 _classCallCheck(this, Dimensions); 5742 this.width = 0; 5743 this.height = 0; 5744 this.scrollWidth = 0; 5745 this.scrollHeight = 0; 5746 this.resize = function () { 5747 _this.onWrapperResize(); 5748 _this.onContentResize(); 5749 }; 5750 this.onWrapperResize = function () { 5751 if (_this.wrapper === window) { 5752 _this.width = window.innerWidth; 5753 _this.height = window.innerHeight; 5754 } else if (_this.wrapper instanceof HTMLElement) { 5755 _this.width = _this.wrapper.clientWidth; 5756 _this.height = _this.wrapper.clientHeight; 5757 } 5758 }; 5759 this.onContentResize = function () { 5760 if (_this.wrapper === window) { 5761 _this.scrollHeight = _this.content.scrollHeight; 5762 _this.scrollWidth = _this.content.scrollWidth; 5763 } else if (_this.wrapper instanceof HTMLElement) { 5764 _this.scrollHeight = _this.wrapper.scrollHeight; 5765 _this.scrollWidth = _this.wrapper.scrollWidth; 5766 } 5767 }; 5768 this.wrapper = wrapper; 5769 this.content = content; 5770 if (autoResize) { 5771 this.debouncedResize = debounce(this.resize, debounceValue); 5772 if (this.wrapper === window) { 5773 window.addEventListener('resize', this.debouncedResize, false); 5774 } else { 5775 this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize); 5776 this.wrapperResizeObserver.observe(this.wrapper); 5777 } 5778 this.contentResizeObserver = new ResizeObserver(this.debouncedResize); 5779 this.contentResizeObserver.observe(this.content); 5780 } 5781 this.resize(); 5782 } 5783 _createClass(Dimensions, [{
5784 key: "destroy", 5785 value: function destroy() { 5786 var _a, _b; 5787 (_a = this.wrapperResizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect(); 5788 (_b = this.contentResizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect(); 5789 window.removeEventListener('resize', this.debouncedResize, false); 5790 } 5791 }, { 5792 key: "limit", 5793 get: function get() { 5794 return { 5795 x: this.scrollWidth - this.width, 5796 y: this.scrollHeight - this.height 5797 }; 5798 } 5799 }]); 5800 return Dimensions; 5801 }(); 5802 var Emitter = /*#__PURE__*/function () { 5803 function Emitter() { 5804 _classCallCheck(this, Emitter); 5805 this.events = {}; 5806 } 5807 _createClass(Emitter, [{ 5808 key: "emit", 5809 value: function emit(event) { 5810 var callbacks = this.events[event] || []; 5811 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 5812 args[_key - 1] = arguments[_key]; 5813 } 5814 for (var i = 0, length = callbacks.length; i < length; i++) { 5815 callbacks[i].apply(callbacks, args); 5816 } 5817 } 5818 }, { 5819 key: "on", 5820 value: function on(event, callback) { 5821 var _this2 = this; 5822 var _a; 5823 ((_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.push(callback)) || (this.events[event] = [callback]); 5824 return function () { 5825 var _a; 5826 _this2.events[event] = (_a = _this2.events[event]) === null || _a === void 0 ? void 0 : _a.filter(function (i) { 5827 return callback !== i; 5828 }); 5829 }; 5830 } 5831 }, { 5832 key: "off", 5833 value: function off(event, callback) { 5834 var _a; 5835 this.events[event] = (_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.filter(function (i) { 5836 return callback !== i; 5837 }); 5838 } 5839 }, { 5840 key: "destroy", 5841 value: function destroy() { 5842 this.events = {}; 5843 } 5844 }]); 5845 return Emitter; 5846 }(); 5847 var LINE_HEIGHT = 100 / 6; 5848 var VirtualScroll = /*#__PURE__*/function () { 5849 function VirtualScroll(element, _ref3) { 5850 var _this3 = this; 5851 var _ref3$wheelMultiplier = _ref3.wheelMultiplier, 5852 wheelMultiplier = _ref3$wheelMultiplier === void 0 ? 1 : _ref3$wheelMultiplier, 5853 _ref3$touchMultiplier = _ref3.touchMultiplier, 5854 touchMultiplier = _ref3$touchMultiplier === void 0 ? 1 : _ref3$touchMultiplier; 5855 _classCallCheck(this, VirtualScroll); 5856 this.lastDelta = { 5857 x: 0, 5858 y: 0 5859 }; 5860 this.windowWidth = 0; 5861 this.windowHeight = 0; 5862 this.onTouchStart = function (event) { 5863 var _ref4 = event.targetTouches ? event.targetTouches[0] : event, 5864 clientX = _ref4.clientX, 5865 clientY = _ref4.clientY; 5866 _this3.touchStart.x = clientX; 5867 _this3.touchStart.y = clientY; 5868 _this3.lastDelta = { 5869 x: 0, 5870 y: 0 5871 }; 5872 _this3.emitter.emit('scroll', { 5873 deltaX: 0, 5874 deltaY: 0, 5875 event: event 5876 }); 5877 }; 5878 this.onTouchMove = function (event) { 5879 var _a, _b, _c, _d; 5880 var _ref5 = event.targetTouches ? event.targetTouches[0] : event, 5881 clientX = _ref5.clientX, 5882 clientY = _ref5.clientY; 5883 var deltaX = -(clientX - ((_b = (_a = _this3.touchStart) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 0)) * _this3.touchMultiplier; 5884 var deltaY = -(clientY - ((_d = (_c = _this3.touchStart) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0)) * _this3.touchMultiplier; 5885 _this3.touchStart.x = clientX; 5886 _this3.touchStart.y = clientY; 5887 _this3.lastDelta = { 5888 x: deltaX, 5889 y: deltaY 5890 }; 5891 _this3.emitter.emit('scroll', { 5892 deltaX: deltaX, 5893 deltaY: deltaY, 5894 event: event 5895 }); 5896 }; 5897 this.onTouchEnd = function (event) { 5898 _this3.emitter.emit('scroll', { 5899 deltaX: _this3.lastDelta.x, 5900 deltaY: _this3.lastDelta.y, 5901 event: event 5902 }); 5903 }; 5904 this.onWheel = function (event) { 5905 var deltaX = event.deltaX, 5906 deltaY = event.deltaY, 5907 deltaMode = event.deltaMode; 5908 var multiplierX = deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? _this3.windowWidth : 1; 5909 var multiplierY = deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? _this3.windowHeight : 1; 5910 deltaX *= multiplierX; 5911 deltaY *= multiplierY; 5912 deltaX *= _this3.wheelMultiplier; 5913 deltaY *= _this3.wheelMultiplier; 5914 _this3.emitter.emit('scroll', { 5915 deltaX: deltaX, 5916 deltaY: deltaY, 5917 event: event 5918 }); 5919 }; 5920 this.onWindowResize = function () { 5921 _this3.windowWidth = window.innerWidth; 5922 _this3.windowHeight = window.innerHeight; 5923 }; 5924 this.element = element; 5925 this.wheelMultiplier = wheelMultiplier; 5926 this.touchMultiplier = touchMultiplier; 5927 this.touchStart = { 5928 x: null, 5929 y: null 5930 }; 5931 this.emitter = new Emitter(); 5932 window.addEventListener('resize', this.onWindowResize, false); 5933 this.onWindowResize(); 5934 this.element.addEventListener('wheel', this.onWheel, { 5935 passive: false 5936 }); 5937 this.element.addEventListener('touchstart', this.onTouchStart, { 5938 passive: false 5939 }); 5940 this.element.addEventListener('touchmove', this.onTouchMove, { 5941 passive: false 5942 }); 5943 this.element.addEventListener('touchend', this.onTouchEnd, { 5944 passive: false 5945 }); 5946 } 5947 _createClass(VirtualScroll, [{ 5948 key: "on", 5949 value: function on(event, callback) { 5950 return this.emitter.on(event, callback); 5951 } 5952 }, {
5953 key: "destroy", 5954 value: function destroy() { 5955 this.emitter.destroy(); 5956 window.removeEventListener('resize', this.onWindowResize, false); 5957 this.element.removeEventListener('wheel', this.onWheel); 5958 this.element.removeEventListener('touchstart', this.onTouchStart); 5959 this.element.removeEventListener('touchmove', this.onTouchMove); 5960 this.element.removeEventListener('touchend', this.onTouchEnd); 5961 } 5962 }]); 5963 return VirtualScroll; 5964 }(); 5965 var Lenis = /*#__PURE__*/function () { 5966 function Lenis() { 5967 var _this4 = this; 5968 var _ref6 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, 5969 _ref6$wrapper = _ref6.wrapper, 5970 wrapper = _ref6$wrapper === void 0 ? window : _ref6$wrapper, 5971 _ref6$content = _ref6.content, 5972 content = _ref6$content === void 0 ? document.documentElement : _ref6$content, 5973 _ref6$wheelEventsTarg = _ref6.wheelEventsTarget, 5974 wheelEventsTarget = _ref6$wheelEventsTarg === void 0 ? wrapper : _ref6$wheelEventsTarg, 5975 _ref6$eventsTarget = _ref6.eventsTarget, 5976 eventsTarget = _ref6$eventsTarget === void 0 ? wheelEventsTarget : _ref6$eventsTarget, 5977 _ref6$smoothWheel = _ref6.smoothWheel, 5978 smoothWheel = _ref6$smoothWheel === void 0 ? true : _ref6$smoothWheel, 5979 _ref6$syncTouch = _ref6.syncTouch, 5980 syncTouch = _ref6$syncTouch === void 0 ? false : _ref6$syncTouch, 5981 _ref6$syncTouchLerp = _ref6.syncTouchLerp, 5982 syncTouchLerp = _ref6$syncTouchLerp === void 0 ? 0.075 : _ref6$syncTouchLerp, 5983 _ref6$touchInertiaMul = _ref6.touchInertiaMultiplier, 5984 touchInertiaMultiplier = _ref6$touchInertiaMul === void 0 ? 35 : _ref6$touchInertiaMul, 5985 duration = _ref6.duration, 5986 _ref6$easing = _ref6.easing, 5987 easing = _ref6$easing === void 0 ? function (t) { 5988 return Math.min(1, 1.001 - Math.pow(2, -10 * t)); 5989 } : _ref6$easing, 5990 _ref6$lerp = _ref6.lerp, 5991 lerp = _ref6$lerp === void 0 ? 0.1 : _ref6$lerp, 5992 _ref6$infinite = _ref6.infinite, 5993 infinite = _ref6$infinite === void 0 ? false : _ref6$infinite, 5994 _ref6$orientation = _ref6.orientation, 5995 orientation = _ref6$orientation === void 0 ? 'vertical' : _ref6$orientation, 5996 _ref6$gestureOrientat = _ref6.gestureOrientation, 5997 gestureOrientation = _ref6$gestureOrientat === void 0 ? 'vertical' : _ref6$gestureOrientat, 5998 _ref6$touchMultiplier = _ref6.touchMultiplier, 5999 touchMultiplier = _ref6$touchMultiplier === void 0 ? 1 : _ref6$touchMultiplier, 6000 _ref6$wheelMultiplier = _ref6.wheelMultiplier, 6001 wheelMultiplier = _ref6$wheelMultiplier === void 0 ? 1 : _ref6$wheelMultiplier, 6002 _ref6$autoResize = _ref6.autoResize, 6003 autoResize = _ref6$autoResize === void 0 ? true : _ref6$autoResize, 6004 prevent = _ref6.prevent, 6005 virtualScroll = _ref6.virtualScroll, 6006 _ref6$__experimental_ = _ref6.__experimental__naiveDimensions, 6007 __experimental__naiveDimensions = _ref6$__experimental_ === void 0 ? false : _ref6$__experimental_; 6008 _classCallCheck(this, Lenis); 6009 this.__isScrolling = false; 6010 this.__isStopped = false; 6011 this.__isLocked = false; 6012 this.userData = {}; 6013 this.lastVelocity = 0; 6014 this.velocity = 0; 6015 this.direction = 0; 6016 this.onPointerDown = function (event) { 6017 if (event.button === 1) { 6018 _this4.reset(); 6019 } 6020 }; 6021 this.onVirtualScroll = function (data) { 6022 if (typeof _this4.options.virtualScroll === 'function' && _this4.options.virtualScroll(data) === false) return; 6023 var deltaX = data.deltaX, 6024 deltaY = data.deltaY, 6025 event = data.event; 6026 _this4.emitter.emit('virtual-scroll', { 6027 deltaX: deltaX, 6028 deltaY: deltaY, 6029 event: event 6030 }); 6031 if (event.ctrlKey) return; 6032 var isTouch = event.type.includes('touch'); 6033 var isWheel = event.type.includes('wheel'); 6034 _this4.isTouching = event.type === 'touchstart' || event.type === 'touchmove'; 6035 var isTapToStop = _this4.options.syncTouch && isTouch && event.type === 'touchstart' && !_this4.isStopped && !_this4.isLocked; 6036 if (isTapToStop) { 6037 _this4.reset(); 6038 return; 6039 }
6040 var isClick = deltaX === 0 && deltaY === 0; 6041 var isUnknownGesture = _this4.options.gestureOrientation === 'vertical' && deltaY === 0 || _this4.options.gestureOrientation === 'horizontal' && deltaX === 0; 6042 if (isClick || isUnknownGesture) { 6043 return; 6044 } 6045 var composedPath = event.composedPath(); 6046 composedPath = composedPath.slice(0, composedPath.indexOf(_this4.rootElement)); 6047 var prevent = _this4.options.prevent; 6048 if (!!composedPath.find(function (node) { 6049 var _a, _b, _c, _d, _e; 6050 return node instanceof Element && (typeof prevent === 'function' && (prevent === null || prevent === void 0 ? void 0 : prevent(node)) || ((_a = node.hasAttribute) === null || _a === void 0 ? void 0 : _a.call(node, 'data-lenis-prevent')) || isTouch && ((_b = node.hasAttribute) === null || _b === void 0 ? void 0 : _b.call(node, 'data-lenis-prevent-touch')) || isWheel && ((_c = node.hasAttribute) === null || _c === void 0 ? void 0 : _c.call(node, 'data-lenis-prevent-wheel')) || ((_d = node.classList) === null || _d === void 0 ? void 0 : _d.contains('lenis')) && !((_e = node.classList) === null || _e === void 0 ? void 0 : _e.contains('lenis-stopped'))); 6051 })) return; 6052 if (_this4.isStopped || _this4.isLocked) { 6053 event.preventDefault(); 6054 return; 6055 } 6056 var isSmooth = _this4.options.syncTouch && isTouch || _this4.options.smoothWheel && isWheel; 6057 if (!isSmooth) { 6058 _this4.isScrolling = 'native'; 6059 _this4.animate.stop(); 6060 return; 6061 } 6062 event.preventDefault(); 6063 var delta = deltaY; 6064 if (_this4.options.gestureOrientation === 'both') { 6065 delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX; 6066 } else if (_this4.options.gestureOrientation === 'horizontal') { 6067 delta = deltaX; 6068 } 6069 var syncTouch = isTouch && _this4.options.syncTouch; 6070 var isTouchEnd = isTouch && event.type === 'touchend'; 6071 var hasTouchInertia = isTouchEnd && Math.abs(delta) > 5; 6072 if (hasTouchInertia) { 6073 delta = _this4.velocity * _this4.options.touchInertiaMultiplier; 6074 } 6075 _this4.scrollTo(_this4.targetScroll + delta, Object.assign({ 6076 programmatic: false 6077 }, syncTouch ? { 6078 lerp: hasTouchInertia ? _this4.options.syncTouchLerp : 1 6079 } : { 6080 lerp: _this4.options.lerp, 6081 duration: _this4.options.duration, 6082 easing: _this4.options.easing 6083 })); 6084 }; 6085 this.onNativeScroll = function () { 6086 clearTimeout(_this4.__resetVelocityTimeout); 6087 delete _this4.__resetVelocityTimeout; 6088 if (_this4.__preventNextNativeScrollEvent) { 6089 delete _this4.__preventNextNativeScrollEvent; 6090 return; 6091 } 6092 if (_this4.isScrolling === false || _this4.isScrolling === 'native') { 6093 var lastScroll = _this4.animatedScroll; 6094 _this4.animatedScroll = _this4.targetScroll = _this4.actualScroll; 6095 _this4.lastVelocity = _this4.velocity; 6096 _this4.velocity = _this4.animatedScroll - lastScroll; 6097 _this4.direction = Math.sign(_this4.animatedScroll - lastScroll); 6098 _this4.isScrolling = 'native'; 6099 _this4.emit(); 6100 if (_this4.velocity !== 0) { 6101 _this4.__resetVelocityTimeout = setTimeout(function () { 6102 _this4.lastVelocity = _this4.velocity; 6103 _this4.velocity = 0; 6104 _this4.isScrolling = false; 6105 _this4.emit(); 6106 }, 400); 6107 } 6108 } 6109 }; 6110 window.lenisVersion = version; 6111 if (!wrapper || wrapper === document.documentElement || wrapper === document.body) { 6112 wrapper = window; 6113 } 6114 this.options = { 6115 wrapper: wrapper, 6116 content: content, 6117 wheelEventsTarget: wheelEventsTarget, 6118 eventsTarget: eventsTarget, 6119 smoothWheel: smoothWheel, 6120 syncTouch: syncTouch, 6121 syncTouchLerp: syncTouchLerp, 6122 touchInertiaMultiplier: touchInertiaMultiplier, 6123 duration: duration, 6124 easing: easing, 6125 lerp: lerp, 6126 infinite: infinite, 6127 gestureOrientation: gestureOrientation, 6128 orientation: orientation, 6129 touchMultiplier: touchMultiplier, 6130 wheelMultiplier: wheelMultiplier, 6131 autoResize: autoResize, 6132 prevent: prevent, 6133 virtualScroll: virtualScroll, 6134 __experimental__naiveDimensions: __experimental__naiveDimensions 6135 }; 6136 this.animate = new Animate(); 6137 this.emitter = new Emitter(); 6138 this.dimensions = new Dimensions({ 6139 wrapper: wrapper, 6140 content: content, 6141 autoResize: autoResize 6142 }); 6143 this.updateClassName(); 6144 this.userData = {}; 6145 this.time = 0; 6146 this.velocity = this.lastVelocity = 0;
6147 this.isLocked = false; 6148 this.isStopped = false; 6149 this.isScrolling = false; 6150 this.targetScroll = this.animatedScroll = this.actualScroll; 6151 this.options.wrapper.addEventListener('scroll', this.onNativeScroll, false); 6152 this.options.wrapper.addEventListener('pointerdown', this.onPointerDown, false); 6153 this.virtualScroll = new VirtualScroll(eventsTarget, { 6154 touchMultiplier: touchMultiplier, 6155 wheelMultiplier: wheelMultiplier 6156 }); 6157 this.virtualScroll.on('scroll', this.onVirtualScroll); 6158 } 6159 _createClass(Lenis, [{ 6160 key: "destroy", 6161 value: function destroy() { 6162 this.emitter.destroy(); 6163 this.options.wrapper.removeEventListener('scroll', this.onNativeScroll, false); 6164 this.options.wrapper.removeEventListener('pointerdown', this.onPointerDown, false); 6165 this.virtualScroll.destroy(); 6166 this.dimensions.destroy(); 6167 this.cleanUpClassName(); 6168 } 6169 }, { 6170 key: "on", 6171 value: function on(event, callback) { 6172 return this.emitter.on(event, callback); 6173 } 6174 }, { 6175 key: "off", 6176 value: function off(event, callback) { 6177 return this.emitter.off(event, callback); 6178 } 6179 }, { 6180 key: "setScroll", 6181 value: function setScroll(scroll) { 6182 if (this.isHorizontal) { 6183 this.rootElement.scrollLeft = scroll; 6184 } else { 6185 this.rootElement.scrollTop = scroll; 6186 } 6187 } 6188 }, { 6189 key: "resize", 6190 value: function resize() { 6191 this.dimensions.resize(); 6192 } 6193 }, { 6194 key: "emit", 6195 value: function emit() { 6196 this.emitter.emit('scroll', this); 6197 } 6198 }, { 6199 key: "reset", 6200 value: function reset() { 6201 this.isLocked = false; 6202 this.isScrolling = false; 6203 this.animatedScroll = this.targetScroll = this.actualScroll; 6204 this.lastVelocity = this.velocity = 0; 6205 this.animate.stop(); 6206 } 6207 }, { 6208 key: "start", 6209 value: function start() { 6210 if (!this.isStopped) return; 6211 this.isStopped = false; 6212 this.reset(); 6213 } 6214 }, { 6215 key: "stop", 6216 value: function stop() { 6217 if (this.isStopped) return; 6218 this.isStopped = true; 6219 this.animate.stop(); 6220 this.reset(); 6221 } 6222 }, { 6223 key: "raf", 6224 value: function raf(time) { 6225 var deltaTime = time - (this.time || time); 6226 this.time = time; 6227 this.animate.advance(deltaTime * 0.001); 6228 } 6229 }, { 6230 key: "scrollTo", 6231 value: function scrollTo(target) { 6232 var _this5 = this; 6233 var _ref7 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, 6234 _ref7$offset = _ref7.offset, 6235 offset = _ref7$offset === void 0 ? 0 : _ref7$offset, 6236 _ref7$immediate = _ref7.immediate, 6237 immediate = _ref7$immediate === void 0 ? false : _ref7$immediate, 6238 _ref7$lock = _ref7.lock, 6239 lock = _ref7$lock === void 0 ? false : _ref7$lock, 6240 _ref7$duration = _ref7.duration, 6241 duration = _ref7$duration === void 0 ? this.options.duration : _ref7$duration, 6242 _ref7$easing = _ref7.easing, 6243 easing = _ref7$easing === void 0 ? this.options.easing : _ref7$easing, 6244 _ref7$lerp = _ref7.lerp, 6245 lerp = _ref7$lerp === void 0 ? this.options.lerp : _ref7$lerp, 6246 _onStart = _ref7.onStart, 6247 onComplete = _ref7.onComplete, 6248 _ref7$force = _ref7.force, 6249 force = _ref7$force === void 0 ? false : _ref7$force, 6250 _ref7$programmatic = _ref7.programmatic, 6251 programmatic = _ref7$programmatic === void 0 ? true : _ref7$programmatic, 6252 _ref7$userData = _ref7.userData, 6253 userData = _ref7$userData === void 0 ? {} : _ref7$userData; 6254 if ((this.isStopped || this.isLocked) && !force) return; 6255 if (typeof target === 'string' && ['top', 'left', 'start'].includes(target)) { 6256 target = 0; 6257 } else if (typeof target === 'string' && ['bottom', 'right', 'end'].includes(target)) { 6258 target = this.limit; 6259 } else { 6260 var node; 6261 if (typeof target === 'string') { 6262 node = document.querySelector(target); 6263 } else if (target instanceof HTMLElement && (target === null || target === void 0 ? void 0 : target.nodeType)) { 6264 node = target; 6265 } 6266 if (node) { 6267 if (this.options.wrapper !== window) { 6268 var wrapperRect = this.rootElement.getBoundingClientRect(); 6269 offset -= this.isHorizontal ? wrapperRect.left : wrapperRect.top; 6270 }
6271 var rect = node.getBoundingClientRect(); 6272 target = (this.isHorizontal ? rect.left : rect.top) + this.animatedScroll; 6273 } 6274 } 6275 if (typeof target !== 'number') return; 6276 target += offset; 6277 target = Math.round(target); 6278 if (this.options.infinite) { 6279 if (programmatic) { 6280 this.targetScroll = this.animatedScroll = this.scroll; 6281 } 6282 } else { 6283 target = clamp(0, target, this.limit); 6284 } 6285 if (target === this.targetScroll) return; 6286 this.userData = userData; 6287 if (immediate) { 6288 this.animatedScroll = this.targetScroll = target; 6289 this.setScroll(this.scroll); 6290 this.reset(); 6291 this.preventNextNativeScrollEvent(); 6292 this.emit(); 6293 onComplete === null || onComplete === void 0 ? void 0 : onComplete(this); 6294 this.userData = {}; 6295 return; 6296 } 6297 if (!programmatic) { 6298 this.targetScroll = target; 6299 } 6300 this.animate.fromTo(this.animatedScroll, target, { 6301 duration: duration, 6302 easing: easing, 6303 lerp: lerp, 6304 onStart: function onStart() { 6305 if (lock) _this5.isLocked = true; 6306 _this5.isScrolling = 'smooth'; 6307 _onStart === null || _onStart === void 0 ? void 0 : _onStart(_this5); 6308 }, 6309 onUpdate: function onUpdate(value, completed) { 6310 _this5.isScrolling = 'smooth'; 6311 _this5.lastVelocity = _this5.velocity; 6312 _this5.velocity = value - _this5.animatedScroll; 6313 _this5.direction = Math.sign(_this5.velocity); 6314 _this5.animatedScroll = value; 6315 _this5.setScroll(_this5.scroll); 6316 if (programmatic) { 6317 _this5.targetScroll = value; 6318 } 6319 if (!completed) _this5.emit(); 6320 if (completed) { 6321 _this5.reset(); 6322 _this5.emit(); 6323 onComplete === null || onComplete === void 0 ? void 0 : onComplete(_this5); 6324 _this5.userData = {}; 6325 _this5.preventNextNativeScrollEvent(); 6326 } 6327 } 6328 }); 6329 } 6330 }, { 6331 key: "preventNextNativeScrollEvent", 6332 value: function preventNextNativeScrollEvent() { 6333 var _this6 = this; 6334 this.__preventNextNativeScrollEvent = true; 6335 requestAnimationFrame(function () { 6336 delete _this6.__preventNextNativeScrollEvent; 6337 }); 6338 } 6339 }, { 6340 key: "rootElement", 6341 get: function get() { 6342 return this.options.wrapper === window ? document.documentElement : this.options.wrapper; 6343 } 6344 }, { 6345 key: "limit", 6346 get: function get() { 6347 if (this.options.__experimental__naiveDimensions) { 6348 if (this.isHorizontal) { 6349 return this.rootElement.scrollWidth - this.rootElement.clientWidth; 6350 } else { 6351 return this.rootElement.scrollHeight - this.rootElement.clientHeight; 6352 } 6353 } else { 6354 return this.dimensions.limit[this.isHorizontal ? 'x' : 'y']; 6355 } 6356 } 6357 }, { 6358 key: "isHorizontal", 6359 get: function get() { 6360 return this.options.orientation === 'horizontal'; 6361 } 6362 }, { 6363 key: "actualScroll", 6364 get: function get() { 6365 return this.isHorizontal ? this.rootElement.scrollLeft : this.rootElement.scrollTop; 6366 } 6367 }, { 6368 key: "scroll", 6369 get: function get() { 6370 return this.options.infinite ? modulo(this.animatedScroll, this.limit) : this.animatedScroll; 6371 } 6372 }, { 6373 key: "progress", 6374 get: function get() { 6375 return this.limit === 0 ? 1 : this.scroll / this.limit; 6376 } 6377 }, { 6378 key: "isScrolling", 6379 get: function get() { 6380 return this.__isScrolling; 6381 }, 6382 set: function set(value) { 6383 if (this.__isScrolling !== value) { 6384 this.__isScrolling = value; 6385 this.updateClassName(); 6386 } 6387 } 6388 }, { 6389 key: "isStopped", 6390 get: function get() { 6391 return this.__isStopped; 6392 }, 6393 set: function set(value) { 6394 if (this.__isStopped !== value) { 6395 this.__isStopped = value; 6396 this.updateClassName(); 6397 } 6398 } 6399 }, {
6400 key: "isLocked", 6401 get: function get() { 6402 return this.__isLocked; 6403 }, 6404 set: function set(value) { 6405 if (this.__isLocked !== value) { 6406 this.__isLocked = value; 6407 this.updateClassName(); 6408 } 6409 } 6410 }, { 6411 key: "isSmooth", 6412 get: function get() { 6413 return this.isScrolling === 'smooth'; 6414 } 6415 }, { 6416 key: "className", 6417 get: function get() { 6418 var className = 'lenis'; 6419 if (this.isStopped) className += ' lenis-stopped'; 6420 if (this.isLocked) className += ' lenis-locked'; 6421 if (this.isScrolling) className += ' lenis-scrolling'; 6422 if (this.isScrolling === 'smooth') className += ' lenis-smooth'; 6423 return className; 6424 } 6425 }, { 6426 key: "updateClassName", 6427 value: function updateClassName() { 6428 this.cleanUpClassName(); 6429 this.rootElement.className = "".concat(this.rootElement.className, " ").concat(this.className).trim(); 6430 } 6431 }, { 6432 key: "cleanUpClassName", 6433 value: function cleanUpClassName() { 6434 this.rootElement.className = this.rootElement.className.replace(/lenis(-\w+)?/g, '').trim(); 6435 } 6436 }]); 6437 return Lenis; 6438 }(); 6439 return Lenis; 6440}); 6441(function(window, $) { 6442 "use strict"; 6443 6444 var counter = 0, 6445 $headCache = $('head'), 6446 oldBigText = window.BigText, 6447 oldjQueryMethod = $.fn.bigtext, 6448 BigText = { 6449 DEBUG_MODE: false, 6450 DEFAULT_MIN_FONT_SIZE_PX: null, 6451 DEFAULT_MAX_FONT_SIZE_PX: 1056, 6452 GLOBAL_STYLE_ID: 'bigtext-style', 6453 STYLE_ID: 'bigtext-id', 6454 LINE_CLASS_PREFIX: 'bigtext-line', 6455 EXEMPT_CLASS: 'bigtext-exempt', 6456 noConflict: function(restore) 6457 { 6458 if(restore) { 6459 $.fn.bigtext = oldjQueryMethod; 6460 window.BigText = oldBigText; 6461 } 6462 return BigText; 6463 }, 6464 supports: { 6465 wholeNumberFontSizeOnly: (function() { 6466 if( !( 'getComputedStyle' in window ) ) { 6467 return true; 6468 } 6469 var test = $('<div/>').css({ 6470 position: 'absolute', 6471 'font-size': '14.1px' 6472 }).insertBefore( $('script').eq(0) ), 6473 computedStyle = window.getComputedStyle( test[0], null ); 6474 6475 var ret = computedStyle && computedStyle.getPropertyValue( 'font-size' ) === '14px'; 6476 test.remove(); 6477 return ret; 6478 })() 6479 }, 6480 init: function() { 6481 if(!$('#'+BigText.GLOBAL_STYLE_ID).length) { 6482 $headCache.append(BigText.generateStyleTag(BigText.GLOBAL_STYLE_ID, ['.bigtext * { white-space: nowrap; } .bigtext > * { display: block; }', 6483 '.bigtext .' + BigText.EXEMPT_CLASS + ', .bigtext .' + BigText.EXEMPT_CLASS + ' * { white-space: normal; }'])); 6484 } 6485 }, 6486 bindResize: function(eventName, resizeFunction) { 6487 var timeoutId; 6488 $(window).off(eventName).on(eventName, function() { 6489 if( timeoutId ) { 6490 clearTimeout( timeoutId ); 6491 } 6492 timeoutId = setTimeout( resizeFunction, 100 ); 6493 }); 6494 }, 6495 getStyleId: function(id) 6496 { 6497 return BigText.STYLE_ID + '-' + id; 6498 }, 6499 generateStyleTag: function(id, css) 6500 { 6501 return $('<style>' + css.join('\n') + '</style>').attr('id', id); 6502 }, 6503 clearCss: function(id) 6504 { 6505 var styleId = BigText.getStyleId(id); 6506 $('#' + styleId).remove(); 6507 }, 6508 generateCss: function(id, linesFontSizes, lineWordSpacings, minFontSizes) 6509 { 6510 var css = []; 6511 6512 BigText.clearCss(id); 6513 6514 for(var j=0, k=linesFontSizes.length; j<k; j++) { 6515 css.push('#' + id + ' .' + BigText.LINE_CLASS_PREFIX + j + ' {' + 6516 (minFontSizes[j] ? ' white-space: normal;' : '') + 6517 (linesFontSizes[j] ? ' font-size: ' + linesFontSizes[j] + 'px;' : '') + 6518 (lineWordSpacings[j] ? ' word-spacing: ' + lineWordSpacings[j] + 'px;' : '') + 6519 '}'); 6520 } 6521 6522 return BigText.generateStyleTag(BigText.getStyleId(id), css); 6523 }, 6524 jQueryMethod: function(options) 6525 {
6526 BigText.init(); 6527 6528 options = $.extend({ 6529 minfontsize: BigText.DEFAULT_MIN_FONT_SIZE_PX, 6530 maxfontsize: BigText.DEFAULT_MAX_FONT_SIZE_PX, 6531 childSelector: '', 6532 resize: true 6533 }, options || {}); 6534 6535 this.each(function() 6536 { 6537 var $t = $(this).addClass('bigtext'), 6538 maxWidth = $t.width(), 6539 id = $t.attr('id'), 6540 $children = options.childSelector ? $t.find( options.childSelector ) : $t.children(); 6541 6542 if(!id) { 6543 id = 'bigtext-id' + (counter++); 6544 $t.attr('id', id); 6545 } 6546 6547 if(options.resize) { 6548 BigText.bindResize('resize.bigtext-event-' + id, function() 6549 { 6550 // TODO only call this if the width has changed. 6551 BigText.jQueryMethod.call($('#' + id), options); 6552 }); 6553 } 6554 6555 BigText.clearCss(id); 6556 6557 $children.addClass(function(lineNumber, className) 6558 { 6559 // remove existing line classes. 6560 return [className.replace(new RegExp('\\b' + BigText.LINE_CLASS_PREFIX + '\\d+\\b'), ''), 6561 BigText.LINE_CLASS_PREFIX + lineNumber].join(' '); 6562 }); 6563 6564 var sizes = BigText.calculateSizes($t, $children, maxWidth, options.maxfontsize, options.minfontsize); 6565 $headCache.append(BigText.generateCss(id, sizes.fontSizes, sizes.wordSpacings, sizes.minFontSizes)); 6566 }); 6567 6568 return this.trigger('bigtext:complete'); 6569 }, 6570 testLineDimensions: function($line, maxWidth, property, size, interval, units, previousWidth) 6571 { 6572 var width; 6573 previousWidth = typeof previousWidth === 'number' ? previousWidth : 0; 6574 $line.css(property, size + units); 6575 6576 width = $line.width(); 6577 6578 if(width >= maxWidth) { 6579 // console.log(width, ' previous: ' + previousWidth, property + ' at ' + interval, 'prior: ' + (parseFloat(size) - interval), 'new:' + parseFloat(size)); 6580 $line.css(property, ''); 6581 6582 if(width === maxWidth) { 6583 return { 6584 match: 'exact', 6585 size: parseFloat((parseFloat(size) - 0.1).toFixed(3)) 6586 }; 6587 } 6588 6589 // Since this is an estimate, we calculate how far over the width we went with the new value. 6590 // If this is word-spacing (our last resort guess) and the over is less than the under, we keep the higher value. 6591 // Otherwise, we revert to the underestimate. 6592 var under = maxWidth - previousWidth, 6593 over = width - maxWidth; 6594 6595 return { 6596 match: 'estimate', 6597 size: parseFloat((parseFloat(size) - (property === 'word-spacing' && previousWidth && ( over < under ) ? 0 : interval)).toFixed(3)) 6598 }; 6599 } 6600 6601 return width; 6602 }, 6603 calculateSizes: function($t, $children, maxWidth, maxFontSize, minFontSize) 6604 { 6605 var $c = $t.clone(true) 6606 .addClass('bigtext-cloned') 6607 .css({ 6608 fontFamily: $t.css('font-family'), 6609 textTransform: $t.css('text-transform'), 6610 wordSpacing: $t.css('word-spacing'), 6611 letterSpacing: $t.css('letter-spacing'), 6612 position: 'absolute', 6613 left: BigText.DEBUG_MODE ? 0 : -9999, 6614 top: BigText.DEBUG_MODE ? 0 : -9999 6615 }) 6616 .appendTo(document.body); 6617 6618 // font-size isn't the only thing we can modify, we can also mess with: 6619 // word-spacing and letter-spacing. WebKit does not respect subpixel 6620 // letter-spacing, word-spacing, or font-size. 6621 // TODO try -webkit-transform: scale() as a workaround. 6622 var fontSizes = [], 6623 wordSpacings = [], 6624 minFontSizes = [], 6625 ratios = []; 6626 6627 $children.css('float', 'left').each(function() { 6628 var $line = $(this), 6629 // TODO replace 8, 4 with a proportional size to the calculated font-size. 6630 intervals = BigText.supports.wholeNumberFontSizeOnly ? [8, 4, 1] : [8, 4, 1, 0.1], 6631 lineMax, 6632 newFontSize; 6633 6634 if($line.hasClass(BigText.EXEMPT_CLASS)) { 6635 fontSizes.push(null); 6636 ratios.push(null); 6637 minFontSizes.push(false); 6638 return; 6639 } 6640 6641 // TODO we can cache this ratio? 6642 var autoGuessSubtraction = 32, // font size in px 6643 currentFontSize = parseFloat($line.css('font-size')), 6644 ratio = ( $line.width() / currentFontSize ).toFixed(6); 6645 6646 newFontSize = parseInt( maxWidth / ratio, 10 ) - autoGuessSubtraction; 6647 6648 outer: for(var m=0, n=intervals.length; m<n; m++) { 6649 inner: for(var j=1, k=10; j<=k; j++) { 6650 if(newFontSize + j*intervals[m] > maxFontSize) { 6651 newFontSize = maxFontSize; 6652 break outer; 6653 } 6654 6655 lineMax = BigText.testLineDimensions($line, maxWidth, 'font-size', newFontSize + j*intervals[m], intervals[m], 'px', lineMax); 6656 if(typeof lineMax !== 'number') { 6657 newFontSize = lineMax.size; 6658 6659 if(lineMax.match === 'exact') { 6660 break outer; 6661 } 6662 break inner; 6663 } 6664 } 6665 } 6666 6667 ratios.push(maxWidth / newFontSize); 6668 6669 if(newFontSize > maxFontSize) { 6670 fontSizes.push(maxFontSize); 6671 minFontSizes.push(false); 6672 } else if(!!minFontSize && newFontSize < minFontSize) { 6673 fontSizes.push(minFontSize); 6674 minFontSizes.push(true); 6675 } else { 6676 fontSizes.push(newFontSize); 6677 minFontSizes.push(false); 6678 } 6679 }).each(function(lineNumber) { 6680 var $line = $(this), 6681 wordSpacing = 0, 6682 interval = 1, 6683 maxWordSpacing; 6684 6685 if($line.hasClass(BigText.EXEMPT_CLASS)) { 6686 wordSpacings.push(null); 6687 return; 6688 } 6689 6690 // must re-use font-size, even though it was removed above. 6691 $line.css('font-size', fontSizes[lineNumber] + 'px'); 6692 6693 for(var m=1, n=3; m<n; m+=interval) { 6694 maxWordSpacing = BigText.testLineDimensions($line, maxWidth, 'word-spacing', m, interval, 'px', maxWordSpacing); 6695 if(typeof maxWordSpacing !== 'number') { 6696 wordSpacing = maxWordSpacing.size; 6697 break; 6698 } 6699 } 6700 6701 $line.css('font-size', ''); 6702 wordSpacings.push(wordSpacing); 6703 }).removeAttr('style'); 6704 6705 if( !BigText.DEBUG_MODE ) { 6706 $c.remove(); 6707 } else { 6708 $c.css({ 6709 'background-color': 'rgba(255,255,255,.4)' 6710 }); 6711 } 6712 6713 return { 6714 fontSizes: fontSizes, 6715 wordSpacings: wordSpacings, 6716 ratios: ratios, 6717 minFontSizes: minFontSizes 6718 }; 6719 } 6720 }; 6721 6722 $.fn.bigtext = BigText.jQueryMethod; 6723 window.BigText = BigText; 6724 6725})(this, jQuery);
vendor: 16,093 bytes, lines 6726-7383
6726/*! 6727 * Isotope PACKAGED v3.0.6 6728 * 6729 * Licensed GPLv3 for open source use 6730 * or Isotope Commercial License for commercial use 6731 * 6732 * https://isotope.metafizzy.co 6733 * Copyright 2010-2018 Metafizzy 6734 */ 6735 6736/** 6737 * Bridget makes jQuery widgets 6738 * v2.0.1 6739 * MIT license 6740 */ 6741 6742/* jshint browser: true, strict: true, undef: true, unused: true */ 6743 6744( function( window, factory ) { 6745 // universal module definition 6746 /*jshint strict: false */ /* globals define, module, require */ 6747 if ( typeof define == 'function' && define.amd ) { 6748 // AMD 6749 define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) { 6750 return factory( window, jQuery ); 6751 }); 6752 } else if ( typeof module == 'object' && module.exports ) { 6753 // CommonJS 6754 module.exports = factory( 6755 window, 6756 require('jquery') 6757 ); 6758 } else { 6759 // browser global 6760 window.jQueryBridget = factory( 6761 window, 6762 window.jQuery 6763 ); 6764 } 6765 6766}( window, function factory( window, jQuery ) { 6767'use strict'; 6768 6769// ----- utils ----- // 6770 6771var arraySlice = Array.prototype.slice; 6772 6773// helper function for logging errors 6774// $.error breaks jQuery chaining 6775var console = window.console; 6776var logError = typeof console == 'undefined' ? function() {} : 6777 function( message ) { 6778 console.error( message ); 6779 }; 6780 6781// ----- jQueryBridget ----- // 6782 6783function jQueryBridget( namespace, PluginClass, $ ) { 6784 $ = $ || jQuery || window.jQuery; 6785 if ( !$ ) { 6786 return; 6787 } 6788 6789 // add option method -> $().plugin('option', {...}) 6790 if ( !PluginClass.prototype.option ) { 6791 // option setter 6792 PluginClass.prototype.option = function( opts ) { 6793 // bail out if not an object 6794 if ( !$.isPlainObject( opts ) ){ 6795 return; 6796 } 6797 this.options = $.extend( true, this.options, opts ); 6798 }; 6799 } 6800 6801 // make jQuery plugin 6802 $.fn[ namespace ] = function( arg0 /*, arg1 */ ) { 6803 if ( typeof arg0 == 'string' ) { 6804 // method call $().plugin( 'methodName', { options } ) 6805 // shift arguments by 1 6806 var args = arraySlice.call( arguments, 1 ); 6807 return methodCall( this, arg0, args ); 6808 } 6809 // just $().plugin({ options }) 6810 plainCall( this, arg0 ); 6811 return this; 6812 }; 6813 6814 // $().plugin('methodName') 6815 function methodCall( $elems, methodName, args ) { 6816 var returnValue; 6817 var pluginMethodStr = '$().' + namespace + '("' + methodName + '")'; 6818 6819 $elems.each( function( i, elem ) { 6820 // get instance 6821 var instance = $.data( elem, namespace ); 6822 if ( !instance ) { 6823 logError( namespace + ' not initialized. Cannot call methods, i.e. ' + 6824 pluginMethodStr ); 6825 return; 6826 } 6827 6828 var method = instance[ methodName ]; 6829 if ( !method || methodName.charAt(0) == '_' ) { 6830 logError( pluginMethodStr + ' is not a valid method' ); 6831 return; 6832 } 6833 6834 // apply method, get return value 6835 var value = method.apply( instance, args ); 6836 // set return value if value is returned, use only first value 6837 returnValue = returnValue === undefined ? value : returnValue; 6838 }); 6839 6840 return returnValue !== undefined ? returnValue : $elems; 6841 } 6842 6843 function plainCall( $elems, options ) { 6844 $elems.each( function( i, elem ) { 6845 var instance = $.data( elem, namespace ); 6846 if ( instance ) { 6847 // set options & init 6848 instance.option( options ); 6849 instance._init(); 6850 } else { 6851 // initialize new instance 6852 instance = new PluginClass( elem, options ); 6853 $.data( elem, namespace, instance ); 6854 } 6855 }); 6856 } 6857 6858 updateJQuery( $ ); 6859 6860} 6861 6862// ----- updateJQuery ----- // 6863 6864// set $.bridget for v1 backwards compatibility 6865function updateJQuery( $ ) { 6866 if ( !$ || ( $ && $.bridget ) ) { 6867 return; 6868 } 6869 $.bridget = jQueryBridget; 6870} 6871 6872updateJQuery( jQuery || window.jQuery ); 6873 6874// ----- ----- // 6875 6876return jQueryBridget; 6877 6878})); 6879 6880/** 6881 * EvEmitter v1.1.0 6882 * Lil' event emitter 6883 * MIT License 6884 */ 6885 6886/* jshint unused: true, undef: true, strict: true */ 6887 6888( function( global, factory ) { 6889 // universal module definition 6890 /* jshint strict: false */ /* globals define, module, window */ 6891 if ( typeof define == 'function' && define.amd ) { 6892 // AMD - RequireJS 6893 define( 'ev-emitter/ev-emitter',factory ); 6894 } else if ( typeof module == 'object' && module.exports ) { 6895 // CommonJS - Browserify, Webpack 6896 module.exports = factory(); 6897 } else { 6898 // Browser globals 6899 global.EvEmitter = factory(); 6900 } 6901 6902}( typeof window != 'undefined' ? window : this, function() { 6903 6904 6905 6906function EvEmitter() {} 6907 6908var proto = EvEmitter.prototype; 6909 6910proto.on = function( eventName, listener ) { 6911 if ( !eventName || !listener ) { 6912 return; 6913 } 6914 // set events hash 6915 var events = this._events = this._events || {}; 6916 // set listeners array 6917 var listeners = events[ eventName ] = events[ eventName ] || []; 6918 // only add once 6919 if ( listeners.indexOf( listener ) == -1 ) { 6920 listeners.push( listener ); 6921 } 6922 6923 return this; 6924}; 6925 6926proto.once = function( eventName, listener ) { 6927 if ( !eventName || !listener ) { 6928 return; 6929 } 6930 // add event 6931 this.on( eventName, listener ); 6932 // set once flag 6933 // set onceEvents hash 6934 var onceEvents = this._onceEvents = this._onceEvents || {}; 6935 // set onceListeners object 6936 var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 6937 // set flag 6938 onceListeners[ listener ] = true; 6939 6940 return this; 6941}; 6942 6943proto.off = function( eventName, listener ) { 6944 var listeners = this._events && this._events[ eventName ]; 6945 if ( !listeners || !listeners.length ) { 6946 return; 6947 } 6948 var index = listeners.indexOf( listener ); 6949 if ( index != -1 ) { 6950 listeners.splice( index, 1 ); 6951 } 6952 6953 return this; 6954}; 6955 6956proto.emitEvent = function( eventName, args ) { 6957 var listeners = this._events && this._events[ eventName ]; 6958 if ( !listeners || !listeners.length ) { 6959 return; 6960 } 6961 // copy over to avoid interference if .off() in listener 6962 listeners = listeners.slice(0); 6963 args = args || []; 6964 // once stuff 6965 var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 6966 6967 for ( var i=0; i < listeners.length; i++ ) { 6968 var listener = listeners[i] 6969 var isOnce = onceListeners && onceListeners[ listener ]; 6970 if ( isOnce ) { 6971 // remove listener 6972 // remove before trigger to prevent recursion 6973 this.off( eventName, listener ); 6974 // unset once flag 6975 delete onceListeners[ listener ]; 6976 } 6977 // trigger listener 6978 listener.apply( this, args ); 6979 } 6980 6981 return this; 6982}; 6983 6984proto.allOff = function() { 6985 delete this._events; 6986 delete this._onceEvents; 6987}; 6988 6989return EvEmitter; 6990 6991})); 6992 6993/*! 6994 * getSize v2.0.3 6995 * measure size of elements 6996 * MIT license 6997 */ 6998 6999/* jshint browser: true, strict: true, undef: true, unused: true */ 7000/* globals console: false */ 7001 7002( function( window, factory ) { 7003 /* jshint strict: false */ /* globals define, module */ 7004 if ( typeof define == 'function' && define.amd ) { 7005 // AMD 7006 define( 'get-size/get-size',factory ); 7007 } else if ( typeof module == 'object' && module.exports ) { 7008 // CommonJS 7009 module.exports = factory(); 7010 } else { 7011 // browser global 7012 window.getSize = factory(); 7013 } 7014 7015})( window, function factory() { 7016'use strict'; 7017 7018// -------------------------- helpers -------------------------- // 7019 7020// get a number from a string, not a percentage 7021function getStyleSize( value ) { 7022 var num = parseFloat( value ); 7023 // not a percent like '100%', and a number 7024 var isValid = value.indexOf('%') == -1 && !isNaN( num ); 7025 return isValid && num; 7026} 7027 7028function noop() {} 7029 7030var logError = typeof console == 'undefined' ? noop : 7031 function( message ) { 7032 console.error( message ); 7033 }; 7034 7035// -------------------------- measurements -------------------------- // 7036 7037var measurements = [ 7038 'paddingLeft', 7039 'paddingRight', 7040 'paddingTop', 7041 'paddingBottom', 7042 'marginLeft', 7043 'marginRight', 7044 'marginTop', 7045 'marginBottom', 7046 'borderLeftWidth', 7047 'borderRightWidth', 7048 'borderTopWidth', 7049 'borderBottomWidth' 7050]; 7051 7052var measurementsLength = measurements.length; 7053 7054function getZeroSize() { 7055 var size = { 7056 width: 0, 7057 height: 0, 7058 innerWidth: 0, 7059 innerHeight: 0, 7060 outerWidth: 0, 7061 outerHeight: 0 7062 }; 7063 for ( var i=0; i < measurementsLength; i++ ) { 7064 var measurement = measurements[i]; 7065 size[ measurement ] = 0; 7066 } 7067 return size; 7068} 7069 7070// -------------------------- getStyle -------------------------- // 7071 7072/** 7073 * getStyle, get style of element, check for Firefox bug 7074 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397 7075 */ 7076function getStyle( elem ) { 7077 var style = getComputedStyle( elem ); 7078 if ( !style ) { 7079 logError( 'Style returned ' + style + 7080 '. Are you running this code in a hidden iframe on Firefox? ' + 7081 'See https://bit.ly/getsizebug1' ); 7082 } 7083 return style; 7084} 7085 7086// -------------------------- setup -------------------------- // 7087 7088var isSetup = false; 7089 7090var isBoxSizeOuter; 7091 7092/** 7093 * setup 7094 * check isBoxSizerOuter 7095 * do on first getSize() rather than on page load for Firefox bug 7096 */ 7097function setup() { 7098 // setup once 7099 if ( isSetup ) { 7100 return; 7101 } 7102 isSetup = true; 7103 7104 // -------------------------- box sizing -------------------------- // 7105 7106 /** 7107 * Chrome & Safari measure the outer-width on style.width on border-box elems 7108 * IE11 & Firefox<29 measures the inner-width 7109 */ 7110 var div = document.createElement('div'); 7111 div.style.width = '200px'; 7112 div.style.padding = '1px 2px 3px 4px'; 7113 div.style.borderStyle = 'solid'; 7114 div.style.borderWidth = '1px 2px 3px 4px'; 7115 div.style.boxSizing = 'border-box'; 7116 7117 var body = document.body || document.documentElement; 7118 body.appendChild( div ); 7119 var style = getStyle( div ); 7120 // round value for browser zoom. desandro/masonry#928 7121 isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200; 7122 getSize.isBoxSizeOuter = isBoxSizeOuter; 7123 7124 body.removeChild( div ); 7125} 7126 7127// -------------------------- getSize -------------------------- // 7128 7129function getSize( elem ) { 7130 setup(); 7131 7132 // use querySeletor if elem is string 7133 if ( typeof elem == 'string' ) { 7134 elem = document.querySelector( elem ); 7135 } 7136 7137 // do not proceed on non-objects 7138 if ( !elem || typeof elem != 'object' || !elem.nodeType ) { 7139 return; 7140 } 7141 7142 var style = getStyle( elem ); 7143 7144 // if hidden, everything is 0 7145 if ( style.display == 'none' ) { 7146 return getZeroSize(); 7147 } 7148 7149 var size = {}; 7150 size.width = elem.offsetWidth; 7151 size.height = elem.offsetHeight; 7152 7153 var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; 7154 7155 // get all measurements 7156 for ( var i=0; i < measurementsLength; i++ ) { 7157 var measurement = measurements[i]; 7158 var value = style[ measurement ]; 7159 var num = parseFloat( value ); 7160 // any 'auto', 'medium' value will be 0 7161 size[ measurement ] = !isNaN( num ) ? num : 0; 7162 } 7163 7164 var paddingWidth = size.paddingLeft + size.paddingRight; 7165 var paddingHeight = size.paddingTop + size.paddingBottom; 7166 var marginWidth = size.marginLeft + size.marginRight; 7167 var marginHeight = size.marginTop + size.marginBottom; 7168 var borderWidth = size.borderLeftWidth + size.borderRightWidth; 7169 var borderHeight = size.borderTopWidth + size.borderBottomWidth; 7170 7171 var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; 7172 7173 // overwrite width and height if we can get it from style 7174 var styleWidth = getStyleSize( style.width ); 7175 if ( styleWidth !== false ) { 7176 size.width = styleWidth + 7177 // add padding and border unless it's already including it 7178 ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); 7179 } 7180 7181 var styleHeight = getStyleSize( style.height ); 7182 if ( styleHeight !== false ) { 7183 size.height = styleHeight + 7184 // add padding and border unless it's already including it 7185 ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); 7186 } 7187 7188 size.innerWidth = size.width - ( paddingWidth + borderWidth ); 7189 size.innerHeight = size.height - ( paddingHeight + borderHeight ); 7190 7191 size.outerWidth = size.width + marginWidth; 7192 size.outerHeight = size.height + marginHeight; 7193 7194 return size; 7195} 7196 7197return getSize; 7198 7199}); 7200 7201/** 7202 * matchesSelector v2.0.2 7203 * matchesSelector( element, '.selector' ) 7204 * MIT license 7205 */ 7206 7207/*jshint browser: true, strict: true, undef: true, unused: true */ 7208 7209( function( window, factory ) { 7210 /*global define: false, module: false */ 7211 'use strict'; 7212 // universal module definition 7213 if ( typeof define == 'function' && define.amd ) { 7214 // AMD 7215 define( 'desandro-matches-selector/matches-selector',factory ); 7216 } else if ( typeof module == 'object' && module.exports ) { 7217 // CommonJS 7218 module.exports = factory(); 7219 } else { 7220 // browser global 7221 window.matchesSelector = factory(); 7222 } 7223 7224}( window, function factory() { 7225 'use strict'; 7226 7227 var matchesMethod = ( function() { 7228 var ElemProto = window.Element.prototype; 7229 // check for the standard method name first 7230 if ( ElemProto.matches ) { 7231 return 'matches'; 7232 } 7233 // check un-prefixed 7234 if ( ElemProto.matchesSelector ) { 7235 return 'matchesSelector'; 7236 } 7237 // check vendor prefixes 7238 var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; 7239 7240 for ( var i=0; i < prefixes.length; i++ ) { 7241 var prefix = prefixes[i]; 7242 var method = prefix + 'MatchesSelector'; 7243 if ( ElemProto[ method ] ) { 7244 return method; 7245 } 7246 } 7247 })(); 7248 7249 return function matchesSelector( elem, selector ) { 7250 return elem[ matchesMethod ]( selector ); 7251 }; 7252 7253})); 7254 7255/** 7256 * Fizzy UI utils v2.0.7 7257 * MIT license 7258 */ 7259 7260/*jshint browser: true, undef: true, unused: true, strict: true */ 7261 7262( function( window, factory ) { 7263 // universal module definition 7264 /*jshint strict: false */ /*globals define, module, require */ 7265 7266 if ( typeof define == 'function' && define.amd ) { 7267 // AMD 7268 define( 'fizzy-ui-utils/utils',[ 7269 'desandro-matches-selector/matches-selector' 7270 ], function( matchesSelector ) { 7271 return factory( window, matchesSelector ); 7272 }); 7273 } else if ( typeof module == 'object' && module.exports ) { 7274 // CommonJS 7275 module.exports = factory( 7276 window, 7277 require('desandro-matches-selector') 7278 ); 7279 } else { 7280 // browser global 7281 window.fizzyUIUtils = factory( 7282 window, 7283 window.matchesSelector 7284 ); 7285 } 7286 7287}( window, function factory( window, matchesSelector ) { 7288 7289 7290 7291var utils = {}; 7292 7293// ----- extend ----- // 7294 7295// extends objects 7296utils.extend = function( a, b ) { 7297 for ( var prop in b ) { 7298 a[ prop ] = b[ prop ]; 7299 } 7300 return a; 7301}; 7302 7303// ----- modulo ----- // 7304 7305utils.modulo = function( num, div ) { 7306 return ( ( num % div ) + div ) % div; 7307}; 7308 7309// ----- makeArray ----- // 7310 7311var arraySlice = Array.prototype.slice; 7312 7313// turn element or nodeList into an array 7314utils.makeArray = function( obj ) { 7315 if ( Array.isArray( obj ) ) { 7316 // use object if already an array 7317 return obj; 7318 } 7319 // return empty array if undefined or null. #6 7320 if ( obj === null || obj === undefined ) { 7321 return []; 7322 } 7323 7324 var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; 7325 if ( isArrayLike ) { 7326 // convert nodeList to array 7327 return arraySlice.call( obj ); 7328 } 7329 7330 // array of single index 7331 return [ obj ]; 7332}; 7333 7334// ----- removeFrom ----- // 7335 7336utils.removeFrom = function( ary, obj ) { 7337 var index = ary.indexOf( obj ); 7338 if ( index != -1 ) { 7339 ary.splice( index, 1 ); 7340 } 7341}; 7342 7343// ----- getParent ----- // 7344 7345utils.getParent = function( elem, selector ) { 7346 while ( elem.parentNode && elem != document.body ) { 7347 elem = elem.parentNode; 7348 if ( matchesSelector( elem, selector ) ) { 7349 return elem; 7350 } 7351 } 7352}; 7353 7354// ----- getQueryElement ----- // 7355 7356// use element as selector string 7357utils.getQueryElement = function( elem ) { 7358 if ( typeof elem == 'string' ) { 7359 return document.querySelector( elem ); 7360 } 7361 return elem; 7362}; 7363 7364// ----- handleEvent ----- // 7365 7366// enable .ontype to trigger from .addEventListener( elem, 'type' ) 7367utils.handleEvent = function( event ) { 7368 var method = 'on' + event.type; 7369 if ( this[ method ] ) { 7370 this[ method ]( event ); 7371 } 7372}; 7373 7374// ----- filterFindElements ----- // 7375 7376utils.filterFindElements = function( elems, selector ) { 7377 // make array of elems 7378 elems = utils.makeArray( elems ); 7379 var ffElems = []; 7380 7381 elems.forEach( function( elem ) { 7382 // check that elem is an actual element 7383
7383// START UNCODE EDIT 7384 // if ( !( elem instanceof HTMLElement ) ) { 7385 if ( !( elem instanceof HTMLElement ) && !SiteParameters.is_frontend_editor ) { 7386 // END UNCODE EDIT
vendor: 75,264 bytes, lines 7386-10291
7386 7387 return; 7388 } 7389 // add elem if no selector 7390 if ( !selector ) { 7391 ffElems.push( elem ); 7392 return; 7393 } 7394 // filter & find items if we have a selector 7395 // filter 7396 if ( matchesSelector( elem, selector ) ) { 7397 ffElems.push( elem ); 7398 } 7399 // find children 7400 var childElems = elem.querySelectorAll( selector ); 7401 // concat childElems to filterFound array 7402 for ( var i=0; i < childElems.length; i++ ) { 7403 ffElems.push( childElems[i] ); 7404 } 7405 }); 7406 7407 return ffElems; 7408}; 7409 7410// ----- debounceMethod ----- // 7411 7412utils.debounceMethod = function( _class, methodName, threshold ) { 7413 threshold = threshold || 100; 7414 // original method 7415 var method = _class.prototype[ methodName ]; 7416 var timeoutName = methodName + 'Timeout'; 7417 7418 _class.prototype[ methodName ] = function() { 7419 var timeout = this[ timeoutName ]; 7420 clearTimeout( timeout ); 7421 7422 var args = arguments; 7423 var _this = this; 7424 this[ timeoutName ] = setTimeout( function() { 7425 method.apply( _this, args ); 7426 delete _this[ timeoutName ]; 7427 }, threshold ); 7428 }; 7429}; 7430 7431// ----- docReady ----- // 7432 7433utils.docReady = function( callback ) { 7434 var readyState = document.readyState; 7435 if ( readyState == 'complete' || readyState == 'interactive' ) { 7436 // do async to allow for other scripts to run. metafizzy/flickity#441 7437 setTimeout( callback ); 7438 } else { 7439 document.addEventListener( 'DOMContentLoaded', callback ); 7440 } 7441}; 7442 7443// ----- htmlInit ----- // 7444 7445// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ 7446utils.toDashed = function( str ) { 7447 return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { 7448 return $1 + '-' + $2; 7449 }).toLowerCase(); 7450}; 7451 7452var console = window.console; 7453/** 7454 * allow user to initialize classes via [data-namespace] or .js-namespace class 7455 * htmlInit( Widget, 'widgetName' ) 7456 * options are parsed from data-namespace-options 7457 */ 7458utils.htmlInit = function( WidgetClass, namespace ) { 7459 utils.docReady( function() { 7460 var dashedNamespace = utils.toDashed( namespace ); 7461 var dataAttr = 'data-' + dashedNamespace; 7462 var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' ); 7463 var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace ); 7464 var elems = utils.makeArray( dataAttrElems ) 7465 .concat( utils.makeArray( jsDashElems ) ); 7466 var dataOptionsAttr = dataAttr + '-options'; 7467 var jQuery = window.jQuery; 7468 7469 elems.forEach( function( elem ) { 7470 var attr = elem.getAttribute( dataAttr ) || 7471 elem.getAttribute( dataOptionsAttr ); 7472 var options; 7473 try { 7474 options = attr && JSON.parse( attr ); 7475 } catch ( error ) { 7476 // log error, do not initialize 7477 if ( console ) { 7478 console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className + 7479 ': ' + error ); 7480 } 7481 return; 7482 } 7483 // initialize 7484 var instance = new WidgetClass( elem, options ); 7485 // make available via $().data('namespace') 7486 if ( jQuery ) { 7487 jQuery.data( elem, namespace, instance ); 7488 } 7489 }); 7490 7491 }); 7492}; 7493 7494// ----- ----- // 7495 7496return utils; 7497 7498})); 7499 7500/** 7501 * Outlayer Item 7502 */ 7503 7504( function( window, factory ) { 7505 // universal module definition 7506 /* jshint strict: false */ /* globals define, module, require */ 7507 if ( typeof define == 'function' && define.amd ) { 7508 // AMD - RequireJS 7509 define( 'outlayer/item',[ 7510 'ev-emitter/ev-emitter', 7511 'get-size/get-size' 7512 ], 7513 factory 7514 ); 7515 } else if ( typeof module == 'object' && module.exports ) { 7516 // CommonJS - Browserify, Webpack 7517 module.exports = factory( 7518 require('ev-emitter'), 7519 require('get-size') 7520 ); 7521 } else { 7522 // browser global 7523 window.Outlayer = {}; 7524 window.Outlayer.Item = factory( 7525 window.EvEmitter, 7526 window.getSize 7527 ); 7528 } 7529 7530}( window, function factory( EvEmitter, getSize ) { 7531'use strict'; 7532 7533// ----- helpers ----- // 7534 7535function isEmptyObj( obj ) { 7536 for ( var prop in obj ) { 7537 return false; 7538 } 7539 prop = null; 7540 return true; 7541} 7542 7543// -------------------------- CSS3 support -------------------------- // 7544 7545 7546var docElemStyle = document.documentElement.style; 7547 7548var transitionProperty = typeof docElemStyle.transition == 'string' ? 7549 'transition' : 'WebkitTransition'; 7550var transformProperty = typeof docElemStyle.transform == 'string' ? 7551 'transform' : 'WebkitTransform'; 7552 7553var transitionEndEvent = { 7554 WebkitTransition: 'webkitTransitionEnd', 7555 transition: 'transitionend' 7556}[ transitionProperty ]; 7557 7558// cache all vendor properties that could have vendor prefix 7559var vendorProperties = { 7560 transform: transformProperty, 7561 transition: transitionProperty, 7562 transitionDuration: transitionProperty + 'Duration', 7563 transitionProperty: transitionProperty + 'Property', 7564 transitionDelay: transitionProperty + 'Delay' 7565}; 7566 7567// -------------------------- Item -------------------------- // 7568 7569function Item( element, layout ) { 7570 if ( !element ) { 7571 return; 7572 } 7573 7574 this.element = element; 7575 // parent layout class, i.e. Masonry, Isotope, or Packery 7576 this.layout = layout; 7577 this.position = { 7578 x: 0, 7579 y: 0 7580 }; 7581 7582 this._create(); 7583} 7584 7585// inherit EvEmitter 7586var proto = Item.prototype = Object.create( EvEmitter.prototype ); 7587proto.constructor = Item; 7588 7589proto._create = function() { 7590 // transition objects 7591 this._transn = { 7592 ingProperties: {}, 7593 clean: {}, 7594 onEnd: {} 7595 }; 7596 7597 this.css({ 7598 position: 'absolute' 7599 }); 7600}; 7601 7602// trigger specified handler for event type 7603proto.handleEvent = function( event ) { 7604 var method = 'on' + event.type; 7605 if ( this[ method ] ) { 7606 this[ method ]( event ); 7607 } 7608}; 7609 7610proto.getSize = function() { 7611 this.size = getSize( this.element ); 7612}; 7613 7614/** 7615 * apply CSS styles to element 7616 * @param {Object} style 7617 */ 7618proto.css = function( style ) { 7619 var elemStyle = this.element.style; 7620 7621 for ( var prop in style ) { 7622 // use vendor property if available 7623 var supportedProp = vendorProperties[ prop ] || prop; 7624 elemStyle[ supportedProp ] = style[ prop ]; 7625 } 7626}; 7627 7628 // measure position, and sets it 7629proto.getPosition = function() { 7630 var style = getComputedStyle( this.element ); 7631 var isOriginLeft = this.layout._getOption('originLeft'); 7632 var isOriginTop = this.layout._getOption('originTop'); 7633 var xValue = style[ isOriginLeft ? 'left' : 'right' ]; 7634 var yValue = style[ isOriginTop ? 'top' : 'bottom' ]; 7635 var x = parseFloat( xValue ); 7636 var y = parseFloat( yValue ); 7637 // convert percent to pixels 7638 var layoutSize = this.layout.size; 7639 if ( xValue.indexOf('%') != -1 ) { 7640 x = ( x / 100 ) * layoutSize.width; 7641 } 7642 if ( yValue.indexOf('%') != -1 ) { 7643 y = ( y / 100 ) * layoutSize.height; 7644 } 7645 // clean up 'auto' or other non-integer values 7646 x = isNaN( x ) ? 0 : x; 7647 y = isNaN( y ) ? 0 : y; 7648 // remove padding from measurement 7649 x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight; 7650 y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom; 7651 7652 this.position.x = x; 7653 this.position.y = y; 7654}; 7655 7656// set settled position, apply padding 7657proto.layoutPosition = function() { 7658 var layoutSize = this.layout.size; 7659 var style = {}; 7660 var isOriginLeft = this.layout._getOption('originLeft'); 7661 var isOriginTop = this.layout._getOption('originTop'); 7662 7663 // x 7664 var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight'; 7665 var xProperty = isOriginLeft ? 'left' : 'right'; 7666 var xResetProperty = isOriginLeft ? 'right' : 'left'; 7667 7668 var x = this.position.x + layoutSize[ xPadding ]; 7669 // set in percentage or pixels 7670 style[ xProperty ] = this.getXValue( x ); 7671 // reset other property 7672 style[ xResetProperty ] = ''; 7673 7674 // y 7675 var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom'; 7676 var yProperty = isOriginTop ? 'top' : 'bottom'; 7677 var yResetProperty = isOriginTop ? 'bottom' : 'top'; 7678 7679 var y = this.position.y + layoutSize[ yPadding ]; 7680 // set in percentage or pixels 7681 style[ yProperty ] = this.getYValue( y ); 7682 // reset other property 7683 style[ yResetProperty ] = ''; 7684 7685 this.css( style ); 7686 this.emitEvent( 'layout', [ this ] ); 7687}; 7688 7689proto.getXValue = function( x ) { 7690 var isHorizontal = this.layout._getOption('horizontal'); 7691 return this.layout.options.percentPosition && !isHorizontal ? 7692 ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px'; 7693}; 7694 7695proto.getYValue = function( y ) { 7696 var isHorizontal = this.layout._getOption('horizontal'); 7697 return this.layout.options.percentPosition && isHorizontal ? 7698 ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px'; 7699}; 7700 7701proto._transitionTo = function( x, y ) { 7702 this.getPosition(); 7703 // get current x & y from top/left 7704 var curX = this.position.x; 7705 var curY = this.position.y; 7706 7707 var didNotMove = x == this.position.x && y == this.position.y; 7708 7709 // save end position 7710 this.setPosition( x, y ); 7711 7712 // if did not move and not transitioning, just go to layout 7713 if ( didNotMove && !this.isTransitioning ) { 7714 this.layoutPosition(); 7715 return; 7716 } 7717 7718 var transX = x - curX; 7719 var transY = y - curY; 7720 var transitionStyle = {}; 7721 transitionStyle.transform = this.getTranslate( transX, transY ); 7722 7723 this.transition({ 7724 to: transitionStyle, 7725 onTransitionEnd: { 7726 transform: this.layoutPosition 7727 }, 7728 isCleaning: true 7729 }); 7730}; 7731 7732proto.getTranslate = function( x, y ) { 7733 // flip cooridinates if origin on right or bottom 7734 var isOriginLeft = this.layout._getOption('originLeft'); 7735 var isOriginTop = this.layout._getOption('originTop'); 7736 x = isOriginLeft ? x : -x; 7737 y = isOriginTop ? y : -y; 7738 return 'translate3d(' + x + 'px, ' + y + 'px, 0)'; 7739}; 7740 7741// non transition + transform support 7742proto.goTo = function( x, y ) { 7743 this.setPosition( x, y ); 7744 this.layoutPosition(); 7745}; 7746 7747proto.moveTo = proto._transitionTo; 7748 7749proto.setPosition = function( x, y ) { 7750 this.position.x = parseFloat( x ); 7751 this.position.y = parseFloat( y ); 7752}; 7753 7754// ----- transition ----- // 7755 7756/** 7757 * @param {Object} style - CSS 7758 * @param {Function} onTransitionEnd 7759 */ 7760 7761// non transition, just trigger callback 7762proto._nonTransition = function( args ) { 7763 this.css( args.to ); 7764 if ( args.isCleaning ) { 7765 this._removeStyles( args.to ); 7766 } 7767 for ( var prop in args.onTransitionEnd ) { 7768 args.onTransitionEnd[ prop ].call( this ); 7769 } 7770}; 7771 7772/** 7773 * proper transition 7774 * @param {Object} args - arguments 7775 * @param {Object} to - style to transition to 7776 * @param {Object} from - style to start transition from 7777 * @param {Boolean} isCleaning - removes transition styles after transition 7778 * @param {Function} onTransitionEnd - callback 7779 */ 7780proto.transition = function( args ) { 7781 // redirect to nonTransition if no transition duration 7782 if ( !parseFloat( this.layout.options.transitionDuration ) ) { 7783 this._nonTransition( args ); 7784 return; 7785 } 7786 7787 var _transition = this._transn; 7788 // keep track of onTransitionEnd callback by css property 7789 for ( var prop in args.onTransitionEnd ) { 7790 _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ]; 7791 } 7792 // keep track of properties that are transitioning 7793 for ( prop in args.to ) { 7794 _transition.ingProperties[ prop ] = true; 7795 // keep track of properties to clean up when transition is done 7796 if ( args.isCleaning ) { 7797 _transition.clean[ prop ] = true; 7798 } 7799 } 7800 7801 // set from styles 7802 if ( args.from ) { 7803 this.css( args.from ); 7804 // force redraw. http://blog.alexmaccaw.com/css-transitions 7805 var h = this.element.offsetHeight; 7806 // hack for JSHint to hush about unused var 7807 h = null; 7808 } 7809 // enable transition 7810 this.enableTransition( args.to ); 7811 // set styles that are transitioning 7812 this.css( args.to ); 7813 7814 this.isTransitioning = true; 7815 7816}; 7817 7818// dash before all cap letters, including first for 7819// WebkitTransform => -webkit-transform 7820function toDashedAll( str ) { 7821 return str.replace( /([A-Z])/g, function( $1 ) { 7822 return '-' + $1.toLowerCase(); 7823 }); 7824} 7825 7826var transitionProps = 'opacity,' + toDashedAll( transformProperty ); 7827 7828proto.enableTransition = function(/* style */) { 7829 // HACK changing transitionProperty during a transition 7830 // will cause transition to jump 7831 if ( this.isTransitioning ) { 7832 return; 7833 } 7834 7835 // make `transition: foo, bar, baz` from style object 7836 // HACK un-comment this when enableTransition can work 7837 // while a transition is happening 7838 // var transitionValues = []; 7839 // for ( var prop in style ) { 7840 // // dash-ify camelCased properties like WebkitTransition 7841 // prop = vendorProperties[ prop ] || prop; 7842 // transitionValues.push( toDashedAll( prop ) ); 7843 // } 7844 // munge number to millisecond, to match stagger 7845 var duration = this.layout.options.transitionDuration; 7846 duration = typeof duration == 'number' ? duration + 'ms' : duration; 7847 // enable transition styles 7848 this.css({ 7849 transitionProperty: transitionProps, 7850 transitionDuration: duration, 7851 transitionDelay: this.staggerDelay || 0 7852 }); 7853 // listen for transition end event 7854 this.element.addEventListener( transitionEndEvent, this, false ); 7855}; 7856 7857// ----- events ----- // 7858 7859proto.onwebkitTransitionEnd = function( event ) { 7860 this.ontransitionend( event ); 7861}; 7862 7863proto.onotransitionend = function( event ) { 7864 this.ontransitionend( event ); 7865}; 7866 7867// properties that I munge to make my life easier 7868var dashedVendorProperties = { 7869 '-webkit-transform': 'transform' 7870}; 7871 7872proto.ontransitionend = function( event ) { 7873 // disregard bubbled events from children 7874 if ( event.target !== this.element ) { 7875 return; 7876 } 7877 var _transition = this._transn; 7878 // get property name of transitioned property, convert to prefix-free 7879 var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName; 7880 7881 // remove property that has completed transitioning 7882 delete _transition.ingProperties[ propertyName ]; 7883 // check if any properties are still transitioning 7884 if ( isEmptyObj( _transition.ingProperties ) ) { 7885 // all properties have completed transitioning 7886 this.disableTransition(); 7887 } 7888 // clean style 7889 if ( propertyName in _transition.clean ) { 7890 // clean up style 7891 this.element.style[ event.propertyName ] = ''; 7892 delete _transition.clean[ propertyName ]; 7893 } 7894 // trigger onTransitionEnd callback 7895 if ( propertyName in _transition.onEnd ) { 7896 var onTransitionEnd = _transition.onEnd[ propertyName ]; 7897 onTransitionEnd.call( this ); 7898 delete _transition.onEnd[ propertyName ]; 7899 } 7900 7901 this.emitEvent( 'transitionEnd', [ this ] ); 7902}; 7903 7904proto.disableTransition = function() { 7905 this.removeTransitionStyles(); 7906 this.element.removeEventListener( transitionEndEvent, this, false ); 7907 this.isTransitioning = false; 7908}; 7909 7910/** 7911 * removes style property from element 7912 * @param {Object} style 7913**/ 7914proto._removeStyles = function( style ) { 7915 // clean up transition styles 7916 var cleanStyle = {}; 7917 for ( var prop in style ) { 7918 cleanStyle[ prop ] = ''; 7919 } 7920 this.css( cleanStyle ); 7921}; 7922 7923var cleanTransitionStyle = { 7924 transitionProperty: '', 7925 transitionDuration: '', 7926 transitionDelay: '' 7927}; 7928 7929proto.removeTransitionStyles = function() { 7930 // remove transition 7931 this.css( cleanTransitionStyle ); 7932}; 7933 7934// ----- stagger ----- // 7935 7936proto.stagger = function( delay ) { 7937 delay = isNaN( delay ) ? 0 : delay; 7938 this.staggerDelay = delay + 'ms'; 7939}; 7940 7941// ----- show/hide/remove ----- // 7942 7943// remove element from DOM 7944proto.removeElem = function() { 7945 this.element.parentNode.removeChild( this.element ); 7946 // remove display: none 7947 this.css({ display: '' }); 7948 this.emitEvent( 'remove', [ this ] ); 7949}; 7950 7951proto.remove = function() { 7952 // just remove element if no transition support or no transition 7953 if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) { 7954 this.removeElem(); 7955 return; 7956 } 7957 7958 // start transition 7959 this.once( 'transitionEnd', function() { 7960 this.removeElem(); 7961 }); 7962 this.hide(); 7963}; 7964 7965proto.reveal = function() { 7966 delete this.isHidden; 7967 // remove display: none 7968 this.css({ display: '' }); 7969 7970 var options = this.layout.options; 7971 7972 var onTransitionEnd = {}; 7973 var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle'); 7974 onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd; 7975 7976 this.transition({ 7977 from: options.hiddenStyle, 7978 to: options.visibleStyle, 7979 isCleaning: true, 7980 onTransitionEnd: onTransitionEnd 7981 }); 7982}; 7983 7984proto.onRevealTransitionEnd = function() { 7985 // check if still visible 7986 // during transition, item may have been hidden 7987 if ( !this.isHidden ) { 7988 this.emitEvent('reveal'); 7989 } 7990}; 7991 7992/** 7993 * get style property use for hide/reveal transition end 7994 * @param {String} styleProperty - hiddenStyle/visibleStyle 7995 * @returns {String} 7996 */ 7997proto.getHideRevealTransitionEndProperty = function( styleProperty ) { 7998 var optionStyle = this.layout.options[ styleProperty ]; 7999 // use opacity 8000 if ( optionStyle.opacity ) { 8001 return 'opacity'; 8002 } 8003 // get first property 8004 for ( var prop in optionStyle ) { 8005 return prop; 8006 } 8007}; 8008 8009proto.hide = function() { 8010 // set flag 8011 this.isHidden = true; 8012 // remove display: none 8013 this.css({ display: '' }); 8014 8015 var options = this.layout.options; 8016 8017 var onTransitionEnd = {}; 8018 var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle'); 8019 onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd; 8020 8021 this.transition({ 8022 from: options.visibleStyle, 8023 to: options.hiddenStyle, 8024 // keep hidden stuff hidden 8025 isCleaning: true, 8026 onTransitionEnd: onTransitionEnd 8027 }); 8028}; 8029 8030proto.onHideTransitionEnd = function() { 8031 // check if still hidden 8032 // during transition, item may have been un-hidden 8033 if ( this.isHidden ) { 8034 this.css({ display: 'none' }); 8035 this.emitEvent('hide'); 8036 } 8037}; 8038 8039proto.destroy = function() { 8040 this.css({ 8041 position: '', 8042 left: '', 8043 right: '', 8044 top: '', 8045 bottom: '', 8046 transition: '', 8047 transform: '' 8048 }); 8049}; 8050 8051return Item; 8052 8053})); 8054 8055/*! 8056 * Outlayer v2.1.1 8057 * the brains and guts of a layout library 8058 * MIT license 8059 */ 8060 8061( function( window, factory ) { 8062 'use strict'; 8063 // universal module definition 8064 /* jshint strict: false */ /* globals define, module, require */ 8065 if ( typeof define == 'function' && define.amd ) { 8066 // AMD - RequireJS 8067 define( 'outlayer/outlayer',[ 8068 'ev-emitter/ev-emitter', 8069 'get-size/get-size', 8070 'fizzy-ui-utils/utils', 8071 './item' 8072 ], 8073 function( EvEmitter, getSize, utils, Item ) { 8074 return factory( window, EvEmitter, getSize, utils, Item); 8075 } 8076 ); 8077 } else if ( typeof module == 'object' && module.exports ) { 8078 // CommonJS - Browserify, Webpack 8079 module.exports = factory( 8080 window, 8081 require('ev-emitter'), 8082 require('get-size'), 8083 require('fizzy-ui-utils'), 8084 require('./item') 8085 ); 8086 } else { 8087 // browser global 8088 window.Outlayer = factory( 8089 window, 8090 window.EvEmitter, 8091 window.getSize, 8092 window.fizzyUIUtils, 8093 window.Outlayer.Item 8094 ); 8095 } 8096 8097}( window, function factory( window, EvEmitter, getSize, utils, Item ) { 8098'use strict'; 8099 8100// ----- vars ----- // 8101 8102var console = window.console; 8103var jQuery = window.jQuery; 8104var noop = function() {}; 8105 8106// -------------------------- Outlayer -------------------------- // 8107 8108// globally unique identifiers 8109var GUID = 0; 8110// internal store of all Outlayer intances 8111var instances = {}; 8112 8113 8114/** 8115 * @param {Element, String} element 8116 * @param {Object} options 8117 * @constructor 8118 */ 8119function Outlayer( element, options ) { 8120 var queryElement = utils.getQueryElement( element ); 8121 if ( !queryElement ) { 8122 if ( console ) { 8123 console.error( 'Bad element for ' + this.constructor.namespace + 8124 ': ' + ( queryElement || element ) ); 8125 } 8126 return; 8127 } 8128 this.element = queryElement; 8129 // add jQuery 8130 if ( jQuery ) { 8131 this.$element = jQuery( this.element ); 8132 } 8133 8134 // options 8135 this.options = utils.extend( {}, this.constructor.defaults ); 8136 this.option( options ); 8137 8138 // add id for Outlayer.getFromElement 8139 var id = ++GUID; 8140 this.element.outlayerGUID = id; // expando 8141 instances[ id ] = this; // associate via id 8142 8143 // kick it off 8144 this._create(); 8145 8146 var isInitLayout = this._getOption('initLayout'); 8147 if ( isInitLayout ) { 8148 this.layout(); 8149 } 8150} 8151 8152// settings are for internal use only 8153Outlayer.namespace = 'outlayer'; 8154Outlayer.Item = Item; 8155 8156// default options 8157Outlayer.defaults = { 8158 containerStyle: { 8159 position: 'relative' 8160 }, 8161 initLayout: true, 8162 originLeft: true, 8163 originTop: true, 8164 resize: true, 8165 resizeContainer: true, 8166 // item options 8167 transitionDuration: '0.4s', 8168 hiddenStyle: { 8169 opacity: 0, 8170 transform: 'scale(0.001)' 8171 }, 8172 visibleStyle: { 8173 opacity: 1, 8174 transform: 'scale(1)' 8175 } 8176}; 8177 8178var proto = Outlayer.prototype; 8179// inherit EvEmitter 8180utils.extend( proto, EvEmitter.prototype ); 8181 8182/** 8183 * set options 8184 * @param {Object} opts 8185 */ 8186proto.option = function( opts ) { 8187 utils.extend( this.options, opts ); 8188}; 8189 8190/** 8191 * get backwards compatible option value, check old name 8192 */ 8193proto._getOption = function( option ) { 8194 var oldOption = this.constructor.compatOptions[ option ]; 8195 return oldOption && this.options[ oldOption ] !== undefined ? 8196 this.options[ oldOption ] : this.options[ option ]; 8197}; 8198 8199Outlayer.compatOptions = { 8200 // currentName: oldName 8201 initLayout: 'isInitLayout', 8202 horizontal: 'isHorizontal', 8203 layoutInstant: 'isLayoutInstant', 8204 originLeft: 'isOriginLeft', 8205 originTop: 'isOriginTop', 8206 resize: 'isResizeBound', 8207 resizeContainer: 'isResizingContainer' 8208}; 8209 8210proto._create = function() { 8211 // get items from children 8212 this.reloadItems(); 8213 // elements that affect layout, but are not laid out 8214 this.stamps = []; 8215 this.stamp( this.options.stamp ); 8216 // set container style 8217 utils.extend( this.element.style, this.options.containerStyle ); 8218 8219 // bind resize method 8220 var canBindResize = this._getOption('resize'); 8221 if ( canBindResize ) { 8222 this.bindResize(); 8223 } 8224}; 8225 8226// goes through all children again and gets bricks in proper order 8227proto.reloadItems = function() { 8228 // collection of item elements 8229 this.items = this._itemize( this.element.children ); 8230}; 8231 8232 8233/** 8234 * turn elements into Outlayer.Items to be used in layout 8235 * @param {Array or NodeList or HTMLElement} elems 8236 * @returns {Array} items - collection of new Outlayer Items 8237 */ 8238proto._itemize = function( elems ) { 8239 8240 var itemElems = this._filterFindItemElements( elems ); 8241 var Item = this.constructor.Item; 8242 8243 // create new Outlayer Items for collection 8244 var items = []; 8245 for ( var i=0; i < itemElems.length; i++ ) { 8246 var elem = itemElems[i]; 8247 var item = new Item( elem, this ); 8248 items.push( item ); 8249 } 8250 8251 return items; 8252}; 8253 8254/** 8255 * get item elements to be used in layout 8256 * @param {Array or NodeList or HTMLElement} elems 8257 * @returns {Array} items - item elements 8258 */ 8259proto._filterFindItemElements = function( elems ) { 8260 return utils.filterFindElements( elems, this.options.itemSelector ); 8261}; 8262 8263/** 8264 * getter method for getting item elements 8265 * @returns {Array} elems - collection of item elements 8266 */ 8267proto.getItemElements = function() { 8268 return this.items.map( function( item ) { 8269 return item.element; 8270 }); 8271}; 8272 8273// ----- init & layout ----- // 8274 8275/** 8276 * lays out all items 8277 */ 8278proto.layout = function() { 8279 this._resetLayout(); 8280 this._manageStamps(); 8281 8282 // don't animate first layout 8283 var layoutInstant = this._getOption('layoutInstant'); 8284 var isInstant = layoutInstant !== undefined ? 8285 layoutInstant : !this._isLayoutInited; 8286 this.layoutItems( this.items, isInstant ); 8287 8288 // flag for initalized 8289 this._isLayoutInited = true; 8290}; 8291 8292// _init is alias for layout 8293proto._init = proto.layout; 8294 8295/** 8296 * logic before any new layout 8297 */ 8298proto._resetLayout = function() { 8299 this.getSize(); 8300}; 8301 8302 8303proto.getSize = function() { 8304 this.size = getSize( this.element ); 8305}; 8306 8307/** 8308 * get measurement from option, for columnWidth, rowHeight, gutter 8309 * if option is String -> get element from selector string, & get size of element 8310 * if option is Element -> get size of element 8311 * else use option as a number 8312 * 8313 * @param {String} measurement 8314 * @param {String} size - width or height 8315 * @private 8316 */ 8317proto._getMeasurement = function( measurement, size ) { 8318 var option = this.options[ measurement ]; 8319 var elem; 8320 if ( !option ) { 8321 // default to 0 8322 this[ measurement ] = 0; 8323 } else { 8324 // use option as an element 8325 if ( typeof option == 'string' ) { 8326 elem = this.element.querySelector( option ); 8327 } else if ( option instanceof HTMLElement ) { 8328 elem = option; 8329 } 8330 // use size of element, if element 8331 this[ measurement ] = elem ? getSize( elem )[ size ] : option; 8332 } 8333}; 8334 8335/** 8336 * layout a collection of item elements 8337 * @api public 8338 */ 8339proto.layoutItems = function( items, isInstant ) { 8340 items = this._getItemsForLayout( items ); 8341 8342 this._layoutItems( items, isInstant ); 8343 8344 this._postLayout(); 8345}; 8346 8347/** 8348 * get the items to be laid out 8349 * you may want to skip over some items 8350 * @param {Array} items 8351 * @returns {Array} items 8352 */ 8353proto._getItemsForLayout = function( items ) { 8354 return items.filter( function( item ) { 8355 return !item.isIgnored; 8356 }); 8357}; 8358 8359/** 8360 * layout items 8361 * @param {Array} items 8362 * @param {Boolean} isInstant 8363 */ 8364proto._layoutItems = function( items, isInstant ) { 8365 this._emitCompleteOnItems( 'layout', items ); 8366 8367 if ( !items || !items.length ) { 8368 // no items, emit event with empty array 8369 return; 8370 } 8371 8372 var queue = []; 8373 8374 items.forEach( function( item ) { 8375 // get x/y object from method 8376 var position = this._getItemLayoutPosition( item ); 8377 // enqueue 8378 position.item = item; 8379 position.isInstant = isInstant || item.isLayoutInstant; 8380 queue.push( position ); 8381 }, this ); 8382 8383 this._processLayoutQueue( queue ); 8384}; 8385 8386/** 8387 * get item layout position 8388 * @param {Outlayer.Item} item 8389 * @returns {Object} x and y position 8390 */ 8391proto._getItemLayoutPosition = function( /* item */ ) { 8392 return { 8393 x: 0, 8394 y: 0 8395 }; 8396}; 8397 8398/** 8399 * iterate over array and position each item 8400 * Reason being - separating this logic prevents 'layout invalidation' 8401 * thx @paul_irish 8402 * @param {Array} queue 8403 */ 8404proto._processLayoutQueue = function( queue ) { 8405 this.updateStagger(); 8406 queue.forEach( function( obj, i ) { 8407 this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i ); 8408 }, this ); 8409}; 8410 8411// set stagger from option in milliseconds number 8412proto.updateStagger = function() { 8413 var stagger = this.options.stagger; 8414 if ( stagger === null || stagger === undefined ) { 8415 this.stagger = 0; 8416 return; 8417 } 8418 this.stagger = getMilliseconds( stagger ); 8419 return this.stagger; 8420}; 8421 8422/** 8423 * Sets position of item in DOM 8424 * @param {Outlayer.Item} item 8425 * @param {Number} x - horizontal position 8426 * @param {Number} y - vertical position 8427 * @param {Boolean} isInstant - disables transitions 8428 */ 8429proto._positionItem = function( item, x, y, isInstant, i ) { 8430 if ( isInstant ) { 8431 // if not transition, just set CSS 8432 item.goTo( x, y ); 8433 } else { 8434 item.stagger( i * this.stagger ); 8435 item.moveTo( x, y ); 8436 } 8437}; 8438 8439/** 8440 * Any logic you want to do after each layout, 8441 * i.e. size the container 8442 */ 8443proto._postLayout = function() { 8444 this.resizeContainer(); 8445}; 8446 8447proto.resizeContainer = function() { 8448 var isResizingContainer = this._getOption('resizeContainer'); 8449 if ( !isResizingContainer ) { 8450 return; 8451 } 8452 var size = this._getContainerSize(); 8453 if ( size ) { 8454 this._setContainerMeasure( size.width, true ); 8455 this._setContainerMeasure( size.height, false ); 8456 } 8457}; 8458 8459/** 8460 * Sets width or height of container if returned 8461 * @returns {Object} size 8462 * @param {Number} width 8463 * @param {Number} height 8464 */ 8465proto._getContainerSize = noop; 8466 8467/** 8468 * @param {Number} measure - size of width or height 8469 * @param {Boolean} isWidth 8470 */ 8471proto._setContainerMeasure = function( measure, isWidth ) { 8472 if ( measure === undefined ) { 8473 return; 8474 } 8475 8476 var elemSize = this.size; 8477 // add padding and border width if border box 8478 if ( elemSize.isBorderBox ) { 8479 measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + 8480 elemSize.borderLeftWidth + elemSize.borderRightWidth : 8481 elemSize.paddingBottom + elemSize.paddingTop + 8482 elemSize.borderTopWidth + elemSize.borderBottomWidth; 8483 } 8484 8485 measure = Math.max( measure, 0 ); 8486 this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px'; 8487}; 8488 8489/** 8490 * emit eventComplete on a collection of items events 8491 * @param {String} eventName 8492 * @param {Array} items - Outlayer.Items 8493 */ 8494proto._emitCompleteOnItems = function( eventName, items ) { 8495 var _this = this; 8496 function onComplete() { 8497 _this.dispatchEvent( eventName + 'Complete', null, [ items ] ); 8498 } 8499 8500 var count = items.length; 8501 if ( !items || !count ) { 8502 onComplete(); 8503 return; 8504 } 8505 8506 var doneCount = 0; 8507 function tick() { 8508 doneCount++; 8509 if ( doneCount == count ) { 8510 onComplete(); 8511 } 8512 } 8513 8514 // bind callback 8515 items.forEach( function( item ) { 8516 item.once( eventName, tick ); 8517 }); 8518}; 8519 8520/** 8521 * emits events via EvEmitter and jQuery events 8522 * @param {String} type - name of event 8523 * @param {Event} event - original event 8524 * @param {Array} args - extra arguments 8525 */ 8526proto.dispatchEvent = function( type, event, args ) { 8527 // add original event to arguments 8528 var emitArgs = event ? [ event ].concat( args ) : args; 8529 this.emitEvent( type, emitArgs ); 8530 8531 if ( jQuery ) { 8532 // set this.$element 8533 this.$element = this.$element || jQuery( this.element ); 8534 if ( event ) { 8535 // create jQuery event 8536 var $event = jQuery.Event( event ); 8537 $event.type = type; 8538 this.$element.trigger( $event, args ); 8539 } else { 8540 // just trigger with type if no event available 8541 this.$element.trigger( type, args ); 8542 } 8543 } 8544}; 8545 8546// -------------------------- ignore & stamps -------------------------- // 8547 8548 8549/** 8550 * keep item in collection, but do not lay it out 8551 * ignored items do not get skipped in layout 8552 * @param {Element} elem 8553 */ 8554proto.ignore = function( elem ) { 8555 var item = this.getItem( elem ); 8556 if ( item ) { 8557 item.isIgnored = true; 8558 } 8559}; 8560 8561/** 8562 * return item to layout collection 8563 * @param {Element} elem 8564 */ 8565proto.unignore = function( elem ) { 8566 var item = this.getItem( elem ); 8567 if ( item ) { 8568 delete item.isIgnored; 8569 } 8570}; 8571 8572/** 8573 * adds elements to stamps 8574 * @param {NodeList, Array, Element, or String} elems 8575 */ 8576proto.stamp = function( elems ) { 8577 elems = this._find( elems ); 8578 if ( !elems ) { 8579 return; 8580 } 8581 8582 this.stamps = this.stamps.concat( elems ); 8583 // ignore 8584 elems.forEach( this.ignore, this ); 8585}; 8586 8587/** 8588 * removes elements to stamps 8589 * @param {NodeList, Array, or Element} elems 8590 */ 8591proto.unstamp = function( elems ) { 8592 elems = this._find( elems ); 8593 if ( !elems ){ 8594 return; 8595 } 8596 8597 elems.forEach( function( elem ) { 8598 // filter out removed stamp elements 8599 utils.removeFrom( this.stamps, elem ); 8600 this.unignore( elem ); 8601 }, this ); 8602}; 8603 8604/** 8605 * finds child elements 8606 * @param {NodeList, Array, Element, or String} elems 8607 * @returns {Array} elems 8608 */ 8609proto._find = function( elems ) { 8610 if ( !elems ) { 8611 return; 8612 } 8613 // if string, use argument as selector string 8614 if ( typeof elems == 'string' ) { 8615 elems = this.element.querySelectorAll( elems ); 8616 } 8617 elems = utils.makeArray( elems ); 8618 return elems; 8619}; 8620 8621proto._manageStamps = function() { 8622 if ( !this.stamps || !this.stamps.length ) { 8623 return; 8624 } 8625 8626 this._getBoundingRect(); 8627 8628 this.stamps.forEach( this._manageStamp, this ); 8629}; 8630 8631// update boundingLeft / Top 8632proto._getBoundingRect = function() { 8633 // get bounding rect for container element 8634 var boundingRect = this.element.getBoundingClientRect(); 8635 var size = this.size; 8636 this._boundingRect = { 8637 left: boundingRect.left + size.paddingLeft + size.borderLeftWidth, 8638 top: boundingRect.top + size.paddingTop + size.borderTopWidth, 8639 right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ), 8640 bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth ) 8641 }; 8642}; 8643 8644/** 8645 * @param {Element} stamp 8646**/ 8647proto._manageStamp = noop; 8648 8649/** 8650 * get x/y position of element relative to container element 8651 * @param {Element} elem 8652 * @returns {Object} offset - has left, top, right, bottom 8653 */ 8654proto._getElementOffset = function( elem ) { 8655 var boundingRect = elem.getBoundingClientRect(); 8656 var thisRect = this._boundingRect; 8657 var size = getSize( elem ); 8658 var offset = { 8659 left: boundingRect.left - thisRect.left - size.marginLeft, 8660 top: boundingRect.top - thisRect.top - size.marginTop, 8661 right: thisRect.right - boundingRect.right - size.marginRight, 8662 bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom 8663 }; 8664 return offset; 8665}; 8666 8667// -------------------------- resize -------------------------- // 8668 8669// enable event handlers for listeners 8670// i.e. resize -> onresize 8671proto.handleEvent = utils.handleEvent; 8672 8673/** 8674 * Bind layout to window resizing 8675 */ 8676proto.bindResize = function() { 8677 window.addEventListener( 'resize', this ); 8678 this.isResizeBound = true; 8679}; 8680 8681/** 8682 * Unbind layout to window resizing 8683 */ 8684proto.unbindResize = function() { 8685 window.removeEventListener( 'resize', this ); 8686 this.isResizeBound = false; 8687}; 8688 8689proto.onresize = function() { 8690 this.resize(); 8691}; 8692 8693utils.debounceMethod( Outlayer, 'onresize', 100 ); 8694 8695proto.resize = function() { 8696 // don't trigger if size did not change 8697 // or if resize was unbound. See #9 8698 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 8699 return; 8700 } 8701 8702 this.layout(); 8703}; 8704 8705/** 8706 * check if layout is needed post layout 8707 * @returns Boolean 8708 */ 8709proto.needsResizeLayout = function() { 8710 var size = getSize( this.element ); 8711 // check that this.size and size are there 8712 // IE8 triggers resize on body size change, so they might not be 8713 var hasSizes = this.size && size; 8714 return hasSizes && size.innerWidth !== this.size.innerWidth; 8715}; 8716 8717// -------------------------- methods -------------------------- // 8718 8719/** 8720 * add items to Outlayer instance 8721 * @param {Array or NodeList or Element} elems 8722 * @returns {Array} items - Outlayer.Items 8723**/ 8724proto.addItems = function( elems ) { 8725 var items = this._itemize( elems ); 8726 // add items to collection 8727 if ( items.length ) { 8728 this.items = this.items.concat( items ); 8729 } 8730 return items; 8731}; 8732 8733/** 8734 * Layout newly-appended item elements 8735 * @param {Array or NodeList or Element} elems 8736 */ 8737proto.appended = function( elems ) { 8738 var items = this.addItems( elems ); 8739 if ( !items.length ) { 8740 return; 8741 } 8742 // layout and reveal just the new items 8743 this.layoutItems( items, true ); 8744 this.reveal( items ); 8745}; 8746 8747/** 8748 * Layout prepended elements 8749 * @param {Array or NodeList or Element} elems 8750 */ 8751proto.prepended = function( elems ) { 8752 var items = this._itemize( elems ); 8753 if ( !items.length ) { 8754 return; 8755 } 8756 // add items to beginning of collection 8757 var previousItems = this.items.slice(0); 8758 this.items = items.concat( previousItems ); 8759 // start new layout 8760 this._resetLayout(); 8761 this._manageStamps(); 8762 // layout new stuff without transition 8763 this.layoutItems( items, true ); 8764 this.reveal( items ); 8765 // layout previous items 8766 this.layoutItems( previousItems ); 8767}; 8768 8769/** 8770 * reveal a collection of items 8771 * @param {Array of Outlayer.Items} items 8772 */ 8773proto.reveal = function( items ) { 8774 this._emitCompleteOnItems( 'reveal', items ); 8775 if ( !items || !items.length ) { 8776 return; 8777 } 8778 var stagger = this.updateStagger(); 8779 items.forEach( function( item, i ) { 8780 item.stagger( i * stagger ); 8781 item.reveal(); 8782 }); 8783}; 8784 8785/** 8786 * hide a collection of items 8787 * @param {Array of Outlayer.Items} items 8788 */ 8789proto.hide = function( items ) { 8790 this._emitCompleteOnItems( 'hide', items ); 8791 if ( !items || !items.length ) { 8792 return; 8793 } 8794 var stagger = this.updateStagger(); 8795 items.forEach( function( item, i ) { 8796 item.stagger( i * stagger ); 8797 item.hide(); 8798 }); 8799}; 8800 8801/** 8802 * reveal item elements 8803 * @param {Array}, {Element}, {NodeList} items 8804 */ 8805proto.revealItemElements = function( elems ) { 8806 var items = this.getItems( elems ); 8807 this.reveal( items ); 8808}; 8809 8810/** 8811 * hide item elements 8812 * @param {Array}, {Element}, {NodeList} items 8813 */ 8814proto.hideItemElements = function( elems ) { 8815 var items = this.getItems( elems ); 8816 this.hide( items ); 8817}; 8818 8819/** 8820 * get Outlayer.Item, given an Element 8821 * @param {Element} elem 8822 * @param {Function} callback 8823 * @returns {Outlayer.Item} item 8824 */ 8825proto.getItem = function( elem ) { 8826 // loop through items to get the one that matches 8827 for ( var i=0; i < this.items.length; i++ ) { 8828 var item = this.items[i]; 8829 if ( item.element == elem ) { 8830 // return item 8831 return item; 8832 } 8833 } 8834}; 8835 8836/** 8837 * get collection of Outlayer.Items, given Elements 8838 * @param {Array} elems 8839 * @returns {Array} items - Outlayer.Items 8840 */ 8841proto.getItems = function( elems ) { 8842 elems = utils.makeArray( elems ); 8843 var items = []; 8844 elems.forEach( function( elem ) { 8845 var item = this.getItem( elem ); 8846 if ( item ) { 8847 items.push( item ); 8848 } 8849 }, this ); 8850 8851 return items; 8852}; 8853 8854/** 8855 * remove element(s) from instance and DOM 8856 * @param {Array or NodeList or Element} elems 8857 */ 8858proto.remove = function( elems ) { 8859 var removeItems = this.getItems( elems ); 8860 8861 this._emitCompleteOnItems( 'remove', removeItems ); 8862 8863 // bail if no items to remove 8864 if ( !removeItems || !removeItems.length ) { 8865 return; 8866 } 8867 8868 removeItems.forEach( function( item ) { 8869 item.remove(); 8870 // remove item from collection 8871 utils.removeFrom( this.items, item ); 8872 }, this ); 8873}; 8874 8875// ----- destroy ----- // 8876 8877// remove and disable Outlayer instance 8878proto.destroy = function() { 8879 // clean up dynamic styles 8880 var style = this.element.style; 8881 style.height = ''; 8882 style.position = ''; 8883 style.width = ''; 8884 // destroy items 8885 this.items.forEach( function( item ) { 8886 item.destroy(); 8887 }); 8888 8889 this.unbindResize(); 8890 8891 var id = this.element.outlayerGUID; 8892 delete instances[ id ]; // remove reference to instance by id 8893 delete this.element.outlayerGUID; 8894 // remove data for jQuery 8895 if ( jQuery ) { 8896 jQuery.removeData( this.element, this.constructor.namespace ); 8897 } 8898 8899}; 8900 8901// -------------------------- data -------------------------- // 8902 8903/** 8904 * get Outlayer instance from element 8905 * @param {Element} elem 8906 * @returns {Outlayer} 8907 */ 8908Outlayer.data = function( elem ) { 8909 elem = utils.getQueryElement( elem ); 8910 var id = elem && elem.outlayerGUID; 8911 return id && instances[ id ]; 8912}; 8913 8914 8915// -------------------------- create Outlayer class -------------------------- // 8916 8917/** 8918 * create a layout class 8919 * @param {String} namespace 8920 */ 8921Outlayer.create = function( namespace, options ) { 8922 // sub-class Outlayer 8923 var Layout = subclass( Outlayer ); 8924 // apply new options and compatOptions 8925 Layout.defaults = utils.extend( {}, Outlayer.defaults ); 8926 utils.extend( Layout.defaults, options ); 8927 Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions ); 8928 8929 Layout.namespace = namespace; 8930 8931 Layout.data = Outlayer.data; 8932 8933 // sub-class Item 8934 Layout.Item = subclass( Item ); 8935 8936 // -------------------------- declarative -------------------------- // 8937 8938 utils.htmlInit( Layout, namespace ); 8939 8940 // -------------------------- jQuery bridge -------------------------- // 8941 8942 // make into jQuery plugin 8943 if ( jQuery && jQuery.bridget ) { 8944 jQuery.bridget( namespace, Layout ); 8945 } 8946 8947 return Layout; 8948}; 8949 8950function subclass( Parent ) { 8951 function SubClass() { 8952 Parent.apply( this, arguments ); 8953 } 8954 8955 SubClass.prototype = Object.create( Parent.prototype ); 8956 SubClass.prototype.constructor = SubClass; 8957 8958 return SubClass; 8959} 8960 8961// ----- helpers ----- // 8962 8963// how many milliseconds are in each unit 8964var msUnits = { 8965 ms: 1, 8966 s: 1000 8967}; 8968 8969// munge time-like parameter into millisecond number 8970// '0.4s' -> 40 8971function getMilliseconds( time ) { 8972 if ( typeof time == 'number' ) { 8973 return time; 8974 } 8975 var matches = time.match( /(^\d*\.?\d*)(\w*)/ ); 8976 var num = matches && matches[1]; 8977 var unit = matches && matches[2]; 8978 if ( !num.length ) { 8979 return 0; 8980 } 8981 num = parseFloat( num ); 8982 var mult = msUnits[ unit ] || 1; 8983 return num * mult; 8984} 8985 8986// ----- fin ----- // 8987 8988// back in global 8989Outlayer.Item = Item; 8990 8991return Outlayer; 8992 8993})); 8994 8995/** 8996 * Isotope Item 8997**/ 8998 8999( function( window, factory ) { 9000 // universal module definition 9001 /* jshint strict: false */ /*globals define, module, require */ 9002 if ( typeof define == 'function' && define.amd ) { 9003 // AMD 9004 define( 'isotope-layout/js/item',[ 9005 'outlayer/outlayer' 9006 ], 9007 factory ); 9008 } else if ( typeof module == 'object' && module.exports ) { 9009 // CommonJS 9010 module.exports = factory( 9011 require('outlayer') 9012 ); 9013 } else { 9014 // browser global 9015 window.Isotope = window.Isotope || {}; 9016 window.Isotope.Item = factory( 9017 window.Outlayer 9018 ); 9019 } 9020 9021}( window, function factory( Outlayer ) { 9022'use strict'; 9023 9024// -------------------------- Item -------------------------- // 9025 9026// sub-class Outlayer Item 9027function Item() { 9028 Outlayer.Item.apply( this, arguments ); 9029} 9030 9031var proto = Item.prototype = Object.create( Outlayer.Item.prototype ); 9032 9033var _create = proto._create; 9034proto._create = function() { 9035 // assign id, used for original-order sorting 9036 this.id = this.layout.itemGUID++; 9037 _create.call( this ); 9038 this.sortData = {}; 9039}; 9040 9041proto.updateSortData = function() { 9042 if ( this.isIgnored ) { 9043 return; 9044 } 9045 // default sorters 9046 this.sortData.id = this.id; 9047 // for backward compatibility 9048 this.sortData['original-order'] = this.id; 9049 this.sortData.random = Math.random(); 9050 // go thru getSortData obj and apply the sorters 9051 var getSortData = this.layout.options.getSortData; 9052 var sorters = this.layout._sorters; 9053 for ( var key in getSortData ) { 9054 var sorter = sorters[ key ]; 9055 this.sortData[ key ] = sorter( this.element, this ); 9056 } 9057}; 9058 9059var _destroy = proto.destroy; 9060proto.destroy = function() { 9061 // call super 9062 _destroy.apply( this, arguments ); 9063 // reset display, #741 9064 this.css({ 9065 display: '' 9066 }); 9067}; 9068 9069return Item; 9070 9071})); 9072 9073/** 9074 * Isotope LayoutMode 9075 */ 9076 9077( function( window, factory ) { 9078 // universal module definition 9079 /* jshint strict: false */ /*globals define, module, require */ 9080 if ( typeof define == 'function' && define.amd ) { 9081 // AMD 9082 define( 'isotope-layout/js/layout-mode',[ 9083 'get-size/get-size', 9084 'outlayer/outlayer' 9085 ], 9086 factory ); 9087 } else if ( typeof module == 'object' && module.exports ) { 9088 // CommonJS 9089 module.exports = factory( 9090 require('get-size'), 9091 require('outlayer') 9092 ); 9093 } else { 9094 // browser global 9095 window.Isotope = window.Isotope || {}; 9096 window.Isotope.LayoutMode = factory( 9097 window.getSize, 9098 window.Outlayer 9099 ); 9100 } 9101 9102}( window, function factory( getSize, Outlayer ) { 9103 'use strict'; 9104 9105 // layout mode class 9106 function LayoutMode( isotope ) { 9107 this.isotope = isotope; 9108 // link properties 9109 if ( isotope ) { 9110 this.options = isotope.options[ this.namespace ]; 9111 this.element = isotope.element; 9112 this.items = isotope.filteredItems; 9113 this.size = isotope.size; 9114 } 9115 } 9116 9117 var proto = LayoutMode.prototype; 9118 9119 /** 9120 * some methods should just defer to default Outlayer method 9121 * and reference the Isotope instance as `this` 9122 **/ 9123 var facadeMethods = [ 9124 '_resetLayout', 9125 '_getItemLayoutPosition', 9126 '_manageStamp', 9127 '_getContainerSize', 9128 '_getElementOffset', 9129 'needsResizeLayout', 9130 '_getOption' 9131 ]; 9132 9133 facadeMethods.forEach( function( methodName ) { 9134 proto[ methodName ] = function() { 9135 return Outlayer.prototype[ methodName ].apply( this.isotope, arguments ); 9136 }; 9137 }); 9138 9139 // ----- ----- // 9140 9141 // for horizontal layout modes, check vertical size 9142 proto.needsVerticalResizeLayout = function() { 9143 // don't trigger if size did not change 9144 var size = getSize( this.isotope.element ); 9145 // check that this.size and size are there 9146 // IE8 triggers resize on body size change, so they might not be 9147 var hasSizes = this.isotope.size && size; 9148 return hasSizes && size.innerHeight != this.isotope.size.innerHeight; 9149 }; 9150 9151 // ----- measurements ----- // 9152 9153 proto._getMeasurement = function() { 9154 this.isotope._getMeasurement.apply( this, arguments ); 9155 }; 9156 9157 proto.getColumnWidth = function() { 9158 this.getSegmentSize( 'column', 'Width' ); 9159 }; 9160 9161 proto.getRowHeight = function() { 9162 this.getSegmentSize( 'row', 'Height' ); 9163 }; 9164 9165 /** 9166 * get columnWidth or rowHeight 9167 * segment: 'column' or 'row' 9168 * size 'Width' or 'Height' 9169 **/ 9170 proto.getSegmentSize = function( segment, size ) { 9171 var segmentName = segment + size; 9172 var outerSize = 'outer' + size; 9173 // columnWidth / outerWidth // rowHeight / outerHeight 9174 this._getMeasurement( segmentName, outerSize ); 9175 // got rowHeight or columnWidth, we can chill 9176 if ( this[ segmentName ] ) { 9177 return; 9178 } 9179 // fall back to item of first element 9180 var firstItemSize = this.getFirstItemSize(); 9181 this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] || 9182 // or size of container 9183 this.isotope.size[ 'inner' + size ]; 9184 }; 9185 9186 proto.getFirstItemSize = function() { 9187 var firstItem = this.isotope.filteredItems[0]; 9188 return firstItem && firstItem.element && getSize( firstItem.element ); 9189 }; 9190 9191 // ----- methods that should reference isotope ----- // 9192 9193 proto.layout = function() { 9194 this.isotope.layout.apply( this.isotope, arguments ); 9195 }; 9196 9197 proto.getSize = function() { 9198 this.isotope.getSize(); 9199 this.size = this.isotope.size; 9200 }; 9201 9202 // -------------------------- create -------------------------- // 9203 9204 LayoutMode.modes = {}; 9205 9206 LayoutMode.create = function( namespace, options ) { 9207 9208 function Mode() { 9209 LayoutMode.apply( this, arguments ); 9210 } 9211 9212 Mode.prototype = Object.create( proto ); 9213 Mode.prototype.constructor = Mode; 9214 9215 // default options 9216 if ( options ) { 9217 Mode.options = options; 9218 } 9219 9220 Mode.prototype.namespace = namespace; 9221 // register in Isotope 9222 LayoutMode.modes[ namespace ] = Mode; 9223 9224 return Mode; 9225 }; 9226 9227 return LayoutMode; 9228 9229})); 9230 9231/*! 9232 * Masonry v4.2.1 9233 * Cascading grid layout library 9234 * https://masonry.desandro.com 9235 * MIT License 9236 * by David DeSandro 9237 */ 9238 9239( function( window, factory ) { 9240 // universal module definition 9241 /* jshint strict: false */ /*globals define, module, require */ 9242 if ( typeof define == 'function' && define.amd ) { 9243 // AMD 9244 define( 'masonry-layout/masonry',[ 9245 'outlayer/outlayer', 9246 'get-size/get-size' 9247 ], 9248 factory ); 9249 } else if ( typeof module == 'object' && module.exports ) { 9250 // CommonJS 9251 module.exports = factory( 9252 require('outlayer'), 9253 require('get-size') 9254 ); 9255 } else { 9256 // browser global 9257 window.Masonry = factory( 9258 window.Outlayer, 9259 window.getSize 9260 ); 9261 } 9262 9263}( window, function factory( Outlayer, getSize ) { 9264 9265 9266 9267// -------------------------- masonryDefinition -------------------------- // 9268 9269 // create an Outlayer layout class 9270 var Masonry = Outlayer.create('masonry'); 9271 // isFitWidth -> fitWidth 9272 Masonry.compatOptions.fitWidth = 'isFitWidth'; 9273 9274 var proto = Masonry.prototype; 9275 9276 proto._resetLayout = function() { 9277 this.getSize(); 9278 this._getMeasurement( 'columnWidth', 'outerWidth' ); 9279 this._getMeasurement( 'gutter', 'outerWidth' ); 9280 this.measureColumns(); 9281 9282 // reset column Y 9283 this.colYs = []; 9284 for ( var i=0; i < this.cols; i++ ) { 9285 this.colYs.push( 0 ); 9286 } 9287 9288 this.maxY = 0; 9289 this.horizontalColIndex = 0; 9290 }; 9291 9292 proto.measureColumns = function() { 9293 this.getContainerWidth(); 9294 // if columnWidth is 0, default to outerWidth of first item 9295 if ( !this.columnWidth ) { 9296 var firstItem = this.items[0]; 9297 var firstItemElem = firstItem && firstItem.element; 9298 // columnWidth fall back to item of first element 9299 this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth || 9300 // if first elem has no width, default to size of container 9301 this.containerWidth; 9302 } 9303 9304 var columnWidth = this.columnWidth += this.gutter; 9305 9306 // calculate columns 9307 var containerWidth = this.containerWidth + this.gutter; 9308 var cols = containerWidth / columnWidth; 9309 // fix rounding errors, typically with gutters 9310 var excess = columnWidth - containerWidth % columnWidth; 9311 // if overshoot is less than a pixel, round up, otherwise floor it 9312 var mathMethod = excess && excess < 1 ? 'round' : 'floor'; 9313 cols = Math[ mathMethod ]( cols ); 9314 this.cols = Math.max( cols, 1 ); 9315 }; 9316 9317 proto.getContainerWidth = function() { 9318 // container is parent if fit width 9319 var isFitWidth = this._getOption('fitWidth'); 9320 var container = isFitWidth ? this.element.parentNode : this.element; 9321 // check that this.size and size are there 9322 // IE8 triggers resize on body size change, so they might not be 9323 var size = getSize( container ); 9324 this.containerWidth = size && size.innerWidth; 9325 }; 9326 9327 proto._getItemLayoutPosition = function( item ) { 9328 item.getSize(); 9329 // how many columns does this brick span 9330 var remainder = item.size.outerWidth % this.columnWidth; 9331 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 9332 // round if off by 1 pixel, otherwise use ceil 9333 var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth ); 9334 colSpan = Math.min( colSpan, this.cols ); 9335 // use horizontal or top column position 9336 var colPosMethod = this.options.horizontalOrder ? 9337 '_getHorizontalColPosition' : '_getTopColPosition'; 9338 var colPosition = this[ colPosMethod ]( colSpan, item ); 9339 // position the brick 9340 var position = { 9341 x: this.columnWidth * colPosition.col, 9342 y: colPosition.y 9343 }; 9344 // apply setHeight to necessary columns 9345 var setHeight = colPosition.y + item.size.outerHeight; 9346 var setMax = colSpan + colPosition.col; 9347 for ( var i = colPosition.col; i < setMax; i++ ) { 9348 this.colYs[i] = setHeight; 9349 } 9350 9351 return position; 9352 }; 9353 9354 proto._getTopColPosition = function( colSpan ) { 9355 var colGroup = this._getTopColGroup( colSpan ); 9356 // get the minimum Y value from the columns 9357 var minimumY = Math.min.apply( Math, colGroup ); 9358 9359 return { 9360 col: colGroup.indexOf( minimumY ), 9361 y: minimumY, 9362 }; 9363 }; 9364 9365 /** 9366 * @param {Number} colSpan - number of columns the element spans 9367 * @returns {Array} colGroup 9368 */ 9369 proto._getTopColGroup = function( colSpan ) { 9370 if ( colSpan < 2 ) { 9371 // if brick spans only one column, use all the column Ys 9372 return this.colYs; 9373 } 9374 9375 var colGroup = []; 9376 // how many different places could this brick fit horizontally 9377 var groupCount = this.cols + 1 - colSpan; 9378 // for each group potential horizontal position 9379 for ( var i = 0; i < groupCount; i++ ) { 9380 colGroup[i] = this._getColGroupY( i, colSpan ); 9381 } 9382 return colGroup; 9383 }; 9384 9385 proto._getColGroupY = function( col, colSpan ) { 9386 if ( colSpan < 2 ) { 9387 return this.colYs[ col ]; 9388 } 9389 // make an array of colY values for that one group 9390 var groupColYs = this.colYs.slice( col, col + colSpan ); 9391 // and get the max value of the array 9392 return Math.max.apply( Math, groupColYs ); 9393 }; 9394 9395 // get column position based on horizontal index. #873 9396 proto._getHorizontalColPosition = function( colSpan, item ) { 9397 var col = this.horizontalColIndex % this.cols; 9398 var isOver = colSpan > 1 && col + colSpan > this.cols; 9399 // shift to next row if item can't fit on current row 9400 col = isOver ? 0 : col; 9401 // don't let zero-size items take up space 9402 var hasSize = item.size.outerWidth && item.size.outerHeight; 9403 this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex; 9404 9405 return { 9406 col: col, 9407 y: this._getColGroupY( col, colSpan ), 9408 }; 9409 }; 9410 9411 proto._manageStamp = function( stamp ) { 9412 var stampSize = getSize( stamp ); 9413 var offset = this._getElementOffset( stamp ); 9414 // get the columns that this stamp affects 9415 var isOriginLeft = this._getOption('originLeft'); 9416 var firstX = isOriginLeft ? offset.left : offset.right; 9417 var lastX = firstX + stampSize.outerWidth; 9418 var firstCol = Math.floor( firstX / this.columnWidth ); 9419 firstCol = Math.max( 0, firstCol ); 9420 var lastCol = Math.floor( lastX / this.columnWidth ); 9421 // lastCol should not go over if multiple of columnWidth #425 9422 lastCol -= lastX % this.columnWidth ? 0 : 1; 9423 lastCol = Math.min( this.cols - 1, lastCol ); 9424 // set colYs to bottom of the stamp 9425 9426 var isOriginTop = this._getOption('originTop'); 9427 var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) + 9428 stampSize.outerHeight; 9429 for ( var i = firstCol; i <= lastCol; i++ ) { 9430 this.colYs[i] = Math.max( stampMaxY, this.colYs[i] ); 9431 } 9432 }; 9433 9434 proto._getContainerSize = function() { 9435 this.maxY = Math.max.apply( Math, this.colYs ); 9436 var size = { 9437 height: this.maxY 9438 }; 9439 9440 if ( this._getOption('fitWidth') ) { 9441 size.width = this._getContainerFitWidth(); 9442 } 9443 9444 return size; 9445 }; 9446 9447 proto._getContainerFitWidth = function() { 9448 var unusedCols = 0; 9449 // count unused columns 9450 var i = this.cols; 9451 while ( --i ) { 9452 if ( this.colYs[i] !== 0 ) { 9453 break; 9454 } 9455 unusedCols++; 9456 } 9457 // fit container to columns that have been used 9458 return ( this.cols - unusedCols ) * this.columnWidth - this.gutter; 9459 }; 9460 9461 proto.needsResizeLayout = function() { 9462 var previousWidth = this.containerWidth; 9463 this.getContainerWidth(); 9464 return previousWidth != this.containerWidth; 9465 }; 9466 9467 return Masonry; 9468 9469})); 9470 9471/*! 9472 * Masonry layout mode 9473 * sub-classes Masonry 9474 * https://masonry.desandro.com 9475 */ 9476 9477( function( window, factory ) { 9478 // universal module definition 9479 /* jshint strict: false */ /*globals define, module, require */ 9480 if ( typeof define == 'function' && define.amd ) { 9481 // AMD 9482 define( 'isotope-layout/js/layout-modes/masonry',[ 9483 '../layout-mode', 9484 'masonry-layout/masonry' 9485 ], 9486 factory ); 9487 } else if ( typeof module == 'object' && module.exports ) { 9488 // CommonJS 9489 module.exports = factory( 9490 require('../layout-mode'), 9491 require('masonry-layout') 9492 ); 9493 } else { 9494 // browser global 9495 factory( 9496 window.Isotope.LayoutMode, 9497 window.Masonry 9498 ); 9499 } 9500 9501}( window, function factory( LayoutMode, Masonry ) { 9502'use strict'; 9503 9504// -------------------------- masonryDefinition -------------------------- // 9505 9506 // create an Outlayer layout class 9507 var MasonryMode = LayoutMode.create('masonry'); 9508 9509 var proto = MasonryMode.prototype; 9510 9511 var keepModeMethods = { 9512 _getElementOffset: true, 9513 layout: true, 9514 _getMeasurement: true 9515 }; 9516 9517 // inherit Masonry prototype 9518 for ( var method in Masonry.prototype ) { 9519 // do not inherit mode methods 9520 if ( !keepModeMethods[ method ] ) { 9521 proto[ method ] = Masonry.prototype[ method ]; 9522 } 9523 } 9524 9525 var measureColumns = proto.measureColumns; 9526 proto.measureColumns = function() { 9527 // set items, used if measuring first item 9528 this.items = this.isotope.filteredItems; 9529 measureColumns.call( this ); 9530 }; 9531 9532 // point to mode options for fitWidth 9533 var _getOption = proto._getOption; 9534 proto._getOption = function( option ) { 9535 if ( option == 'fitWidth' ) { 9536 return this.options.isFitWidth !== undefined ? 9537 this.options.isFitWidth : this.options.fitWidth; 9538 } 9539 return _getOption.apply( this.isotope, arguments ); 9540 }; 9541 9542 return MasonryMode; 9543 9544})); 9545 9546/** 9547 * fitRows layout mode 9548 */ 9549 9550( function( window, factory ) { 9551 // universal module definition 9552 /* jshint strict: false */ /*globals define, module, require */ 9553 if ( typeof define == 'function' && define.amd ) { 9554 // AMD 9555 define( 'isotope-layout/js/layout-modes/fit-rows',[ 9556 '../layout-mode' 9557 ], 9558 factory ); 9559 } else if ( typeof exports == 'object' ) { 9560 // CommonJS 9561 module.exports = factory( 9562 require('../layout-mode') 9563 ); 9564 } else { 9565 // browser global 9566 factory( 9567 window.Isotope.LayoutMode 9568 ); 9569 } 9570 9571}( window, function factory( LayoutMode ) { 9572'use strict'; 9573 9574var FitRows = LayoutMode.create('fitRows'); 9575 9576var proto = FitRows.prototype; 9577 9578proto._resetLayout = function() { 9579 this.x = 0; 9580 this.y = 0; 9581 this.maxY = 0; 9582 this._getMeasurement( 'gutter', 'outerWidth' ); 9583}; 9584 9585proto._getItemLayoutPosition = function( item ) { 9586 item.getSize(); 9587 9588 var itemWidth = item.size.outerWidth + this.gutter; 9589 // if this element cannot fit in the current row 9590 var containerWidth = this.isotope.size.innerWidth + this.gutter; 9591 if ( this.x !== 0 && itemWidth + this.x > containerWidth ) { 9592 this.x = 0; 9593 this.y = this.maxY; 9594 } 9595 9596 var position = { 9597 x: this.x, 9598 y: this.y 9599 }; 9600 9601 this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight ); 9602 this.x += itemWidth; 9603 9604 return position; 9605}; 9606 9607proto._getContainerSize = function() { 9608 return { height: this.maxY }; 9609}; 9610 9611return FitRows; 9612 9613})); 9614 9615/** 9616 * vertical layout mode 9617 */ 9618 9619( function( window, factory ) { 9620 // universal module definition 9621 /* jshint strict: false */ /*globals define, module, require */ 9622 if ( typeof define == 'function' && define.amd ) { 9623 // AMD 9624 define( 'isotope-layout/js/layout-modes/vertical',[ 9625 '../layout-mode' 9626 ], 9627 factory ); 9628 } else if ( typeof module == 'object' && module.exports ) { 9629 // CommonJS 9630 module.exports = factory( 9631 require('../layout-mode') 9632 ); 9633 } else { 9634 // browser global 9635 factory( 9636 window.Isotope.LayoutMode 9637 ); 9638 } 9639 9640}( window, function factory( LayoutMode ) { 9641'use strict'; 9642 9643var Vertical = LayoutMode.create( 'vertical', { 9644 horizontalAlignment: 0 9645}); 9646 9647var proto = Vertical.prototype; 9648 9649proto._resetLayout = function() { 9650 this.y = 0; 9651}; 9652 9653proto._getItemLayoutPosition = function( item ) { 9654 item.getSize(); 9655 var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) * 9656 this.options.horizontalAlignment; 9657 var y = this.y; 9658 this.y += item.size.outerHeight; 9659 return { x: x, y: y }; 9660}; 9661 9662proto._getContainerSize = function() { 9663 return { height: this.y }; 9664}; 9665 9666return Vertical; 9667 9668})); 9669 9670/*! 9671 * Isotope v3.0.6 9672 * 9673 * Licensed GPLv3 for open source use 9674 * or Isotope Commercial License for commercial use 9675 * 9676 * https://isotope.metafizzy.co 9677 * Copyright 2010-2018 Metafizzy 9678 */ 9679 9680( function( window, factory ) { 9681 // universal module definition 9682 /* jshint strict: false */ /*globals define, module, require */ 9683 if ( typeof define == 'function' && define.amd ) { 9684 // AMD 9685 define( [ 9686 'outlayer/outlayer', 9687 'get-size/get-size', 9688 'desandro-matches-selector/matches-selector', 9689 'fizzy-ui-utils/utils', 9690 'isotope-layout/js/item', 9691 'isotope-layout/js/layout-mode', 9692 // include default layout modes 9693 'isotope-layout/js/layout-modes/masonry', 9694 'isotope-layout/js/layout-modes/fit-rows', 9695 'isotope-layout/js/layout-modes/vertical' 9696 ], 9697 function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) { 9698 return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ); 9699 }); 9700 } else if ( typeof module == 'object' && module.exports ) { 9701 // CommonJS 9702 module.exports = factory( 9703 window, 9704 require('outlayer'), 9705 require('get-size'), 9706 require('desandro-matches-selector'), 9707 require('fizzy-ui-utils'), 9708 require('isotope-layout/js/item'), 9709 require('isotope-layout/js/layout-mode'), 9710 // include default layout modes 9711 require('isotope-layout/js/layout-modes/masonry'), 9712 require('isotope-layout/js/layout-modes/fit-rows'), 9713 require('isotope-layout/js/layout-modes/vertical') 9714 ); 9715 } else { 9716 // browser global 9717 window.Isotope = factory( 9718 window, 9719 window.Outlayer, 9720 window.getSize, 9721 window.matchesSelector, 9722 window.fizzyUIUtils, 9723 window.Isotope.Item, 9724 window.Isotope.LayoutMode 9725 ); 9726 } 9727 9728}( window, function factory( window, Outlayer, getSize, matchesSelector, utils, 9729 Item, LayoutMode ) { 9730 9731 9732 9733// -------------------------- vars -------------------------- // 9734 9735var jQuery = window.jQuery; 9736 9737// -------------------------- helpers -------------------------- // 9738 9739var trim = String.prototype.trim ? 9740 function( str ) { 9741 return str.trim(); 9742 } : 9743 function( str ) { 9744 return str.replace( /^\s+|\s+$/g, '' ); 9745 }; 9746 9747// -------------------------- isotopeDefinition -------------------------- // 9748 9749 // create an Outlayer layout class 9750 var Isotope = Outlayer.create( 'isotope', { 9751 layoutMode: 'masonry', 9752 isJQueryFiltering: true, 9753 sortAscending: true 9754 }); 9755 9756 Isotope.Item = Item; 9757 Isotope.LayoutMode = LayoutMode; 9758 9759 var proto = Isotope.prototype; 9760 9761 proto._create = function() { 9762 this.itemGUID = 0; 9763 // functions that sort items 9764 this._sorters = {}; 9765 this._getSorters(); 9766 // call super 9767 Outlayer.prototype._create.call( this ); 9768 9769 // create layout modes 9770 this.modes = {}; 9771 // start filteredItems with all items 9772 this.filteredItems = this.items; 9773 // keep of track of sortBys 9774 this.sortHistory = [ 'original-order' ]; 9775 // create from registered layout modes 9776 for ( var name in LayoutMode.modes ) { 9777 this._initLayoutMode( name ); 9778 } 9779 }; 9780 9781 proto.reloadItems = function() { 9782 // reset item ID counter 9783 this.itemGUID = 0; 9784 // call super 9785 Outlayer.prototype.reloadItems.call( this ); 9786 }; 9787 9788 proto._itemize = function() { 9789 var items = Outlayer.prototype._itemize.apply( this, arguments ); 9790 // assign ID for original-order 9791 for ( var i=0; i < items.length; i++ ) { 9792 var item = items[i]; 9793 item.id = this.itemGUID++; 9794 } 9795 this._updateItemsSortData( items ); 9796 return items; 9797 }; 9798 9799 9800 // -------------------------- layout -------------------------- // 9801 9802 proto._initLayoutMode = function( name ) { 9803 var Mode = LayoutMode.modes[ name ]; 9804 // set mode options 9805 // HACK extend initial options, back-fill in default options 9806 var initialOpts = this.options[ name ] || {}; 9807 this.options[ name ] = Mode.options ? 9808 utils.extend( Mode.options, initialOpts ) : initialOpts; 9809 // init layout mode instance 9810 this.modes[ name ] = new Mode( this ); 9811 }; 9812 9813 9814 proto.layout = function() { 9815 // if first time doing layout, do all magic 9816 if ( !this._isLayoutInited && this._getOption('initLayout') ) { 9817 this.arrange(); 9818 return; 9819 } 9820 this._layout(); 9821 }; 9822 9823 // private method to be used in layout() & magic() 9824 proto._layout = function() { 9825 // don't animate first layout 9826 var isInstant = this._getIsInstant(); 9827 // layout flow 9828 this._resetLayout(); 9829 this._manageStamps(); 9830 this.layoutItems( this.filteredItems, isInstant ); 9831 9832 // flag for initalized 9833 this._isLayoutInited = true; 9834 }; 9835 9836 // filter + sort + layout 9837 proto.arrange = function( opts ) { 9838 // set any options pass 9839 this.option( opts ); 9840 this._getIsInstant(); 9841 // filter, sort, and layout 9842 9843 // filter 9844 var filtered = this._filter( this.items ); 9845 this.filteredItems = filtered.matches; 9846 9847 this._bindArrangeComplete(); 9848 9849 if ( this._isInstant ) { 9850 this._noTransition( this._hideReveal, [ filtered ] ); 9851 } else { 9852 this._hideReveal( filtered ); 9853 } 9854 9855 this._sort(); 9856 this._layout(); 9857 }; 9858 // alias to _init for main plugin method 9859 proto._init = proto.arrange; 9860 9861 proto._hideReveal = function( filtered ) { 9862 this.reveal( filtered.needReveal ); 9863 this.hide( filtered.needHide ); 9864 }; 9865 9866 // HACK 9867 // Don't animate/transition first layout 9868 // Or don't animate/transition other layouts 9869 proto._getIsInstant = function() { 9870 var isLayoutInstant = this._getOption('layoutInstant'); 9871 var isInstant = isLayoutInstant !== undefined ? isLayoutInstant : 9872 !this._isLayoutInited; 9873 this._isInstant = isInstant; 9874 return isInstant; 9875 }; 9876 9877 // listen for layoutComplete, hideComplete and revealComplete 9878 // to trigger arrangeComplete 9879 proto._bindArrangeComplete = function() { 9880 // listen for 3 events to trigger arrangeComplete 9881 var isLayoutComplete, isHideComplete, isRevealComplete; 9882 var _this = this; 9883 function arrangeParallelCallback() { 9884 if ( isLayoutComplete && isHideComplete && isRevealComplete ) { 9885 _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] ); 9886 } 9887 } 9888 this.once( 'layoutComplete', function() { 9889 isLayoutComplete = true; 9890 arrangeParallelCallback(); 9891 }); 9892 this.once( 'hideComplete', function() { 9893 isHideComplete = true; 9894 arrangeParallelCallback(); 9895 }); 9896 this.once( 'revealComplete', function() { 9897 isRevealComplete = true; 9898 arrangeParallelCallback(); 9899 }); 9900 }; 9901 9902 // -------------------------- filter -------------------------- // 9903 9904 proto._filter = function( items ) { 9905 var filter = this.options.filter; 9906 filter = filter || '*'; 9907 var matches = []; 9908 var hiddenMatched = []; 9909 var visibleUnmatched = []; 9910 9911 var test = this._getFilterTest( filter ); 9912 9913 // test each item 9914 for ( var i=0; i < items.length; i++ ) { 9915 var item = items[i]; 9916 if ( item.isIgnored ) { 9917 continue; 9918 } 9919 // add item to either matched or unmatched group 9920 var isMatched = test( item ); 9921 // item.isFilterMatched = isMatched; 9922 // add to matches if its a match 9923 if ( isMatched ) { 9924 matches.push( item ); 9925 } 9926 // add to additional group if item needs to be hidden or revealed 9927 if ( isMatched && item.isHidden ) { 9928 hiddenMatched.push( item ); 9929 } else if ( !isMatched && !item.isHidden ) { 9930 visibleUnmatched.push( item ); 9931 } 9932 } 9933 9934 // return collections of items to be manipulated 9935 return { 9936 matches: matches, 9937 needReveal: hiddenMatched, 9938 needHide: visibleUnmatched 9939 }; 9940 }; 9941 9942 // get a jQuery, function, or a matchesSelector test given the filter 9943 proto._getFilterTest = function( filter ) { 9944 if ( jQuery && this.options.isJQueryFiltering ) { 9945 // use jQuery 9946 return function( item ) { 9947 return jQuery( item.element ).is( filter ); 9948 }; 9949 } 9950 if ( typeof filter == 'function' ) { 9951 // use filter as function 9952 return function( item ) { 9953 return filter( item.element ); 9954 }; 9955 } 9956 // default, use filter as selector string 9957 return function( item ) { 9958 return matchesSelector( item.element, filter ); 9959 }; 9960 }; 9961 9962 // -------------------------- sorting -------------------------- // 9963 9964 /** 9965 * @params {Array} elems 9966 * @public 9967 */ 9968 proto.updateSortData = function( elems ) { 9969 // get items 9970 var items; 9971 if ( elems ) { 9972 elems = utils.makeArray( elems ); 9973 items = this.getItems( elems ); 9974 } else { 9975 // update all items if no elems provided 9976 items = this.items; 9977 } 9978 9979 this._getSorters(); 9980 this._updateItemsSortData( items ); 9981 }; 9982 9983 proto._getSorters = function() { 9984 var getSortData = this.options.getSortData; 9985 for ( var key in getSortData ) { 9986 var sorter = getSortData[ key ]; 9987 this._sorters[ key ] = mungeSorter( sorter ); 9988 } 9989 }; 9990 9991 /** 9992 * @params {Array} items - of Isotope.Items 9993 * @private 9994 */ 9995 proto._updateItemsSortData = function( items ) { 9996 // do not update if no items 9997 var len = items && items.length; 9998 9999 for ( var i=0; len && i < len; i++ ) { 10000 var item = items[i]; 10001 item.updateSortData(); 10002 } 10003 }; 10004 10005 // ----- munge sorter ----- // 10006 10007 // encapsulate this, as we just need mungeSorter 10008 // other functions in here are just for munging 10009 var mungeSorter = ( function() { 10010 // add a magic layer to sorters for convienent shorthands 10011 // `.foo-bar` will use the text of .foo-bar querySelector 10012 // `[foo-bar]` will use attribute 10013 // you can also add parser 10014 // `.foo-bar parseInt` will parse that as a number 10015 function mungeSorter( sorter ) { 10016 // if not a string, return function or whatever it is 10017 if ( typeof sorter != 'string' ) { 10018 return sorter; 10019 } 10020 // parse the sorter string 10021 var args = trim( sorter ).split(' '); 10022 var query = args[0]; 10023 // check if query looks like [an-attribute] 10024 var attrMatch = query.match( /^\[(.+)\]$/ ); 10025 var attr = attrMatch && attrMatch[1]; 10026 var getValue = getValueGetter( attr, query ); 10027 // use second argument as a parser 10028 var parser = Isotope.sortDataParsers[ args[1] ]; 10029 // parse the value, if there was a parser 10030 sorter = parser ? function( elem ) { 10031 return elem && parser( getValue( elem ) ); 10032 } : 10033 // otherwise just return value 10034 function( elem ) { 10035 return elem && getValue( elem ); 10036 }; 10037 10038 return sorter; 10039 } 10040 10041 // get an attribute getter, or get text of the querySelector 10042 function getValueGetter( attr, query ) { 10043 // if query looks like [foo-bar], get attribute 10044 if ( attr ) { 10045 return function getAttribute( elem ) { 10046 return elem.getAttribute( attr ); 10047 }; 10048 } 10049 10050 // otherwise, assume its a querySelector, and get its text 10051 return function getChildText( elem ) { 10052 var child = elem.querySelector( query ); 10053 return child && child.textContent; 10054 }; 10055 } 10056 10057 return mungeSorter; 10058 })(); 10059 10060 // parsers used in getSortData shortcut strings 10061 Isotope.sortDataParsers = { 10062 'parseInt': function( val ) { 10063 return parseInt( val, 10 ); 10064 }, 10065 'parseFloat': function( val ) { 10066 return parseFloat( val ); 10067 } 10068 }; 10069 10070 // ----- sort method ----- // 10071 10072 // sort filteredItem order 10073 proto._sort = function() { 10074 if ( !this.options.sortBy ) { 10075 return; 10076 } 10077 // keep track of sortBy History 10078 var sortBys = utils.makeArray( this.options.sortBy ); 10079 if ( !this._getIsSameSortBy( sortBys ) ) { 10080 // concat all sortBy and sortHistory, add to front, oldest goes in last 10081 this.sortHistory = sortBys.concat( this.sortHistory ); 10082 } 10083 // sort magic 10084 var itemSorter = getItemSorter( this.sortHistory, this.options.sortAscending ); 10085 this.filteredItems.sort( itemSorter ); 10086 }; 10087 10088 // check if sortBys is same as start of sortHistory 10089 proto._getIsSameSortBy = function( sortBys ) { 10090 for ( var i=0; i < sortBys.length; i++ ) { 10091 if ( sortBys[i] != this.sortHistory[i] ) { 10092 return false; 10093 } 10094 } 10095 return true; 10096 }; 10097 10098 // returns a function used for sorting 10099 function getItemSorter( sortBys, sortAsc ) { 10100 return function sorter( itemA, itemB ) { 10101 // cycle through all sortKeys 10102 for ( var i = 0; i < sortBys.length; i++ ) { 10103 var sortBy = sortBys[i]; 10104 var a = itemA.sortData[ sortBy ]; 10105 var b = itemB.sortData[ sortBy ]; 10106 if ( a > b || a < b ) { 10107 // if sortAsc is an object, use the value given the sortBy key 10108 var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc; 10109 var direction = isAscending ? 1 : -1; 10110 return ( a > b ? 1 : -1 ) * direction; 10111 } 10112 } 10113 return 0; 10114 }; 10115 } 10116 10117 // -------------------------- methods -------------------------- // 10118 10119 // get layout mode 10120 proto._mode = function() { 10121 var layoutMode = this.options.layoutMode; 10122 var mode = this.modes[ layoutMode ]; 10123 if ( !mode ) { 10124 // TODO console.error 10125 throw new Error( 'No layout mode: ' + layoutMode ); 10126 } 10127 // HACK sync mode's options 10128 // any options set after init for layout mode need to be synced 10129 mode.options = this.options[ layoutMode ]; 10130 return mode; 10131 }; 10132 10133 proto._resetLayout = function() { 10134 // trigger original reset layout 10135 Outlayer.prototype._resetLayout.call( this ); 10136 this._mode()._resetLayout(); 10137 }; 10138 10139 proto._getItemLayoutPosition = function( item ) { 10140 return this._mode()._getItemLayoutPosition( item ); 10141 }; 10142 10143 proto._manageStamp = function( stamp ) { 10144 this._mode()._manageStamp( stamp ); 10145 }; 10146 10147 proto._getContainerSize = function() { 10148 return this._mode()._getContainerSize(); 10149 }; 10150 10151 proto.needsResizeLayout = function() { 10152 return this._mode().needsResizeLayout(); 10153 }; 10154 10155 // -------------------------- adding & removing -------------------------- // 10156 10157 // HEADS UP overwrites default Outlayer appended 10158 proto.appended = function( elems ) { 10159 var items = this.addItems( elems ); 10160 if ( !items.length ) { 10161 return; 10162 } 10163 // filter, layout, reveal new items 10164 var filteredItems = this._filterRevealAdded( items ); 10165 // add to filteredItems 10166 this.filteredItems = this.filteredItems.concat( filteredItems ); 10167 }; 10168 10169 // HEADS UP overwrites default Outlayer prepended 10170 proto.prepended = function( elems ) { 10171 var items = this._itemize( elems ); 10172 if ( !items.length ) { 10173 return; 10174 } 10175 // start new layout 10176 this._resetLayout(); 10177 this._manageStamps(); 10178 // filter, layout, reveal new items 10179 var filteredItems = this._filterRevealAdded( items ); 10180 // layout previous items 10181 this.layoutItems( this.filteredItems ); 10182 // add to items and filteredItems 10183 this.filteredItems = filteredItems.concat( this.filteredItems ); 10184 this.items = items.concat( this.items ); 10185 }; 10186 10187 proto._filterRevealAdded = function( items ) { 10188 var filtered = this._filter( items ); 10189 this.hide( filtered.needHide ); 10190 // reveal all new items 10191 this.reveal( filtered.matches ); 10192 // layout new items, no transition 10193 this.layoutItems( filtered.matches, true ); 10194 return filtered.matches; 10195 }; 10196 10197 /** 10198 * Filter, sort, and layout newly-appended item elements 10199 * @param {Array or NodeList or Element} elems 10200 */ 10201 proto.insert = function( elems ) { 10202 var items = this.addItems( elems ); 10203 if ( !items.length ) { 10204 return; 10205 } 10206 // append item elements 10207 var i, item; 10208 var len = items.length; 10209 for ( i=0; i < len; i++ ) { 10210 item = items[i]; 10211 this.element.appendChild( item.element ); 10212 } 10213 // filter new stuff 10214 var filteredInsertItems = this._filter( items ).matches; 10215 // set flag 10216 for ( i=0; i < len; i++ ) { 10217 items[i].isLayoutInstant = true; 10218 } 10219 this.arrange(); 10220 // reset flag 10221 for ( i=0; i < len; i++ ) { 10222 delete items[i].isLayoutInstant; 10223 } 10224 this.reveal( filteredInsertItems ); 10225 }; 10226 10227 var _remove = proto.remove; 10228 proto.remove = function( elems ) { 10229 elems = utils.makeArray( elems ); 10230 var removeItems = this.getItems( elems ); 10231 // do regular thing 10232 _remove.call( this, elems ); 10233 // bail if no items to remove 10234 var len = removeItems && removeItems.length; 10235 // remove elems from filteredItems 10236 for ( var i=0; len && i < len; i++ ) { 10237 var item = removeItems[i]; 10238 // remove item from collection 10239 utils.removeFrom( this.filteredItems, item ); 10240 } 10241 }; 10242 10243 proto.shuffle = function() { 10244 // update random sortData 10245 for ( var i=0; i < this.items.length; i++ ) { 10246 var item = this.items[i]; 10247 item.sortData.random = Math.random(); 10248 } 10249 this.options.sortBy = 'random'; 10250 this._sort(); 10251 this._layout(); 10252 }; 10253 10254 /** 10255 * trigger fn without transition 10256 * kind of hacky to have this in the first place 10257 * @param {Function} fn 10258 * @param {Array} args 10259 * @returns ret 10260 * @private 10261 */ 10262 proto._noTransition = function( fn, args ) { 10263 // save transitionDuration before disabling 10264 var transitionDuration = this.options.transitionDuration; 10265 // disable transition 10266 this.options.transitionDuration = 0; 10267 // do it 10268 var returnValue = fn.apply( this, args ); 10269 // re-enable transition for reveal 10270 this.options.transitionDuration = transitionDuration; 10271 return returnValue; 10272 }; 10273 10274 // ----- helper methods ----- // 10275 10276 /** 10277 * getter method for getting filtered item elements 10278 * @returns {Array} elems - collection of item elements 10279 */ 10280 proto.getFilteredItemElements = function() { 10281 return this.filteredItems.map( function( item ) { 10282 return item.element; 10283 }); 10284 }; 10285 10286 // ----- ----- // 10287 10288 return Isotope; 10289 10290})); 10291
10292/*! 10293 * Packery layout mode PACKAGED v2.0.1 10294 * sub-classes Packery 10295 */ 10296 10297/** 10298 * Rect 10299 * low-level utility class for basic geometry 10300 */ 10301 10302( function( window, factory ) { 10303 // universal module definition 10304 /* jshint strict: false */ /* globals define, module */ 10305 if ( typeof define == 'function' && define.amd ) { 10306 // AMD 10307 define( 'packery/js/rect',factory ); 10308 } else if ( typeof module == 'object' && module.exports ) { 10309 // CommonJS 10310 module.exports = factory(); 10311 } else { 10312 // browser global 10313 window.Packery = window.Packery || {}; 10314 window.Packery.Rect = factory(); 10315 } 10316 10317}( window, function factory() { 10318 10319 10320// -------------------------- Rect -------------------------- // 10321 10322function Rect( props ) { 10323 // extend properties from defaults 10324 for ( var prop in Rect.defaults ) { 10325 this[ prop ] = Rect.defaults[ prop ]; 10326 } 10327 10328 for ( prop in props ) { 10329 this[ prop ] = props[ prop ]; 10330 } 10331 10332} 10333 10334Rect.defaults = { 10335 x: 0, 10336 y: 0, 10337 width: 0, 10338 height: 0 10339}; 10340 10341var proto = Rect.prototype; 10342 10343/** 10344 * Determines whether or not this rectangle wholly encloses another rectangle or point. 10345 * @param {Rect} rect 10346 * @returns {Boolean} 10347**/ 10348proto.contains = function( rect ) { 10349 // points don't have width or height 10350 var otherWidth = rect.width || 0; 10351 var otherHeight = rect.height || 0; 10352 return this.x <= rect.x && 10353 this.y <= rect.y && 10354 this.x + this.width >= rect.x + otherWidth && 10355 this.y + this.height >= rect.y + otherHeight; 10356}; 10357 10358/** 10359 * Determines whether or not the rectangle intersects with another. 10360 * @param {Rect} rect 10361 * @returns {Boolean} 10362**/ 10363proto.overlaps = function( rect ) { 10364 var thisRight = this.x + this.width; 10365 var thisBottom = this.y + this.height; 10366 var rectRight = rect.x + rect.width; 10367 var rectBottom = rect.y + rect.height; 10368 10369 // http://stackoverflow.com/a/306332 10370 return this.x < rectRight && 10371 thisRight > rect.x && 10372 this.y < rectBottom && 10373 thisBottom > rect.y; 10374}; 10375 10376/** 10377 * @param {Rect} rect - the overlapping rect 10378 * @returns {Array} freeRects - rects representing the area around the rect 10379**/ 10380proto.getMaximalFreeRects = function( rect ) { 10381 10382 // if no intersection, return false 10383 if ( !this.overlaps( rect ) ) { 10384 return false; 10385 } 10386 10387 var freeRects = []; 10388 var freeRect; 10389 10390 var thisRight = this.x + this.width; 10391 var thisBottom = this.y + this.height; 10392 var rectRight = rect.x + rect.width; 10393 var rectBottom = rect.y + rect.height; 10394 10395 // top 10396 if ( this.y < rect.y ) { 10397 freeRect = new Rect({ 10398 x: this.x, 10399 y: this.y, 10400 width: this.width, 10401 height: rect.y - this.y 10402 }); 10403 freeRects.push( freeRect ); 10404 } 10405 10406 // right 10407 if ( thisRight > rectRight ) { 10408 freeRect = new Rect({ 10409 x: rectRight, 10410 y: this.y, 10411 width: thisRight - rectRight, 10412 height: this.height 10413 }); 10414 freeRects.push( freeRect ); 10415 } 10416 10417 // bottom 10418 if ( thisBottom > rectBottom ) { 10419 freeRect = new Rect({ 10420 x: this.x, 10421 y: rectBottom, 10422 width: this.width, 10423 height: thisBottom - rectBottom 10424 }); 10425 freeRects.push( freeRect ); 10426 } 10427 10428 // left 10429 if ( this.x < rect.x ) { 10430 freeRect = new Rect({ 10431 x: this.x, 10432 y: this.y, 10433 width: rect.x - this.x, 10434 height: this.height 10435 }); 10436 freeRects.push( freeRect ); 10437 } 10438 10439 return freeRects; 10440}; 10441 10442proto.canFit = function( rect ) { 10443 return this.width >= rect.width && this.height >= rect.height; 10444}; 10445 10446return Rect; 10447 10448})); 10449 10450/** 10451 * Packer 10452 * bin-packing algorithm 10453 */ 10454 10455( function( window, factory ) { 10456 // universal module definition 10457 /* jshint strict: false */ /* globals define, module, require */ 10458 if ( typeof define == 'function' && define.amd ) { 10459 // AMD 10460 define( 'packery/js/packer',[ './rect' ], factory ); 10461 } else if ( typeof module == 'object' && module.exports ) { 10462 // CommonJS 10463 module.exports = factory( 10464 require('./rect') 10465 ); 10466 } else { 10467 // browser global 10468 var Packery = window.Packery = window.Packery || {}; 10469 Packery.Packer = factory( Packery.Rect ); 10470 } 10471 10472}( window, function factory( Rect ) { 10473 10474 10475// -------------------------- Packer -------------------------- // 10476 10477/** 10478 * @param {Number} width 10479 * @param {Number} height 10480 * @param {String} sortDirection 10481 * topLeft for vertical, leftTop for horizontal 10482 */ 10483function Packer( width, height, sortDirection ) { 10484 this.width = width || 0; 10485 this.height = height || 0; 10486 this.sortDirection = sortDirection || 'downwardLeftToRight'; 10487 10488 this.reset(); 10489} 10490 10491var proto = Packer.prototype; 10492 10493proto.reset = function() { 10494 this.spaces = []; 10495 10496 var initialSpace = new Rect({ 10497 x: 0, 10498 y: 0, 10499 width: this.width, 10500 height: this.height 10501 }); 10502 10503 this.spaces.push( initialSpace ); 10504 // set sorter 10505 this.sorter = sorters[ this.sortDirection ] || sorters.downwardLeftToRight; 10506}; 10507 10508// change x and y of rect to fit with in Packer's available space
10508s 10509proto.pack = function( rect ) { 10510 for ( var i=0; i < this.spaces.length; i++ ) { 10511 var space = this.spaces[i]; 10512 if ( space.canFit( rect ) ) { 10513 this.placeInSpace( rect, space ); 10514 break; 10515 } 10516 } 10517}; 10518 10519proto.columnPack = function( rect ) { 10520 for ( var i=0; i < this.spaces.length; i++ ) { 10521 var space = this.spaces[i]; 10522 var canFitInSpaceColumn = space.x <= rect.x && 10523 space.x + space.width >= rect.x + rect.width && 10524 space.height >= rect.height - 0.01; // fudge number for rounding error 10525 if ( canFitInSpaceColumn ) { 10526 rect.y = space.y; 10527 this.placed( rect ); 10528 break; 10529 } 10530 } 10531}; 10532 10533proto.rowPack = function( rect ) { 10534 for ( var i=0; i < this.spaces.length; i++ ) { 10535 var space = this.spaces[i]; 10536 var canFitInSpaceRow = space.y <= rect.y && 10537 space.y + space.height >= rect.y + rect.height && 10538 space.width >= rect.width - 0.01; // fudge number for rounding error 10539 if ( canFitInSpaceRow ) { 10540 rect.x = space.x; 10541 this.placed( rect ); 10542 break; 10543 } 10544 } 10545}; 10546 10547proto.placeInSpace = function( rect, space ) { 10548 // place rect in space 10549 rect.x = space.x; 10550 rect.y = space.y; 10551 10552 this.placed( rect ); 10553}; 10554 10555// update spaces with placed rect 10556proto.placed = function( rect ) { 10557 // update spaces 10558 var revisedSpaces = []; 10559 for ( var i=0; i < this.spaces.length; i++ ) { 10560 var space = this.spaces[i]; 10561 var newSpaces = space.getMaximalFreeRects( rect ); 10562 // add either the original space or the new spaces to the revised spaces 10563 if ( newSpaces ) { 10564 revisedSpaces.push.apply( revisedSpaces, newSpaces ); 10565 } else { 10566 revisedSpaces.push( space ); 10567 } 10568 } 10569 10570 this.spaces = revisedSpaces; 10571 10572 this.mergeSortSpaces(); 10573}; 10574 10575proto.mergeSortSpaces = function() { 10576 // remove redundant spaces 10577 Packer.mergeRects( this.spaces ); 10578 this.spaces.sort( this.sorter ); 10579}; 10580 10581// add a space back 10582proto.addSpace = function( rect ) { 10583 this.spaces.push( rect ); 10584 this.mergeSortSpaces(); 10585}; 10586 10587// -------------------------- utility functions -------------------------- // 10588 10589/** 10590 * Remove redundant rectangle from array of rectangles 10591 * @param {Array} rects: an array of Rects 10592 * @returns {Array} rects: an array of Rects 10593**/ 10594Packer.mergeRects = function( rects ) { 10595 var i = 0; 10596 var rect = rects[i]; 10597 10598 rectLoop: 10599 while ( rect ) { 10600 var j = 0; 10601 var compareRect = rects[ i + j ]; 10602 10603 while ( compareRect ) { 10604 if ( compareRect == rect ) { 10605 j++; // next 10606 } else if ( compareRect.contains( rect ) ) { 10607 // remove rect 10608 rects.splice( i, 1 ); 10609 rect = rects[i]; // set next rect 10610 continue rectLoop; // bail on compareLoop 10611 } else if ( rect.contains( compareRect ) ) { 10612 // remove compareRect 10613 rects.splice( i + j, 1 ); 10614 } else { 10615 j++; 10616 } 10617 compareRect = rects[ i + j ]; // set next compareRect 10618 } 10619 i++; 10620 rect = rects[i]; 10621 } 10622 10623 return rects; 10624}; 10625 10626 10627// -------------------------- sorters -------------------------- // 10628 10629// functions for sorting rects in order 10630var sorters = { 10631 // top down, then left to right 10632 downwardLeftToRight: function( a, b ) { 10633 return a.y - b.y || a.x - b.x; 10634 }, 10635 // left to right, then top down 10636 rightwardTopToBottom: function( a, b ) { 10637 return a.x - b.x || a.y - b.y; 10638 } 10639}; 10640 10641 10642// -------------------------- -------------------------- // 10643 10644return Packer; 10645 10646})); 10647 10648/** 10649 * Packery Item Element 10650**/ 10651 10652( function( window, factory ) { 10653 // universal module definition 10654 /* jshint strict: false */ /* globals define, module, require */ 10655 if ( typeof define == 'function' && define.amd ) { 10656 // AMD 10657 define( 'packery/js/item',[ 10658 'outlayer/outlayer', 10659 './rect' 10660 ], 10661 factory ); 10662 } else if ( typeof module == 'object' && module.exports ) { 10663 // CommonJS 10664 module.exports = factory( 10665 require('outlayer'), 10666 require('./rect') 10667 ); 10668 } else { 10669 // browser global 10670 window.Packery.Item = factory( 10671 window.Outlayer, 10672 window.Packery.Rect 10673 ); 10674 } 10675 10676}( window, function factory( Outlayer, Rect ) { 10677 10678 10679// -------------------------- Item -------------------------- // 10680 10681var docElemStyle = document.documentElement.style; 10682 10683var transformProperty = typeof docElemStyle.transform == 'string' ? 10684 'transform' : 'WebkitTransform'; 10685 10686// sub-class Item 10687var Item = function PackeryItem() { 10688 Outlayer.Item.apply( this, arguments ); 10689}; 10690 10691var proto = Item.prototype = Object.create( Outlayer.Item.prototype ); 10692 10693var __create = proto._create; 10694proto._create = function() { 10695 // call default _create logic 10696 __create.call( this ); 10697 this.rect = new Rect(); 10698}; 10699 10700var _moveTo = proto.moveTo; 10701proto.moveTo = function( x, y ) {
10702 // don't shift 1px while dragging 10703 var dx = Math.abs( this.position.x - x ); 10704 var dy = Math.abs( this.position.y - y ); 10705 10706 var canHackGoTo = this.layout.dragItemCount && !this.isPlacing && 10707 !this.isTransitioning && dx < 1 && dy < 1; 10708 if ( canHackGoTo ) { 10709 this.goTo( x, y ); 10710 return; 10711 } 10712 _moveTo.apply( this, arguments ); 10713}; 10714 10715// -------------------------- placing -------------------------- // 10716 10717proto.enablePlacing = function() { 10718 this.removeTransitionStyles(); 10719 // remove transform property from transition 10720 if ( this.isTransitioning && transformProperty ) { 10721 this.element.style[ transformProperty ] = 'none'; 10722 } 10723 this.isTransitioning = false; 10724 this.getSize(); 10725 this.layout._setRectSize( this.element, this.rect ); 10726 this.isPlacing = true; 10727}; 10728 10729proto.disablePlacing = function() { 10730 this.isPlacing = false; 10731}; 10732 10733// ----- ----- // 10734 10735// remove element from DOM 10736proto.removeElem = function() { 10737 this.element.parentNode.removeChild( this.element ); 10738 // add space back to packer 10739 this.layout.packer.addSpace( this.rect ); 10740 this.emitEvent( 'remove', [ this ] ); 10741}; 10742 10743// ----- dropPlaceholder ----- // 10744 10745proto.showDropPlaceholder = function() { 10746 var dropPlaceholder = this.dropPlaceholder; 10747 if ( !dropPlaceholder ) { 10748 // create dropPlaceholder 10749 dropPlaceholder = this.dropPlaceholder = document.createElement('div'); 10750 dropPlaceholder.className = 'packery-drop-placeholder'; 10751 dropPlaceholder.style.position = 'absolute'; 10752 } 10753 10754 dropPlaceholder.style.width = this.size.width + 'px'; 10755 dropPlaceholder.style.height = this.size.height + 'px'; 10756 this.positionDropPlaceholder(); 10757 this.layout.element.appendChild( dropPlaceholder ); 10758}; 10759 10760proto.positionDropPlaceholder = function() { 10761 this.dropPlaceholder.style[ transformProperty ] = 'translate(' + 10762 this.rect.x + 'px, ' + this.rect.y + 'px)'; 10763}; 10764 10765proto.hideDropPlaceholder = function() { 10766 this.layout.element.removeChild( this.dropPlaceholder ); 10767}; 10768 10769// ----- ----- // 10770 10771return Item; 10772 10773})); 10774 10775/*! 10776 * Packery v2.0.0 10777 * Gapless, draggable grid layouts 10778 * 10779 * Licensed GPLv3 for open source use 10780 * or Packery Commercial License for commercial use 10781 * 10782 * http://packery.metafizzy.co 10783 * Copyright 2016 Metafizzy 10784 */ 10785 10786( function( window, factory ) { 10787 // universal module definition 10788 /* jshint strict: false */ /* globals define, module, require */ 10789 if ( typeof define == 'function' && define.amd ) { 10790 // AMD 10791 define( 'packery/js/packery',[ 10792 'get-size/get-size', 10793 'outlayer/outlayer', 10794 './rect', 10795 './packer', 10796 './item' 10797 ], 10798 factory ); 10799 } else if ( typeof module == 'object' && module.exports ) { 10800 // CommonJS 10801 module.exports = factory( 10802 require('get-size'), 10803 require('outlayer'), 10804 require('./rect'), 10805 require('./packer'), 10806 require('./item') 10807 ); 10808 } else { 10809 // browser global 10810 window.Packery = factory( 10811 window.getSize, 10812 window.Outlayer, 10813 window.Packery.Rect, 10814 window.Packery.Packer, 10815 window.Packery.Item 10816 ); 10817 } 10818 10819}( window, function factory( getSize, Outlayer, Rect, Packer, Item ) { 10820 10821 10822// ----- Rect ----- // 10823 10824// allow for pixel rounding errors IE8-IE11 & Firefox; #227 10825Rect.prototype.canFit = function( rect ) { 10826 return this.width >= rect.width - 1 && this.height >= rect.height - 1; 10827}; 10828 10829// -------------------------- Packery -------------------------- // 10830 10831// create an Outlayer layout class 10832var Packery = Outlayer.create('packery'); 10833Packery.Item = Item; 10834 10835var proto = Packery.prototype; 10836 10837proto._create = function() { 10838 // call super 10839 Outlayer.prototype._create.call( this ); 10840 10841 // initial properties 10842 this.packer = new Packer(); 10843 // packer for drop targets 10844 this.shiftPacker = new Packer(); 10845 this.isEnabled = true; 10846 10847 this.dragItemCount = 0; 10848 10849 // create drag handlers 10850 var _this = this; 10851 this.handleDraggabilly = { 10852 dragStart: function() { 10853 _this.itemDragStart( this.element ); 10854 }, 10855 dragMove: function() { 10856 _this.itemDragMove( this.element, this.position.x, this.position.y ); 10857 }, 10858 dragEnd: function() { 10859 _this.itemDragEnd( this.element ); 10860 } 10861 }; 10862 10863 this.handleUIDraggable = { 10864 start: function handleUIDraggableStart( event, ui ) { 10865 // HTML5 may trigger dragstart, dismiss HTML5 dragging 10866 if ( !ui ) { 10867 return; 10868 } 10869 _this.itemDragStart( event.currentTarget ); 10870 }, 10871 drag: function handleUIDraggableDrag( event, ui ) { 10872 if ( !ui ) { 10873 return; 10874 } 10875 _this.itemDragMove( event.currentTarget, ui.position.left, ui.position.top ); 10876 }, 10877 stop: function handleUIDraggableStop( event, ui ) { 10878 if ( !ui ) { 10879 return; 10880 } 10881 _this.itemDragEnd( event.currentTarget ); 10882 } 10883 }; 10884 10885}; 10886 10887 10888// ----- init & layout ----- // 10889 10890/** 10891 * logic before any new layout 10892 */ 10893proto._resetLayout = function() {
10894 this.getSize(); 10895 10896 this._getMeasurements(); 10897 10898 // reset packer 10899 var width, height, sortDirection; 10900 // packer settings, if horizontal or vertical 10901 if ( this._getOption('horizontal') ) { 10902 width = Infinity; 10903 height = this.size.innerHeight + this.gutter; 10904 sortDirection = 'rightwardTopToBottom'; 10905 } else { 10906 width = this.size.innerWidth + this.gutter; 10907 height = Infinity; 10908 sortDirection = 'downwardLeftToRight'; 10909 } 10910 10911 this.packer.width = this.shiftPacker.width = width; 10912 this.packer.height = this.shiftPacker.height = height; 10913 this.packer.sortDirection = this.shiftPacker.sortDirection = sortDirection; 10914 10915 this.packer.reset(); 10916 10917 // layout 10918 this.maxY = 0; 10919 this.maxX = 0; 10920}; 10921 10922/** 10923 * update columnWidth, rowHeight, & gutter 10924 * @private 10925 */ 10926proto._getMeasurements = function() { 10927 this._getMeasurement( 'columnWidth', 'width' ); 10928 this._getMeasurement( 'rowHeight', 'height' ); 10929 this._getMeasurement( 'gutter', 'width' ); 10930}; 10931 10932proto._getItemLayoutPosition = function( item ) { 10933 this._setRectSize( item.element, item.rect ); 10934 if ( this.isShifting || this.dragItemCount > 0 ) { 10935 var packMethod = this._getPackMethod(); 10936 this.packer[ packMethod ]( item.rect ); 10937 } else { 10938 this.packer.pack( item.rect ); 10939 } 10940 10941 this._setMaxXY( item.rect ); 10942 return item.rect; 10943}; 10944 10945proto.shiftLayout = function() { 10946 this.isShifting = true; 10947 this.layout(); 10948 delete this.isShifting; 10949}; 10950 10951proto._getPackMethod = function() { 10952 return this._getOption('horizontal') ? 'rowPack' : 'columnPack'; 10953}; 10954 10955 10956/** 10957 * set max X and Y value, for size of container 10958 * @param {Packery.Rect} rect 10959 * @private 10960 */ 10961proto._setMaxXY = function( rect ) { 10962 this.maxX = Math.max( rect.x + rect.width, this.maxX ); 10963 this.maxY = Math.max( rect.y + rect.height, this.maxY ); 10964}; 10965 10966/** 10967 * set the width and height of a rect, applying columnWidth and rowHeight 10968 * @param {Element} elem 10969 * @param {Packery.Rect} rect 10970 */ 10971proto._setRectSize = function( elem, rect ) { 10972 var size = getSize( elem ); 10973 var w = size.outerWidth; 10974 var h = size.outerHeight; 10975 // size for columnWidth and rowHeight, if available 10976 // only check if size is non-zero, #177 10977 if ( w || h ) { 10978 w = this._applyGridGutter( w, this.columnWidth ); 10979 h = this._applyGridGutter( h, this.rowHeight ); 10980 } 10981 // rect must fit in packer 10982 rect.width = Math.min( w, this.packer.width ); 10983 rect.height = Math.min( h, this.packer.height ); 10984}; 10985 10986/** 10987 * fits item to columnWidth/rowHeight and adds gutter 10988 * @param {Number} measurement - item width or height 10989 * @param {Number} gridSize - columnWidth or rowHeight 10990 * @returns measurement 10991 */ 10992proto._applyGridGutter = function( measurement, gridSize ) { 10993 // just add gutter if no gridSize 10994 if ( !gridSize ) { 10995 return measurement + this.gutter; 10996 } 10997 gridSize += this.gutter; 10998 // fit item to columnWidth/rowHeight 10999 var remainder = measurement % gridSize; 11000 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 11001 measurement = Math[ mathMethod ]( measurement / gridSize ) * gridSize; 11002 return measurement; 11003}; 11004 11005proto._getContainerSize = function() { 11006 if ( this._getOption('horizontal') ) { 11007 return { 11008 width: this.maxX - this.gutter 11009 }; 11010 } else { 11011 return { 11012 height: this.maxY - this.gutter 11013 }; 11014 } 11015}; 11016 11017 11018// -------------------------- stamp -------------------------- // 11019 11020/** 11021 * makes space for element 11022 * @param {Element} elem 11023 */ 11024proto._manageStamp = function( elem ) { 11025 11026 var item = this.getItem( elem ); 11027 var rect; 11028 if ( item && item.isPlacing ) { 11029 rect = item.rect; 11030 } else { 11031 var offset = this._getElementOffset( elem ); 11032 rect = new Rect({ 11033 x: this._getOption('originLeft') ? offset.left : offset.right, 11034 y: this._getOption('originTop') ? offset.top : offset.bottom 11035 }); 11036 } 11037 11038 this._setRectSize( elem, rect ); 11039 // save its space in the packer 11040 this.packer.placed( rect ); 11041 this._setMaxXY( rect ); 11042}; 11043 11044// -------------------------- methods -------------------------- // 11045 11046function verticalSorter( a, b ) { 11047 return a.position.y - b.position.y || a.position.x - b.position.x; 11048} 11049 11050function horizontalSorter( a, b ) { 11051 return a.position.x - b.position.x || a.position.y - b.position.y; 11052} 11053
11054proto.sortItemsByPosition = function() { 11055 var sorter = this._getOption('horizontal') ? horizontalSorter : verticalSorter; 11056 this.items.sort( sorter ); 11057}; 11058 11059/** 11060 * Fit item element in its current position 11061 * Packery will position elements around it 11062 * useful for expanding elements 11063 * 11064 * @param {Element} elem 11065 * @param {Number} x - horizontal destination position, optional 11066 * @param {Number} y - vertical destination position, optional 11067 */ 11068proto.fit = function( elem, x, y ) { 11069 var item = this.getItem( elem ); 11070 if ( !item ) { 11071 return; 11072 } 11073 11074 // stamp item to get it out of layout 11075 this.stamp( item.element ); 11076 // set placing flag 11077 item.enablePlacing(); 11078 this.updateShiftTargets( item ); 11079 // fall back to current position for fitting 11080 x = x === undefined ? item.rect.x: x; 11081 y = y === undefined ? item.rect.y: y; 11082 // position it best at its destination 11083 this.shift( item, x, y ); 11084 this._bindFitEvents( item ); 11085 item.moveTo( item.rect.x, item.rect.y ); 11086 // layout everything else 11087 this.shiftLayout(); 11088 // return back to regularly scheduled programming 11089 this.unstamp( item.element ); 11090 this.sortItemsByPosition(); 11091 item.disablePlacing(); 11092}; 11093 11094/** 11095 * emit event when item is fit and other items are laid out 11096 * @param {Packery.Item} item 11097 * @private 11098 */ 11099proto._bindFitEvents = function( item ) { 11100 var _this = this; 11101 var ticks = 0; 11102 function onLayout() { 11103 ticks++; 11104 if ( ticks != 2 ) { 11105 return; 11106 } 11107 _this.dispatchEvent( 'fitComplete', null, [ item ] ); 11108 } 11109 // when item is laid out 11110 item.once( 'layout', onLayout ); 11111 // when all items are laid out 11112 this.once( 'layoutComplete', onLayout ); 11113}; 11114 11115// -------------------------- resize -------------------------- // 11116 11117// debounced, layout on resize 11118proto.resize = function() { 11119 // don't trigger if size did not change 11120 // or if resize was unbound. See #285, outlayer#9 11121 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 11122 return; 11123 } 11124 11125 if ( this.options.shiftPercentResize ) { 11126 this.resizeShiftPercentLayout(); 11127 } else { 11128 this.layout(); 11129 } 11130}; 11131 11132/** 11133 * check if layout is needed post layout 11134 * @returns Boolean 11135 */ 11136proto.needsResizeLayout = function() { 11137 var size = getSize( this.element ); 11138 var innerSize = this._getOption('horizontal') ? 'innerHeight' : 'innerWidth'; 11139 return size[ innerSize ] != this.size[ innerSize ]; 11140}; 11141 11142proto.resizeShiftPercentLayout = function() { 11143 var items = this._getItemsForLayout( this.items ); 11144 11145 var isHorizontal = this._getOption('horizontal'); 11146 var coord = isHorizontal ? 'y' : 'x'; 11147 var measure = isHorizontal ? 'height' : 'width'; 11148 var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth'; 11149 var innerSize = isHorizontal ? 'innerHeight' : 'innerWidth'; 11150 11151 // proportional re-align items 11152 var previousSegment = this[ segmentName ]; 11153 previousSegment = previousSegment && previousSegment + this.gutter; 11154 11155 if ( previousSegment ) { 11156 this._getMeasurements(); 11157 var currentSegment = this[ segmentName ] + this.gutter; 11158 items.forEach( function( item ) { 11159 var seg = Math.round( item.rect[ coord ] / previousSegment ); 11160 item.rect[ coord ] = seg * currentSegment; 11161 }); 11162 } else { 11163 var currentSize = getSize( this.element )[ innerSize ] + this.gutter; 11164 var previousSize = this.packer[ measure ]; 11165 items.forEach( function( item ) { 11166 item.rect[ coord ] = ( item.rect[ coord ] / previousSize ) * currentSize; 11167 }); 11168 } 11169 11170 this.shiftLayout(); 11171}; 11172 11173// -------------------------- drag -------------------------- // 11174 11175/** 11176 * handle an item drag start event 11177 * @param {Element} elem 11178 */ 11179proto.itemDragStart = function( elem ) { 11180 if ( !this.isEnabled ) { 11181 return; 11182 } 11183 this.stamp( elem ); 11184 // this.ignore( elem ); 11185 var item = this.getItem( elem ); 11186 if ( !item ) { 11187 return; 11188 } 11189 11190 item.enablePlacing(); 11191 item.showDropPlaceholder(); 11192 this.dragItemCount++; 11193 this.updateShiftTargets( item ); 11194}; 11195 11196proto.updateShiftTargets = function( dropItem ) { 11197 this.shiftPacker.reset(); 11198 11199 // pack stamps 11200 this._getBoundingRect(); 11201 var isOriginLeft = this._getOption('originLeft'); 11202 var isOriginTop = this._getOption('originTop'); 11203 this.stamps.forEach( function( stamp ) { 11204 // ignore dragged item 11205 var item = this.getItem( stamp ); 11206 if ( item && item.isPlacing ) { 11207 return; 11208 } 11209 var offset = this._getElementOffset( stamp ); 11210 var rect = new Rect({ 11211 x: isOriginLeft ? offset.left : offset.right, 11212 y: isOriginTop ? offset.top : offset.bottom 11213 }); 11214 this._setRectSize( stamp, rect ); 11215 // save its space in the packer 11216 this.shiftPacker.placed( rect ); 11217 }, this ); 11218 11219 // reset shiftTargets 11220 var isHorizontal = this._getOption('horizontal'); 11221 var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth'; 11222 var measure = isHorizontal ? 'height' : 'width'; 11223 11224 this.shiftTargetKeys = []; 11225 this.shiftTargets = []; 11226 var boundsSize; 11227 var segment = this[ segmentName ]; 11228 segment = segment && segment + this.gutter; 11229 11230 if ( segment ) { 11231 var segmentSpan = Math.ceil( dropItem.rect[ measure ] / segment ); 11232 var segs = Math.floor( ( this.shiftPacker[ measure ] + this.gutter ) / segment ); 11233 boundsSize = ( segs - segmentSpan ) * segment; 11234 // add targets on top 11235 for ( var i=0; i < segs; i++ ) { 11236 this._addShiftTarget( i * segment, 0, boundsSize ); 11237 } 11238 } else { 11239 boundsSize = ( this.shiftPacker[ measure ] + this.gutter ) - dropItem.rect[ measure ]; 11240 this._addShiftTarget( 0, 0, boundsSize ); 11241 } 11242 11243 // pack each item to measure where shiftTargets are 11244 var items = this._getItemsForLayout( this.items ); 11245 var packMethod = this._getPackMethod();
11246 items.forEach( function( item ) { 11247 var rect = item.rect; 11248 this._setRectSize( item.element, rect ); 11249 this.shiftPacker[ packMethod ]( rect ); 11250 11251 // add top left corner 11252 this._addShiftTarget( rect.x, rect.y, boundsSize ); 11253 // add bottom left / top right corner 11254 var cornerX = isHorizontal ? rect.x + rect.width : rect.x; 11255 var cornerY = isHorizontal ? rect.y : rect.y + rect.height; 11256 this._addShiftTarget( cornerX, cornerY, boundsSize ); 11257 11258 if ( segment ) { 11259 // add targets for each column on bottom / row on right 11260 var segSpan = Math.round( rect[ measure ] / segment ); 11261 for ( var i=1; i < segSpan; i++ ) { 11262 var segX = isHorizontal ? cornerX : rect.x + segment * i; 11263 var segY = isHorizontal ? rect.y + segment * i : cornerY; 11264 this._addShiftTarget( segX, segY, boundsSize ); 11265 } 11266 } 11267 }, this ); 11268 11269}; 11270 11271proto._addShiftTarget = function( x, y, boundsSize ) { 11272 var checkCoord = this._getOption('horizontal') ? y : x; 11273 if ( checkCoord !== 0 && checkCoord > boundsSize ) { 11274 return; 11275 } 11276 // create string for a key, easier to keep track of what targets 11277 var key = x + ',' + y; 11278 var hasKey = this.shiftTargetKeys.indexOf( key ) != -1; 11279 if ( hasKey ) { 11280 return; 11281 } 11282 this.shiftTargetKeys.push( key ); 11283 this.shiftTargets.push({ x: x, y: y }); 11284}; 11285 11286// -------------------------- drop -------------------------- // 11287 11288proto.shift = function( item, x, y ) { 11289 var shiftPosition; 11290 var minDistance = Infinity; 11291 var position = { x: x, y: y }; 11292 this.shiftTargets.forEach( function( target ) { 11293 var distance = getDistance( target, position ); 11294 if ( distance < minDistance ) { 11295 shiftPosition = target; 11296 minDistance = distance; 11297 } 11298 }); 11299 item.rect.x = shiftPosition.x; 11300 item.rect.y = shiftPosition.y; 11301}; 11302 11303function getDistance( a, b ) { 11304 var dx = b.x - a.x; 11305 var dy = b.y - a.y; 11306 return Math.sqrt( dx * dx + dy * dy ); 11307} 11308 11309// -------------------------- drag move -------------------------- // 11310 11311var DRAG_THROTTLE_TIME = 120; 11312 11313/** 11314 * handle an item drag move event 11315 * @param {Element} elem 11316 * @param {Number} x - horizontal change in position 11317 * @param {Number} y - vertical change in position 11318 */ 11319proto.itemDragMove = function( elem, x, y ) { 11320 var item = this.isEnabled && this.getItem( elem ); 11321 if ( !item ) { 11322 return; 11323 } 11324 11325 x -= this.size.paddingLeft; 11326 y -= this.size.paddingTop; 11327 11328 var _this = this; 11329 function onDrag() { 11330 _this.shift( item, x, y ); 11331 item.positionDropPlaceholder(); 11332 _this.layout(); 11333 } 11334 11335 // throttle 11336 var now = new Date(); 11337 if ( this._itemDragTime && now - this._itemDragTime < DRAG_THROTTLE_TIME ) { 11338 clearTimeout( this.dragTimeout ); 11339 this.dragTimeout = setTimeout( onDrag, DRAG_THROTTLE_TIME ); 11340 } else { 11341 onDrag(); 11342 this._itemDragTime = now; 11343 } 11344}; 11345 11346// -------------------------- drag end -------------------------- // 11347 11348/** 11349 * handle an item drag end event 11350 * @param {Element} elem 11351 */ 11352proto.itemDragEnd = function( elem ) { 11353 var item = this.isEnabled && this.getItem( elem ); 11354 if ( !item ) { 11355 return; 11356 } 11357 11358 clearTimeout( this.dragTimeout ); 11359 item.element.classList.add('is-positioning-post-drag'); 11360 11361 var completeCount = 0; 11362 var _this = this; 11363 function onDragEndLayoutComplete() { 11364 completeCount++; 11365 if ( completeCount != 2 ) { 11366 return; 11367 } 11368 // reset drag item 11369 item.element.classList.remove('is-positioning-post-drag'); 11370 item.hideDropPlaceholder(); 11371 _this.dispatchEvent( 'dragItemPositioned', null, [ item ] ); 11372 } 11373 11374 item.once( 'layout', onDragEndLayoutComplete ); 11375 this.once( 'layoutComplete', onDragEndLayoutComplete ); 11376 item.moveTo( item.rect.x, item.rect.y ); 11377 this.layout(); 11378 this.dragItemCount = Math.max( 0, this.dragItemCount - 1 ); 11379 this.sortItemsByPosition(); 11380 item.disablePlacing(); 11381 this.unstamp( item.element ); 11382}; 11383 11384/** 11385 * binds Draggabilly events 11386 * @param {Draggabilly} draggie 11387 */ 11388proto.bindDraggabillyEvents = function( draggie ) { 11389 this._bindDraggabillyEvents( draggie, 'on' ); 11390}; 11391 11392proto.unbindDraggabillyEvents = function( draggie ) { 11393 this._bindDraggabillyEvents( draggie, 'off' ); 11394}; 11395 11396proto._bindDraggabillyEvents = function( draggie, method ) { 11397 var handlers = this.handleDraggabilly; 11398 draggie[ method ]( 'dragStart', handlers.dragStart ); 11399 draggie[ method ]( 'dragMove', handlers.dragMove ); 11400 draggie[ method ]( 'dragEnd', handlers.dragEnd ); 11401}; 11402 11403/** 11404 * binds jQuery UI Draggable events 11405 * @param {jQuery} $elems 11406 */ 11407proto.bindUIDraggableEvents = function( $elems ) { 11408 this._bindUIDraggableEvents( $elems, 'on' ); 11409}; 11410 11411proto.unbindUIDraggableEvents = function( $elems ) { 11412 this._bindUIDraggableEvents( $elems, 'off' ); 11413}; 11414 11415proto._bindUIDraggableEvents = function( $elems, method ) { 11416 var handlers = this.handleUIDraggable; 11417 $elems 11418 [ method ]( 'dragstart', handlers.start ) 11419 [ method ]( 'drag', handlers.drag ) 11420 [ method ]( 'dragstop', handlers.stop ); 11421}; 11422 11423// ----- destroy ----- // 11424 11425var _destroy = proto.destroy; 11426proto.destroy = function() { 11427 _destroy.apply( this, arguments ); 11428 // disable flag; prevent drag events from triggering. #72 11429 this.isEnabled = false;
11430}; 11431 11432// ----- ----- // 11433 11434Packery.Rect = Rect; 11435Packery.Packer = Packer; 11436 11437return Packery; 11438 11439})); 11440 11441/*! 11442 * Packery layout mode v2.0.1 11443 * sub-classes Packery 11444 */ 11445 11446/*jshint browser: true, strict: true, undef: true, unused: true */ 11447 11448( function( window, factory ) { 11449 11450 // universal module definition 11451 if ( typeof define == 'function' && define.amd ) { 11452 // AMD 11453 define( [ 11454 'isotope-layout/js/layout-mode', 11455 'packery/js/packery' 11456 ], 11457 factory ); 11458 } else if ( typeof module == 'object' && module.exports ) { 11459 // CommonJS 11460 module.exports = factory( 11461 require('isotope-layout/js/layout-mode'), 11462 require('packery') 11463 ); 11464 } else { 11465 // browser global 11466 factory( 11467 window.Isotope.LayoutMode, 11468 window.Packery 11469 ); 11470 } 11471 11472}( window, function factor( LayoutMode, Packery ) { 11473 11474 11475 // create an Outlayer layout class 11476 var PackeryMode = LayoutMode.create('packery'); 11477 var proto = PackeryMode.prototype; 11478 11479 var keepModeMethods = { 11480 _getElementOffset: true, 11481 _getMeasurement: true 11482 }; 11483 11484 // inherit Packery prototype 11485 for ( var method in Packery.prototype ) { 11486 // do not inherit mode methods 11487 if ( !keepModeMethods[ method ] ) { 11488 proto[ method ] = Packery.prototype[ method ]; 11489 } 11490 } 11491 11492 // set packer in _resetLayout 11493 var _resetLayout = proto._resetLayout; 11494 proto._resetLayout = function() { 11495 this.packer = this.packer || new Packery.Packer(); 11496 this.shiftPacker = this.shiftPacker || new Packery.Packer(); 11497 _resetLayout.apply( this, arguments ); 11498 }; 11499 11500 var _getItemLayoutPosition = proto._getItemLayoutPosition; 11501 proto._getItemLayoutPosition = function( item ) { 11502 // set packery rect 11503 item.rect = item.rect || new Packery.Rect(); 11504 return _getItemLayoutPosition.call( this, item ); 11505 }; 11506 11507 // needsResizeLayout for vertical or horizontal 11508 var _needsResizeLayout = proto.needsResizeLayout; 11509 proto.needsResizeLayout = function() { 11510 if ( this._getOption('horizontal') ) { 11511 return this.needsVerticalResizeLayout(); 11512 } else { 11513 return _needsResizeLayout.call( this ); 11514 } 11515 }; 11516 11517 // point to mode options for horizontal 11518 var _getOption = proto._getOption; 11519 proto._getOption = function( option ) { 11520 if ( option == 'horizontal' ) { 11521 return this.options.isHorizontal !== undefined ? 11522 this.options.isHorizontal : this.options.horizontal; 11523 } 11524 return _getOption.apply( this.isotope, arguments ); 11525 }; 11526 11527 return PackeryMode; 11528 11529})); 11530 11531/*! 11532 * cellsByRows layout mode for Isotope 11533 * v1.1.3 11534 * http://isotope.metafizzy.co/layout-modes/cellsbyrow.html 11535 */ 11536 11537/*jshint browser: true, devel: false, strict: true, undef: true, unused: true */ 11538 11539( function( window, factory ) { 11540 // universal module definition 11541 /* jshint strict: false */ /*globals define, module, require */ 11542 if ( typeof define === 'function' && define.amd ) { 11543 // AMD 11544 define( [ 11545 'isotope/js/layout-mode' 11546 ], 11547 factory ); 11548 } else if ( typeof exports === 'object' ) { 11549 // CommonJS 11550 module.exports = factory( 11551 require('isotope-layout/js/layout-mode') 11552 ); 11553 } else { 11554 // browser global 11555 factory( 11556 window.Isotope.LayoutMode 11557 ); 11558 } 11559 11560}( window, function factory( LayoutMode ) { 11561 'use strict'; 11562 11563 var CellsByRow = LayoutMode.create( 'cellsByRow' ); 11564 var proto = CellsByRow.prototype; 11565 11566 proto._resetLayout = function() { 11567 // reset properties 11568 this.itemIndex = 0; 11569 // measurements 11570 this.getColumnWidth(); 11571 this.getRowHeight(); 11572 // set cols 11573 this.cols = Math.floor( this.isotope.size.innerWidth / this.columnWidth ); 11574 this.cols = Math.max( this.cols, 1 ); 11575 }; 11576 11577 proto._getItemLayoutPosition = function( item ) { 11578 item.getSize(); 11579 var col = this.itemIndex % this.cols; 11580 var row = Math.floor( this.itemIndex / this.cols ); 11581 // center item within cell 11582 var x = ( col + 0.5 ) * this.columnWidth - item.size.outerWidth / 2; 11583 var y = ( row + 0.5 ) * this.rowHeight - item.size.outerHeight / 2; 11584 this.itemIndex++; 11585 return { x: x, y: y }; 11586 }; 11587 11588 proto._getContainerSize = function() { 11589 return { 11590 height: Math.ceil( this.itemIndex / this.cols ) * this.rowHeight 11591 }; 11592 }; 11593 11594 return CellsByRow; 11595 11596})); 11597/*global jQuery: true */ 11598 11599/*! 11600 -------------------------------- 11601 Infinite Scroll 11602 -------------------------------- 11603 + https://github.com/paulirish/infinite-scroll 11604 + version 2.1.0 11605 + Copyright 2011/12 Paul Irish & Luke Shumard 11606 + Licensed under the MIT license 11607 11608 + Documentation: http://infinite-scroll.com/ 11609*/ 11610 11611// Uses AMD or browser globals to create a jQuery plugin. 11612(function (factory) { 11613 if (typeof define === 'function' && define.amd) { 11614 // AMD. Register as an anonymous module. 11615 define(['jquery'], factory); 11616 } else { 11617 // Browser globals 11618 factory(jQuery); 11619 } 11620}(function ($, undefined) { 11621 'use strict'; 11622
11623 $.infinitescroll = function infscr(options, callback, element) { 11624 this.element = $(element); 11625 11626 // Flag the object in the event of a failed creation 11627 if (!this._create(options, callback)) { 11628 this.failed = true; 11629 } 11630 }; 11631 11632 $.infinitescroll.defaults = { 11633 loading: { 11634 finished: undefined, 11635 finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>", 11636 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
11636MzExnbRvQ2Sy7vN0zvVtNfU2tLY3rPgLdnDvca4VQS/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
11636iqpQpZ4apwSwRtjqrB3muoF9BboaXKmshlqWqsWiGt2wphJkQbAU5hoCACH5BAUKABsALAcABADOAAsAAAX/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', 11637 msg: null, 11638 msgText: '<em>Loading the next set of posts...</em>', 11639 selector: null, 11640 speed: 'fast', 11641 start: undefined 11642 }, 11643 state: { 11644 isDuringAjax: false, 11645 isInvalidPage: false,
11646 isDestroyed: false, 11647 isDone: false, // For when it goes all the way through the archive. 11648 isPaused: false, 11649 isBeyondMaxPage: false, 11650 currPage: 1 11651 }, 11652 debug: false, 11653 behavior: undefined, 11654 binder: $(window), // used to cache the selector 11655 nextSelector: 'div.navigation a:first', 11656 navSelector: 'div.navigation', 11657 contentSelector: null, // rename to pageFragment 11658 extraScrollPx: 150, 11659 itemSelector: 'div.post', 11660 animate: false, 11661 pathParse: undefined, 11662 dataType: 'html', 11663 appendCallback: true, 11664 bufferPx: 40, 11665 errorCallback: function () { }, 11666 infid: 0, //Instance ID 11667 pixelsFromNavToBottom: undefined, 11668 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 11669 prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted 11670 maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work) 11671 }; 11672 11673 $.infinitescroll.prototype = { 11674 11675 /* 11676 ---------------------------- 11677 Private methods 11678 ---------------------------- 11679 */ 11680 11681 // Bind or unbind from scroll 11682 _binding: function infscr_binding(binding) { 11683 11684 var instance = this, 11685 opts = instance.options; 11686 11687 opts.v = '2.0b2.120520'; 11688 11689 // if behavior is defined and this function is extended, call that instead of default 11690 if (!!opts.behavior && this['_binding_' + opts.behavior] !== undefined) { 11691 this['_binding_' + opts.behavior].call(this); 11692 return; 11693 } 11694 11695 if (binding !== 'bind' && binding !== 'unbind') { 11696 this._debug('Binding value ' + binding + ' not valid'); 11697 return false; 11698 } 11699 11700 if (binding === 'unbind') { 11701 (this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid); 11702 } else { 11703 (this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () { 11704 instance.scroll(); 11705 }); 11706 } 11707 11708 this._debug('Binding', binding); 11709 }, 11710 11711 // Fundamental aspects of the plugin are initialized 11712 _create: function infscr_create(options, callback) { 11713 11714 // Add custom options to defaults 11715 var opts = $.extend(true, {}, $.infinitescroll.defaults, options); 11716 this.options = opts; 11717 var $window = $(window); 11718 var instance = this; 11719 11720 // Validate selectors 11721 if (!instance._validate(options)) { 11722 return false; 11723 } 11724 11725 // Validate page fragment path 11726 var path = $(opts.nextSelector).attr('href'); 11727 if (!path) { 11728 this._debug('Navigation selector not found'); 11729 return false; 11730 } 11731 11732 // Set the path to be a relative URL from root. 11733 opts.path = opts.path || this._determinepath(path); 11734 11735 // contentSelector is 'page fragment' option for .load() / .ajax() calls 11736 opts.contentSelector = opts.contentSelector || this.element; 11737 11738 // loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector 11739 opts.loading.selector = opts.loading.selector || opts.contentSelector; 11740 11741 // Define loading.msg 11742 opts.loading.msg = opts.loading.msg || $('<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>'); 11743 11744 // Preload loading.img 11745 (new Image()).src = opts.loading.img; 11746 11747 // distance from nav links to bottom 11748 // computed as: height of the document + top offset of container - top offset of nav link 11749 if (opts.pixelsFromNavToBottom === undefined) { 11750 opts.pixelsFromNavToBottom = $(document).height() - $(opts.navSelector).offset().top; 11751 this._debug('pixelsFromNavToBottom: ' + opts.pixelsFromNavToBottom); 11752 } 11753 11754 var self = this; 11755 11756 // determine loading.start actions 11757 opts.loading.start = opts.loading.start || function () { 11758 $(opts.navSelector).hide(); 11759 opts.loading.msg 11760 .appendTo(opts.loading.selector) 11761 .show(opts.loading.speed, $.proxy(function () { 11762 this.beginAjax(opts); 11763 }, self)); 11764 }; 11765 11766 // determine loading.finished actions 11767 opts.loading.finished = opts.loading.finished || function () { 11768 if (!opts.state.isBeyondMaxPage) 11769 opts.loading.msg.fadeOut(opts.loading.speed); 11770 }; 11771 11772 // callback loading 11773 opts.callback = function (instance, data, url) { 11774 if (!!opts.behavior && instance['_callback_' + opts.behavior] !== undefined) { 11775 instance['_callback_' + opts.behavior].call($(opts.contentSelector)[0], data, url); 11776 } 11777 11778 if (callback) { 11779 callback.call($(opts.contentSelector)[0], data, opts, url); 11780 } 11781 11782 if (opts.prefill) { 11783 $window.bind('resize.infinite-scroll', instance._prefill); 11784 } 11785 }; 11786 11787 if (options.debug) { 11788 // Tell IE9 to use its built-in console 11789 if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log === 'object') { 11790 ['log', 'info', 'warn', 'error', 'assert', 'dir', 'clear', 'profile', 'profileEnd'] 11791 .forEach(function (method) { 11792 console[method] = this.call(console[method], console); 11793 }, Function.prototype.bind); 11794 } 11795 } 11796 11797 this._setup(); 11798 11799 // Setups the prefill method for use 11800 if (opts.prefill) { 11801 this._prefill(); 11802 } 11803 11804 // Return true to indicate successful creation 11805 return true; 11806 }, 11807 11808 _prefill: function infscr_prefill() { 11809 var instance = this; 11810 var $window = $(window); 11811 11812 function needsPrefill() { 11813 return ($(instance.options.contentSelector).height() <= $window.height()); 11814 } 11815 11816 this._prefill = function () { 11817 if (needsPrefill()) { 11818 instance.scroll(); 11819 } 11820 11821 $window.bind('resize.infinite-scroll', function () { 11822 if (needsPrefill()) { 11823 $window.unbind('resize.infinite-scroll'); 11824 instance.scroll(); 11825 } 11826 }); 11827 }; 11828 11829 // Call self after setting up the new function 11830 this._prefill(); 11831 }, 11832 11833 // Console log wrapper 11834 _debug: function infscr_debug() { 11835 if (true !== this.options.debug) { 11836 return; 11837 } 11838 11839 if (typeof console !== 'undefined' && typeof console.log === 'function') { 11840 // Modern browsers 11841 // Single argument, which is a string 11842 if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') { 11843 console.log((Array.prototype.slice.call(arguments)).toString()); 11844 } else { 11845 console.log(Array.prototype.slice.call(arguments)); 11846 } 11847 } else if (!Function.prototype.bind && typeof console !== 'undefined' && typeof console.log === 'object') { 11848 // IE8 11849 Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments)); 11850 } 11851 }, 11852 11853 // find the number to increment in the path.
11854 _determinepath: function infscr_determinepath(path) { 11855 11856 var opts = this.options; 11857 11858 // if behavior is defined and this function is extended, call that instead of default 11859 if (!!opts.behavior && this['_determinepath_' + opts.behavior] !== undefined) { 11860 return this['_determinepath_' + opts.behavior].call(this, path); 11861 } 11862 11863 var url = new URL(path); 11864 var pathname = url.pathname; 11865 var hasNumber = /\d/.test(pathname); 11866 11867 if (!!opts.pathParse) { 11868 this._debug('pathParse manual'); 11869 return opts.pathParse(path, this.options.state.currPage + 1); 11870 } else if (hasNumber && path.match(/(\?|\&)(upage=)(\d+)/)) { 11871 var parts = path.split(/(\?|\&)(upage=)(\d+)/); 11872 return [parts[0] + parts[1] + parts[2], parts[4]]; 11873 } else if (path.match(/^(.*?)\b2\b(.*?$)/)) { 11874 path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1); 11875 11876 // if there is any 2 in the url at all. 11877 } else if (path.match(/^(.*?)2(.*?$)/)) { 11878 // page= is used in django: 11879 // http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127 11880 if (path.match(/^(.*?page=)2(\/.*|$)/)) { 11881 path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1); 11882 return path; 11883 } 11884 11885 path = path.match(/^(.*?)2(.*?$)/).slice(1); 11886 11887 } else { 11888 // page= is used in drupal too but second page is page=1 not page=2: 11889 // thx Jerod Fritz, vladikoff 11890 if (path.match(/^(.*?page=)1(\/.*|$)/)) { 11891 path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1); 11892 return path; 11893 } else { 11894 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."); 11895 // Get rid of isInvalidPage to allow permalink to state 11896 opts.state.isInvalidPage = true; //prevent it from running on this page. 11897 } 11898 } 11899 this._debug('determinePath', path); 11900 return path; 11901 11902 }, 11903 11904 // Custom error 11905 _error: function infscr_error(xhr) { 11906 11907 var opts = this.options; 11908 11909 // if behavior is defined and this function is extended, call that instead of default 11910 if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) { 11911 this['_error_'+opts.behavior].call(this,xhr); 11912 return; 11913 } 11914 11915 if (xhr !== 'destroy' && xhr !== 'end') { 11916 xhr = 'unknown'; 11917 } 11918 11919 this._debug('Error', xhr); 11920 11921 if (xhr === 'end' || opts.state.isBeyondMaxPage) { 11922 this._showdonemsg(); 11923 } 11924 11925 opts.state.isDone = true; 11926 opts.state.currPage = 1; // if you need to go back to this instance 11927 opts.state.isPaused = false; 11928 opts.state.isBeyondMaxPage = false; 11929 this._binding('unbind'); 11930 11931 }, 11932 11933 // Load Callback 11934 _loadcallback: function infscr_loadcallback(box, data, url) { 11935 var opts = this.options, 11936 callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK 11937 result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append', 11938 frag; 11939 11940 // if behavior is defined and this function is extended, call that instead of default 11941 if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) { 11942 this['_loadcallback_'+opts.behavior].call(this,box,data); 11943 return; 11944 } 11945 11946 switch (result) { 11947 case 'done': 11948 this._showdonemsg(); 11949 return false; 11950 11951 case 'no-append': 11952 if (opts.dataType === 'html') { 11953 data = '<div>' + data + '</div>'; 11954 data = $(data).find(opts.itemSelector); 11955 } 11956 11957 // if it didn't return anything 11958 if (data.length === 0) { 11959 return this._error('end'); 11960 } 11961 11962 break; 11963 11964 case 'append': 11965 var children = box.children(); 11966 // if it didn't return anything 11967 if (children.length === 0) { 11968 return this._error('end'); 11969 } 11970 11971 // use a documentFragment because it works when content is going into a table or UL 11972 frag = document.createDocumentFragment(); 11973 while (box[0].firstChild) { 11974 frag.appendChild(box[0].firstChild); 11975 } 11976 11977 this._debug('contentSelector', $(opts.contentSelector)[0]); 11978 $(opts.contentSelector)[0].appendChild(frag); 11979 // previously, we would pass in the new DOM element as context for the callback 11980 // however we're now using a documentfragment, which doesn't have parents or children, 11981 // so the context is the contentContainer guy, and we pass in an array 11982 // of the elements collected as the first argument. 11983 11984 data = children.get(); 11985 break; 11986 } 11987 11988 // loadingEnd function 11989 opts.loading.finished.call($(opts.contentSelector)[0],opts); 11990 11991 // smooth scroll to ease in the new content 11992 if (opts.animate) { 11993 var scrollTo = $(window).scrollTop() + $(opts.loading.msg).height() + opts.extraScrollPx + 'px'; 11994 $('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; }); 11995 } 11996 11997 if (!opts.animate) { 11998 // once the call is done, we can allow it again. 11999 opts.state.isDuringAjax = false;
12000 } 12001 12002 callback(this, data, url); 12003 12004 if (opts.prefill) { 12005 this._prefill(); 12006 } 12007 }, 12008 12009 _nearbottom: function infscr_nearbottom() { 12010 12011 var opts = this.options, 12012 pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height(); 12013 12014 // if behavior is defined and this function is extended, call that instead of default 12015 if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) { 12016 return this['_nearbottom_'+opts.behavior].call(this); 12017 } 12018 12019 this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom); 12020 12021 // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom.... 12022 return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom); 12023 12024 }, 12025 12026 // Pause / temporarily disable plugin from firing 12027 _pausing: function infscr_pausing(pause) { 12028 12029 var opts = this.options; 12030 12031 // if behavior is defined and this function is extended, call that instead of default 12032 if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) { 12033 this['_pausing_'+opts.behavior].call(this,pause); 12034 return; 12035 } 12036 12037 // If pause is not 'pause' or 'resume', toggle it's value 12038 if (pause !== 'pause' && pause !== 'resume' && pause !== null) { 12039 this._debug('Invalid argument. Toggling pause value instead'); 12040 } 12041 12042 pause = (pause && (pause === 'pause' || pause === 'resume')) ? pause : 'toggle'; 12043 12044 switch (pause) { 12045 case 'pause': 12046 opts.state.isPaused = true; 12047 break; 12048 12049 case 'resume': 12050 opts.state.isPaused = false; 12051 break; 12052 12053 case 'toggle': 12054 opts.state.isPaused = !opts.state.isPaused; 12055 break; 12056 } 12057 12058 this._debug('Paused', opts.state.isPaused); 12059 return false; 12060 12061 }, 12062 12063 // Behavior is determined 12064 // If the behavior option is undefined, it will set to default and bind to scroll 12065 _setup: function infscr_setup() { 12066 12067 var opts = this.options; 12068 12069 // if behavior is defined and this function is extended, call that instead of default 12070 if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) { 12071 this['_setup_'+opts.behavior].call(this); 12072 return; 12073 } 12074 12075 this._binding('bind'); 12076 12077 return false; 12078 12079 }, 12080 12081 // Show done message 12082 _showdonemsg: function infscr_showdonemsg() { 12083 12084 var opts = this.options; 12085 12086 // if behavior is defined and this function is extended, call that instead of default 12087 if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) { 12088 this['_showdonemsg_'+opts.behavior].call(this); 12089 return; 12090 } 12091 12092 opts.loading.msg 12093 .find('img') 12094 .hide() 12095 .parent() 12096 .find('div').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () { 12097 $(this).parent().fadeOut(opts.loading.speed); 12098 }); 12099 12100 // user provided callback when done 12101 opts.errorCallback.call($(opts.contentSelector)[0],'done'); 12102 }, 12103 12104 // grab each selector option and see if any fail 12105 _validate: function infscr_validate(opts) { 12106 for (var key in opts) { 12107 if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) { 12108 this._debug('Your ' + key + ' found no elements.'); 12109 return false; 12110 } 12111 } 12112 12113 return true; 12114 }, 12115 12116 /* 12117 ---------------------------- 12118 Public methods 12119 ---------------------------- 12120 */ 12121 12122 // Bind to scroll 12123 bind: function infscr_bind() { 12124 this._binding('bind'); 12125 }, 12126 12127 // Destroy current instance of plugin 12128 destroy: function infscr_destroy() { 12129 this.options.state.isDestroyed = true; 12130 this.options.loading.finished(); 12131 return this._error('destroy'); 12132 }, 12133 12134 // Set pause value to false 12135 pause: function infscr_pause() { 12136 this._pausing('pause'); 12137 }, 12138 12139 // Set pause value to false 12140 resume: function infscr_resume() { 12141 this._pausing('resume'); 12142 }, 12143 12144 beginAjax: function infscr_ajax(opts) { 12145 var instance = this, 12146 path = opts.path, 12147 box, desturl, method, condition; 12148 12149 // increment the URL bit. e.g. /page/3/ 12150 opts.state.currPage++; 12151 12152 // Manually control maximum page 12153 if ( opts.maxPage !== undefined && opts.state.currPage > opts.maxPage ){ 12154 opts.state.isBeyondMaxPage = true; 12155 this.destroy(); 12156 return; 12157 } 12158 12159 // if we're dealing with a table we can't use DIVs 12160 box = $(opts.contentSelector).is('table, tbody') ? $('<tbody/>') : $('<div/>'); 12161 12162 desturl = (typeof path === 'function') ? path(opts.state.currPage) : path.join(opts.state.currPage); 12163 12164 instance._debug('heading into ajax', desturl); 12165 12166 method = (opts.dataType === 'html' || opts.dataType === 'json' ) ? opts.dataType : 'html+callback'; 12167 if (opts.appendCallback && opts.dataType === 'html') { 12168 method += '+callback'; 12169 } 12170 12171 switch (method) { 12172 case 'html+callback': 12173 instance._debug('Using HTML via .load() method'); 12174 box.load(desturl + ' ' + opts.itemSelector, undefined, function infscr_ajax_callback(responseText) { 12175 instance._loadcallback(box, responseText, desturl); 12176 }); 12177 12178 break; 12179 12180 case 'html': 12181 instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); 12182 $.ajax({ 12183 // params 12184 url: desturl, 12185 dataType: opts.dataType, 12186 complete: function infscr_ajax_callback(jqXHR, textStatus) { 12187 condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified'); 12188 if (condition) { 12189 instance._loadcallback(box, jqXHR.responseText, desturl); 12190 } else { 12191 instance._error('end'); 12192 } 12193 } 12194 }); 12195 12196 break; 12197 case 'json': 12198 instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method'); 12199 $.ajax({ 12200 dataType: 'json', 12201 type: 'GET', 12202 url: desturl, 12203 success: function (data, textStatus, jqXHR) { 12204 condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified'); 12205 if (opts.appendCallback) { 12206 // if appendCallback is true, you must defined template in options. 12207 // note that data passed into _loadcallback is already an html (after processed in opts.template(data)). 12208 if (opts.template !== undefined) { 12209 var theData = opts.template(data); 12210 box.append(theData); 12211 if (condition) { 12212 instance._loadcallback(box, theData); 12213 } else { 12214 instance._error('end'); 12215 } 12216 } else { 12217 instance._debug('template must be defined.'); 12218 instance._error('end'); 12219 } 12220 } else { 12221 // if appendCallback is false, we will pass in the JSON object. you should handle it yourself in your callback. 12222 if (condition) { 12223 instance._loadcallback(box, data, desturl); 12224 } else { 12225 instance._error('end'); 12226 } 12227 } 12228 }, 12229 error: function() { 12230 instance._debug('JSON ajax request failed.'); 12231 instance._error('end'); 12232 } 12233 }); 12234 12235 break; 12236 } 12237 }, 12238 12239 // Retrieve next set of content items 12240 retrieve: function infscr_retrieve(pageNum) { 12241 pageNum = pageNum || null; 12242 12243 var instance = this, 12244 opts = instance.options; 12245 12246 // if behavior is defined and this function is extended, call that instead of default 12247 if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) { 12248 this['retrieve_'+opts.behavior].call(this,pageNum); 12249 return; 12250 } 12251 12252 // for manual triggers, if destroyed, get out of here 12253 if (opts.state.isDestroyed) { 12254 this._debug('Instance is destroyed'); 12255 return false;
12256 } 12257 12258 // we dont want to fire the ajax multiple times 12259 opts.state.isDuringAjax = true; 12260 12261 opts.loading.start.call($(opts.contentSelector)[0],opts); 12262 }, 12263 12264 // Check to see next page is needed 12265 scroll: function infscr_scroll() { 12266 12267 var opts = this.options, 12268 state = opts.state; 12269 12270 // if behavior is defined and this function is extended, call that instead of default 12271 if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) { 12272 this['scroll_'+opts.behavior].call(this); 12273 return; 12274 } 12275 12276 if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) { 12277 return; 12278 } 12279 12280 if (!this._nearbottom()) { 12281 return; 12282 } 12283 12284 this.retrieve(); 12285 12286 }, 12287 12288 // Toggle pause value 12289 toggle: function infscr_toggle() { 12290 this._pausing(); 12291 }, 12292 12293 // Unbind from scroll 12294 unbind: function infscr_unbind() { 12295 this._binding('unbind'); 12296 }, 12297 12298 // update options 12299 update: function infscr_options(key) { 12300 if ($.isPlainObject(key)) { 12301 this.options = $.extend(true,this.options,key); 12302 } 12303 } 12304 }; 12305 12306 12307 /* 12308 ---------------------------- 12309 Infinite Scroll function 12310 ---------------------------- 12311 12312 Borrowed logic from the following... 12313 12314 jQuery UI 12315 - https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js 12316 12317 jCarousel 12318 - https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js 12319 12320 Masonry 12321 - https://github.com/desandro/masonry/blob/master/jquery.masonry.js 12322 12323*/ 12324 12325 $.fn.infinitescroll = function infscr_init(options, callback) { 12326 12327 12328 var thisCall = typeof options; 12329 12330 switch (thisCall) { 12331 12332 // method 12333 case 'string': 12334 var args = Array.prototype.slice.call(arguments, 1); 12335 12336 this.each(function () { 12337 var instance = $.data(this, 'infinitescroll'); 12338 12339 if (!instance) { 12340 // not setup yet 12341 // return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup'); 12342 return false; 12343 } 12344 12345 if (!$.isFunction(instance[options]) || options.charAt(0) === '_') { 12346 // return $.error('No such method ' + options + ' for Infinite Scroll'); 12347 return false; 12348 } 12349 12350 // no errors! 12351 instance[options].apply(instance, args); 12352 }); 12353 12354 break; 12355 12356 // creation 12357 case 'object': 12358 12359 this.each(function () { 12360 12361 var instance = $.data(this, 'infinitescroll'); 12362 12363 if (instance) { 12364 12365 // update options of current instance 12366 instance.update(options); 12367 12368 } else { 12369 12370 // initialize new instance 12371 instance = new $.infinitescroll(options, callback, this); 12372 12373 // don't attach if instantiation failed 12374 if (!instance.failed) { 12375 $.data(this, 'infinitescroll', instance); 12376 } 12377 12378 } 12379 12380 }); 12381 12382 break; 12383 12384 } 12385 12386 return this; 12387 }; 12388 12389 12390 12391 /* 12392 * smartscroll: debounced scroll event for jQuery * 12393 * https://github.com/lukeshumard/smartscroll 12394 * Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js * 12395 * Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. * 12396 */ 12397 12398 var event = $.event, 12399 scrollTimeout; 12400 12401 event.special.smartscroll = { 12402 setup: function () { 12403 $(this).bind('scroll', event.special.smartscroll.handler); 12404 }, 12405 teardown: function () { 12406 $(this).unbind('scroll', event.special.smartscroll.handler); 12407 }, 12408 handler: function (event, execAsap) { 12409 // Save the context 12410 var context = this, 12411 args = arguments; 12412 12413 // set correct event type 12414 event.type = 'smartscroll'; 12415 12416 if (scrollTimeout) { clearTimeout(scrollTimeout); } 12417 scrollTimeout = setTimeout(function () { 12418 $(context).trigger('smartscroll', args); 12419 }, execAsap === 'execAsap' ? 0 : 100); 12420 } 12421 }; 12422 12423 $.fn.smartscroll = function (fn) {
12424 return fn ? this.bind('smartscroll', fn) : this.trigger('smartscroll', ['execAsap']); 12425 }; 12426 12427})); 12428 12429/*! 12430Waypoints - 4.0.1 12431Copyright © 2011-2016 Caleb Troughton 12432Licensed under the MIT license. 12433https://github.com/imakewebthings/waypoints/blob/master/licenses.txt 12434*/ 12435(function() { 12436 'use strict' 12437 12438 var keyCounter = 0 12439 var allWaypoints = {} 12440 12441 /* http://imakewebthings.com/waypoints/api/waypoint */ 12442 function Waypoint(options) { 12443 if (!options) { 12444 throw new Error('No options passed to Waypoint constructor') 12445 } 12446 if (!options.element) { 12447 throw new Error('No element option passed to Waypoint constructor') 12448 } 12449 if (!options.handler) { 12450 throw new Error('No handler option passed to Waypoint constructor') 12451 } 12452 12453 this.key = 'waypoint-' + keyCounter 12454 this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options) 12455 this.element = this.options.element 12456 this.adapter = new Waypoint.Adapter(this.element) 12457 this.callback = options.handler 12458 this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 12459 this.enabled = this.options.enabled 12460 this.triggerPoint = null 12461 this.group = Waypoint.Group.findOrCreate({ 12462 name: this.options.group, 12463 axis: this.axis 12464 }) 12465 this.context = Waypoint.Context.findOrCreateByElement(this.options.context) 12466 12467 if (Waypoint.offsetAliases[this.options.offset]) { 12468 this.options.offset = Waypoint.offsetAliases[this.options.offset] 12469 } 12470 this.group.add(this) 12471 this.context.add(this) 12472 allWaypoints[this.key] = this 12473 keyCounter += 1 12474 } 12475 12476 /* Private */ 12477 Waypoint.prototype.queueTrigger = function(direction) { 12478 this.group.queueTrigger(this, direction) 12479 } 12480 12481 /* Private */ 12482 Waypoint.prototype.trigger = function(args) { 12483 if (!this.enabled) { 12484 return 12485 } 12486 if (this.callback) { 12487 this.callback.apply(this, args) 12488 } 12489 } 12490 12491 /* Public */ 12492 /* http://imakewebthings.com/waypoints/api/destroy */ 12493 Waypoint.prototype.destroy = function() { 12494 this.context.remove(this) 12495 this.group.remove(this) 12496 delete allWaypoints[this.key] 12497 } 12498 12499 /* Public */ 12500 /* http://imakewebthings.com/waypoints/api/disable */ 12501 Waypoint.prototype.disable = function() { 12502 this.enabled = false 12503 return this 12504 } 12505 12506 /* Public */ 12507 /* http://imakewebthings.com/waypoints/api/enable */ 12508 Waypoint.prototype.enable = function() { 12509 this.context.refresh() 12510 this.enabled = true 12511 return this 12512 } 12513 12514 /* Public */ 12515 /* http://imakewebthings.com/waypoints/api/next */ 12516 Waypoint.prototype.next = function() { 12517 return this.group.next(this) 12518 } 12519 12520 /* Public */ 12521 /* http://imakewebthings.com/waypoints/api/previous */ 12522 Waypoint.prototype.previous = function() { 12523 return this.group.previous(this) 12524 } 12525 12526 /* Private */ 12527 Waypoint.invokeAll = function(method) { 12528 var allWaypointsArray = []
12529 for (var waypointKey in allWaypoints) { 12530 allWaypointsArray.push(allWaypoints[waypointKey]) 12531 } 12532 for (var i = 0, end = allWaypointsArray.length; i < end; i++) { 12533 allWaypointsArray[i][method]() 12534 } 12535 } 12536 12537 /* Public */ 12538 /* http://imakewebthings.com/waypoints/api/destroy-all */ 12539 Waypoint.destroyAll = function() { 12540 Waypoint.invokeAll('destroy') 12541 } 12542 12543 /* Public */ 12544 /* http://imakewebthings.com/waypoints/api/disable-all */ 12545 Waypoint.disableAll = function() { 12546 Waypoint.invokeAll('disable') 12547 } 12548 12549 /* Public */ 12550 /* http://imakewebthings.com/waypoints/api/enable-all */ 12551 Waypoint.enableAll = function() { 12552 Waypoint.Context.refreshAll() 12553 for (var waypointKey in allWaypoints) { 12554 allWaypoints[waypointKey].enabled = true 12555 } 12556 return this 12557 } 12558 12559 /* Public */ 12560 /* http://imakewebthings.com/waypoints/api/refresh-all */ 12561 Waypoint.refreshAll = function() { 12562 Waypoint.Context.refreshAll() 12563 } 12564 12565 /* Public */ 12566 /* http://imakewebthings.com/waypoints/api/viewport-height */ 12567 Waypoint.viewportHeight = function() { 12568 return window.innerHeight || document.documentElement.clientHeight 12569 } 12570 12571 /* Public */ 12572 /* http://imakewebthings.com/waypoints/api/viewport-width */ 12573 Waypoint.viewportWidth = function() { 12574 return document.documentElement.clientWidth 12575 } 12576 12577 Waypoint.adapters = [] 12578 12579 Waypoint.defaults = { 12580 context: window, 12581 continuous: true, 12582 enabled: true, 12583 group: 'default', 12584 horizontal: false, 12585 offset: 0 12586 } 12587 12588 Waypoint.offsetAliases = { 12589 'bottom-in-view': function() { 12590 return this.context.innerHeight() - this.adapter.outerHeight() 12591 }, 12592 'right-in-view': function() { 12593 return this.context.innerWidth() - this.adapter.outerWidth() 12594 } 12595 } 12596 12597 window.Waypoint = Waypoint 12598}()) 12599;(function() { 12600 'use strict' 12601 12602 function requestAnimationFrameShim(callback) { 12603 window.setTimeout(callback, 1000 / 60) 12604 } 12605 12606 var keyCounter = 0 12607 var contexts = {} 12608 var Waypoint = window.Waypoint 12609 var oldWindowLoad = window.onload 12610 12611 /* http://imakewebthings.com/waypoints/api/context */ 12612 function Context(element) { 12613 this.element = element 12614 this.Adapter = Waypoint.Adapter 12615 this.adapter = new this.Adapter(element) 12616 this.key = 'waypoint-context-' + keyCounter 12617 this.didScroll = false 12618 this.didResize = false 12619 this.oldScroll = { 12620 x: this.adapter.scrollLeft(), 12621 y: this.adapter.scrollTop() 12622 } 12623 this.waypoints = { 12624 vertical: {}, 12625 horizontal: {} 12626 } 12627 12628 element.waypointContextKey = this.key 12629 contexts[element.waypointContextKey] = this 12630 keyCounter += 1 12631 if (!Waypoint.windowContext) { 12632 Waypoint.windowContext = true 12633 Waypoint.windowContext = new Context(window) 12634 } 12635 12636 this.createThrottledScrollHandler() 12637 this.createThrottledResizeHandler() 12638 } 12639 12640 /* Private */ 12641 Context.prototype.add = function(waypoint) { 12642 var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical' 12643 this.waypoints[axis][waypoint.key] = waypoint 12644 this.refresh() 12645 } 12646 12647 /* Private */ 12648 Context.prototype.checkEmpty = function() { 12649 var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal) 12650 var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical) 12651 var isWindow = this.element == this.element.window 12652 if (horizontalEmpty && verticalEmpty && !isWindow) { 12653 this.adapter.off('.waypoints') 12654 delete contexts[this.key] 12655 } 12656 } 12657 12658 /* Private */ 12659 Context.prototype.createThrottledResizeHandler = function() { 12660 var self = this 12661 12662 function resizeHandler() { 12663 self.handleResize() 12664 self.didResize = false 12665 } 12666 12667 this.adapter.on('resize.waypoints', function() { 12668 if (!self.didResize) { 12669 self.didResize = true 12670 Waypoint.requestAnimationFrame(resizeHandler) 12671 } 12672 }) 12673 } 12674 12675 /* Private */ 12676 Context.prototype.createThrottledScrollHandler = function() { 12677 var self = this 12678 function scrollHandler() { 12679 self.handleScroll() 12680 self.didScroll = false 12681 } 12682 12683 this.adapter.on('scroll.waypoints', function() { 12684 if (!self.didScroll || Waypoint.isTouch) { 12685 self.didScroll = true 12686 Waypoint.requestAnimationFrame(scrollHandler) 12687 } 12688 }) 12689 } 12690 12691 /* Private */ 12692 Context.prototype.handleResize = function() { 12693 Waypoint.Context.refreshAll() 12694 } 12695 12696 /* Private */ 12697 Context.prototype.handleScroll = function() { 12698 var triggeredGroups = {} 12699 var axes = { 12700 horizontal: { 12701 newScroll: this.adapter.scrollLeft(), 12702 oldScroll: this.oldScroll.x, 12703 forward: 'right', 12704 backward: 'left' 12705 }, 12706 vertical: { 12707 newScroll: this.adapter.scrollTop(), 12708 oldScroll: this.oldScroll.y, 12709 forward: 'down', 12710 backward: 'up' 12711 } 12712 } 12713 12714 for (var axisKey in axes) { 12715 var axis = axes[axisKey] 12716 var isForward = axis.newScroll > axis.oldScroll 12717 var direction = isForward ? axis.forward : axis.backward 12718
12719 for (var waypointKey in this.waypoints[axisKey]) { 12720 var waypoint = this.waypoints[axisKey][waypointKey] 12721 if (waypoint.triggerPoint === null) { 12722 continue 12723 } 12724 var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint 12725 var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint 12726 var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint 12727 var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint 12728 if (crossedForward || crossedBackward) { 12729 waypoint.queueTrigger(direction) 12730 triggeredGroups[waypoint.group.id] = waypoint.group 12731 } 12732 } 12733 } 12734 12735 for (var groupKey in triggeredGroups) { 12736 triggeredGroups[groupKey].flushTriggers() 12737 } 12738 12739 this.oldScroll = { 12740 x: axes.horizontal.newScroll, 12741 y: axes.vertical.newScroll 12742 } 12743 } 12744 12745 /* Private */ 12746 Context.prototype.innerHeight = function() { 12747 /*eslint-disable eqeqeq */ 12748 if (this.element == this.element.window) { 12749 return Waypoint.viewportHeight() 12750 } 12751 /*eslint-enable eqeqeq */ 12752 return this.adapter.innerHeight() 12753 } 12754 12755 /* Private */ 12756 Context.prototype.remove = function(waypoint) { 12757 delete this.waypoints[waypoint.axis][waypoint.key] 12758 this.checkEmpty() 12759 } 12760 12761 /* Private */ 12762 Context.prototype.innerWidth = function() { 12763 /*eslint-disable eqeqeq */ 12764 if (this.element == this.element.window) { 12765 return Waypoint.viewportWidth() 12766 } 12767 /*eslint-enable eqeqeq */ 12768 return this.adapter.innerWidth() 12769 } 12770 12771 /* Public */ 12772 /* http://imakewebthings.com/waypoints/api/context-destroy */ 12773 Context.prototype.destroy = function() { 12774 var allWaypoints = [] 12775 for (var axis in this.waypoints) {
12776 for (var waypointKey in this.waypoints[axis]) { 12777 allWaypoints.push(this.waypoints[axis][waypointKey]) 12778 } 12779 } 12780 for (var i = 0, end = allWaypoints.length; i < end; i++) { 12781 allWaypoints[i].destroy() 12782 } 12783 } 12784 12785 /* Public */ 12786 /* http://imakewebthings.com/waypoints/api/context-refresh */ 12787 Context.prototype.refresh = function() { 12788 /*eslint-disable eqeqeq */ 12789 var isWindow = this.element == this.element.window 12790 /*eslint-enable eqeqeq */ 12791 var contextOffset = isWindow ? undefined : this.adapter.offset() 12792 var triggeredGroups = {} 12793 var axes 12794 12795 this.handleScroll() 12796 axes = { 12797 horizontal: { 12798 contextOffset: isWindow ? 0 : contextOffset.left, 12799 contextScroll: isWindow ? 0 : this.oldScroll.x, 12800 contextDimension: this.innerWidth(), 12801 oldScroll: this.oldScroll.x, 12802 forward: 'right', 12803 backward: 'left', 12804 offsetProp: 'left' 12805 }, 12806 vertical: { 12807 contextOffset: isWindow ? 0 : contextOffset.top, 12808 contextScroll: isWindow ? 0 : this.oldScroll.y, 12809 contextDimension: this.innerHeight(), 12810 oldScroll: this.oldScroll.y, 12811 forward: 'down', 12812 backward: 'up', 12813 offsetProp: 'top' 12814 } 12815 } 12816 12817 for (var axisKey in axes) { 12818 var axis = axes[axisKey]
12819 for (var waypointKey in this.waypoints[axisKey]) { 12820 var waypoint = this.waypoints[axisKey][waypointKey] 12821 var adjustment = waypoint.options.offset 12822 var oldTriggerPoint = waypoint.triggerPoint 12823 var elementOffset = 0 12824 var freshWaypoint = oldTriggerPoint == null 12825 var contextModifier, wasBeforeScroll, nowAfterScroll 12826 var triggeredBackward, triggeredForward 12827 12828 if (waypoint.element !== waypoint.element.window) { 12829 elementOffset = waypoint.adapter.offset()[axis.offsetProp] 12830 } 12831 12832 if (typeof adjustment === 'function') { 12833 adjustment = adjustment.apply(waypoint) 12834 } 12835 else if (typeof adjustment === 'string') { 12836 adjustment = parseFloat(adjustment) 12837 if (waypoint.options.offset.indexOf('%') > - 1) { 12838 adjustment = Math.ceil(axis.contextDimension * adjustment / 100) 12839 } 12840 } 12841 12842 contextModifier = axis.contextScroll - axis.contextOffset 12843 waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment) 12844 wasBeforeScroll = oldTriggerPoint < axis.oldScroll 12845 nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll 12846 triggeredBackward = wasBeforeScroll && nowAfterScroll 12847 triggeredForward = !wasBeforeScroll && !nowAfterScroll 12848 12849 if (!freshWaypoint && triggeredBackward) { 12850 waypoint.queueTrigger(axis.backward) 12851 triggeredGroups[waypoint.group.id] = waypoint.group 12852 } 12853 else if (!freshWaypoint && triggeredForward) { 12854 waypoint.queueTrigger(axis.forward) 12855 triggeredGroups[waypoint.group.id] = waypoint.group 12856 } 12857 else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) { 12858 waypoint.queueTrigger(axis.forward) 12859 triggeredGroups[waypoint.group.id] = waypoint.group 12860 } 12861 } 12862 } 12863 12864 Waypoint.requestAnimationFrame(function() { 12865 for (var groupKey in triggeredGroups) { 12866 triggeredGroups[groupKey].flushTriggers() 12867 } 12868 }) 12869 12870 return this 12871 } 12872 12873 /* Private */ 12874 Context.findOrCreateByElement = function(element) { 12875 return Context.findByElement(element) || new Context(element) 12876 } 12877 12878 /* Private */ 12879 Context.refreshAll = function() { 12880 for (var contextId in contexts) { 12881 contexts[contextId].refresh() 12882 } 12883 } 12884 12885 /* Public */ 12886 /* http://imakewebthings.com/waypoints/api/context-find-by-element */ 12887 Context.findByElement = function(element) { 12888 return contexts[element.waypointContextKey] 12889 } 12890 12891 window.onload = function() { 12892 if (oldWindowLoad) { 12893 oldWindowLoad() 12894 } 12895 Context.refreshAll() 12896 } 12897 12898 12899 Waypoint.requestAnimationFrame = function(callback) { 12900 var requestFn = window.requestAnimationFrame || 12901 window.mozRequestAnimationFrame || 12902 window.webkitRequestAnimationFrame || 12903 requestAnimationFrameShim 12904 requestFn.call(window, callback) 12905 } 12906 Waypoint.Context = Context 12907}()) 12908;(function() { 12909 'use strict' 12910 12911 function byTriggerPoint(a, b) { 12912 return a.triggerPoint - b.triggerPoint 12913 } 12914 12915 function byReverseTriggerPoint(a, b) { 12916 return b.triggerPoint - a.triggerPoint 12917 } 12918 12919 var groups = { 12920 vertical: {}, 12921 horizontal: {} 12922 } 12923 var Waypoint = window.Waypoint 12924 12925 /* http://imakewebthings.com/waypoints/api/group */ 12926 function Group(options) { 12927 this.name = options.name 12928 this.axis = options.axis 12929 this.id = this.name + '-' + this.axis 12930 this.waypoints = [] 12931 this.clearTriggerQueues() 12932 groups[this.axis][this.name] = this 12933 } 12934 12935 /* Private */ 12936 Group.prototype.add = function(waypoint) { 12937 this.waypoints.push(waypoint) 12938 } 12939 12940 /* Private */ 12941 Group.prototype.clearTriggerQueues = function() { 12942 this.triggerQueues = { 12943 up: [], 12944 down: [], 12945 left: [], 12946 right: [] 12947 } 12948 } 12949 12950 /* Private */ 12951 Group.prototype.flushTriggers = function() { 12952 for (var direction in this.triggerQueues) { 12953 var waypoints = this.triggerQueues[direction] 12954 var reverse = direction === 'up' || direction === 'left' 12955 waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint) 12956 for (var i = 0, end = waypoints.length; i < end; i += 1) { 12957 var waypoint = waypoints[i] 12958 if (waypoint.options.continuous || i === waypoints.length - 1) { 12959 waypoint.trigger([direction]) 12960 } 12961 } 12962 } 12963 this.clearTriggerQueues() 12964 } 12965 12966 /* Private */ 12967 Group.prototype.next = function(waypoint) { 12968 this.waypoints.sort(byTriggerPoint) 12969 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 12970 var isLast = index === this.waypoints.length - 1 12971 return isLast ? null : this.waypoints[index + 1] 12972 } 12973 12974 /* Private */ 12975 Group.prototype.previous = function(waypoint) { 12976 this.waypoints.sort(byTriggerPoint) 12977 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 12978 return index ? this.waypoints[index - 1] : null 12979 } 12980 12981 /* Private */ 12982 Group.prototype.queueTrigger = function(waypoint, direction) { 12983 this.triggerQueues[direction].push(waypoint) 12984 } 12985 12986 /* Private */ 12987 Group.prototype.remove = function(waypoint) { 12988 var index = Waypoint.Adapter.inArray(waypoint, this.waypoints) 12989 if (index > -1) { 12990 this.waypoints.splice(index, 1) 12991 } 12992 } 12993 12994 /* Public */ 12995 /* http://imakewebthings.com/waypoints/api/first */ 12996 Group.prototype.first = function() { 12997 return this.waypoints[0] 12998 } 12999 13000 /* Public */ 13001 /* http://imakewebthings.com/waypoints/api/last */ 13002 Group.prototype.last = function() { 13003 return this.waypoints[this.waypoints.length - 1] 13004 } 13005 13006 /* Private */ 13007 Group.findOrCreate = function(options) { 13008 return groups[options.axis][options.name] || new Group(options) 13009 } 13010 13011 Waypoint.Group = Group 13012}()) 13013;(function() { 13014 'use strict' 13015 13016 var $ = window.jQuery 13017 var Waypoint = window.Waypoint 13018 13019 function JQueryAdapter(element) { 13020 this.$element = $(element) 13021 } 13022 13023 $.each([
13024 'innerHeight', 13025 'innerWidth', 13026 'off', 13027 'offset', 13028 'on', 13029 'outerHeight', 13030 'outerWidth', 13031 'scrollLeft', 13032 'scrollTop' 13033 ], function(i, method) { 13034 JQueryAdapter.prototype[method] = function() { 13035 var args = Array.prototype.slice.call(arguments) 13036 return this.$element[method].apply(this.$element, args) 13037 } 13038 }) 13039 13040 $.each([ 13041 'extend', 13042 'inArray', 13043 'isEmptyObject' 13044 ], function(i, method) { 13045 JQueryAdapter[method] = $[method] 13046 }) 13047 13048 Waypoint.adapters.push({ 13049 name: 'jquery', 13050 Adapter: JQueryAdapter 13051 }) 13052 Waypoint.Adapter = JQueryAdapter 13053}()) 13054;(function() { 13055 'use strict' 13056 13057 var Waypoint = window.Waypoint 13058 13059 function createExtension(framework) { 13060 return function() { 13061 var waypoints = [] 13062 var overrides = arguments[0] 13063 13064 if (framework.isFunction(arguments[0])) { 13065 overrides = framework.extend({}, arguments[1]) 13066 overrides.handler = arguments[0] 13067 } 13068 13069 this.each(function() { 13070 var options = framework.extend({}, overrides, { 13071 element: this 13072 }) 13073 if (typeof options.context === 'string') { 13074 options.context = framework(this).closest(options.context)[0] 13075 } 13076 waypoints.push(new Waypoint(options)) 13077 }) 13078 13079 return waypoints 13080 } 13081 } 13082 13083 if (window.jQuery) { 13084 window.jQuery.fn.waypoint = createExtension(window.jQuery) 13085 } 13086 if (window.Zepto) { 13087 window.Zepto.fn.waypoint = createExtension(window.Zepto) 13088 } 13089}()) 13090; 13091/*! 13092Waypoints Inview Shortcut - 4.0.1 13093Copyright © 2011-2016 Caleb Troughton 13094Licensed under the MIT license. 13095https://github.com/imakewebthings/waypoints/blob/master/licenses.txt 13096*/ 13097(function() { 13098 'use strict' 13099 13100 function noop() {} 13101 13102 var Waypoint = window.Waypoint 13103 13104 /* http://imakewebthings.com/waypoints/shortcuts/inview */ 13105 function Inview(options) { 13106 this.options = Waypoint.Adapter.extend({}, Inview.defaults, options) 13107 this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 13108 this.waypoints = [] 13109 this.element = this.options.element 13110 this.createWaypoints() 13111 } 13112 13113 /* Private */ 13114 Inview.prototype.createWaypoints = function() { 13115 var configs = { 13116 vertical: [{ 13117 down: 'enter', 13118 up: 'exited', 13119 offset: '100%' 13120 }, { 13121 down: 'entered', 13122 up: 'exit', 13123 offset: 'bottom-in-view' 13124 }, { 13125 down: 'exit', 13126 up: 'entered', 13127 offset: 0 13128 }, { 13129 down: 'exited', 13130 up: 'enter', 13131 offset: function() { 13132 return -this.adapter.outerHeight() 13133 } 13134 }], 13135 horizontal: [{ 13136 right: 'enter', 13137 left: 'exited', 13138 offset: '100%' 13139 }, { 13140 right: 'entered', 13141 left: 'exit', 13142 offset: 'right-in-view' 13143 }, { 13144 right: 'exit', 13145 left: 'entered', 13146 offset: 0 13147 }, { 13148 right: 'exited', 13149 left: 'enter', 13150 offset: function() { 13151 return -this.adapter.outerWidth() 13152 } 13153 }] 13154 } 13155 13156 for (var i = 0, end = configs[this.axis].length; i < end; i++) { 13157 var config = configs[this.axis][i] 13158 this.createWaypoint(config) 13159 } 13160 } 13161 13162 /* Private */ 13163 Inview.prototype.createWaypoint = function(config) { 13164 var self = this 13165 this.waypoints.push(new Waypoint({ 13166 context: this.options.context, 13167 element: this.options.element, 13168 enabled: this.options.enabled, 13169 handler: (function(config) { 13170 return function(direction) { 13171 self.options[config[direction]].call(self, direction) 13172 } 13173 }(config)), 13174 offset: config.offset, 13175 horizontal: this.options.horizontal 13176 })) 13177 } 13178 13179 /* Public */ 13180 Inview.prototype.destroy = function() { 13181 for (var i = 0, end = this.waypoints.length; i < end; i++) { 13182 this.waypoints[i].destroy() 13183 } 13184 this.waypoints = [] 13185 } 13186 13187 Inview.prototype.disable = function() { 13188 for (var i = 0, end = this.waypoints.length; i < end; i++) { 13189 this.waypoints[i].disable() 13190 } 13191 } 13192 13193 Inview.prototype.enable = function() { 13194 for (var i = 0, end = this.waypoints.length; i < end; i++) { 13195 this.waypoints[i].enable() 13196 } 13197 } 13198 13199 Inview.defaults = { 13200 context: window, 13201 enabled: true, 13202 enter: noop, 13203 entered: noop,
13204 exit: noop, 13205 exited: noop 13206 } 13207 13208 Waypoint.Inview = Inview 13209}()) 13210; 13211 13212/* 13213 * SmartMenus jQuery v0.9.6 13214 * http://www.smartmenus.org/ 13215 * 13216 * Copyright 2014 Vasil Dinkov, Vadikom Web Ltd. 13217 * http://vadikom.com/ 13218 * 13219 * Released under the MIT license: 13220 * http://www.opensource.org/licenses/MIT 13221 */ 13222 13223(function($) { 13224 13225 var menuTrees = [], 13226 IE = !!window.createPopup, // we need to detect it, unfortunately 13227 IElt9 = IE && !document.defaultView, 13228 IElt8 = IE && !document.querySelector, 13229 IE6 = IE && typeof document.documentElement.currentStyle.minWidth == 'undefined', 13230 mouse = false, // optimize for touch by default - we will detect for mouse input 13231 mouseDetectionEnabled = false; 13232 13233 // Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.) 13234 function initMouseDetection(disable) { 13235 if (!mouseDetectionEnabled && !disable) { 13236 // if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present 13237 // 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) 13238 var firstTime = true, 13239 lastMove = null; 13240 $(document).bind({ 13241 'mousemove.smartmenus_mouse': function(e) { 13242 var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() }; 13243 if (lastMove) { 13244 var deltaX = Math.abs(lastMove.x - thisMove.x), 13245 deltaY = Math.abs(lastMove.y - thisMove.y); 13246 if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) { 13247 mouse = true; 13248 // 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 13249 if (firstTime) { 13250 var $a = $(e.target).closest('a'); 13251 if ($a.is('a')) { 13252 $.each(menuTrees, function() { 13253 if ($.contains(this.$root[0], $a[0])) { 13254 this.itemEnter({ currentTarget: $a[0] }); 13255 return false; 13256 } 13257 }); 13258 } 13259 firstTime = false; 13260 } 13261 } 13262 } 13263 lastMove = thisMove; 13264 }, 13265 'touchstart.smartmenus_mouse pointerover.smartmenus_mouse MSPointerOver.smartmenus_mouse': function(e) { 13266 if (!/^(4|mouse|pen)$/.test(e.originalEvent.pointerType)) { 13267 mouse = false; 13268 } 13269 } 13270 }); 13271 mouseDetectionEnabled = true; 13272 } else if (mouseDetectionEnabled && disable) { 13273 $(document).unbind('.smartmenus_mouse'); 13274 mouseDetectionEnabled = false; 13275 } 13276 }; 13277 13278 $.SmartMenus = function(elm, options) { 13279 this.$root = $(elm); 13280 this.opts = options; 13281 this.rootId = ''; // internal 13282 this.$subArrow = null; 13283 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) 13284 this.activatedItems = []; // stores last activated A's for each level 13285 this.visibleSubMenus = []; // stores visible sub menus UL's 13286 this.showTimeout = 0; 13287 this.hideTimeout = 0; 13288 this.scrollTimeout = 0; 13289 this.clickActivated = false; 13290 this.zIndexInc = 0; 13291 this.$firstLink = null; // we'll use these for some tests 13292 this.$firstSub = null; // at runtime so we'll cache them 13293 this.disabled = false; 13294 this.$disableOverlay = null; 13295 this.lastLevel = 0; 13296 this.init(); 13297 }; 13298 13299 $.extend($.SmartMenus, { 13300 hideAll: function() { 13301 $.each(menuTrees, function() { 13302 this.menuHideAll(); 13303 }); 13304 }, 13305 destroy: function() { 13306 while (menuTrees.length) { 13307 menuTrees[0].destroy(); 13308 } 13309 initMouseDetection(true); 13310 }, 13311 prototype: { 13312 init: function(refresh) { 13313 var self = this; 13314 13315 if (!refresh) { 13316 menuTrees.push(this); 13317 13318 this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, ''); 13319 13320 if (this.$root.hasClass('sm-rtl')) { 13321 this.opts.rightToLeftSubMenus = true; 13322 } 13323 13324 // init root (main menu) 13325 this.$root 13326 .data('smartmenus', this) 13327 .attr('data-smartmenus-id', this.rootId) 13328 .dataSM('level', 1) 13329 .bind({ 13330 // 'mouseover.smartmenus focusin.smartmenus': $.proxy(this.rootOver, this),
13331 // 'mouseout.smartmenus focusout.smartmenus': $.proxy(this.rootOut, this) 13332 'mouseover.smartmenus': $.proxy(this.rootOver, this), 13333 'mouseout.smartmenus': $.proxy(this.rootOut, this) 13334 }) 13335 .delegate('a, div.logo-container', { 13336 'mouseenter.smartmenus': $.proxy(this.itemEnter, this), 13337 'mouseleave.smartmenus': $.proxy(this.itemLeave, this), 13338 'mousedown.smartmenus': $.proxy(this.itemDown, this), 13339 'focus.smartmenus': $.proxy(this.itemFocus, this), 13340 'blur.smartmenus': $.proxy(this.itemBlur, this), 13341 'click.smartmenus': $.proxy(this.itemClick, this), 13342 'touchend.smartmenus': $.proxy(this.itemTouchEnd, this) 13343 }); 13344 13345 var eNamespace = '.smartmenus' + this.rootId; 13346 // hide menus on tap or click outside the root UL 13347 if (this.opts.hideOnClick) { 13348 $(document).on('touchstart' + eNamespace, $.proxy(this.docTouchStart, this)) 13349 .on('touchmove' + eNamespace, $.proxy(this.docTouchMove, this)) 13350 .on('touchend' + eNamespace, $.proxy(this.docTouchEnd, this)) 13351 // for Opera Mobile < 11.5, webOS browser, etc. we'll check click too 13352 .on('click' + eNamespace, $.proxy(this.docClick, this)); 13353 } 13354 // hide sub menus on resize 13355 $(window).on('resize' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this)); 13356 var $vmenu = $('body.vmenu .vmenu-container'); 13357 if ( ! $vmenu.length && UNCODE.wwidth > UNCODE.mediaQuery ) { 13358 $(window).on('scroll' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this)); 13359 } 13360 13361 if (this.opts.subIndicators) { 13362 this.$subArrow = $('<span/>').addClass('sub-arrow'); 13363 if (this.opts.subIndicatorsText) { 13364 this.$subArrow.html(this.opts.subIndicatorsText); 13365 } 13366 } 13367 13368 // make sure mouse detection is enabled 13369 initMouseDetection(); 13370 } 13371 13372 // init sub menus 13373 this.$firstSub = this.$root.find('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').each(function() { self.menuInit($(this)); }).eq(0); 13374 13375 this.$firstLink = this.$root.find('a').eq(0); 13376 13377 // find current item 13378 if (this.opts.markCurrentItem) { 13379 var reDefaultDoc = /(index|default)\.[^#\?\/]*/i, 13380 reHash = /#.*/, 13381 locHref = window.location.href.replace(reDefaultDoc, ''), 13382 locHrefNoHash = locHref.replace(reHash, ''); 13383 this.$root.find('a').each(function() { 13384 var href = this.href.replace(reDefaultDoc, ''), 13385 $this = $(this); 13386 if (href == locHref || href == locHrefNoHash) { 13387 $this.addClass('current'); 13388 if (self.opts.markCurrentTree) { 13389 $this.parents('li').each(function() { 13390 var $this = $(this); 13391 if ($this.dataSM('sub')) { 13392 $this.children('a').addClass('current'); 13393 } 13394 }); 13395 } 13396 } 13397 }); 13398 } 13399 }, 13400 destroy: function() { 13401 this.menuHideAll(); 13402 this.$root 13403 .removeData('smartmenus') 13404 .removeAttr('data-smartmenus-id') 13405 .removeDataSM('level') 13406 .unbind('.smartmenus') 13407 .undelegate('.smartmenus'); 13408 var eNamespace = '.smartmenus' + this.rootId; 13409 $(document).unbind(eNamespace); 13410 $(window).unbind(eNamespace); 13411 if (this.opts.subIndicators) { 13412 this.$subArrow = null; 13413 } 13414 var self = this; 13415 $.each(this.subMenus, function() { 13416 if (this.hasClass('mega-menu')) { 13417 this.find('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').removeDataSM('in-mega'); 13418 } 13419 if (this.dataSM('shown-before')) { 13420 if (IElt8) { 13421 this.children().css({ styleFloat: '', width: '' }); 13422 } 13423 if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) { 13424 if (!IE6) { 13425 this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap'); 13426 } else { 13427 this.css({ width: '', overflowX: '', overflowY: '' }).children().children('a').css('white-space', ''); 13428 } 13429 } 13430 if (this.dataSM('scroll-arrows')) { 13431 this.dataSM('scroll-arrows').remove(); 13432 } 13433 this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' }); 13434 } 13435 if (self.opts.subIndicators) { 13436 this.dataSM('parent-a').removeClass('has-submenu').children('span.sub-arrow').remove(); 13437 } 13438 this.removeDataSM('shown-before') 13439 .removeDataSM('ie-shim') 13440 .removeDataSM('scroll-arrows') 13441 .removeDataSM('parent-a') 13442 .removeDataSM('level') 13443 .removeDataSM('beforefirstshowfired') 13444 .parent().removeDataSM('sub'); 13445 }); 13446 if (this.opts.markCurrentItem) { 13447 this.$root.find('a.current').removeClass('current'); 13448 } 13449 this.$root = null; 13450 this.$firstLink = null; 13451 this.$firstSub = null; 13452 if (this.$disableOverlay) { 13453 this.$disableOverlay.remove(); 13454 this.$disableOverlay = null; 13455 } 13456 menuTrees.splice($.inArray(this, menuTrees), 1); 13457 }, 13458 disable: function(noOverlay) { 13459 if (!this.disabled) { 13460 this.menuHideAll(); 13461 // display overlay over the menu to prevent interaction 13462 if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) { 13463 var pos = this.$root.offset(); 13464 this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({ 13465 position: 'absolute', 13466 top: pos.top, 13467 left: pos.left, 13468 width: this.$root.outerWidth(), 13469 height: this.$root.outerHeight(),
13470 zIndex: this.getStartZIndex() + 1, 13471 opacity: 0 13472 }).appendTo(document.body); 13473 } 13474 this.disabled = true; 13475 } 13476 }, 13477 docClick: function(e) { 13478 // hide on any click outside the menu or on a menu link 13479 if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).is('a:not([data-filter])')) { 13480 this.menuHideAll($(e.target)); 13481 } 13482 }, 13483 docTouchEnd: function(e) { 13484 if (!this.lastTouch) { 13485 return; 13486 } 13487 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))) { 13488 if (this.hideTimeout) { 13489 clearTimeout(this.hideTimeout); 13490 this.hideTimeout = 0; 13491 } 13492 // hide with a delay to prevent triggering accidental unwanted click on some page element 13493 var self = this; 13494 this.hideTimeout = setTimeout(function() { self.menuHideAll($(e.target)); }, 350); 13495 } 13496 this.lastTouch = null; 13497 }, 13498 docTouchMove: function(e) { 13499 if (!this.lastTouch) { 13500 return; 13501 } 13502 var touchPoint = e.originalEvent.touches[0]; 13503 this.lastTouch.x2 = touchPoint.pageX; 13504 this.lastTouch.y2 = touchPoint.pageY; 13505 }, 13506 docTouchStart: function(e) { 13507 var touchPoint = e.originalEvent.touches[0]; 13508 this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target }; 13509 }, 13510 enable: function() { 13511 if (this.disabled) { 13512 if (this.$disableOverlay) { 13513 this.$disableOverlay.remove(); 13514 this.$disableOverlay = null; 13515 } 13516 this.disabled = false; 13517 } 13518 }, 13519 getHeight: function($elm) { 13520 return this.getOffset($elm, true); 13521 }, 13522 // returns precise width/height float values in IE9+, FF4+, recent WebKit 13523 // http://vadikom.com/dailies/offsetwidth-offsetheight-useless-in-ie9-firefox4/ 13524 getOffset: function($elm, height) { 13525 var old, 13526 $win = $(window), 13527 winW = $win.width(); 13528 if ($elm.css('display') == 'none') { 13529 old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility }; 13530 $elm.css({ position: 'absolute', visibility: 'hidden' }).show(); 13531 if ( 13532 ($('body').hasClass('menu-mobile-off-canvas') && winW < 960 && $elm.closest('.main-menu-container').length) 13533 || 13534 (( $('body').hasClass('vmenu-offcanvas-overlay') || $('body').hasClass('vmenu') ) && winW >= 960 && $elm.closest('.main-menu-container').length && !$elm.closest('.menu-horizontal-inner').length) 13535 ) { 13536 $elm.closest('li').addClass('smartmenu-open-item'); 13537 } 13538 } 13539 var defaultView = $elm[0].ownerDocument.defaultView, 13540 compStyle = defaultView && defaultView.getComputedStyle && defaultView.getComputedStyle($elm[0], null), 13541 val = compStyle && parseFloat(compStyle[height ? 'height' : 'width']); 13542 if (val) { 13543 val += parseFloat(compStyle[height ? 'paddingTop' : 'paddingLeft']) 13544 + parseFloat(compStyle[height ? 'paddingBottom' : 'paddingRight']) 13545 + parseInt(compStyle[height ? 'borderTopWidth' : 'borderLeftWidth']) 13546 + parseInt(compStyle[height ? 'borderBottomWidth' : 'borderRightWidth']); 13547 } else { 13548 val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth; 13549 } 13550 if (old) { 13551 $elm.hide().css(old); 13552 } 13553 return val; 13554 }, 13555 getWidth: function($elm) { 13556 return this.getOffset($elm); 13557 }, 13558 getStartZIndex: function() { 13559 var zIndex = parseInt(this.$root.css('z-index')); 13560 return !isNaN(zIndex) ? zIndex : 1; 13561 }, 13562 handleEvents: function() { 13563 return !this.disabled && this.isCSSOn(); 13564 }, 13565 handleItemEvents: function($a) { 13566 return this.handleEvents() && !this.isLinkInMegaMenu($a); 13567 }, 13568 isCollapsible: function() { 13569 return this.$firstSub.css('position') == 'static'; 13570 }, 13571 isCSSOn: function() { 13572 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'; 13573 }, 13574 isFixed: function() { 13575 return this.$root.css('position') == 'fixed'; 13576 }, 13577 isLinkInMegaMenu: function($a) { 13578 return !$a.parent().parent().dataSM('level'); 13579 }, 13580 isTouchMode: function() { 13581 return !mouse || this.isCollapsible(); 13582 }, 13583 itemActivate: function($a, $show) { 13584 var $li = $a.parent(), 13585 $ul = $li.parent(), 13586 level = $ul.dataSM('level'), 13587 winh = $(window).height(); 13588 // 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 13589 if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) { 13590 var self = this; 13591 $($ul.parentsUntil('[data-smartmenus-id]', 'ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').get().reverse()).add($ul).each(function() { 13592 self.itemActivate($(this).dataSM('parent-a')); 13593 }); 13594 } 13595 // hide any visible deeper level sub menus 13596 if (this.visibleSubMenus.length > level) { 13597 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--) { 13598 this.lastLevel = level; 13599 if ( typeof $show === 'undefined' && this.isCollapsible() ) { 13600 this.menuHide(this.visibleSubMenus[i], $a); 13601 return; 13602 } else { 13603 this.menuHide(this.visibleSubMenus[i]); 13604 } 13605 } 13606 } 13607 // save new active item and sub menu for this level 13608 this.activatedItems[level - 1] = $a; 13609 this.visibleSubMenus[level - 1] = $ul; 13610 if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) { 13611 return; 13612 } 13613 // show the sub menu if this item has one 13614 var $sub = $li.dataSM('sub'); 13615 if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) { 13616 // if ($sub && (this.isTouchMode() || (!this.opts.showOnClick))) { 13617 var aRect = $a[0].getBoundingClientRect(); 13618 if ( (aRect.y < 0 || aRect.y > winh) && this.isCollapsible() && (this.lastLevel === this.activatedItems.length) ) { 13619 setTimeout(function(){ 13620 var currentScroll = $a.closest('.main-menu-container').scrollTop(); 13621 $a.closest('.main-menu-container').scrollTop(currentScroll + aRect.y); 13622 }, 1); 13623 } 13624 this.menuShow($sub); 13625 } 13626 }, 13627 itemBlur: function(e) { 13628 var $a = $(e.currentTarget); 13629 if (!this.handleItemEvents($a)) { 13630 return; 13631 } 13632 this.$root.triggerHandler('blur.smapi', $a[0]); 13633 }, 13634 itemClick: function(e) { 13635 var $a = $(e.currentTarget); 13636 13637 if (!this.handleItemEvents($a)) { 13638 return; 13639 } 13640 $a.removeDataSM('mousedown'); 13641 if (this.$root.triggerHandler('click.smapi', $a[0]) === false) { 13642 return false;
13643 } 13644 var $sub = $a.parent().dataSM('sub'); 13645 if (this.isTouchMode()) { 13646 // undo fix: prevent the address bar on iPhone from sliding down when expanding a sub menu 13647 if ($a.dataSM('href')) { 13648 $a.attr('href', $a.dataSM('href')).removeDataSM('href'); 13649 } 13650 // if the sub is not visible 13651 if ($sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) { 13652 // try to activate the item and show the sub 13653 this.itemActivate($a); 13654 // if "itemActivate" showed the sub, prevent the click so that the link is not loaded 13655 // 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 13656 if ($sub.is(':visible')) { 13657 return false; 13658 } 13659 } 13660 // } else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub && !$sub.is(':visible')) { 13661 } else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub) { 13662 this.clickActivated = true; 13663 this.menuShow($sub); 13664 return false; 13665 } 13666 if ($a.hasClass('disabled')) { 13667 return false; 13668 } 13669 if (this.$root.triggerHandler('select.smapi', $a[0]) === false) { 13670 return false; 13671 } 13672 }, 13673 itemDown: function(e) { 13674 var $a = $(e.currentTarget); 13675 if (!this.handleItemEvents($a)) { 13676 return; 13677 } 13678 $a.dataSM('mousedown', true); 13679 }, 13680 itemEnter: function(e) { 13681 // if ( this.opts.showOnClick ) { 13682 // return 13683 // } 13684 var $a = $(e.currentTarget); 13685 if (!this.handleItemEvents($a)) { 13686 return; 13687 } 13688 if (!this.isTouchMode()) { 13689 if (this.showTimeout) { 13690 clearTimeout(this.showTimeout); 13691 this.showTimeout = 0; 13692 } 13693 var self = this; 13694 this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 ? 1 : this.opts.showTimeout); 13695 } 13696 this.$root.triggerHandler('mouseenter.smapi', $a[0]); 13697 }, 13698 itemFocus: function(e) { 13699 var $a = $(e.currentTarget); 13700 if (!this.handleItemEvents($a)) { 13701 return; 13702 } 13703 // 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 13704 if ((!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) { 13705 this.itemActivate($a); 13706 } 13707 this.$root.triggerHandler('focus.smapi', $a[0]); 13708 }, 13709 itemLeave: function(e) { 13710 // if ( this.opts.showOnClick ) { 13711 // return 13712 // } 13713 var $a = $(e.currentTarget); 13714 if (!this.handleItemEvents($a)) { 13715 return; 13716 } 13717 if (!this.isTouchMode()) { 13718 if ($a[0].blur) { 13719 $a[0].blur(); 13720 } 13721 if (this.showTimeout) { 13722 clearTimeout(this.showTimeout); 13723 this.showTimeout = 0; 13724 } 13725 } 13726 $a.removeDataSM('mousedown'); 13727 this.$root.triggerHandler('mouseleave.smapi', $a[0]); 13728 }, 13729 itemTouchEnd: function(e) { 13730 var $a = $(e.currentTarget); 13731 if (!this.handleItemEvents($a)) { 13732 return; 13733 } 13734 // prevent the address bar on iPhone from sliding down when expanding a sub menu 13735 var $sub = $a.parent().dataSM('sub'); 13736 if ($a.attr('href').charAt(0) !== '#' && $sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) { 13737 $a.dataSM('href', $a.attr('href')); 13738 $a.attr('href', '#'); 13739 } 13740 }, 13741 menuFixLayout: function($ul) { 13742 // fixes a menu that is being shown for the first time 13743 if (!$ul.dataSM('shown-before')) { 13744 $ul.hide().dataSM('shown-before', true); 13745 // fix the layout of the items in IE<8 13746 if (IElt8) { 13747 $ul.children().css({ styleFloat: 'left', width: '100%' }); 13748 } 13749 } 13750 }, 13751 menuHide: function($sub, $show) { 13752 if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) { 13753 return; 13754 } 13755 $sub.stop(true, true); 13756 if ($sub.is(':visible')) { 13757 var self = this; 13758 var complete = function() { 13759 // unset z-index 13760 if (IElt9) { 13761 $sub.parent().css('z-index', ''); 13762 } else { 13763 $sub.css('z-index', ''); 13764 } 13765 if ( typeof $show !== 'undefined' ) { 13766 self.itemActivate($show, true) 13767 } 13768 }; 13769 // if sub is collapsible (mobile view) 13770 if (this.isCollapsible()) { 13771 if (this.opts.collapsibleHideFunction) { 13772 this.opts.collapsibleHideFunction.call(this, $sub, complete); 13773 } else { 13774 $sub.hide(this.opts.collapsibleHideDuration, complete); 13775 } 13776 } else { 13777 if (this.opts.hideFunction) { 13778 this.opts.hideFunction.call(this, $sub, complete); 13779 } else { 13780 $sub.hide(this.opts.hideDuration, complete); 13781 } 13782 } 13783 // remove IE iframe shim 13784 if ($sub.dataSM('ie-shim')) { 13785 $sub.dataSM('ie-shim').remove(); 13786 } 13787 // deactivate scrolling if it is activated for this sub 13788 if ($sub.dataSM('scroll')) { 13789 $sub.unbind('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide(); 13790 } 13791 // unhighlight parent item 13792 $sub.dataSM('parent-a').removeClass('highlighted'); 13793 var level = $sub.dataSM('level'); 13794 this.activatedItems.splice(level - 1, 1); 13795 this.visibleSubMenus.splice(level - 1, 1); 13796 this.$root.triggerHandler('hide.smapi', $sub[0]); 13797 } 13798 }, 13799 menuHideAll: function($item) { 13800 if ($item != undefined && $item.parent().hasClass('menu-item') && !$item.parent().hasClass('menu-item-has-children')) return; 13801 var $win = $(window), 13802 winW = $win.width(); 13803 if (this.showTimeout) { 13804 clearTimeout(this.showTimeout); 13805 this.showTimeout = 0; 13806 } 13807 // hide all subs 13808 for (var i = this.visibleSubMenus.length - 1; i > 0; i--) { 13809 if ( this.visibleSubMenus[i].closest('.smartmenu-open-item').length ) { 13810 if ( $item != undefined && $item.closest('.smartmenu-open-item').length ) { 13811 this.menuHide(this.visibleSubMenus[i]); 13812 $(this.visibleSubMenus[i]).closest('.smartmenu-open-item').removeClass('smartmenu-open-item'); 13813 } else { 13814 return; 13815 } 13816 } else { 13817 //if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) { 13818 this.menuHide(this.visibleSubMenus[i]); 13819 //} 13820 } 13821 } 13822 // hide root if it's popup 13823 if (this.opts.isPopup) { 13824 this.$root.stop(true, true); 13825 if (this.$root.is(':visible')) { 13826 if (this.opts.hideFunction) { 13827 this.opts.hideFunction.call(this, this.$root); 13828 } else { 13829 this.$root.hide(this.opts.hideDuration); 13830 } 13831 // remove IE iframe shim 13832 if (this.$root.dataSM('ie-shim')) { 13833 this.$root.dataSM('ie-shim').remove(); 13834 } 13835 } 13836 } 13837 this.activatedItems = []; 13838 this.visibleSubMenus = []; 13839 this.clickActivated = false;
13840 // reset z-index increment 13841 this.zIndexInc = 0; 13842 }, 13843 menuIframeShim: function($ul) { 13844 // create iframe shim for the menu 13845 if (IE && this.opts.overlapControlsInIE && !$ul.dataSM('ie-shim')) { 13846 $ul.dataSM('ie-shim', $('<iframe/>').attr({ src: 'javascript:0', tabindex: -9 }) 13847 .css({ position: 'absolute', top: 'auto', left: '0', opacity: 0, border: '0' }) 13848 ); 13849 } 13850 }, 13851 menuInit: function($ul) { 13852 if (!$ul.dataSM('in-mega')) { 13853 this.subMenus.push($ul); 13854 // mark UL's in mega drop downs (if any) so we can neglect them 13855 if ($ul.hasClass('mega-menu')) { 13856 $ul.find('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').dataSM('in-mega', true); 13857 } 13858 // get level (much faster than, for example, using parentsUntil) 13859 var level = 2, 13860 par = $ul[0]; 13861 while (par != null && par.parentNode != null && ( par = par.parentNode.parentNode) != this.$root[0]) { 13862 level++; 13863 } 13864 // cache stuff 13865 $ul.dataSM('parent-a', $ul.prevAll('a').eq(-1)) 13866 .dataSM('level', level) 13867 .parent().dataSM('sub', $ul); 13868 // add sub indicator to parent item 13869 if (this.opts.subIndicators) { 13870 $ul.dataSM('parent-a').addClass('has-submenu')[this.opts.subIndicatorsPos](this.$subArrow.clone()); 13871 } 13872 } 13873 if ( $('.vc_row[data-parent].has-bg', $ul).length && !$('.vc_row[data-parent]:not(.has-bg)', $ul).length ) { 13874 $ul.addClass('has-bg-items'); 13875 } 13876 }, 13877 menuPosition: function($sub) { 13878 var fixIE = $('html.ie').length; 13879 // if (fixIE) { 13880 // var $rowParent = $($sub).closest('.main-menu-container'); 13881 // $rowParent.height($rowParent.height()); 13882 // } 13883 var $a = $sub.dataSM('parent-a'), 13884 $li = $sub.parent(), 13885 $ul = $sub.parent().parent(), 13886 // $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'), 13887 $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'), 13888 level = $sub.dataSM('level'), 13889 subW = this.getWidth($sub), 13890 subH = this.getHeight($sub), 13891 itemOffset = $a.offset(), 13892 itemX = itemOffset.left, 13893 itemY = itemOffset.top, 13894 itemW = this.getWidth($a), 13895 itemH = this.getHeight($a), 13896 $win = $(window), 13897 winX = $win.scrollLeft(), 13898 winY = $win.scrollTop(), 13899 winW = $win.width(), 13900 winH = $win.height(), 13901 containerW = $container.width(), 13902 containerOffsetX = containerW + ((winW - containerW) / 2), 13903 horizontalParent = $ul.hasClass('sm') && !$ul.hasClass('sm-vertical'), 13904 subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX, 13905 subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY, 13906 x, y, leftPos; 13907 13908 if (horizontalParent) { 13909 x = this.opts.rightToLeftSubMenus ? itemW - subW - subOffsetX : subOffsetX; 13910 y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY; 13911 } else { 13912 x = this.opts.rightToLeftSubMenus ? subOffsetX - subW : subW - subOffsetX; 13913 y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY; 13914 } 13915 if (this.opts.keepInViewport && !this.isCollapsible()) { 13916 if (this.isFixed()) { 13917 itemX -= winX; 13918 itemY -= winY; 13919 winX = winY = 0; 13920 } 13921 var absX = itemX + x, 13922 absY = itemY + y; 13923 if (this.opts.rightToLeftSubMenus && absX < winX) { 13924 x = horizontalParent ? winX - absX + x : itemW - subOffsetX; 13925 } else if (!this.opts.rightToLeftSubMenus && absX + subW > winX + containerOffsetX ) { 13926 x = horizontalParent ? winX + containerOffsetX - subW - absX + x : subOffsetX - subW; 13927 } 13928 if (!horizontalParent) { 13929 if (subH < winH && absY + subH > winY + winH) { 13930 y += winY + winH - subH - absY; 13931 } else if (subH >= winH || absY < winY) { 13932 y += winY - absY; 13933 } 13934 } 13935 // do we need scrolling? 13936 // 0.49 added for the sake of IE9/FF4+ where we might be dealing with float numbers for "subH" 13937 if (mouse && (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49)) { 13938 var self = this; 13939 if (!$sub.dataSM('scroll-arrows')) { 13940 $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]]) 13941 .bind({ 13942 mouseenter: function() { self.menuScroll($sub, $(this).hasClass('scroll-up')); }, 13943 mouseleave: function(e) { 13944 self.menuScrollStop($sub); 13945 self.menuScrollOut($sub, e); 13946 }, 13947 'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); } 13948 }) 13949 .insertAfter($sub) 13950 ); 13951 } 13952 // bind events to show/hide arrows on hover and save scrolling data for this sub 13953 var vportY = winY - (itemY + itemH); 13954 $sub.dataSM('scroll', { 13955 vportY: vportY, 13956 subH: subH, 13957 winH: winH, 13958 step: 1 13959 }) 13960 .bind({ 13961 'mouseover.smartmenus_scroll': function(e) { self.menuScrollOver($sub, e); }, 13962 'mouseout.smartmenus_scroll': function(e) { self.menuScrollOut($sub, e); }, 13963 'mousewheel.smartmenus_scroll DOMMouseScroll.smartmenus_scroll': function(e) { self.menuScrollMousewheel($sub, e); } 13964 }) 13965 .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
13965StartZIndex() + this.zIndexInc }) 13966 .eq(0).css('margin-top', vportY).end() 13967 .eq(1).css('margin-top', vportY + winH - this.getHeight($sub.dataSM('scroll-arrows').eq(1))).end() 13968 .eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show(); 13969 } 13970 } 13971 if ( !$sub.closest('.menu-accordion').length ) { 13972 var rightPos = 'auto'; 13973 if ( $sub.closest('.grid-filters').length ) { 13974 if ( $sub.closest('.text-right').length ) { 13975 leftPos = '0px'; 13976 rightPos = 'auto'; 13977 } else { 13978 leftPos = 'auto'; 13979 rightPos = '0px'; 13980 } 13981 x = 0; 13982 } else { 13983 if ( $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)').length && $sub.closest('.row-menu').is('.limit-width') && level === 2) { 13984 var parentContW = $sub.closest('.menu-container').width(); 13985 $sub.css({ width: parentContW}); 13986 $sub.addClass('need-focus'); 13987 leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.menu-container').offset().left)); 13988 x = 0; 13989 } else if ( $sub.hasClass('mega-menu-inner') || $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)').length ) { 13990 $sub.css({ width: containerW}); 13991 $sub.addClass('need-focus'); 13992 leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.row-menu').offset().left)); 13993 if ( ! $('body').hasClass('megamenu-side-to-side') ) { 13994 leftPos += parseFloat($sub.closest('.row-menu-inner').css('paddingLeft')); 13995 } 13996 x = 0; 13997 } else { 13998 if ( $sub.is('.block-wrapper-parent') && !$sub.find('.col-custom-width').length && !$sub.find('.row-parent-limit').length && level === 2 ) { 13999 leftPos = ( $li.position().left - ( (UNCODE.wwidth - $sub.outerWidth() )/2) ) + 'px'; 14000 } else { 14001 leftPos = (level > 2 ? $li.position().left - parseFloat($li.closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').css('paddingLeft')) : $li.position().left ) + 'px'; 14002 } 14003 x = (level > 2 && x >= 0) ? x + 1 : x - 1; 14004 } 14005 } 14006 } 14007 14008 // $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) }); 14009 $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) }); 14010 // IE iframe shim 14011 this.menuIframeShim($sub); 14012 if ($sub.dataSM('ie-shim')) { 14013 $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) }); 14014 } 14015 }, 14016 menuScroll: function($sub, up, wheel) { 14017 var y = parseFloat($sub.css('margin-top')), 14018 scroll = $sub.dataSM('scroll'), 14019 navH = $('.navbar-main').outerHeight(), 14020 end = scroll.vportY + (up ? navH + 54 : scroll.winH - scroll.subH), 14021 step = wheel || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor($sub.dataSM('scroll').step); 14022 $sub.add($sub.dataSM('ie-shim')).css('margin-top', Math.abs(end - y) > step ? y + (up ? step : -step) : end); 14023 y = parseFloat($sub.css('margin-top')); 14024 // show opposite arrow if appropriate 14025 if (up && y + scroll.subH > scroll.vportY + scroll.winH || !up && y < scroll.vportY) { 14026 $sub.dataSM('scroll-arrows').eq(up ? 1 : 0).show(); 14027 } 14028 // accelerate when not using mousewheel to scroll 14029 if (!wheel && this.opts.scrollAccelerate && $sub.dataSM('scroll').step < this.opts.scrollStep) { 14030 $sub.dataSM('scroll').step += 0.5; 14031 } 14032 // "y" and "end" might be float numbers in IE9/FF4+ so this weird way to check is used 14033 if (Math.abs(y - end) < 1) { 14034 $sub.dataSM('scroll-arrows').eq(up ? 0 : 1).hide(); 14035 $sub.dataSM('scroll').step = 1; 14036 } else if (!wheel) { 14037 var self = this; 14038 this.scrollTimeout = setTimeout(function() { self.menuScroll($sub, up); }, this.opts.scrollInterval); 14039 } 14040 }, 14041 menuScrollMousewheel: function($sub, e) { 14042 var $closestSub = $(e.target).closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)'); 14043 while ($closestSub.dataSM('in-mega')) { 14044 $closestSub = $closestSub.parent().closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)'); 14045 } 14046 if ($closestSub[0] == $sub[0]) { 14047 var up = (e.originalEvent.wheelDelta || -e.originalEvent.detail) > 0; 14048 if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) { 14049 this.menuScroll($sub, up, true); 14050 } 14051 } 14052 if ( ! $sub.hasClass('mega-menu-inner') && ! $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)') ) { 14053 e.preventDefault(); 14054 } 14055 }, 14056 menuScrollOut: function($sub, e) { 14057 var reClass = /^scroll-(up|down)/, 14058 $closestSub = $(e.relatedTarget).closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)'); 14059 while ($closestSub.dataSM('in-mega')) { 14060 $closestSub = $closestSub.parent().closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)'); 14061 } 14062 if (!reClass.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || $closestSub[0] != $sub[0])) { 14063 $sub.dataSM('scroll-arrows').css('visibility', 'hidden'); 14064 } 14065 }, 14066 menuScrollOver: function($sub, e) { 14067 var reClass = /^scroll-(up|down)/, 14068 $closestSub = $(e.target).closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)'); 14069 while ($closestSub.dataSM('in-mega')) { 14070 $closestSub = $closestSub.parent().closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)'); 14071 } 14072 if (!reClass.test(e.target.className) && $closestSub[0] == $sub[0]) { 14073 $sub.dataSM('scroll-arrows').css('visibility', 'visible'); 14074 } 14075 }, 14076 menuScrollStop: function($sub) { 14077 if (this.scrollTimeout) { 14078 clearTimeout(this.scrollTimeout); 14079 this.scrollTimeout = 0; 14080 $sub.dataSM('scroll').step = 1; 14081 } 14082 }, 14083 menuShow: function($sub) { 14084 if (!$sub.dataSM('beforefirstshowfired')) { 14085 $sub.dataSM('beforefirstshowfired', true); 14086 if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) { 14087 return; 14088 } 14089 } 14090 if ( this.isCollapsible() ) {
14091 this.$root.triggerHandler('beforecollapse.smapi', $sub[0]); 14092 } 14093 if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) { 14094 return; 14095 } 14096 this.menuFixLayout($sub); 14097 $sub.stop(true, true); 14098 if (!$sub.is(':visible')) { 14099 $sub.css({ 14100 'visibility': 'visible', 14101 'pointer-events': 'auto', 14102 }); 14103 // set z-index - for IE < 9 set it to the parent LI 14104 var zIndex = this.getStartZIndex() + (++this.zIndexInc); 14105 if (IElt9) { 14106 $sub.parent().css('z-index', zIndex); 14107 } else { 14108 $sub.css('z-index', zIndex); 14109 } 14110 // highlight parent item 14111 if (this.opts.keepHighlighted || this.isCollapsible()) { 14112 if ($sub.dataSM('parent-a').attr('data-type') != 'title') 14113 $sub.dataSM('parent-a').addClass('highlighted'); 14114 } 14115 // min/max-width fix - no way to rely purely on CSS as all UL's are nested 14116 if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) { 14117 if (!IElt8) { 14118 $sub.css({ width: ($sub.hasClass('mega-menu-inner') || $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 14119 if (this.opts.subMenusMinWidth) { 14120 $sub.css('min-width', this.opts.subMenusMinWidth); 14121 } 14122 if (this.opts.subMenusMaxWidth) { 14123 var noMaxWidth = this.getWidth($sub); 14124 if ( ! $sub.hasClass('mega-menu-inner') && ! $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)') ) { 14125 $sub.css('max-width', this.opts.subMenusMaxWidth); 14126 } 14127 if (noMaxWidth > this.getWidth($sub)) { 14128 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 14129 } 14130 } 14131 // IE6,7 14132 } else { 14133 $sub.children().css('styleFloat', 'none'); 14134 if (IE6) { 14135 $sub.width(this.opts.subMenusMinWidth ? this.opts.subMenusMinWidth : 1) 14136 .children().children('a').css('white-space', 'nowrap'); 14137 } else { // IE7 14138 $sub.css({ width: ($sub.hasClass('mega-menu-inner') || $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap'); 14139 if (this.opts.subMenusMinWidth) { 14140 $sub.css('min-width', this.opts.subMenusMinWidth); 14141 } 14142 } 14143 if (this.opts.subMenusMaxWidth) { 14144 var noMaxWidth = $sub.width(); 14145 if (IE6) { 14146 var maxWidth = $sub.css({ width: this.opts.subMenusMaxWidth, overflowX: 'hidden', overflowY: 'hidden' }).width(); 14147 if (noMaxWidth > maxWidth) { 14148 $sub.css({ width: maxWidth, overflowX: 'visible', overflowY: 'visible' }).children().children('a').css('white-space', ''); 14149 } else { 14150 $sub.css({ width: noMaxWidth, overflowX: 'visible', overflowY: 'visible' }); 14151 } 14152 } else { // IE7 14153 if ( ! $sub.hasClass('mega-menu-inner') && ! $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)') ) { 14154 $sub.css('max-width', this.opts.subMenusMaxWidth); 14155 } 14156 if (noMaxWidth > $sub.width()) { 14157 $sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth); 14158 } else { 14159 $sub.width(noMaxWidth); 14160 } 14161 } 14162 } else { 14163 $sub.width($sub.width()); 14164 } 14165 $sub.children().css('styleFloat', 'left'); 14166 } 14167 } 14168 if ( ( ( ($sub.hasClass('mega-menu-inner') || $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)')) && $('body').hasClass('scrollable-megamenu') ) ) && UNCODE.wwidth > UNCODE.mediaQuery ) { 14169 var $nav = $('.navbar-main'), 14170 navH = 0, 14171 navTop = 0, 14172 $vmenu = $('body.vmenu .vmenu-container, body.menu-overlay .vmenu-container, body.menu-offcanvas .vmenu-container'); 14173 if ( $nav.length && typeof $nav[0] !== 'undefined' ) { 14174 var navRect = $nav[0].getBoundingClientRect(); 14175 navH = navRect.height; 14176 navTop = navRect.top; 14177 } 14178 if ( ! $vmenu.length ) { 14179 $sub.css({ maxHeight: UNCODE.wheight - navH }); 14180 if ( $('.megamenu-block-wrapper', $sub).length ) { 14181 $sub.find('> li').addClass('has-scroll').css({ maxHeight: UNCODE.wheight - navH }); 14182 } 14183 } 14184 } 14185 this.menuPosition($sub); 14186 // insert IE iframe shim 14187 if ($sub.dataSM('ie-shim')) { 14188 $sub.dataSM('ie-shim').insertBefore($sub); 14189 } 14190 var complete = function() { 14191 // fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used 14192 $sub.css('overflow', ''); 14193 }; 14194 // if sub is collapsible (mobile view) 14195 if (this.isCollapsible()) { 14196 if (this.opts.collapsibleShowFunction) { 14197 this.opts.collapsibleShowFunction.call(this, $sub, complete); 14198 } else { 14199 $sub.show(this.opts.collapsibleShowDuration, complete); 14200 } 14201 } else { 14202 if (this.opts.showFunction) { 14203 this.opts.showFunction.call(this, $sub, complete); 14204 } else { 14205 $sub.show(this.opts.showDuration, complete); 14206 } 14207 } 14208 // save new sub menu for this level 14209 this.visibleSubMenus[$sub.dataSM('level') - 1] = $sub; 14210 this.$root.triggerHandler('show.smapi', $sub[0]); 14211 } 14212 }, 14213 popupHide: function(noHideTimeout) { 14214 if (this.hideTimeout) { 14215 clearTimeout(this.hideTimeout); 14216 this.hideTimeout = 0; 14217 } 14218 var self = this; 14219 this.hideTimeout = setTimeout(function() { 14220 self.menuHideAll(); 14221 }, noHideTimeout ? 1 : this.opts.hideTimeout); 14222 }, 14223 popupShow: function(left, top) { 14224 if (!this.opts.isPopup) { 14225 alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'); 14226 return; 14227 } 14228 if (this.hideTimeout) { 14229 clearTimeout(this.hideTimeout); 14230 this.hideTimeout = 0; 14231 } 14232 this.menuFixLayout(this.$root); 14233 this.$root.stop(true, true); 14234 if (!this.$root.is(':visible')) { 14235 this.$root.css({ left: left, top: top }); 14236 // IE iframe shim 14237 this.menuIframeShim(this.$root); 14238 if (this.$root.dataSM('ie-shim')) { 14239 this.$root.dataSM('ie-shim').css({ zIndex: this.$root.css('z-index'), width: this.getWidth(this.$root), height: this.getHeight(this.$root), left
14239: left, top: top }).insertBefore(this.$root); 14240 } 14241 // show menu 14242 if (this.opts.showFunction) { 14243 this.opts.showFunction.call(this, this.$root); 14244 } else { 14245 this.$root.show(this.opts.showDuration); 14246 } 14247 this.visibleSubMenus[0] = this.$root; 14248 } 14249 }, 14250 refresh: function() { 14251 this.menuHideAll(); 14252 this.$root.find('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').each(function() { 14253 var $this = $(this); 14254 if ($this.dataSM('scroll-arrows')) { 14255 $this.dataSM('scroll-arrows').remove(); 14256 } 14257 }) 14258 .removeDataSM('in-mega') 14259 .removeDataSM('shown-before') 14260 .removeDataSM('ie-shim') 14261 .removeDataSM('scroll-arrows') 14262 .removeDataSM('parent-a') 14263 .removeDataSM('level') 14264 .removeDataSM('beforefirstshowfired'); 14265 this.$root.find('a.has-submenu').removeClass('has-submenu') 14266 .parent().removeDataSM('sub'); 14267 if (this.opts.subIndicators) { 14268 this.$root.find('span.sub-arrow').remove(); 14269 } 14270 if (this.opts.markCurrentItem) { 14271 this.$root.find('a.current').removeClass('current'); 14272 } 14273 this.subMenus = []; 14274 this.init(true); 14275 }, 14276 rootOut: function(e) { 14277 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 14278 return; 14279 } 14280 if (this.hideTimeout) { 14281 clearTimeout(this.hideTimeout); 14282 this.hideTimeout = 0; 14283 } 14284 if (!this.opts.showOnClick || !this.opts.hideOnClick) { 14285 var self = this; 14286 this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout); 14287 } 14288 }, 14289 rootOver: function(e) { 14290 if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) { 14291 return; 14292 } 14293 if (this.hideTimeout) { 14294 clearTimeout(this.hideTimeout); 14295 this.hideTimeout = 0; 14296 } 14297 }, 14298 winResize: function(e) { 14299 if (!this.handleEvents()) { 14300 // we still need to resize the disable overlay if it's visible 14301 if (this.$disableOverlay) { 14302 var pos = this.$root.offset(); 14303 this.$disableOverlay.css({ 14304 top: pos.top, 14305 left: pos.left, 14306 width: this.$root.outerWidth(), 14307 height: this.$root.outerHeight() 14308 }); 14309 } 14310 return; 14311 } 14312 // hide sub menus on resize - on mobile do it only on orientation change 14313 if (!this.isCollapsible() && (!('onorientationchange' in window) || e.type == 'orientationchange')) { 14314 if (this.activatedItems.length) { 14315 this.activatedItems[this.activatedItems.length - 1][0].blur(); 14316 } 14317 this.menuHideAll(); 14318 } 14319 } 14320 } 14321 }); 14322 14323 $.fn.dataSM = function(key, val) { 14324 if (val) { 14325 return this.data(key + '_smartmenus', val); 14326 } 14327 return this.data(key + '_smartmenus'); 14328 } 14329 14330 $.fn.removeDataSM = function(key) { 14331 return this.removeData(key + '_smartmenus'); 14332 } 14333 14334 $.fn.smartmenus = function(options) { 14335 if (typeof options == 'string') { 14336 var args = arguments, 14337 method = options; 14338 Array.prototype.shift.call(args); 14339 return this.each(function() { 14340 var smartmenus = $(this).data('smartmenus'); 14341 if (smartmenus && smartmenus[method]) { 14342 smartmenus[method].apply(smartmenus, args); 14343 } 14344 }); 14345 } 14346 var opts = $.extend({}, $.fn.smartmenus.defaults, options); 14347 return this.each(function() { 14348 new $.SmartMenus(this, opts); 14349 }); 14350 } 14351 14352 // default settings 14353 $.fn.smartmenus.defaults = { 14354 isPopup: false, // is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar 14355 mainMenuSubOffsetX: 0, // pixels offset from default position
14356 mainMenuSubOffsetY: 0, // pixels offset from default position 14357 subMenusSubOffsetX: 0, // pixels offset from default position 14358 subMenusSubOffsetY: 0, // pixels offset from default position 14359 subMenusMinWidth: false, //'10em', // min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 14360 subMenusMaxWidth: false, //'20em', // max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored 14361 subIndicators: true, // create sub menu indicators - creates a SPAN and inserts it in the A 14362 subIndicatorsPos: 'prepend', // position of the SPAN relative to the menu item content ('prepend', 'append') 14363 subIndicatorsText: '+', // [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too) 14364 scrollStep: 30, // pixels step when scrolling long sub menus that do not fit in the viewport height 14365 scrollInterval: 30, // interval between each scrolling step 14366 scrollAccelerate: true, // accelerate scrolling or use a fixed step 14367 showTimeout: 250, // timeout before showing the sub menus 14368 hideTimeout: 500, // timeout before hiding the sub menus 14369 showDuration: 0, // duration for show animation - set to 0 for no animation - matters only if showFunction:null 14370 showFunction: null, // custom function to use when showing a sub menu (the default is the jQuery 'show') 14371 // don't forget to call complete() at the end of whatever you do 14372 // e.g.: function($ul, complete) { $ul.fadeIn(250, complete); } 14373 hideDuration: 0, // duration for hide animation - set to 0 for no animation - matters only if hideFunction:null 14374 hideFunction: function($ul, complete) { $ul.fadeOut(200, complete); }, // custom function to use when hiding a sub menu (the default is the jQuery 'hide') 14375 // don't forget to call complete() at the end of whatever you do 14376 // e.g.: function($ul, complete) { $ul.fadeOut(250, complete); } 14377 collapsibleShowDuration:0, // duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null 14378 collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); }, // custom function to use when showing a collapsible sub menu 14379 // (i.e. when mobile styles are used to make the sub menus collapsible) 14380 collapsibleHideDuration:0, // duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null 14381 collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); }, // custom function to use when hiding a collapsible sub menu 14382 // (i.e. when mobile styles are used to make the sub menus collapsible) 14383 showOnClick: false, // show the first-level sub menus onclick instead of onmouseover (matters only for mouse input) 14384 hideOnClick: true, // hide the sub menus on click/tap anywhere on the page 14385 keepInViewport: true, // reposition the sub menus if needed to make sure they always appear inside the viewport 14386 keepHighlighted: true, // keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's) 14387 markCurrentItem: false, // automatically add the 'current' class to the A element of the item linking to the current URL 14388 markCurrentTree: true, // add the 'current' class also to the A elements of all ancestor items of the current item 14389 rightToLeftSubMenus: false, // right to left display of the sub menus (check the CSS for the sub indicators' position) 14390 bottomToTopSubMenus: false, // bottom to top display of the sub menus 14391 overlapControlsInIE: true // make sure sub menus appear on top of special OS controls in IE (i.e. SELECT, OBJECT, EMBED, etc.) 14392 }; 14393 14394})(jQuery); 14395/* 14396 * jQuery Easing v1.4.1 - http://gsgd.co.uk/sandbox/jquery/easing/ 14397 * Open source under the BSD License. 14398 * Copyright © 2008 George McGinley Smith 14399 * All rights reserved. 14400 * https://raw.github.com/gdsmith/jquery.easing/master/LICENSE 14401*/ 14402 14403/* globals jQuery, define, module, require */ 14404(function (factory) { 14405 if (typeof define === "function" && define.amd) { 14406 define(['jquery'], function ($) { 14407 return factory($); 14408 }); 14409 } else if (typeof module === "object" && typeof module.exports === "object") { 14410 module.exports = factory(require('jquery')); 14411 } else { 14412 factory(jQuery); 14413 } 14414})(function($){ 14415 14416 // Preserve the original jQuery "swing" easing as "jswing" 14417 if (typeof $.easing !== 'undefined') { 14418 $.easing['jswing'] = $.easing['swing']; 14419 } 14420 14421 var pow = Math.pow, 14422 sqrt = Math.sqrt, 14423 sin = Math.sin, 14424 cos = Math.cos, 14425 PI = Math.PI,
14426 c1 = 1.70158, 14427 c2 = c1 * 1.525, 14428 c3 = c1 + 1, 14429 c4 = ( 2 * PI ) / 3, 14430 c5 = ( 2 * PI ) / 4.5; 14431 14432 // x is the fraction of animation progress, in the range 0..1 14433 function bounceOut(x) { 14434 var n1 = 7.5625, 14435 d1 = 2.75; 14436 if ( x < 1/d1 ) { 14437 return n1*x*x; 14438 } else if ( x < 2/d1 ) { 14439 return n1*(x-=(1.5/d1))*x + .75; 14440 } else if ( x < 2.5/d1 ) { 14441 return n1*(x-=(2.25/d1))*x + .9375; 14442 } else { 14443 return n1*(x-=(2.625/d1))*x + .984375; 14444 } 14445 } 14446 14447 $.extend( $.easing, { 14448 def: 'easeOutQuad', 14449 swing: function (x) { 14450 return $.easing[$.easing.def](x); 14451 }, 14452 easeInQuad: function (x) { 14453 return x * x; 14454 }, 14455 easeOutQuad: function (x) { 14456 return 1 - ( 1 - x ) * ( 1 - x ); 14457 }, 14458 easeInOutQuad: function (x) { 14459 return x < 0.5 ? 14460 2 * x * x : 14461 1 - pow( -2 * x + 2, 2 ) / 2; 14462 }, 14463 easeInCubic: function (x) { 14464 return x * x * x; 14465 }, 14466 easeOutCubic: function (x) { 14467 return 1 - pow( 1 - x, 3 ); 14468 }, 14469 easeInOutCubic: function (x) { 14470 return x < 0.5 ? 14471 4 * x * x * x : 14472 1 - pow( -2 * x + 2, 3 ) / 2; 14473 }, 14474 easeInQuart: function (x) { 14475 return x * x * x * x; 14476 }, 14477 easeOutQuart: function (x) { 14478 return 1 - pow( 1 - x, 4 ); 14479 }, 14480 easeInOutQuart: function (x) { 14481 return x < 0.5 ? 14482 8 * x * x * x * x : 14483 1 - pow( -2 * x + 2, 4 ) / 2; 14484 }, 14485 easeInQuint: function (x) { 14486 return x * x * x * x * x; 14487 }, 14488 easeOutQuint: function (x) { 14489 return 1 - pow( 1 - x, 5 ); 14490 }, 14491 easeInOutQuint: function (x) { 14492 return x < 0.5 ? 14493 16 * x * x * x * x * x : 14494 1 - pow( -2 * x + 2, 5 ) / 2; 14495 }, 14496 easeInSine: function (x) { 14497 return 1 - cos( x * PI/2 ); 14498 }, 14499 easeOutSine: function (x) { 14500 return sin( x * PI/2 ); 14501 }, 14502 easeInOutSine: function (x) { 14503 return -( cos( PI * x ) - 1 ) / 2; 14504 }, 14505 easeInExpo: function (x) { 14506 return x === 0 ? 0 : pow( 2, 10 * x - 10 ); 14507 }, 14508 easeOutExpo: function (x) { 14509 return x === 1 ? 1 : 1 - pow( 2, -10 * x ); 14510 }, 14511 easeInOutExpo: function (x) { 14512 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 14513 pow( 2, 20 * x - 10 ) / 2 : 14514 ( 2 - pow( 2, -20 * x + 10 ) ) / 2; 14515 }, 14516 easeInCirc: function (x) { 14517 return 1 - sqrt( 1 - pow( x, 2 ) ); 14518 }, 14519 easeOutCirc: function (x) { 14520 return sqrt( 1 - pow( x - 1, 2 ) ); 14521 }, 14522 easeInOutCirc: function (x) { 14523 return x < 0.5 ? 14524 ( 1 - sqrt( 1 - pow( 2 * x, 2 ) ) ) / 2 : 14525 ( sqrt( 1 - pow( -2 * x + 2, 2 ) ) + 1 ) / 2; 14526 }, 14527 easeInElastic: function (x) { 14528 return x === 0 ? 0 : x === 1 ? 1 : 14529 -pow( 2, 10 * x - 10 ) * sin( ( x * 10 - 10.75 ) * c4 ); 14530 }, 14531 easeOutElastic: function (x) { 14532 return x === 0 ? 0 : x === 1 ? 1 : 14533 pow( 2, -10 * x ) * sin( ( x * 10 - 0.75 ) * c4 ) + 1; 14534 }, 14535 easeInOutElastic: function (x) { 14536 return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? 14537 -( pow( 2, 20 * x - 10 ) * sin( ( 20 * x - 11.125 ) * c5 )) / 2 : 14538 pow( 2, -20 * x + 10 ) * sin( ( 20 * x - 11.125 ) * c5 ) / 2 + 1; 14539 }, 14540 easeInBack: function (x) { 14541 return c3 * x * x * x - c1 * x * x; 14542 }, 14543 easeOutBack: function (x) { 14544 return 1 + c3 * pow( x - 1, 3 ) + c1 * pow( x - 1, 2 ); 14545 }, 14546 easeInOutBack: function (x) { 14547 return x < 0.5 ? 14548 ( pow( 2 * x, 2 ) * ( ( c2 + 1 ) * 2 * x - c2 ) ) / 2 : 14549 ( pow( 2 * x - 2, 2 ) *( ( c2 + 1 ) * ( x * 2 - 2 ) + c2 ) + 2 ) / 2; 14550 }, 14551 easeInBounce: function (x) { 14552 return 1 - bounceOut( 1 - x ); 14553 }, 14554 easeOutBounce: bounceOut, 14555 easeInOutBounce: function (x) { 14556 return x < 0.5 ? 14557 ( 1 - bounceOut( 1 - 2 * x ) ) / 2 : 14558 ( 1 + bounceOut( 2 * x - 1 ) ) / 2; 14559 } 14560 }); 14561 return $; 14562}); 14563 14564/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) 14565 * Licensed under the MIT License (LICENSE.txt). 14566 * 14567 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 14568 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 14569 * Thanks to: Seamus Leahy for adding deltaX and deltaY 14570 * 14571 * Version: 3.0.6 14572 * 14573 * Requires: 1.2.2+ 14574 */ 14575(function($) { 14576 var types = ['DOMMouseScroll', 'mousewheel']; 14577 if ($.event.fixHooks) { 14578 for (var i = types.length; i;) { 14579 $.event.fixHooks[types[--i]] = $.event.mouseHooks; 14580 } 14581 } 14582 $.event.special.mousewheel = { 14583 setup: function() { 14584 if (this.addEventListener) { 14585 for (var i = types.length; i;) { 14586 this.addEventListener(types[--i], handler, false); 14587 } 14588 } else { 14589 this.onmousewheel = handler; 14590 } 14591 }, 14592 teardown: function() { 14593 if (this.removeEventListener) { 14594 for (var i = types.length; i;) { 14595 this.removeEventListener(types[--i], handler, false); 14596 } 14597 } else { 14598 this.onmousewheel = null; 14599 } 14600 } 14601 }; 14602 $.fn.extend({ 14603 mousewheel: function(fn) { 14604 return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); 14605 }, 14606 unmousewheel: function(fn) { 14607 return this.unbind("mousewheel", fn); 14608 } 14609 }); 14610 14611 function handler(event) { 14612 var orgEvent = event || window.event, 14613 args = [].slice.call(arguments, 1), 14614 delta = 0, 14615 returnValue = true, 14616 deltaX = 0, 14617 deltaY = 0; 14618 event = $.event.fix(orgEvent); 14619 event.type = "mousewheel"; 14620 // Old school scrollwheel delta 14621 if (orgEvent.wheelDelta) { 14622 delta = orgEvent.wheelDelta / 120; 14623 } 14624 if (orgEvent.detail) { 14625 delta = -orgEvent.detail / 3; 14626 } 14627 // New school multidimensional scroll (touchpads) deltas 14628 deltaY = delta; 14629 // Gecko 14630 if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) { 14631 deltaY = 0; 14632 deltaX = -1 * delta; 14633 } 14634 // Webkit 14635 if (orgEvent.wheelDeltaY !== undefined) { 14636 deltaY = orgEvent.wheelDeltaY / 120; 14637 } 14638 if (orgEvent.wheelDeltaX !== undefined) { 14639 deltaX = -1 * orgEvent.wheelDeltaX / 120; 14640 } 14641 // Add event and delta to the front of the arguments 14642 args.unshift(event, delta, deltaX, deltaY); 14643 return ($.event.dispatch || $.event.handle).apply(this, args); 14644 } 14645})(jQuery); 14646/** 14647 * jQuery iLightBox - Revolutionary Lightbox Plugin 14648 * http://www.ilightbox.net/ 14649 * 14650 * @version: 2.2.4 - October 14, 2017 14651 * 14652 * @author: iProDev (Hemn Chawroka) 14653 * http://www.iprodev.com/ 14654 * 14655 */ 14656(function($, window, undefined) { 14657 14658 var extensions = { 14659 flash: ['swf'], 14660 image: ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe', 'webp'], 14661 iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'jsp', 'php', 'pl', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt'], 14662 video: ['avi', 'mov', 'mpg', 'mpeg', 'movie', 'mp4', 'webm', 'ogv', 'ogg', '3gp', 'm4v'] 14663 }, 14664 14665 // Global DOM elements 14666 $win = $(window), 14667 $doc = $(document), 14668
14669 // Support indicators 14670 browser, 14671 transform, 14672 gpuAcceleration, 14673 fullScreenApi = '', 14674 userAgent = navigator.userAgent || navigator.vendor || window.opera, 14675 supportTouch = "ontouchstart" in window || navigator.msMaxTouchPoints || (navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1), 14676 ishybrid = navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1, 14677 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)), 14678 14679 // Events 14680 clickEvent = ishybrid ? "itap.iLightBox click.iLightBox" : supportTouch ? "itap.iLightBox" : "click.iLightBox", 14681 touchStartEvent = ishybrid ? "touchstart.iLightBox mousedown.iLightBox" : supportTouch ? "touchstart.iLightBox" : "mousedown.iLightBox", 14682 touchStopEvent = ishybrid ? "touchend.iLightBox mouseup.iLightBox" : supportTouch ? "touchend.iLightBox" : "mouseup.iLightBox", 14683 touchMoveEvent = ishybrid ? "touchmove.iLightBox mousemove.iLightBox" : supportTouch ? "touchmove.iLightBox" : "mousemove.iLightBox", 14684 14685 // Math shorthands 14686 abs = Math.abs, 14687 sqrt = Math.sqrt, 14688 round = Math.round, 14689 max = Math.max, 14690 min = Math.min, 14691 floor = Math.floor, 14692 random = Math.random, 14693 14694 pluginspages = { 14695 quicktime: 'http://www.apple.com/quicktime/download', 14696 flash: 'http://www.adobe.com/go/getflash' 14697 }, 14698 14699 iLightBox = function(el, options, items, instant) { 14700 var iL = this; 14701 14702 iL.options = options, 14703 iL.selector = options.selector || el, 14704 iL.context = document, 14705 iL.instant = instant; 14706 14707 if (items.length < 1) iL.attachItems(); 14708 else iL.items = items; 14709 14710 iL.vars = { 14711 total: iL.items.length, 14712 start: 0, 14713 current: null, 14714 next: null, 14715 prev: null, 14716 BODY: $('body'), 14717 loadRequests: 0, 14718 overlay: $('<div class="ilightbox-overlay"></div>'), 14719 loader: $('<div class="ilightbox-loader"><div></div></div>'), 14720 toolbar: $('<div class="ilightbox-toolbar"></div>'), 14721 innerToolbar: $('<div class="ilightbox-inner-toolbar"></div>'), 14722 title: $('<div class="ilightbox-title"></div>'), 14723 closeButton: $('<a class="ilightbox-close" title="' + iL.options.text.close + '"></a>'), 14724 fullScreenButton: $('<a class="ilightbox-fullscreen" title="' + iL.options.text.enterFullscreen + '"></a>'), 14725 innerPlayButton: $('<a class="ilightbox-play" title="' + iL.options.text.slideShow + '"></a>'), 14726 innerNextButton: $('<a class="ilightbox-next-button" title="' + iL.options.text.next + '"></a>'), 14727 innerPrevButton: $('<a class="ilightbox-prev-button" title="' + iL.options.text.previous + '"></a>'), 14728 holder: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + '" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 14729 nextPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-next" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 14730 prevPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-prev" ondragstart="return false;"><div class="ilightbox-container"></div></div>'), 14731 nextButton: $('<a class="ilightbox-button ilightbox-next-button" ondragstart="return false;" title="' + iL.options.text.next + '"><span></span></a>'), 14732 prevButton: $('<a class="ilightbox-button ilightbox-prev-button" ondragstart="return false;" title="' + iL.options.text.previous + '"><span></span></a>'),
14733 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>'), 14734 thumbs: false, 14735 nextLock: false, 14736 prevLock: false, 14737 hashLock: false, 14738 isMobile: false, 14739 mobileMaxWidth: 980, 14740 isInFullScreen: false, 14741 isSwipe: false, 14742 mouseID: 0, 14743 cycleID: 0, 14744 isPaused: 0, 14745 captionHeight: 39, 14746 }; 14747 14748 // Hideable elements with mousemove event 14749 iL.vars.hideableElements = iL.vars.nextButton.add(iL.vars.prevButton); 14750 14751 iL.normalizeItems(); 14752 14753 //Check necessary plugins 14754 iL.availPlugins(); 14755 14756 //Set startFrom 14757 iL.options.startFrom = (iL.options.startFrom > 0 && iL.options.startFrom >= iL.vars.total) ? iL.vars.total - 1 : iL.options.startFrom; 14758 14759 //If randomStart 14760 iL.options.startFrom = (iL.options.randomStart) ? floor(random() * iL.vars.total) : iL.options.startFrom; 14761 iL.vars.start = iL.options.startFrom; 14762 14763 if (instant) iL.instantCall(); 14764 else iL.patchItemsEvents(); 14765 14766 if (iL.options.linkId) { 14767 iL.hashChangeHandler(); 14768 $win.iLightBoxHashChange(function() { 14769 iL.hashChangeHandler(); 14770 }); 14771 } 14772 14773 if (supportTouch) { 14774 var RegExp = /(click|mouseenter|mouseleave|mouseover|mouseout)/ig, 14775 replace = "itap"; 14776 iL.options.caption.show = iL.options.caption.show.replace(RegExp, replace), 14777 iL.options.caption.hide = iL.options.caption.hide.replace(RegExp, replace), 14778 iL.options.social.show = iL.options.social.show.replace(RegExp, replace), 14779 iL.options.social.hide = iL.options.social.hide.replace(RegExp, replace); 14780 } 14781 14782 if (iL.options.controls.arrows || $(window).width() < UNCODE.mediaQuery) { 14783 $.extend(iL.options.styles, { 14784 nextOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 14785 prevOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4, 14786 nextOpacity: 0, 14787 prevOpacity: 0 14788 }); 14789 } 14790 }; 14791 14792 //iLightBox helpers 14793 iLightBox.prototype = { 14794 showLoader: function() { 14795 var iL = this; 14796 iL.vars.loadRequests += 1; 14797 if (iL.options.path.toLowerCase() == "horizontal") iL.vars.loader.addClass('ilightbox-show').stop().animate({ 14798 //top: '-30px' 14799 opacity: '1' 14800 }, iL.options.show.speed, 'easeOutCirc'); 14801 else iL.vars.loader.addClass('ilightbox-show').stop().animate({ 14802 //left: '-30px' 14803 opacity: '1' 14804 }, iL.options.show.speed, 'easeOutCirc'); 14805 }, 14806 14807 hideLoader: function() { 14808 var iL = this; 14809 iL.vars.loadRequests -= 1; 14810 iL.vars.loadRequests = (iL.vars.loadRequests < 0) ? 0 : iL.vars.loadRequests; 14811 if (iL.options.path.toLowerCase() == "horizontal") { 14812 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 14813 //top: '-192px' 14814 opacity: '0' 14815 }, iL.options.show.speed, 'easeInCirc'); 14816 } else { 14817 if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({ 14818 //left: '-192px' 14819 opacity: '0' 14820 }, iL.options.show.speed, 'easeInCirc'); 14821 } 14822 }, 14823 14824 createUI: function() { 14825 var iL = this; 14826 14827 iL.ui = { 14828 currentElement: iL.vars.holder, 14829 nextElement: iL.vars.nextPhoto, 14830 prevElement: iL.vars.prevPhoto, 14831 currentItem: iL.vars.current, 14832 nextItem: iL.vars.next, 14833 prevItem: iL.vars.prev, 14834 hide: function() { 14835 iL.closeAction(); 14836 }, 14837 refresh: function() { 14838 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 14839 }, 14840 fullscreen: function() { 14841 iL.fullScreenAction(); 14842 } 14843 }; 14844 }, 14845 14846 attachItems: function() { 14847 var iL = this, 14848 itemsObject = new Array(), 14849 items = new Array(); 14850 14851 $(iL.selector, iL.context).each(function() { 14852 var t = $(this), 14853 URL = t.attr(iL.options.attr) || null, 14854 options = t.data("options") && eval("({" + t.data("options") + "})") || {}, 14855 caption = t.data('caption'), 14856 title = t.data('title'), 14857 type = t.data('type') || getTypeByExtension(URL), 14858 clone = t.data('lbox-clone') || false; 14859 14860 //Uncode addition ##START## 14861 if (type === false) { 14862 return; 14863 } 14864 //Uncode addition ##END## 14865 14866 if (t.data('lbox-clone') != undefined) return; 14867 14868 //Uncode addition ##START## 14869 if ( typeof t.attr('data-album') != 'undefined' && t.attr('data-album') != '' ) { 14870 var ALBUM_URLS = JSON.parse(t.attr('data-album')), 14871 URL_i, 14872 URLS_LENGHT = ALBUM_URLS.length; 14873 14874 for (URL_i = 0; URL_i < URLS_LENGHT; URL_i++) { 14875 if ( typeof ALBUM_URLS[URL_i].url !== 'undefined' && ALBUM_URLS[URL_i].url != '' ) { 14876 var item_opts = 'width:' + ALBUM_URLS[URL_i].width + ',height:' + ALBUM_URLS[URL_i].height + ',thumbnail: \'' + ALBUM_URLS[URL_i].thumbnail + '\''; 14877 item_opts = item_opts && eval("({" + item_opts + "})") || {}, 14878 items.push({ 14879 URL: ALBUM_URLS[URL_i].url, 14880 caption: ALBUM_URLS[URL_i].caption, 14881 title: ALBUM_URLS[URL_i].title, 14882 type: getTypeByExtension(ALBUM_URLS[URL_i].url), 14883 options: item_opts, 14884 clone: clone 14885 }); 14886 var newT = t; 14887 newT.attr('href',ALBUM_URLS[URL_i].url); 14888 if (!iL.instant) itemsObject.push(newT); 14889 } 14890 } 14891 } else { 14892 //Uncode addition ##END## 14893 items.push({ 14894 URL: URL, 14895 caption: caption, 14896 title: title, 14897 type: type, 14898 options: options, 14899 clone: clone 14900 }); 14901 } 14902 14903 14904 if (iL.vars != undefined) iL.vars.total = items.length; 14905 14906 if (!iL.instant) itemsObject.push(t); 14907 }); 14908 14909 iL.items = items, 14910 iL.itemsObject = itemsObject; 14911 14912 }, 14913 14914 normalizeItems: function() { 14915 var iL = this, 14916 newItems = new Array(); 14917 14918 $.each(iL.items, function(key, val) { 14919 14920 if (typeof val == "string") val = { 14921 url: val 14922 }; 14923 14924 var URL = val.url || val.URL || null, 14925 options = val.options || {}, 14926 caption = val.caption || null, 14927 title = val.title || null, 14928 type = (val.type) ? val.type.toLowerCase() : getTypeByExtension(URL), 14929 ext = (typeof URL != 'object') ? getExtension(URL) : ''; 14930 14931 options.thumbnail = options.thumbnail || ((type == "image") ? URL : null),
14932 options.videoType = options.videoType || null, 14933 options.skin = options.skin || iL.options.skin, 14934 options.width = options.width || null, 14935 options.height = options.height || null, 14936 options.mousewheel = (typeof options.mousewheel != 'undefined') ? options.mousewheel : true, 14937 options.swipe = (typeof options.swipe != 'undefined') ? options.swipe : true, 14938 options.social = (typeof options.social != 'undefined') ? options.social : iL.options.social.buttons && $.extend({}, {}, iL.options.social.buttons); 14939 14940 if (type == "video") { 14941 options.html5video = (typeof options.html5video != 'undefined') ? options.html5video : {}; 14942 14943 options.html5video.webm = options.html5video.webm || options.html5video.WEBM || null; 14944 options.html5video.controls = (typeof options.html5video.controls != 'undefined') ? options.html5video.controls : "controls"; 14945 options.html5video.preload = options.html5video.preload || "metadata"; 14946 options.html5video.autoplay = (typeof options.html5video.autoplay != 'undefined') ? options.html5video.autoplay : false; 14947 //UNCODE addition 14948 options.html5video.loop = (typeof options.html5video.loop != 'undefined') ? options.html5video.loop : false; 14949 } 14950 14951 if (!options.width || !options.height) { 14952 if (type == "video") options.width = 1280, options.height = 720; 14953 else if (type == "iframe") options.width = '100%', options.height = '90%'; 14954 else if (type == "flash") options.width = 1280, options.height = 720; 14955 } 14956 14957 delete val.url; 14958 val.index = key; 14959 val.URL = URL; 14960 val.caption = caption; 14961 val.title = title; 14962 val.type = type; 14963 val.options = options; 14964 val.ext = ext; 14965 14966 newItems.push(val); 14967 }); 14968 14969 iL.items = newItems; 14970 }, 14971 14972 instantCall: function() { 14973 var iL = this, 14974 key = iL.vars.start; 14975 14976 iL.vars.current = key; 14977 iL.vars.next = (iL.items[key + 1]) ? key + 1 : null; 14978 iL.vars.prev = (iL.items[key - 1]) ? key - 1 : null; 14979 14980 iL.addContents(); 14981 iL.patchEvents(); 14982 }, 14983 14984 addContents: function() { 14985 var iL = this, 14986 vars = iL.vars, 14987 opts = iL.options, 14988 viewport = getViewport(), 14989 path = opts.path.toLowerCase(), 14990 recognizingItems = vars.total > 0 && iL.items.filter(function(e, i, arr) { 14991 return ['image', 'flash', 'video'].indexOf(e.type) === -1 && typeof e.recognized === 'undefined' && (opts.smartRecognition || e.options.smartRecognition); 14992 }), 14993 needRecognition = recognizingItems.length > 0; 14994 14995 if (opts.mobileOptimizer && !opts.innerToolbar) 14996 vars.isMobile = viewport.width <= vars.mobileMaxWidth; 14997 14998 vars.overlay.addClass(opts.skin).hide().css('opacity', opts.overlay.opacity); 14999 15000 if (opts.linkId) 15001 vars.overlay[0].setAttribute('linkid', opts.linkId); 15002 15003 //Add Toolbar Buttons 15004 if (opts.controls.toolbar) { 15005 vars.toolbar.addClass(opts.skin).append(vars.closeButton); 15006 if (opts.controls.fullscreen) 15007 vars.toolbar.append(vars.fullScreenButton); 15008 if (opts.controls.slideshow) 15009 vars.toolbar.append(vars.innerPlayButton); 15010 if (vars.total > 1) 15011 vars.toolbar.append(vars.innerPrevButton).append(vars.innerNextButton); 15012 } 15013 15014 //Append elements to body 15015 vars.BODY.addClass('ilightbox-noscroll').append(vars.overlay).append(vars.loader).append(vars.holder).append(vars.nextPhoto).append(vars.prevPhoto); 15016 15017 if (!opts.innerToolbar) 15018 vars.BODY.append(vars.toolbar); 15019 if (opts.controls.arrows) 15020 vars.BODY.append(vars.nextButton).append(vars.prevButton); 15021 15022 if (opts.controls.thumbnail && vars.total > 1) { 15023 vars.BODY.append(vars.thumbnails); 15024 vars.thumbnails.addClass(opts.skin).addClass('ilightbox-' + path); 15025 $('div.ilightbox-thumbnails-grid', vars.thumbnails).empty(); 15026 vars.thumbs = true; 15027 } 15028 15029 //Configure loader and arrows 15030 var loaderCss = (opts.path.toLowerCase() == "horizontal") ? { 15031 left: parseInt((viewport.width / 2) - (vars.loader.outerWidth() / 2)) 15032 } : { 15033 top: parseInt((viewport.height / 2) - (vars.loader.outerHeight() / 2)) 15034 }; 15035 vars.loader.addClass(opts.skin).css(loaderCss); 15036 vars.nextButton.add(vars.prevButton).addClass(opts.skin); 15037 if (path == "horizontal") 15038 vars.loader.add(vars.nextButton).add(vars.prevButton).addClass('horizontal'); 15039 15040 // Configure arrow buttons 15041 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 15042 15043 if (!opts.infinite) { 15044 vars.prevButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 15045 15046 if (vars.current == 0) 15047 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 15048 if (vars.current >= vars.total - 1) 15049 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 15050 } 15051 15052 if (opts.show.effect) { 15053 vars.overlay.stop().fadeIn(opts.show.speed); 15054 vars.toolbar.stop().fadeIn(opts.show.speed); 15055 } else { 15056 vars.overlay.show(); 15057 vars.toolbar.show(); 15058 } 15059 15060 var length = recognizingItems.length; 15061 if (needRecognition) { 15062 iL.showLoader(); 15063 15064 $.each(recognizingItems, function(key, val) { 15065 var resultFnc = function(result) { 15066 var key = -1, 15067 filter = iL.items.filter(function(e, i, arr) { 15068 if (e.URL == result.url) 15069 key = i; 15070 15071 return e.URL == result.url; 15072 }), 15073 self = iL.items[key]; 15074 15075 if (result) 15076 $.extend(true, self, { 15077 URL: result.source, 15078 type: result.type, 15079 recognized: true, 15080 options: { 15081 html5video: result.html5video, 15082 width: (result.type == "image") ? 0 : (result.width || self.width), 15083 height: (result.type == "image") ? 0 : (result.height || self.height), 15084 thumbnail: self.options.thumbnail || result.thumbnail 15085 } 15086 }); 15087 15088 length--; 15089 15090 if (length == 0) { 15091 iL.hideLoader(); 15092 15093 vars.dontGenerateThumbs = false;
15094 iL.generateThumbnails(); 15095 15096 if (opts.show.effect) 15097 setTimeout(function() { 15098 iL.generateBoxes(); 15099 }, opts.show.speed); 15100 else 15101 iL.generateBoxes(); 15102 } 15103 }; 15104 15105 iL.ogpRecognition(this, resultFnc); 15106 }); 15107 } 15108 else { 15109 if (opts.show.effect) 15110 setTimeout(function() { 15111 iL.generateBoxes(); 15112 }, opts.show.speed); 15113 else 15114 iL.generateBoxes(); 15115 } 15116 15117 iL.createUI(); 15118 15119 window.iLightBox = { 15120 close: function() { 15121 iL.closeAction(); 15122 }, 15123 fullscreen: function() { 15124 iL.fullScreenAction(); 15125 }, 15126 moveNext: function() { 15127 iL.moveTo('next'); 15128 }, 15129 movePrev: function() { 15130 iL.moveTo('prev'); 15131 }, 15132 goTo: function(index) { 15133 iL.goTo(index); 15134 }, 15135 refresh: function() { 15136 iL.refresh(); 15137 }, 15138 reposition: function() { 15139 (arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto(); 15140 }, 15141 setOption: function(options) { 15142 iL.setOption(options); 15143 }, 15144 destroy: function() { 15145 iL.closeAction(); 15146 iL.dispatchItemsEvents(); 15147 } 15148 }; 15149 15150 if (opts.linkId) { 15151 vars.hashLock = true; 15152 window.location.hash = opts.linkId + '/' + vars.current; 15153 setTimeout(function() { 15154 vars.hashLock = false; 15155 }, 55); 15156 } 15157 15158 if (!opts.slideshow.startPaused) { 15159 iL.resume(); 15160 vars.innerPlayButton.removeClass('ilightbox-play').addClass('ilightbox-pause'); 15161 } 15162 15163 //Trigger the onOpen callback 15164 if (typeof iL.options.callback.onOpen == 'function') iL.options.callback.onOpen.call(iL); 15165 }, 15166 15167 loadContent: function(obj, opt, speed) { 15168 var iL = this, 15169 holder, item; 15170 15171 iL.createUI(); 15172 15173 obj.speed = speed || iL.options.effects.loadedFadeSpeed; 15174 15175 if (opt == 'current') { 15176 if (!obj.options.mousewheel) iL.vars.lockWheel = true; 15177 else iL.vars.lockWheel = false; 15178 15179 if (!obj.options.swipe) iL.vars.lockSwipe = true; 15180 else iL.vars.lockSwipe = false; 15181 } 15182 15183 switch (opt) { 15184 case 'current': 15185 holder = iL.vars.holder, item = iL.vars.current; 15186 break; 15187 case 'next': 15188 holder = iL.vars.nextPhoto, item = iL.vars.next; 15189 break; 15190 case 'prev': 15191 holder = iL.vars.prevPhoto, item = iL.vars.prev; 15192 break; 15193 } 15194 15195 holder.removeAttr('style class').addClass('ilightbox-holder' + (supportTouch ? ' supportTouch' : '')).addClass(obj.options.skin); 15196 $('div.ilightbox-inner-toolbar', holder).remove(); 15197 15198 if (obj.title || iL.options.innerToolbar) { 15199 var innerToolbar = iL.vars.innerToolbar.clone(); 15200 if (obj.title && iL.options.show.title) { 15201 var title = iL.vars.title.clone(); 15202 title.empty().html(obj.title); 15203 innerToolbar.append(title); 15204 } 15205 if (iL.options.innerToolbar) { 15206 innerToolbar.append((iL.vars.total > 1) ? iL.vars.toolbar.clone() : iL.vars.toolbar); 15207 } 15208 holder.prepend(innerToolbar); 15209 } 15210 15211 //console.warn('loadContent', arguments); 15212 15213 iL.loadSwitcher(obj, holder, item, opt); 15214 }, 15215 15216 loadSwitcher: function(obj, holder, item, opt) { 15217 var iL = this, 15218 opts = iL.options, 15219 api = { 15220 element: holder, 15221 position: item 15222 }; 15223 15224 switch (obj.type) { 15225 case 'image': 15226 //Trigger the onBeforeLoad callback 15227 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 15228 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 15229 15230 iL.loadImage(obj.URL, function(img) { 15231 //Trigger the onAfterLoad callback 15232 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 15233 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 15234 15235 var width = (img) ? img.width : 400, 15236 height = (img) ? img.height : 200; 15237 15238 holder.data({ 15239 naturalWidth: width, 15240 naturalHeight: height 15241 }); 15242 15243 $('div.ilightbox-container', holder).empty().append((img) ? '<img src="' + obj.URL + '" class="ilightbox-image" />' : '<span class="ilightbox-alert">' + opts.errors.loadImage + '</span>'); 15244 15245 //Trigger the onRender callback 15246 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 15247 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 15248 15249 iL.configureHolder(obj, opt, holder); 15250 }); 15251 15252 break; 15253
15254 case 'video': 15255 holder.data({ 15256 naturalWidth: obj.options.width, 15257 naturalHeight: obj.options.height 15258 }); 15259 15260 if (opt === 'current') { 15261 iL.addContent(holder, obj); 15262 15263 //Trigger the onRender callback 15264 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 15265 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 15266 } else { 15267 $('div.ilightbox-container', holder).empty(); 15268 } 15269 15270 iL.configureHolder(obj, opt, holder); 15271 15272 break; 15273 15274 case 'iframe': 15275 //iL.showLoader(); 15276 holder.data({ 15277 naturalWidth: obj.options.width, 15278 naturalHeight: obj.options.height 15279 }); 15280 15281 iL.configureHolder(obj, opt, holder); 15282 15283 if (opt === 'current') { 15284 var el = iL.addContent(holder, obj); 15285 15286 //Trigger the onRender callback 15287 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 15288 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 15289 15290 //Trigger the onBeforeLoad callback 15291 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 15292 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 15293 15294 el.bind('load', function() { 15295 //Trigger the onAfterLoad callback 15296 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 15297 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 15298 15299 //iL.hideLoader(); 15300 el.unbind('load'); 15301 }); 15302 } else { 15303 $('div.ilightbox-container', holder).empty(); 15304 } 15305 15306 break; 15307 15308 case 'inline': 15309 var el = $(obj.URL), 15310 content = iL.addContent(holder, obj), 15311 images = findImageInElement(holder); 15312 15313 holder.data({ 15314 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 15315 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 15316 }); 15317 content.children().eq(0).show(); 15318 15319 //Trigger the onRender callback 15320 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 15321 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 15322 15323 //Trigger the onBeforeLoad callback 15324 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 15325 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 15326 15327 iL.loadImage(images, function() { 15328 //Trigger the onAfterLoad callback 15329 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 15330 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 15331 15332 iL.configureHolder(obj, opt, holder); 15333 }); 15334 15335 break; 15336 15337 case 'flash': 15338 var el = iL.addContent(holder, obj); 15339 15340 holder.data({ 15341 naturalWidth: (iL.items[item].options.width || el.outerWidth()), 15342 naturalHeight: (iL.items[item].options.height || el.outerHeight()) 15343 }); 15344 15345 //Trigger the onRender callback 15346 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 15347 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 15348 15349 iL.configureHolder(obj, opt, holder); 15350 15351 break; 15352 15353 case 'ajax': 15354 var ajax = obj.options.ajax || {}; 15355 //Trigger the onBeforeLoad callback 15356 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 15357 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 15358 15359 iL.showLoader(); 15360 $.ajax({ 15361 url: obj.URL || opts.ajaxSetup.url, 15362 data: ajax.data || null, 15363 dataType: ajax.dataType || "html", 15364 type: ajax.type || opts.ajaxSetup.type, 15365 cache: ajax.cache || opts.ajaxSetup.cache, 15366 crossDomain: ajax.crossDomain || opts.ajaxSetup.crossDomain, 15367 global: ajax.global || opts.ajaxSetup.global, 15368 ifModified: ajax.ifModified || opts.ajaxSetup.ifModified, 15369 username: ajax.username || opts.ajaxSetup.username, 15370 password: ajax.password || opts.ajaxSetup.password, 15371 beforeSend: ajax.beforeSend || opts.ajaxSetup.beforeSend, 15372 complete: ajax.complete || opts.ajaxSetup.complete, 15373 success: function(data, textStatus, jqXHR) { 15374 iL.hideLoader(); 15375 15376 var el = $(data), 15377 container = $('div.ilightbox-container', holder), 15378 elWidth = iL.items[item].options.width || parseInt(el[0].getAttribute('width')), 15379 elHeight = iL.items[item].options.height || parseInt(el[0].getAttribute('height')), 15380 css = (el[0].getAttribute('width') && el[0].getAttribute('height')) ? { 15381 'overflow': 'hidden' 15382 } : {}; 15383 15384 container.empty().append($('<div class="ilightbox-wrapper"></div>').css(css).html(el)); 15385 holder.show().data({
15386 naturalWidth: (elWidth || container.outerWidth()), 15387 naturalHeight: (elHeight || container.outerHeight()) 15388 }).hide(); 15389 15390 //Trigger the onRender callback 15391 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 15392 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 15393 15394 var images = findImageInElement(holder); 15395 iL.loadImage(images, function() { 15396 //Trigger the onAfterLoad callback 15397 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 15398 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 15399 15400 iL.configureHolder(obj, opt, holder); 15401 }); 15402 15403 opts.ajaxSetup.success(data, textStatus, jqXHR); 15404 if (typeof ajax.success == 'function') ajax.success(data, textStatus, jqXHR); 15405 }, 15406 error: function(jqXHR, textStatus, errorThrown) { 15407 //Trigger the onAfterLoad callback 15408 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 15409 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 15410 15411 iL.hideLoader(); 15412 $('div.ilightbox-container', holder).empty().append('<span class="ilightbox-alert">' + opts.errors.loadContents + '</span>'); 15413 iL.configureHolder(obj, opt, holder); 15414 15415 opts.ajaxSetup.error(jqXHR, textStatus, errorThrown); 15416 if (typeof ajax.error == 'function') ajax.error(jqXHR, textStatus, errorThrown); 15417 } 15418 }); 15419 15420 break; 15421 15422 case 'html': 15423 var object = obj.URL, 15424 el 15425 container = $('div.ilightbox-container', holder); 15426 15427 if (object[0].nodeName) el = object.clone(); 15428 else { 15429 var dom = $(object); 15430 if (dom.selector) el = $('<div>' + dom + '</div>'); 15431 else el = dom; 15432 } 15433 15434 var elWidth = iL.items[item].options.width || parseInt(el.attr('width')), 15435 elHeight = iL.items[item].options.height || parseInt(el.attr('height')); 15436 15437 iL.addContent(holder, obj); 15438 15439 el.appendTo(document.documentElement).hide(); 15440 15441 //Trigger the onRender callback 15442 if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item); 15443 if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api); 15444 15445 var images = findImageInElement(holder); 15446 15447 //Trigger the onBeforeLoad callback 15448 if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item); 15449 if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api); 15450 15451 iL.loadImage(images, function() { 15452 //Trigger the onAfterLoad callback 15453 if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item); 15454 if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api); 15455 15456 holder.show().data({ 15457 naturalWidth: (elWidth || container.outerWidth()), 15458 naturalHeight: (elHeight || container.outerHeight()) 15459 }).hide(); 15460 el.remove(); 15461 15462 iL.configureHolder(obj, opt, holder); 15463 }); 15464 15465 break; 15466 } 15467 }, 15468 15469 configureHolder: function(obj, opt, holder) { 15470 var iL = this, 15471 vars = iL.vars, 15472 opts = iL.options; 15473 15474 if (opt != "current")(opt == "next") ? holder.addClass('ilightbox-next') : holder.addClass('ilightbox-prev'); 15475 15476 if (opt == "current") 15477 var item = vars.current; 15478 else if (opt == "next") 15479 var opacity = opts.styles.nextOpacity, 15480 item = vars.next; 15481 else 15482 var opacity = opts.styles.prevOpacity, 15483 item = vars.prev; 15484 15485 var api = { 15486 element: holder, 15487 position: item 15488 }; 15489 15490 iL.items[item].options.width = iL.items[item].options.width || 0, 15491 iL.items[item].options.height = iL.items[item].options.height || 0; 15492 15493 if (opt == "current") { 15494 if (opts.show.effect) holder.css(transform, gpuAcceleration).fadeIn(obj.speed, function() { 15495 holder.css(transform, ''); 15496 if (obj.caption) { 15497 iL.setCaption(obj, holder); 15498 var caption = $('div.ilightbox-caption', holder), 15499 percent = parseInt((caption.outerHeight() / holder.outerHeight()) * 100); 15500 if (opts.caption.start & percent <= 50) caption.fadeIn(opts.effects.fade
15500Speed); 15501 } 15502 15503 var social = obj.options.social; 15504 if (social) { 15505 iL.setSocial(social, obj.URL, holder); 15506 if (opts.social.start) $('div.ilightbox-social', holder).fadeIn(opts.effects.fadeSpeed); 15507 } 15508 15509 //Generate thumbnails 15510 iL.generateThumbnails(); 15511 15512 //Trigger the onShow callback 15513 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 15514 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 15515 }); 15516 else { 15517 holder.show(); 15518 15519 //Generate thumbnails 15520 iL.generateThumbnails(); 15521 15522 //Trigger the onShow callback 15523 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 15524 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 15525 } 15526 } else { 15527 if (opts.show.effect) holder.fadeTo(obj.speed, opacity, function() { 15528 if (opt == "next") vars.nextLock = false; 15529 else vars.prevLock = false; 15530 15531 //Generate thumbnails 15532 iL.generateThumbnails(); 15533 15534 //Trigger the onShow callback 15535 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 15536 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 15537 }); 15538 else { 15539 holder.css({ 15540 opacity: opacity 15541 }).show(); 15542 if (opt == "next") vars.nextLock = false; 15543 else vars.prevLock = false; 15544 15545 //Generate thumbnails 15546 iL.generateThumbnails(); 15547 15548 //Trigger the onShow callback 15549 if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item); 15550 if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api); 15551 } 15552 } 15553 15554 setTimeout(function() { 15555 iL.repositionPhoto(); 15556 }, 0); 15557 }, 15558 15559 generateBoxes: function() { 15560 var iL = this, 15561 vars = iL.vars, 15562 opts = iL.options; 15563 15564 if (opts.infinite && vars.total >= 3) { 15565 if (vars.current == vars.total - 1) vars.next = 0; 15566 if (vars.current == 0) vars.prev = vars.total - 1; 15567 } else opts.infinite = false; 15568 15569 //UNCODE addition 15570 if ( typeof iL.items[vars.current] == 'undefined' ) 15571 vars.current = 0; 15572 15573 iL.loadContent(iL.items[vars.current], 'current', opts.show.speed); 15574 15575 if (iL.items[vars.next]) iL.loadContent(iL.items[vars.next], 'next', opts.show.speed); 15576 if (iL.items[vars.prev]) iL.loadContent(iL.items[vars.prev], 'prev', opts.show.speed); 15577 }, 15578 15579 generateThumbnails: function() { 15580 var iL = this, 15581 vars = iL.vars, 15582 opts = iL.options, 15583 timeOut = null; 15584 15585 if (vars.thumbs && !iL.vars.dontGenerateThumbs) { 15586 var thumbnails = vars.thumbnails, 15587 container = $('div.ilightbox-thumbnails-container', thumbnails), 15588 grid = $('div.ilightbox-thumbnails-grid', container), 15589 i = 0; 15590 15591 grid.removeAttr('style').empty(); 15592 15593 $.each(iL.items, function(key, val) { 15594 var isActive = (vars.current == key) ? 'ilightbox-active' : '', 15595 opacity = (vars.current == key) ? opts.thumbnails.activeOpacity : opts.thumbnails.normalOpacity, 15596 thumb = val.options.thumbnail, 15597 thumbnail = $('<div class="ilightbox-thumbnail"></div>'), 15598 icon = $('<div class="ilightbox-thumbnail-icon"></div>'); 15599 15600 thumbnail.css({ 15601 opacity: 0 15602 }).addClass(isActive); 15603 15604 if ((val.type == "video" || val.type == "flash") && typeof val.options.icon == 'undefined') { 15605 icon.addClass('ilightbox-thumbnail-video'); 15606 thumbnail.append(icon); 15607 } else if (val.options.icon) { 15608 icon.addClass('ilightbox-thumbnail-' + val.options.icon); 15609 thumbnail.append(icon); 15610 } 15611 15612 if (thumb) iL.loadImage(thumb, function(img) { 15613 i++; 15614 if (img) thumbnail.data({ 15615 naturalWidth: img.width, 15616 naturalHeight: img.height 15617 }).append('<img src="' + thumb + '" border="0" />'); 15618 else thumbnail.data({ 15619 naturalWidth: opts.thumbnails.maxWidth, 15620 naturalHeight: opts.thumbnails.maxHeight 15621 }); 15622 15623 clearTimeout(timeOut); 15624 timeOut = setTimeout(function() { 15625 iL.positionThumbnails(thumbnails, container, grid); 15626 }, 20); 15627 setTimeout(function() { 15628 thumbnail.fadeTo(opts.effects.loadedFadeSpeed, opacity); 15629 }, i * 20); 15630 }); 15631 15632 grid.append(thumbnail); 15633 }); 15634 iL.vars.dontGenerateThumbs = true; 15635 } 15636 }, 15637
15638 positionThumbnails: function(thumbnails, container, grid) { 15639 var iL = this, 15640 vars = iL.vars, 15641 opts = iL.options, 15642 viewport = getViewport(), 15643 path = opts.path.toLowerCase(); 15644 15645 if (!thumbnails) thumbnails = vars.thumbnails; 15646 if (!container) container = $('div.ilightbox-thumbnails-container', thumbnails); 15647 if (!grid) grid = $('div.ilightbox-thumbnails-grid', container); 15648 15649 var thumbs = $('.ilightbox-thumbnail', grid), 15650 widthAvail = (path == 'horizontal') ? viewport.width - opts.styles.pageOffsetX : thumbs.eq(0).outerWidth() - opts.styles.pageOffsetX, 15651 heightAvail = (path == 'horizontal') ? thumbs.eq(0).outerHeight() - opts.styles.pageOffsetY : viewport.height - opts.styles.pageOffsetY, 15652 gridWidth = (path == 'horizontal') ? 0 : widthAvail, 15653 gridHeight = (path == 'horizontal') ? heightAvail : 0, 15654 active = $('.ilightbox-active', grid), 15655 gridCss = {}, 15656 css = {}; 15657 15658 if (arguments.length < 3) { 15659 thumbs.css({ 15660 opacity: opts.thumbnails.normalOpacity 15661 }); 15662 active.css({ 15663 opacity: opts.thumbnails.activeOpacity 15664 }); 15665 } 15666 15667 thumbs.each(function(i) { 15668 var t = $(this), 15669 data = t.data(), 15670 width = (path == 'horizontal') ? 0 : opts.thumbnails.maxWidth; 15671 height = (path == 'horizontal') ? opts.thumbnails.maxHeight : 0; 15672 dims = iL.getNewDimenstions(width, height, data.naturalWidth, data.naturalHeight, true); 15673 15674 t.css({ 15675 width: dims.width, 15676 height: dims.height 15677 }); 15678 if (path == 'horizontal') t.css({ 15679 'float': 'left' 15680 }); 15681 15682 (path == 'horizontal') ? ( 15683 gridWidth += t.outerWidth() 15684 ) : ( 15685 gridHeight += t.outerHeight() 15686 ); 15687 }); 15688 15689 gridCss = { 15690 width: gridWidth, 15691 height: gridHeight 15692 }; 15693 15694 grid.css(gridCss); 15695 15696 gridCss = {}; 15697 15698 var gridOffset = grid.offset(), 15699 activeOffset = (active.length) ? active.offset() : { 15700 top: parseInt(heightAvail / 2), 15701 left: parseInt(widthAvail / 2) 15702 }; 15703 15704 gridOffset.top = (gridOffset.top - $doc.scrollTop()), 15705 gridOffset.left = (gridOffset.left - $doc.scrollLeft()), 15706 activeOffset.top = (activeOffset.top - gridOffset.top - $doc.scrollTop()), 15707 activeOffset.left = (activeOffset.left - gridOffset.left - $doc.scrollLeft()); 15708 15709 (path == 'horizontal') ? ( 15710 gridCss.top = 0, 15711 gridCss.left = parseInt((widthAvail / 2) - activeOffset.left - (active.outerWidth() / 2)) 15712 ) : ( 15713 gridCss.top = parseInt(((heightAvail / 2) - activeOffset.top - (active.outerHeight() / 2))), 15714 gridCss.left = 0 15715 ); 15716 15717 if (arguments.length < 3) grid.stop().animate(gridCss, opts.effects.repositionSpeed, 'easeOutCirc'); 15718 else grid.css(gridCss); 15719 }, 15720 15721 loadImage: function(image, callback) { 15722 if (!$.isArray(image)) image = [image]; 15723 15724 var iL = this, 15725 length = image.length; 15726 15727 if (length > 0) { 15728 iL.showLoader(); 15729 $.each(image, function(index, value) { 15730 var img = new Image(); 15731 img.onload = function() { 15732 length -= 1; 15733 if (length == 0) { 15734 iL.hideLoader(); 15735 callback(img); 15736 } 15737 }; 15738 img.onerror = img.onabort = function() { 15739 length -= 1; 15740 if (length == 0) { 15741 iL.hideLoader(); 15742 callback(false); 15743 } 15744 }; 15745 img.src = image[index]; 15746 }); 15747 } else callback(false); 15748 }, 15749 15750 patchItemsEvents: function() { 15751 var iL = this, 15752 vars = iL.vars, 15753 clickEvent = ishybrid ? "itap.iL click.iL" : supportTouch ? "itap.iL" : "click.iL", 15754 vEvent = ishybrid ? "click.iL itap.iL" : supportTouch ? "click.iL" : "itap.iL"; 15755 15756 if (iL.context && iL.selector) { 15757 var $items = $(iL.selector, iL.context); 15758 15759 $(iL.context).on(clickEvent, iL.selector, function() { 15760 var $this = $(this), 15761 //UNCODE addition 15762 key = typeof $(this).data('lb-index') !== '' && $(this).closest('.owl-item').length ? $(this).data('lb-index') : $items.index($this); 15763 if (UNCODE.isMobile) { 15764 var isCarousel = $this.closest('.owl-carousel'); 15765 if (isCarousel.length) { 15766 if (isCarousel.hasClass('owl-translating')) return false; 15767 } 15768 } 15769 15770 vars.current = key; 15771 vars.next = iL.items[key + 1] ? key + 1 : null; 15772 vars.prev = iL.items[key - 1] ? key - 1 : null; 15773 15774 //UNCODE addition 15775 if ( vars.BODY.hasClass('fp-slide-scrolling') ) 15776 return false;
15777 15778 iL.addContents(); 15779 iL.patchEvents(); 15780 15781 return false; 15782 }).on(vEvent, iL.selector, function() { 15783 return false; 15784 }); 15785 } else 15786 $.each(iL.itemsObject, function(key, val) { 15787 val.on(clickEvent, function() { 15788 vars.current = key; 15789 vars.next = iL.items[key + 1] ? key + 1 : null; 15790 vars.prev = iL.items[key - 1] ? key - 1 : null; 15791 15792 iL.addContents(); 15793 iL.patchEvents(); 15794 15795 return false; 15796 }).on(vEvent, function() { 15797 return false; 15798 }); 15799 }); 15800 }, 15801 15802 dispatchItemsEvents: function() { 15803 var iL = this, 15804 vars = iL.vars, 15805 opts = iL.options; 15806 15807 if (iL.context && iL.selector) 15808 $(iL.context).off('.iL', iL.selector); 15809 else 15810 $.each(iL.itemsObject, function(key, val) { 15811 val.off('.iL'); 15812 }); 15813 }, 15814 15815 refresh: function() { 15816 var iL = this; 15817 15818 iL.dispatchItemsEvents(); 15819 iL.attachItems(); 15820 iL.normalizeItems(); 15821 iL.patchItemsEvents(); 15822 }, 15823 15824 patchEvents: function() { 15825 var iL = this, 15826 vars = iL.vars, 15827 opts = iL.options, 15828 path = opts.path.toLowerCase(), 15829 holders = $('.ilightbox-holder'), 15830 fullscreenEvent = fullScreenApi.fullScreenEventName + '.iLightBox', 15831 durationThreshold = 1000, 15832 horizontalDistanceThreshold = 15833 verticalDistanceThreshold = 100, 15834 buttonsArray = [vars.nextButton[0], vars.prevButton[0], vars.nextButton[0].firstChild, vars.prevButton[0].firstChild]; 15835 15836 $win.bind('resize.iLightBox', function() { 15837 var viewport = getViewport(); 15838 15839 if (opts.mobileOptimizer && !opts.innerToolbar) vars.isMobile = viewport.width <= vars.mobileMaxWidth; 15840 vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile'); 15841 15842 iL.repositionPhoto(null); 15843 if (supportTouch) { 15844 clearTimeout(vars.setTime); 15845 vars.setTime = setTimeout(function() { 15846 var scrollTop = getScrollXY().y; 15847 window.scrollTo(0, scrollTop - 30); 15848 window.scrollTo(0, scrollTop + 30); 15849 window.scrollTo(0, scrollTop); 15850 }, 2000); 15851 } 15852 if (vars.thumbs) iL.positionThumbnails(); 15853 }).bind('keydown.iLightBox', function(event) { 15854 if (opts.controls.keyboard) { 15855 switch (event.keyCode) { 15856 case 13: 15857 if (event.shiftKey && opts.keyboard.shift_enter) iL.fullScreenAction(); 15858 break; 15859 case 27: 15860 if (opts.keyboard.esc) iL.closeAction(); 15861 break; 15862 case 37: 15863 if (opts.keyboard.left && !vars.lockKey) iL.moveTo('prev'); 15864 break; 15865 case 38: 15866 if (opts.keyboard.up && !vars.lockKey) iL.moveTo('prev'); 15867 break; 15868 case 39: 15869 if (opts.keyboard.right && !vars.lockKey) iL.moveTo('next'); 15870 break; 15871 case 40: 15872 if (opts.keyboard.down && !vars.lockKey) iL.moveTo('next'); 15873 break; 15874 } 15875 } 15876 }); 15877 15878 if (fullScreenApi.supportsFullScreen) $win.bind(fullscreenEvent, function() { 15879 iL.doFullscreen(); 15880 }); 15881 15882 var holderEventsArr = [opts.caption.show + '.iLightBox', opts.caption.hide + '.iLightBox', opts.social.show + '.iLightBox', opts.social.hide + '.iLightBox'].filter(function(e, i, arr) { 15883 return arr.lastIndexOf(e) === i; 15884 }), 15885 holderEvents = ""; 15886 15887 $.each(holderEventsArr, function(key, val) { 15888 if (key != 0) holderEvents += ' '; 15889 holderEvents += val; 15890 }); 15891 15892 $doc.on(clickEvent, '.ilightbox-overlay', function() { 15893 if (opts.overlay.blur) iL.closeAction(); 15894 }).on(clickEvent, '.ilightbox-next, .ilightbox-next-button', function() { 15895 iL.moveTo('next'); 15896 }).on(clickEvent, '.ilightbox-prev, .ilightbox-prev-button', function() { 15897 iL.moveTo('prev'); 15898 }).on(clickEvent, '.ilightbox-thumbnail', function() { 15899 var t = $(this), 15900 thumbs = $('.ilightbox-thumbnail', vars.thumbnails), 15901 index = thumbs.index(t); 15902 15903 if (index != vars.current) iL.goTo(index); 15904 }).on(holderEvents, '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 15905 var caption = $('div.ilightbox-caption', vars.holder), 15906 social = $('div.ilightbox-social', vars.holder), 15907 fadeSpeed = opts.effects.fadeSpeed; 15908 15909 if (vars.nextLock || vars.prevLock) { 15910 if (e.type == opts.caption.show && !caption.is(':visible')) caption.fadeIn(fadeSpeed); 15911 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.fadeOut(fadeSpeed); 15912 15913 if (e.type == opts.social.show && !social.is(':visible')) social.fadeIn(fadeSpeed); 15914 else if (e.type == opts.social.hide && social.is(':visible')) social.fadeOut(fadeSpeed); 15915 } else { 15916 if (e.type == opts.caption.show && !caption.is(':visible')) caption.stop().fadeIn(fadeSpeed); 15917 else if (e.type == opts.caption.hide && caption.is(':visible')) caption.stop().fadeOut(fadeSpeed); 15918 15919 if (e.type == opts.social.show && !social.is(':visible')) social.stop().fadeIn(fadeSpeed); 15920 else if (e.type == opts.social.hide && social.is(':visible')) social.stop().fadeOut(fadeSpeed); 15921 } 15922 }).on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-wrapper', function(e) { 15923 if (e.type == 'mouseenter') vars.lockWheel = true; 15924 else vars.lockWheel = false;
15925 }).on(clickEvent, '.ilightbox-toolbar a.ilightbox-close, .ilightbox-toolbar a.ilightbox-fullscreen, .ilightbox-toolbar a.ilightbox-play, .ilightbox-toolbar a.ilightbox-pause', function() { 15926 var t = $(this); 15927 15928 if (t.hasClass('ilightbox-fullscreen')) iL.fullScreenAction(); 15929 else if (t.hasClass('ilightbox-play')) { 15930 iL.resume(); 15931 t.addClass('ilightbox-pause').removeClass('ilightbox-play'); 15932 } else if (t.hasClass('ilightbox-pause')) { 15933 iL.pause(); 15934 t.addClass('ilightbox-play').removeClass('ilightbox-pause'); 15935 } else iL.closeAction(); 15936 }).on(touchMoveEvent, '.ilightbox-overlay, .ilightbox-thumbnails-container', function(e) { 15937 // prevent scrolling 15938 e.preventDefault(); 15939 }); 15940 15941 function mouseMoveHandler(e) { 15942 if (!vars.isMobile) { 15943 if (!vars.mouseID) { 15944 vars.hideableElements.show(); 15945 } 15946 15947 vars.mouseID = clearTimeout(vars.mouseID); 15948 15949 if (buttonsArray.indexOf(e.target) === -1) 15950 vars.mouseID = setTimeout(function() { 15951 vars.hideableElements.hide(); 15952 vars.mouseID = clearTimeout(vars.mouseID); 15953 }, 3000); 15954 } 15955 } 15956 15957 if (opts.controls.arrows && !supportTouch) $doc.on('mousemove.iLightBox', mouseMoveHandler); 15958 15959 if (opts.controls.slideshow && opts.slideshow.pauseOnHover) $doc.on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) { 15960 if (e.type == 'mouseenter' && vars.cycleID) iL.pause(); 15961 else if (e.type == 'mouseleave' && vars.isPaused) iL.resume(); 15962 }); 15963 15964 var switchers = $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails'), 15965 delay = false; 15966 15967 if (opts.controls.mousewheel) switchers.on('mousewheel.iLightBox', function(event, delta) { 15968 event.preventDefault(); 15969 if (delay) return; 15970 delay = true; 15971 if (!vars.lockWheel) { 15972 event.preventDefault(); 15973 if (delta < 0) { 15974 iL.moveTo('next'); 15975 } else if (delta > 0) { 15976 iL.moveTo('prev'); 15977 } 15978 } 15979 setTimeout(function(){
15980 delay = false; 15981 }, 2000); 15982 }); 15983 15984 if (opts.controls.swipe) holders.on(touchStartEvent, function(event) { 15985 if (vars.nextLock || vars.prevLock || vars.total == 1 || vars.lockSwipe) return; 15986 15987 vars.BODY.addClass('ilightbox-closedhand'); 15988 15989 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event, 15990 scrollTop = $doc.scrollTop(), 15991 scrollLeft = $doc.scrollLeft(), 15992 offsets = [ 15993 holders.eq(0).offset(), 15994 holders.eq(1).offset(), 15995 holders.eq(2).offset() 15996 ], 15997 offSet = [{ 15998 top: offsets[0].top - scrollTop, 15999 left: offsets[0].left - scrollLeft 16000 }, { 16001 top: offsets[1].top - scrollTop, 16002 left: offsets[1].left - scrollLeft 16003 }, { 16004 top: offsets[2].top - scrollTop, 16005 left: offsets[2].left - scrollLeft 16006 }], 16007 start = { 16008 time: (new Date()).getTime(), 16009 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 16010 }, 16011 stop; 16012 16013 function moveEachHandler(i) { 16014 var t = $(this), 16015 offset = offSet[i], 16016 scroll = [(start.coords[0] - stop.coords[0]), (start.coords[1] - stop.coords[1])]; 16017 16018 t[0].style[path == "horizontal" ? 'left' : 'top'] = (path == "horizontal" ? offset.left - scroll[0] : offset.top - scroll[1]) + 'px'; 16019 } 16020 16021 function moveHandler(event) { 16022 16023 if (!start) return; 16024 16025 var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event; 16026 16027 stop = { 16028 time: (new Date()).getTime(), 16029 coords: [data.pageX - scrollLeft, data.pageY - scrollTop] 16030 }; 16031 16032 holders.each(moveEachHandler); 16033 16034 // prevent scrolling 16035 event.preventDefault(); 16036 } 16037 16038 function repositionHolders() { 16039 holders.each(function() { 16040 var t = $(this), 16041 offset = t.data('offset') || { 16042 top: t.offset().top - scrollTop, 16043 left: t.offset().left - scrollLeft 16044 }, 16045 top = offset.top, 16046 left = offset.left; 16047 16048 t.css(transform, gpuAcceleration).stop().animate({ 16049 top: top, 16050 left: left 16051 }, 500, 'easeOutCirc', function() { 16052 t.css(transform, ''); 16053 }); 16054 }); 16055 } 16056 16057 holders.bind(touchMoveEvent, moveHandler); 16058 $doc.one(touchStopEvent, function(event) { 16059 holders.unbind(touchMoveEvent, moveHandler); 16060 16061 vars.BODY.removeClass('ilightbox-closedhand'); 16062 16063 if (start && stop) { 16064 if (path == "horizontal" && stop.time - start.time < durationThreshold && abs(start.coords[0] - stop.coords[0]) > horizontalDistanceThreshold && abs(start.coords[1] - stop.coords[1]) < verticalDistanceThreshold) { 16065 if (start.coords[0] > stop.coords[0]) { 16066 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 16067 else { 16068 vars.isSwipe = true; 16069 iL.moveTo('next'); 16070 } 16071 } else { 16072 if (vars.current == 0 && !opts.infinite) repositionHolders(); 16073 else { 16074 vars.isSwipe = true; 16075 iL.moveTo('prev'); 16076 } 16077 } 16078 } 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) { 16079 if (start.coords[1] > stop.coords[1]) { 16080 if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders(); 16081 else { 16082 vars.isSwipe = true; 16083 iL.moveTo('next'); 16084 } 16085 } else { 16086 if (vars.current == 0 && !opts.infinite) repositionHolders(); 16087 else { 16088 vars.isSwipe = true; 16089 iL.moveTo('prev'); 16090 } 16091 } 16092 } else repositionHolders(); 16093 } 16094 start = stop = undefined; 16095 }); 16096 }); 16097 16098 }, 16099 16100 goTo: function(index) { 16101 var iL = this, 16102 vars = iL.vars, 16103 opts = iL.options, 16104 diff = (index - vars.current); 16105 16106 if (opts.infinite) { 16107 if (index == vars.total - 1 && vars.current == 0) diff = -1; 16108 if (vars.current == vars.total - 1 && index == 0) diff = 1; 16109 } 16110 16111 if (diff == 1) iL.moveTo('next'); 16112 else if (diff == -1) iL.moveTo('prev'); 16113 else { 16114 16115 if (vars.nextLock || vars.prevLock) return false; 16116 16117 //Trigger the onBeforeChange callback 16118 if (typeof opts.callback.onBeforeChange == 'function') opts.callback.onBeforeChange.call(iL, iL.ui); 16119 16120 if (opts.linkId) { 16121 vars.hashLock = true; 16122 window.location.hash = opts.linkId + '/' + index; 16123 } 16124 16125 if (iL.items[index]) { 16126 if (!iL.items[index].options.mousewheel) vars.lockWheel = true; 16127 else iL.vars.lockWheel = false;
16128 16129 if (!iL.items[index].options.swipe) vars.lockSwipe = true; 16130 else vars.lockSwipe = false; 16131 } 16132 16133 $.each([vars.holder, vars.nextPhoto, vars.prevPhoto], function(key, val) { 16134 val.css(transform, gpuAcceleration).fadeOut(opts.effects.loadedFadeSpeed); 16135 }); 16136 16137 vars.current = index; 16138 vars.next = index + 1; 16139 vars.prev = index - 1; 16140 16141 iL.createUI(); 16142 16143 setTimeout(function() { 16144 iL.generateBoxes(); 16145 }, opts.effects.loadedFadeSpeed + 50); 16146 16147 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(index).addClass('ilightbox-active'); 16148 iL.positionThumbnails(); 16149 16150 if (opts.linkId) setTimeout(function() { 16151 vars.hashLock = false; 16152 }, 55); 16153 16154 // Configure arrow buttons 16155 if (!opts.infinite) { 16156 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 16157 16158 if (vars.current == 0) { 16159 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 16160 } 16161 if (vars.current >= vars.total - 1) { 16162 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 16163 } 16164 } 16165 16166 // Reset next cycle timeout 16167 iL.resetCycle(); 16168 16169 //Trigger the onAfterChange callback 16170 if (typeof opts.callback.onAfterChange == 'function') opts.callback.onAfterChange.call(iL, iL.ui); 16171 } 16172 }, 16173 16174 moveTo: function(side) { 16175 var iL = this, 16176 vars = iL.vars, 16177 opts = iL.options, 16178 path = opts.path.toLowerCase(), 16179 viewport = getViewport(), 16180 switchSpeed = opts.effects.switchSpeed; 16181 16182 if (vars.nextLock || vars.prevLock) return false; 16183 else { 16184 16185 var item = (side == "next") ? vars.next : vars.prev; 16186 16187 if (opts.linkId) { 16188 vars.hashLock = true; 16189 window.location.hash = opts.linkId + '/' + item; 16190 } 16191 16192 if (side == "next") { 16193 if (!iL.items[item]) return false; 16194 var firstHolder = vars.nextPhoto, 16195 secondHolder = vars.holder, 16196 lastHolder = vars.prevPhoto, 16197 firstClass = 'ilightbox-prev', 16198 secondClass = 'ilightbox-next'; 16199 } else if (side == "prev") { 16200 if (!iL.items[item]) return false; 16201 var firstHolder = vars.prevPhoto, 16202 secondHolder = vars.holder, 16203 lastHolder = vars.nextPhoto, 16204 firstClass = 'ilightbox-next', 16205 secondClass = 'ilightbox-prev'; 16206 } 16207 16208 //Trigger the onBeforeChange callback 16209 if (typeof opts.callback.onBeforeChange == 'function') 16210 opts.callback.onBeforeChange.call(iL, iL.ui); 16211 16212 (side == "next") ? vars.nextLock = true: vars.prevLock = true; 16213 16214 var captionFirst = $('div.ilightbox-caption', secondHolder), 16215 socialFirst = $('div.ilightbox-social', secondHolder); 16216 16217 if (captionFirst.length) 16218 captionFirst.stop().fadeOut(switchSpeed, function() { 16219 $(this).remove(); 16220 }); 16221 if (socialFirst.length) 16222 socialFirst.stop().fadeOut(switchSpeed, function() { 16223 $(this).remove(); 16224 }); 16225 16226 if (iL.items[item].caption) { 16227 iL.setCaption(iL.items[item], firstHolder); 16228 var caption = $('div.ilightbox-caption', firstHolder), 16229 percent = parseInt((caption.outerHeight() / firstHolder.outerHeight()) * 100); 16230 if (opts.caption.start && percent <= 50) caption.fadeIn(switchSpeed); 16231 } 16232 16233 var social = iL.items[item].options.social; 16234 if (social) { 16235 iL.setSocial(social, iL.items[item].URL, firstHolder); 16236 if (opts.social.start) $('div.ilightbox-social', firstHolder).fadeIn(opts.effects.fadeSpeed); 16237 } 16238 16239 $.each([firstHolder, secondHolder, lastHolder], function(key, val) { 16240 val.removeClass('ilightbox-next ilightbox-prev'); 16241 }); 16242 16243 var firstOffset = firstHolder.data('offset'), 16244 winW = (viewport.width - (opts.styles.pageOffsetX)), 16245 winH = (viewport.height - (opts.styles.pageOffsetY)), 16246 width = firstOffset.newDims.width, 16247 height = firstOffset.newDims.height, 16248 thumbsOffset = firstOffset.thumbsOffset, 16249 diff = firstOffset.diff, 16250 top = parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)), 16251 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 16252 16253 var secondOffset = secondHolder.data('offset'), 16254 object = secondOffset.object; 16255 16256 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 16257 var objRatio = width / height; 16258 height = height - vars.captionHeight; 16259 width = height * objRatio; 16260 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top, 16261 left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2)); 16262 }*/ 16263 16264 firstHolder.show().css(transform, gpuAcceleration).animate({ 16265 top: top, 16266 left: left, 16267 opacity: 1 16268 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 16269 firstHolder.css(transform, ''); 16270 }); 16271 16272 $('div.ilightbox-container', firstHolder).animate({ 16273 width: width, 16274 height: height 16275 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 16276 16277 diff = secondOffset.diff; 16278 16279 width = secondOffset.newDims.width, 16280 height = secondOffset.newDims.height; 16281 16282 width = parseInt(width * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 16283 height = parseInt(height * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']), 16284 top = (path == 'horizontal') ? parseInt((winH / 2) - object.offsetY - (height / 2) - diff.H - (thumbsOffset.H / 2)) : parseInt(winH - object.offsetX - diff.H - (thumbsOffset.H / 2)); 16285 16286 if (side == 'prev') 16287 left = (path == 'horizontal') ? parseInt(winW - object.offsetX - diff.W - (thumbsOffset.W / 2)) : parseInt((winW / 2) - (width / 2) - diff.W - object.offsetY - (thumbsOffset.W / 2)); 16288 else { 16289 top = (path == 'horizontal') ? top : parseInt(object.offsetX - diff.H - height - (thumbsOffset.H / 2)), 16290 left = (path == 'horizontal') ? parseInt(object.offsetX - diff.W - width - (thumbsOffset.W / 2)) : parseInt((winW / 2) - object.offsetY - (width / 2) - diff.W - (thumbsOffset.W / 2)); 16291 } 16292 16293 /*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) { 16294 var objRatio = width / height; 16295 height = height - vars.captionHeight; 16296 width = height * objRatio; 16297 top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top; 16298 }*/ 16299 16300 $('div.ilightbox-container', secondHolder).animate({ 16301 width: width, 16302 height: height 16303 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc'); 16304 16305 secondHolder.addClass(firstClass).css(transform, gpuAcceleration).animate({ 16306 top: top, 16307 left: left, 16308 opacity: opts.styles.prevOpacity, 16309 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 16310 secondHolder.css(transform, ''); 16311
16312 $('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(item).addClass('ilightbox-active'); 16313 iL.positionThumbnails(); 16314 16315 if (iL.items[item]) { 16316 if (!iL.items[item].options.mousewheel) vars.lockWheel = true; 16317 else vars.lockWheel = false; 16318 16319 if (!iL.items[item].options.swipe) vars.lockSwipe = true; 16320 else vars.lockSwipe = false; 16321 } 16322 16323 vars.isSwipe = false; 16324 16325 // Remove iframe & video from previous slide 16326 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 16327 $('div.ilightbox-container', secondHolder).empty(); 16328 } 16329 16330 if (side == "next") { 16331 vars.nextPhoto = lastHolder, 16332 vars.prevPhoto = secondHolder, 16333 vars.holder = firstHolder; 16334 16335 vars.nextPhoto.hide(); 16336 16337 vars.next = vars.next + 1, 16338 vars.prev = vars.current, 16339 vars.current = vars.current + 1; 16340 16341 if (opts.infinite) { 16342 if (vars.current > vars.total - 1) vars.current = 0; 16343 if (vars.current == vars.total - 1) vars.next = 0; 16344 if (vars.current == 0) vars.prev = vars.total - 1; 16345 } 16346 16347 iL.createUI(); 16348 16349 if (!iL.items[vars.next]) 16350 vars.nextLock = false; 16351 else 16352 iL.loadContent(iL.items[vars.next], 'next'); 16353 } else { 16354 vars.prevPhoto = lastHolder; 16355 vars.nextPhoto = secondHolder; 16356 vars.holder = firstHolder; 16357 16358 vars.prevPhoto.hide(); 16359 16360 vars.next = vars.current; 16361 vars.current = vars.prev; 16362 vars.prev = vars.current - 1; 16363 16364 if (opts.infinite) { 16365 if (vars.current == vars.total - 1) vars.next = 0; 16366 if (vars.current == 0) vars.prev = vars.total - 1; 16367 } 16368 16369 iL.createUI(); 16370 16371 if (!iL.items[vars.prev]) 16372 vars.prevLock = false; 16373 else 16374 iL.loadContent(iL.items[vars.prev], 'prev'); 16375 } 16376 16377 // Add iframe & video content for current slide 16378 if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) { 16379 iL.loadContent(iL.items[vars.current], 'current'); 16380 } 16381 16382 if (opts.linkId) setTimeout(function() { 16383 vars.hashLock = false; 16384 }, 55); 16385 16386 // Configure arrow buttons 16387 if (!opts.infinite) { 16388 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 16389 16390 if (vars.current == 0) 16391 vars.prevButton.add(vars.innerPrevButton).addClass('disabled'); 16392 if (vars.current >= vars.total - 1) 16393 vars.nextButton.add(vars.innerNextButton).addClass('disabled'); 16394 } 16395 16396 iL.repositionPhoto(); 16397 16398 // Reset next cycle timeout 16399 iL.resetCycle(); 16400 16401 //Trigger the onAfterChange callback 16402 if (typeof opts.callback.onAfterChange == 'function') 16403 opts.callback.onAfterChange.call(iL, iL.ui); 16404 }); 16405 16406 top = (path == 'horizontal') ? getPixel(lastHolder, 'top') : ((side == "next") ? parseInt(-(winH / 2) - lastHolder.outerHeight()) : parseInt(top * 2)), 16407 left = (path == 'horizontal') ? ((side == "next") ? parseInt(-(winW / 2) - lastHolder.outerWidth()) : parseInt(left * 2)) : getPixel(lastHolder, 'left'); 16408 16409 lastHolder.css(transform, gpuAcceleration).animate({ 16410 top: top, 16411 left: left, 16412 opacity: opts.styles.nextOpacity 16413 }, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() { 16414 lastHolder.css(transform, ''); 16415 }).addClass(secondClass); 16416 } 16417 }, 16418 16419 setCaption: function(obj, target) { 16420 var iL = this, 16421 caption = $('<div class="ilightbox-caption"></div>'); 16422 16423 if (obj.caption) { 16424 caption.html(obj.caption); 16425 $('div.ilightbox-container', target).append(caption); 16426 } 16427 }, 16428 16429 normalizeSocial: function(obj, url) { 16430 var iL = this, 16431 vars = iL.vars, 16432 opts = iL.options, 16433 baseURL = window.location.href; 16434 16435 $.each(obj, function(key, value) { 16436 if (!value) 16437 return true; 16438 16439 var item = key.toLowerCase(), 16440 source, text; 16441 16442 switch (item) { 16443 case 'facebook': 16444 source = "http://www.facebook.com/share.php?v=4&src=bm&u={URL}", 16445 text = "Share on Facebook"; 16446 break; 16447 case 'twitter': 16448 source = "http://twitter.com/home?status={URL}", 16449 text = "Share on Twitter"; 16450 break; 16451 case 'digg': 16452 source = "http://digg.com/submit?phase=2&url={URL}", 16453 text = "Share on Digg"; 16454 break; 16455 case 'reddit': 16456 source = "http://reddit.com/submit?url={URL}", 16457 text = "Share on reddit"; 16458 break; 16459 } 16460 16461 obj[key] = { 16462 URL: value.URL && absolutizeURI(baseURL, value.URL) || opts.linkId && window.location.href || typeof url !== 'string' && baseURL || url && absolutizeURI(baseURL, url) || baseURL, 16463 source: value.source || source || value.URL && absolutizeURI(baseURL, value.URL) || url && absolutizeURI(baseURL, url), 16464 text: value.text || text || "Share on " + key, 16465 width: (typeof(value.width) != 'undefined' && !isNaN(value.width)) ? parseInt(value.width) : 640, 16466 height: value.height || 360 16467 }; 16468 16469 }); 16470 16471 return obj; 16472 }, 16473 16474 setSocial: function(obj, url, target) { 16475 var iL = this, 16476 socialBar = $('<div class="ilightbox-social"></div>'), 16477 buttons = '<ul>'; 16478 16479 obj = iL.normalizeSocial(obj, url); 16480 16481 $.each(obj, function(key, value) { 16482 var item = key.toLowerCase(), 16483 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, '+')); 16484 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>'; 16485 }); 16486 16487 buttons += '</ul>'; 16488 16489 socialBar.html(buttons); 16490 $('div.ilightbox-container', target).append(socialBar); 16491 }, 16492 16493 fullScreenAction: function() { 16494 var iL = this, 16495 vars = iL.vars; 16496 16497 if (fullScreenApi.supportsFullScreen) { 16498 if (fullScreenApi.isFullScreen()) fullScreenApi.cancelFullScreen(document.documentElement); 16499 else fullScreenApi.requestFullScreen(document.documentElement); 16500 } else { 16501 iL.doFullscreen(); 16502 } 16503 }, 16504 16505 doFullscreen: function() { 16506 var iL = this, 16507 vars = iL.vars, 16508 viewport = getViewport(), 16509 opts = iL.options; 16510 16511 if (opts.fullAlone) { 16512 var currentHolder = vars.holder, 16513 current = iL.items[vars.current], 16514 windowWidth = viewport.width, 16515 windowHeight = viewport.height, 16516 elements = [currentHolder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.overlay, vars.toolbar, vars.thumbnails, vars.loader], 16517 hideElements = [vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 16518 16519 if (!vars.isInFullScreen) { 16520 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = true; 16521 vars.overlay.css({ 16522 opacity: 1 16523 }); 16524 16525 $.each(hideElements, function(i, element) { 16526 element.hide(); 16527 }); 16528 16529 vars.fullScreenButton.attr('title', opts.text.exitFullscreen); 16530 16531 if (opts.fullStretchTypes.indexOf(current.type) != -1) currentHolder.data({
16532 naturalWidthOld: currentHolder.data('naturalWidth'), 16533 naturalHeightOld: currentHolder.data('naturalHeight'), 16534 naturalWidth: windowWidth, 16535 naturalHeight: windowHeight 16536 }); 16537 else { 16538 var viewport = current.options.fullViewPort || opts.fullViewPort || '', 16539 newWidth = windowWidth, 16540 newHeight = windowHeight, 16541 width = currentHolder.data('naturalWidth'), 16542 height = currentHolder.data('naturalHeight'); 16543 16544 if (viewport.toLowerCase() == 'fill') { 16545 newHeight = (newWidth / width) * height; 16546 16547 if (newHeight < windowHeight) { 16548 newWidth = (windowHeight / height) * width, 16549 newHeight = windowHeight; 16550 } 16551 } else if (viewport.toLowerCase() == 'fit') { 16552 var dims = iL.getNewDimenstions(newWidth, newHeight, width, height, true); 16553 16554 newWidth = dims.width, 16555 newHeight = dims.height; 16556 } else if (viewport.toLowerCase() == 'stretch') { 16557 newWidth = newWidth, 16558 newHeight = newHeight; 16559 } else { 16560 var scale = (width > newWidth || height > newHeight) ? true : false, 16561 dims = iL.getNewDimenstions(newWidth, newHeight, width, height, scale); 16562 newWidth = dims.width, 16563 newHeight = dims.height; 16564 } 16565 16566 currentHolder.data({ 16567 naturalWidthOld: currentHolder.data('naturalWidth'), 16568 naturalHeightOld: currentHolder.data('naturalHeight'), 16569 naturalWidth: newWidth, 16570 naturalHeight: newHeight 16571 }); 16572 } 16573 16574 $.each(elements, function(key, val) { 16575 val.addClass('ilightbox-fullscreen'); 16576 }); 16577 16578 //Trigger the onEnterFullScreen callback 16579 if (typeof opts.callback.onEnterFullScreen == 'function') opts.callback.onEnterFullScreen.call(iL, iL.ui); 16580 } else { 16581 vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = false; 16582 vars.overlay.css({ 16583 opacity: iL.options.overlay.opacity 16584 }); 16585 16586 $.each(hideElements, function(i, element) { 16587 element.show(); 16588 }); 16589 16590 vars.fullScreenButton.attr('title', opts.text.enterFullscreen); 16591 16592 currentHolder.data({ 16593 naturalWidth: currentHolder.data('naturalWidthOld'), 16594 naturalHeight: currentHolder.data('naturalHeightOld'), 16595 naturalWidthOld: null, 16596 naturalHeightOld: null 16597 }); 16598 16599 $.each(elements, function(key, val) { 16600 val.removeClass('ilightbox-fullscreen'); 16601 }); 16602 16603 //Trigger the onExitFullScreen callback 16604 if (typeof opts.callback.onExitFullScreen == 'function') opts.callback.onExitFullScreen.call(iL, iL.ui); 16605 } 16606 } else { 16607 if (!vars.isInFullScreen) vars.isInFullScreen = true; 16608 else vars.isInFullScreen = false; 16609 } 16610 iL.repositionPhoto(true); 16611 }, 16612 16613 closeAction: function() { 16614 var iL = this, 16615 vars = iL.vars, 16616 opts = iL.options; 16617 16618 $win.unbind('.iLightBox'); 16619 $doc.off('.iLightBox'); 16620 16621 if (vars.isInFullScreen) fullScreenApi.cancelFullScreen(document.documentElement); 16622 16623 $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails').off('.iLightBox'); 16624 16625 if (opts.hide.effect) vars.overlay.stop().fadeOut(opts.hide.speed, function() { 16626 vars.overlay.remove(); 16627 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 16628 }); 16629 else { 16630 vars.overlay.remove(); 16631 vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox'); 16632 } 16633 16634 var fadeOuts = [vars.toolbar, vars.holder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails]; 16635 16636 $.each(fadeOuts, function(i, element) { 16637 element.removeAttr('style').remove(); 16638 }); 16639 16640 vars.dontGenerateThumbs = vars.isInFullScreen = false; 16641 16642 window.iLightBox = null; 16643 16644 if (opts.linkId) { 16645 vars.hashLock = true; 16646 removeHash(); 16647 setTimeout(function() { 16648 vars.hashLock = false; 16649 }, 55); 16650 } 16651 16652 vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled'); 16653 16654 //Trigger the onHide callback 16655 if (typeof opts.callback.onHide == 'function') opts.callback.onHide.call(iL, iL.ui); 16656 }, 16657 16658 repositionPhoto: function() { 16659 var iL = this, 16660 vars = iL.vars, 16661 opts = iL.options, 16662 path = opts.path.toLowerCase(), 16663 viewport = getViewport(), 16664 winWidth = viewport.width, 16665 winHeight = viewport.height; 16666 16667 if (viewport.width < UNCODE.mediaQuery) opts.styles.nextOffsetX = 0; 16668 16669 var thumbsOffsetW = (vars.isInFullScreen && opts.fullAlone || vars.isMobile) ? 0 : ((path == 'horizontal') ? 0 : vars.thumbnails.outerWidth()), 16670 thumbsOffsetH = vars.isMobile ? vars.toolbar.outerHeight() : ((vars.isInFullScreen && opts.fullAlone) ? 0 : ((path == 'horizontal') ? vars.thumbnails.outerHeight() : 0)), 16671 width = (vars.isInFullScreen && opts.fullAlone) ? winWidth : (winWidth - (opts.styles.pageOffsetX)), 16672 height = (vars.isInFullScreen && opts.fullAlone) ? winHeight : (winHeight - (opts.styles.pageOffsetY)), 16673 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, 16674 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))); 16675 16676 var elObject = { 16677 type: 'current', 16678 width: width, 16679 height: height, 16680 item: iL.items[vars.current], 16681 offsetW: offsetW, 16682 offsetH: offsetH,
16683 thumbsOffsetW: thumbsOffsetW, 16684 thumbsOffsetH: thumbsOffsetH, 16685 animate: arguments.length, 16686 holder: vars.holder 16687 }; 16688 16689 iL.repositionEl(elObject); 16690 16691 if (iL.items[vars.next]) { 16692 elObject = $.extend(elObject, { 16693 type: 'next', 16694 item: iL.items[vars.next], 16695 offsetX: opts.styles.nextOffsetX, 16696 offsetY: opts.styles.nextOffsetY, 16697 holder: vars.nextPhoto 16698 }); 16699 16700 iL.repositionEl(elObject); 16701 } 16702 16703 if (iL.items[vars.prev]) { 16704 elObject = $.extend(elObject, { 16705 type: 'prev', 16706 item: iL.items[vars.prev], 16707 offsetX: opts.styles.nextOffsetX, 16708 offsetY: opts.styles.prevOffsetY, 16709 holder: vars.prevPhoto 16710 }); 16711 16712 iL.repositionEl(elObject); 16713 } 16714 16715 var loaderCss = (path == "horizontal") ? { 16716 left: parseInt((width / 2) - (vars.loader.outerWidth() / 2)) 16717 } : { 16718 top: parseInt((height / 2) - (vars.loader.outerHeight() / 2)) 16719 }; 16720 vars.loader.css(loaderCss); 16721 }, 16722 16723 repositionEl: function(obj) { 16724 var iL = this, 16725 vars = iL.vars, 16726 opts = iL.options, 16727 path = opts.path.toLowerCase(), 16728 widthAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.width : (obj.width - obj.offsetW)) : (obj.width - obj.offsetW), 16729 heightAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.height : (obj.height - obj.offsetH)) : (obj.height - obj.offsetH), 16730 itemParent = obj.item, 16731 item = obj.item.options, 16732 holder = obj.holder, 16733 offsetX = obj.offsetX || 0, 16734 offsetY = obj.offsetY || 0, 16735 //Uncode change ##START## 16736 toolbarHeight = $('.ilightbox-inner-toolbar', holder).length ? parseInt( $('.ilightbox-inner-toolbar', holder).outerHeight() ) : 0, 16737 //Uncode change ##END## 16738 thumbsOffsetW = obj.thumbsOffsetW, 16739 thumbsOffsetH = obj.thumbsOffsetH; 16740 16741 if (obj.type == 'current') { 16742 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); 16743 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); 16744 } else { 16745 if (typeof item.width == 'number' && item.width) widthAvail = (item.width > widthAvail) ? widthAvail : item.width; 16746 if (typeof item.height == 'number' && item.height) heightAvail = (item.height > heightAvail) ? heightAvail : item.height; 16747 } 16748 16749 16750 //Uncode change ##START## 16751 heightAvail = parseInt(heightAvail - toolbarHeight); 16752 // heightAvail = parseInt(heightAvail - $('.ilightbox-inner-toolbar', holder).outerHeight()); 16753 //Uncode change ##END## 16754 16755 var width = (typeof item.width == 'string' && item.width.indexOf('%') != -1) ? percentToValue(parseInt(item.width.replace('%', '')), obj.width) : holder.data('naturalWidth'), 16756 height = (typeof item.height == 'string' && item.height.indexOf('%') != -1) ? percentToValue(parseInt(item.height.replace('%', '')), obj.height) : holder.data('naturalHeight'); 16757 16758 var dims = ((typeof item.width == 'string' && item.width.indexOf('%') != -1 || typeof item.height == 'string' && item.height.indexOf('%') != -1) ? { 16759 width: width, 16760 height: height 16761 } : iL.getNewDimenstions(widthAvail, heightAvail, width, height)), 16762 newDims = $.extend({}, dims, {}); 16763 16764 if (obj.type == 'prev' || obj.type == 'next') 16765 width = parseInt(dims.width * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)), 16766 height = parseInt(dims.height * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)); 16767 else 16768 width = dims.width, 16769 height = dims.height; 16770 16771 var widthDiff = parseInt((getPixel(holder, 'padding-left') + getPixel(holder, 'padding-right') + getPixel(holder, 'border-left-width') + getPixel(holder, 'border-right-width')) / 2), 16772 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); 16773 16774 switch (obj.type) { 16775 case 'current': 16776 var top = parseInt((obj.height / 2) - (height / 2) - heightDiff - (thumbsOffsetH / 2)), 16777 left = parseInt((obj.width / 2) - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 16778 break; 16779
16780 case 'next': 16781 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(obj.height - offsetX - heightDiff - (thumbsOffsetH / 2)), 16782 left = (path == 'horizontal') ? parseInt(obj.width - offsetX - widthDiff - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - (width / 2) - widthDiff - offsetY - (thumbsOffsetW / 2)); 16783 break; 16784 16785 case 'prev': 16786 var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(offsetX - heightDiff - height - (thumbsOffsetH / 2)), 16787 left = (path == 'horizontal') ? parseInt(offsetX - widthDiff - width - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - offsetY - (width / 2) - widthDiff - (thumbsOffsetW / 2)); 16788 break; 16789 } 16790 16791 holder.data('offset', { 16792 top: top, 16793 left: left, 16794 newDims: newDims, 16795 diff: { 16796 W: widthDiff, 16797 H: heightDiff 16798 }, 16799 thumbsOffset: { 16800 W: thumbsOffsetW, 16801 H: thumbsOffsetH 16802 }, 16803 object: obj 16804 }); 16805 16806 var opacityMobile; 16807 if ( isMobile ) { 16808 opacityMobile = { 16809 opacity: 1, 16810 top: top, 16811 left: left 16812 }; 16813 } else { 16814 opacityMobile = { 16815 top: top, 16816 left: left 16817 }; 16818 } 16819 16820 if (obj.animate > 0 && opts.effects.reposition) { 16821 holder.css(transform, gpuAcceleration).stop().animate( 16822 opacityMobile, 16823 opts.effects.repositionSpeed, 'easeOutCirc', function() { 16824 holder.css(transform, ''); 16825 }); 16826 $('div.ilightbox-container', holder).stop().animate({ 16827 width: width, 16828 height: height 16829 }, opts.effects.repositionSpeed, 'easeOutCirc'); 16830 $('div.ilightbox-inner-toolbar', holder).stop().animate({ 16831 width: width 16832 }, opts.effects.repositionSpeed, 'easeOutCirc', function() { 16833 $(this).css('overflow', 'visible'); 16834 }); 16835 } else { 16836 holder.css(opacityMobile); 16837 $('div.ilightbox-container', holder).css({ 16838 width: width, 16839 height: height 16840 }); 16841 $('div.ilightbox-inner-toolbar', holder).css({ 16842 width: width 16843 }); 16844 } 16845 }, 16846 16847 16848 resume: function(priority) { 16849 var iL = this, 16850 vars = iL.vars, 16851 opts = iL.options; 16852 16853 if (!opts.slideshow.pauseTime || opts.controls.slideshow && vars.total <= 1 || priority < vars.isPaused) { 16854 return; 16855 } 16856 16857 vars.isPaused = 0; 16858 16859 if (vars.cycleID) { 16860 vars.cycleID = clearTimeout(vars.cycleID); 16861 } 16862 16863 vars.cycleID = setTimeout(function() { 16864 if (vars.current == vars.total - 1) iL.goTo(0); 16865 else iL.moveTo('next'); 16866 }, opts.slideshow.pauseTime); 16867 }, 16868 16869 pause: function(priority) { 16870 var iL = this, 16871 vars = iL.vars, 16872 opts = iL.options; 16873 16874 if (priority < vars.isPaused) { 16875 return; 16876 } 16877 16878 vars.isPaused = priority || 100; 16879 16880 if (vars.cycleID) { 16881 vars.cycleID = clearTimeout(vars.cycleID); 16882 } 16883 }, 16884 16885 resetCycle: function() { 16886 var iL = this, 16887 vars = iL.vars, 16888 opts = iL.options; 16889 16890 if (opts.controls.slideshow && vars.cycleID && !vars.isPaused) { 16891 iL.resume(); 16892 } 16893 }, 16894 16895 getNewDimenstions: function(width, height, width_old, height_old, thumb) { 16896 var iL = this; 16897 16898 if (!width) factor = height / height_old; 16899 else if (!height) factor = width / width_old; 16900 else factor = min(width / width_old, height / height_old); 16901 16902 if (!thumb) { 16903 if (factor > iL.options.maxScale) factor = iL.options.maxScale; 16904 else if (factor < iL.options.minScale) factor = iL.options.minScale; 16905 } 16906 16907 var final_width = (iL.options.keepAspectRatio) ? round(width_old * factor) : width, 16908 final_height = (iL.options.keepAspectRatio) ? round(height_old * factor) : height; 16909 16910 return { 16911 width: final_width, 16912 height: final_height, 16913 ratio: factor 16914 }; 16915 }, 16916 16917 setOption: function(options) { 16918 var iL = this; 16919 16920 iL.options = $.extend(true, iL.options, options || {}); 16921 iL.refresh(); 16922 }, 16923 16924 availPlugins: function() { 16925 var iL = this, 16926 testEl = document.createElement("video"); 16927 16928 iL.plugins = { 16929 flash: !isMobile, 16930 quicktime: (parseInt(PluginDetect.getVersion("QuickTime")) >= 0) ? true : false, 16931 html5H264: !!(testEl.canPlayType && testEl.canPlayType('video/mp4').replace(/no/, '')), 16932 html5WebM: !!(testEl.canPlayType && testEl.canPlayType('video/webm').replace(/no/, '')), 16933 html5Vorbis: !!(testEl.canPlayType && testEl.canPlayType('video/ogg').replace(/no/, '')), 16934 html5QuickTime: !!(testEl.canPlayType && testEl.canPlayType('video/quicktime').replace(/no/, '')) 16935 }; 16936 }, 16937 16938 addContent: function(element, obj) { 16939 var iL = this, 16940 el; 16941 16942 switch (obj.type) { 16943 case 'video': 16944 var HTML5 = false, 16945 videoType = obj.videoType, 16946 html5video = obj.options.html5video; 16947 16948 if (((videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v') || html5video.h264) && iL.plugins.html5H264) 16949 obj.ext = 'mp4', 16950 obj.URL = html5video.h264 || obj.URL; 16951 else if (html5video.webm && iL.plugins.html5WebM) 16952 obj.ext = 'webm', 16953 obj.URL = html5video.webm || obj.URL; 16954 else if (html5video.ogg && iL.plugins.html5Vorbis) 16955 obj.ext = 'ogv', 16956 obj.URL = html5video.ogg || obj.URL; 16957 16958 if (iL.plugins.html5H264 && (videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v')) HTML5 = true, videoType = "video/mp4"; 16959 else if (iL.plugins.html5WebM && (videoType == 'video/webm' || obj.ext == 'webm')) HTML5 = true, videoType = "video/webm"; 16960 else if (iL.plugins.html5Vorbis && (videoType == 'video/ogg' || obj.ext == 'ogv')) HTML5 = true, videoType = "video/ogg"; 16961 else if (iL.plugins.html5QuickTime && (videoType == 'video/quicktime' || obj.ext == 'mov' || obj.ext == 'qt')) HTML5 = true, videoType = "video/quicktime"; 16962 16963 if (HTML5) { 16964 el = $('<video />
16964', { 16965 "width": "100%", 16966 "height": "100%", 16967 "preload": html5video.preload, 16968 "autoplay": html5video.autoplay, 16969 "loop": html5video.loop, 16970 "poster": html5video.poster, 16971 "controls": html5video.controls, 16972 "controlslist": "nodownload" 16973 }).append($('<source />', { 16974 "src": obj.URL, 16975 "type": videoType 16976 })); 16977 } else { 16978 if (!iL.plugins.quicktime) el = $('<span />', { 16979 "class": "ilightbox-alert", 16980 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.quicktime).replace('{type}', 'QuickTime') 16981 }); 16982 else { 16983 16984 el = $('<object />', { 16985 "type": "video/quicktime", 16986 "pluginspage": pluginspages.quicktime 16987 }).attr({ 16988 "data": obj.URL, 16989 "width": "100%", 16990 "height": "100%" 16991 }).append($('<param />', { 16992 "name": "src", 16993 "value": obj.URL 16994 })).append($('<param />', { 16995 "name": "autoplay", 16996 "value": "false" 16997 })).append($('<param />', { 16998 "name": "loop", 16999 "value": "false" 17000 })).append($('<param />', { 17001 "name": "scale", 17002 "value": "tofit" 17003 })); 17004 17005 if (browser.msie) el = QT_GenerateOBJECTText(obj.URL, '100%', '100%', '', 'SCALE', 'tofit', 'AUTOPLAY', 'false', 'LOOP', 'false'); 17006 } 17007 } 17008 17009 break; 17010 17011 case 'flash': 17012 if (!iL.plugins.flash) el = $('<span />', { 17013 "class": "ilightbox-alert", 17014 html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.flash).replace('{type}', 'Adobe Flash player') 17015 }); 17016 else { 17017 var flashvars = "", 17018 i = 0; 17019 17020 if (obj.options.flashvars) $.each(obj.options.flashvars, function(k, v) { 17021 if (i != 0) flashvars += "&"; 17022 flashvars += k + "=" + encodeURIComponent(v); 17023 i++; 17024 }); 17025 else flashvars = null; 17026 17027 el = $('<embed />').attr({ 17028 "type": "application/x-shockwave-flash", 17029 "src": obj.URL, 17030 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 17031 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 17032 "quality": "high", 17033 "bgcolor": "#000000", 17034 "play": "true", 17035 "loop": "true", 17036 "menu": "true", 17037 "wmode": "transparent", 17038 "scale": "showall", 17039 "allowScriptAccess": "always", 17040 "allowFullScreen": "true", 17041 "flashvars": flashvars, 17042 "fullscreen": "yes" 17043 }); 17044 } 17045 17046 break; 17047 17048 case 'iframe': 17049 el = $('<iframe />').attr({ 17050 "width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%", 17051 "height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%", 17052 src: obj.URL, 17053 frameborder: 0, 17054 'hspace': 0, 17055 'vspace': 0, 17056 'scrolling': supportTouch ? 'auto' : 'scroll', 17057 'webkitAllowFullScreen': '', 17058 'mozallowfullscreen': '', 17059 'allowFullScreen': '' 17060 }); 17061 17062 break; 17063 17064 case 'inline': 17065 el = $('<div class="ilightbox-wrapper"></div>').html($(obj.URL).clone(true)); 17066 17067 break; 17068 17069 case 'html': 17070 var object = obj.URL, 17071 el; 17072 17073 if (object[0].nodeName) { 17074 el = $('<div class="ilightbox-wrapper"></div>').html(object); 17075 } else { 17076 var dom = $(obj.URL), 17077 html = (dom.selector) ? $('<div>' + dom + '</div>') : dom; 17078 el = $('<div class="ilightbox-wrapper"></div>').html(html); 17079 } 17080 17081 break; 17082 } 17083 17084 $('div.ilightbox-container', element).empty().html(el); 17085 17086 // For fixing Chrome about just playing the video for first time 17087 if (el[0].tagName.toLowerCase() === 'video' && browser.webkit) setTimeout(function() { 17088 var src = el[0].currentSrc + '?' + floor(random() * 30000); 17089 el[0].currentSrc = src; 17090 el[0].src = src; 17091 }); 17092 17093 return el; 17094 }, 17095 17096 ogpRecognition: function(obj, callback) { 17097 var iL = this, 17098 url = obj.URL; 17099 17100 iL.showLoader(); 17101 doAjax(url, function(data) { 17102 iL.hideLoader(); 17103 if (data) { 17104 var object = new Object(); 17105 17106 object.length = false, 17107 object.url = data.url; 17108 17109 if (data.status == 200) { 17110 var result = data.results, 17111 type = result.type, 17112 source = result.source; 17113 17114 object.source = source.src, 17115 object.width = source.width && parseInt(source.width) || 0, 17116 object.height = source.height && parseInt(source.height) || 0, 17117 object.type = type, 17118 object.thumbnail = source.thumbnail || result.images && result.images[0], 17119 object.html5video = result.html5video || {}, 17120 object.length = true; 17121 17122 if (source.type == 'application/x-shockwave-flash') object.type = "flash"; 17123 else if (source.type.indexOf("video/") != -1) object.type = "video"; 17124 else if (source.type.indexOf("/html") != -1) object.type = "iframe"; 17125 else if (source.type.indexOf("image/") != -1) object.type = "image"; 17126 17127 } else if (typeof data.response != 'undefined') 17128 throw data.response; 17129 17130 callback.call(this, object.length ? object : false); 17131 } 17132 }); 17133 }, 17134 17135 hashChangeHandler: function(url) { 17136 var iL = this, 17137 vars = iL.vars, 17138 opts = iL.options, 17139 URL = url || window.location.href, 17140 hash = parseURI(URL).hash, 17141 split = hash.split('/'), 17142 index = split[1]; 17143 17144 if (vars.hashLock || ('#' + opts.linkId != split[0] && hash.length > 1)) return; 17145 17146 if (index) { 17147 var target = split[1] || 0; 17148 if (iL.items[target]) {
17149 var overlay = $('.ilightbox-overlay'); 17150 if (overlay.length && overlay.attr('linkid') == opts.linkId) { 17151 iL.goTo(target); 17152 } else { 17153 iL.itemsObject[target].trigger(ishybrid ? "itap click" : supportTouch ? 'itap' : 'click'); 17154 //iL.goTo(target); 17155 } 17156 } else { 17157 var overlay = $('.ilightbox-overlay'); 17158 if (overlay.length) iL.closeAction(); 17159 } 17160 } else { 17161 var overlay = $('.ilightbox-overlay'); 17162 if (overlay.length) iL.closeAction(); 17163 } 17164 } 17165 }; 17166 17167 /** 17168 * Parse style to pixels. 17169 * 17170 * @param {Object} $element jQuery object with element. 17171 * @param {Property} property CSS property to get the pixels from. 17172 * 17173 * @return {Int} 17174 */ 17175 function getPixel($element, property) { 17176 return parseInt($element.css(property), 10) || 0; 17177 } 17178 17179 /** 17180 * Make sure that number is within the limits. 17181 * 17182 * @param {Number} number 17183 * @param {Number} min 17184 * @param {Number} max 17185 * 17186 * @return {Number} 17187 */ 17188 function within(number, min, max) { 17189 return number < min ? min : number > max ? max : number; 17190 } 17191 17192 /** 17193 * Get viewport/window size (width and height). 17194 * 17195 * @return {Object} 17196 */ 17197 function getViewport() { 17198 var e = window, 17199 a = 'inner'; 17200 if (!('innerWidth' in window)) { 17201 a = 'client'; 17202 e = document.documentElement || document.body; 17203 } 17204 return { 17205 width: e[a + 'Width'], 17206 height: e[a + 'Height'] 17207 } 17208 } 17209 17210 /** 17211 * Remove hash tag from the URL 17212 * 17213 * @return {Void} 17214 */ 17215 function removeHash() { 17216 var scroll = getScrollXY(); 17217 17218 //UNCODE change 17219 // window.location.hash = ""; 17220 // history.pushState("", document.title, window.location.pathname + window.location.search); 17221 history.replaceState({}, document.title, window.location.pathname + window.location.search); 17222 17223 // Restore the scroll offset, should be flicker free 17224 window.scrollTo(scroll.x, scroll.y); 17225 } 17226 17227 /** 17228 * Do the ajax requests with callback. 17229 * 17230 * @param {String} url 17231 * @param {Function} callback 17232 * 17233 * @return {Void} 17234 */ 17235 function doAjax(url, callback) { 17236 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'); 17237 $.ajax({ 17238 url: url, 17239 dataType: 'jsonp' 17240 }); 17241 17242 iLCallback = function(data) { 17243 callback.call(this, data); 17244 }; 17245 } 17246 17247 /** 17248 * Find image from DOM elements 17249 * 17250 * @param {Element} element 17251 * 17252 * @return {Void} 17253 */ 17254 function findImageInElement(element) { 17255 var elements = $('*', element), 17256 imagesArr = new Array(); 17257 17258 elements.each(function() { 17259 var url = "", 17260 element = this; 17261 17262 if ($(element).css("background-image") != "none") { 17263 url = $(element).css("background-image"); 17264 } else if (typeof($(element).attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") { 17265 url = $(element).attr("src"); 17266 } 17267 17268 if (url.indexOf("gradient") == -1) { 17269 url = url.replace(/url\(\"/g, ""); 17270 url = url.replace(/url\(/g, ""); 17271 url = url.replace(/\"\)/g, ""); 17272 url = url.replace(/\)/g, ""); 17273 17274 var urls = url.split(","); 17275 17276 for (var i = 0; i < urls.length; i++) { 17277 if (urls[i].length > 0 && $.inArray(urls[i], imagesArr) == -1) { 17278 var extra = ""; 17279 if (browser.msie && browser.version < 9) { 17280 extra = "?" + floor(random() * 3000); 17281 } 17282 imagesArr.push(urls[i] + extra); 17283 } 17284 } 17285 } 17286 }); 17287 17288 return imagesArr; 17289 } 17290 17291 /** 17292 * Get file extension. 17293 * 17294 * @param {String} URL 17295 * 17296 * @return {String} 17297 */ 17298 function getExtension(URL) { 17299 if (URL !== null) { 17300 //UNCODE: fix issue to detect media type with query strings 17301 var ext = URL.indexOf('?') !== -1 ? URL.split('?')[0] : URL; 17302 ext = ext.split('.').pop().toLowerCase(); 17303 17304 return ext; 17305 } 17306 } 17307 17308 /** 17309 * Get type via extension. 17310 * 17311 * @param {String} URL 17312 * 17313 * @return {String} 17314 */ 17315 function getTypeByExtension(URL) { 17316 var type, 17317 ext = getExtension(URL); 17318 17319 //Uncode addition ##START## 17320 if (URL == undefined) { 17321 return false; 17322 } 17323 //Uncode addition ##END## 17324 17325 if (extensions.image.indexOf(ext) !== -1) type = 'image'; 17326 else if (extensions.flash.indexOf(ext) !== -1) type = 'flash'; 17327 else if (extensions.video.indexOf(ext) !== -1) type = 'video'; 17328 else if (ext.substring(0, 1) == "#") type = 'inline'; //Uncode addition 17329 else type = 'iframe'; 17330 17331 return type; 17332 } 17333 17334 /** 17335 * Return value from percent of a number. 17336 * 17337 * @param {Number} percent 17338 * @param {Number} total 17339 * 17340 * @return {Number} 17341 */ 17342 function percentToValue(percent, total) { 17343 return parseInt((total / 100) * percent); 17344 } 17345 17346 /** 17347 * A JavaScript equivalent of PHPâs parse_url. 17348 * 17349 * @param {String} url The URL to parse. 17350 * 17351 * @return {Mixed} 17352 */ 17353 function parseURI(url) { 17354 var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); 17355 // authority = '//' + user + ':' + pass '@' + hostname + ':' port 17356 return (m ? { 17357 href: m[0] || '', 17358 protocol: m[1] || '', 17359 authority: m[2] || '', 17360 host: m[3] || '', 17361 hostname: m[4] || '', 17362 port: m[5] || '', 17363 pathname: m[6] || '', 17364 search: m[7] || '', 17365 hash: m[8] || '' 17366 } : null); 17367 } 17368 17369 /** 17370 * Gets the absolute URI. 17371 * 17372 * @param {String} href The relative URL. 17373 * @param {String} base The base URL. 17374 * 17375 * @return {String} The absolute URL. 17376 */ 17377 function absolutizeURI(base, href) { // RFC 3986 17378 var iL = this; 17379 17380 function removeDotSegments(input) { 17381 var output = []; 17382 input.replace(/^(\.\.?(\/|$))+/, '') 17383 .replace(/\/(\.(\/|$))+/g, '/') 17384 .replace(/\/\.\.$/, '/../') 17385 .replace(/\/?[^\/]*/g, function(p) { 17386 if (p === '/..') { 17387 output.pop(); 17388 } else { 17389 output.push(p); 17390 } 17391 }); 17392 return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); 17393 } 17394 17395 href = parseURI(href || ''); 17396 base = parseURI(base || ''); 17397 17398 return !href || !base ? null : (href.protocol || base.protocol) + 17399 (href.protocol || href.authority ? href.authority : base.authority) + 17400 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)) + 17401 (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) + 17402 href.hash; 17403 } 17404 17405 /** 17406 * A JavaScript equivalent of PHPâs version_compare. 17407 * 17408 * @param {String} v1 17409 * @param {String} v2 17410 * @param {String} operator
17411 * 17412 * @return {Boolean} 17413 */ 17414 function version_compare(v1, v2, operator) { 17415 this.php_js = this.php_js || {}; 17416 this.php_js.ENV = this.php_js.ENV || {}; 17417 var i = 0, 17418 x = 0, 17419 compare = 0, 17420 vm = { 17421 'dev': -6, 17422 'alpha': -5, 17423 'a': -5, 17424 'beta': -4, 17425 'b': -4, 17426 'RC': -3, 17427 'rc': -3, 17428 '#': -2, 17429 'p': 1, 17430 'pl': 1 17431 }, 17432 prepVersion = function(v) { 17433 v = ('' + v).replace(/[_\-+]/g, '.'); 17434 v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.'); 17435 return (!v.length ? [-8] : v.split('.')); 17436 }, 17437 numVersion = function(v) { 17438 return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10)); 17439 }; 17440 v1 = prepVersion(v1); 17441 v2 = prepVersion(v2); 17442 x = max(v1.length, v2.length); 17443 for (i = 0; i < x; i++) { 17444 if (v1[i] == v2[i]) { 17445 continue; 17446 } 17447 v1[i] = numVersion(v1[i]); 17448 v2[i] = numVersion(v2[i]); 17449 if (v1[i] < v2[i]) { 17450 compare = -1; 17451 break; 17452 } else if (v1[i] > v2[i]) { 17453 compare = 1; 17454 break; 17455 } 17456 } 17457 if (!operator) { 17458 return compare; 17459 } 17460 17461 switch (operator) { 17462 case '>': 17463 case 'gt': 17464 return (compare > 0); 17465 case '>=': 17466 case 'ge': 17467 return (compare >= 0); 17468 case '<=': 17469 case 'le': 17470 return (compare <= 0); 17471 case '==': 17472 case '=': 17473 case 'eq': 17474 return (compare === 0); 17475 case '<>': 17476 case '!=': 17477 case 'ne': 17478 return (compare !== 0); 17479 case '': 17480 case '<': 17481 case 'lt': 17482 return (compare < 0); 17483 default: 17484 return null; 17485 } 17486 } 17487 17488 17489 // Begin the iLightBox plugin 17490 $.fn.iLightBox = function() { 17491 17492 var args = arguments, 17493 opt = ($.isPlainObject(args[0])) ? args[0] : args[1], 17494 items = ($.isArray(args[0]) || typeof args[0] == 'string') ? args[0] : args[1]; 17495 17496 if (!opt) opt = {}; 17497 17498 // Default options. Play carefully. 17499 var options = $.extend(true, { 17500 attr: 'href', 17501 path: 'vertical', 17502 skin: 'dark', 17503 linkId: false, 17504 infinite: false, 17505 startFrom: 0, 17506 randomStart: false, 17507 keepAspectRatio: true, 17508 maxScale: 1, 17509 minScale: .2, 17510 innerToolbar: false, 17511 smartRecognition: false, 17512 mobileOptimizer: true, 17513 fullAlone: true, 17514 fullViewPort: null, 17515 fullStretchTypes: 'flash, video', 17516 overlay: { 17517 blur: true, 17518 opacity: .85 17519 }, 17520 controls: { 17521 arrows: false, 17522 slideshow: false, 17523 toolbar: true, 17524 fullscreen: true, 17525 thumbnail: true, 17526 keyboard: true, 17527 mousewheel: true, 17528 swipe: true 17529 }, 17530 keyboard: { 17531 left: true, // previous 17532 right: true, // next 17533 up: true, // previous 17534 down: true, // next 17535 esc: true, // close 17536 shift_enter: true // fullscreen 17537 }, 17538 show: { 17539 effect: true, 17540 speed: 300, 17541 title: true 17542 }, 17543 hide: { 17544 effect: true, 17545 speed: 300 17546 }, 17547 caption: { 17548 start: true, 17549 show: 'mouseenter', 17550 hide: 'mouseleave' 17551 }, 17552 social: { 17553 start: true, 17554 show: 'mouseenter', 17555 hide: 'mouseleave',
17556 buttons: false 17557 }, 17558 styles: { 17559 pageOffsetX: 0, 17560 pageOffsetY: 0, 17561 nextOffsetX: 45, 17562 nextOffsetY: 0, 17563 nextOpacity: 1, 17564 nextScale: 1, 17565 prevOffsetX: 45, 17566 prevOffsetY: 0, 17567 prevOpacity: 1, 17568 prevScale: 1 17569 }, 17570 thumbnails: { 17571 maxWidth: 120, 17572 maxHeight: 80, 17573 normalOpacity: 1, 17574 activeOpacity: .6 17575 }, 17576 effects: { 17577 reposition: true, 17578 repositionSpeed: 200, 17579 switchSpeed: 500, 17580 loadedFadeSpeed: 180, 17581 fadeSpeed: 200 17582 }, 17583 slideshow: { 17584 pauseTime: 5000, 17585 pauseOnHover: false, 17586 startPaused: true 17587 }, 17588 text: { 17589 close: "Press Esc to close", 17590 enterFullscreen: "Enter Fullscreen (Shift+Enter)", 17591 exitFullscreen: "Exit Fullscreen (Shift+Enter)", 17592 slideShow: "Slideshow", 17593 next: "Next", 17594 previous: "Previous" 17595 }, 17596 errors: { 17597 loadImage: "An error occurred when trying to load photo.", 17598 loadContents: "An error occurred when trying to load contents.", 17599 missingPlugin: "The content your are attempting to view requires the <a href='{pluginspage}' target='_blank'>{type} plugin<\/a>." 17600 }, 17601 ajaxSetup: { 17602 url: '', 17603 beforeSend: function(jqXHR, settings) {}, 17604 cache: false, 17605 complete: function(jqXHR, textStatus) {}, 17606 crossDomain: false, 17607 error: function(jqXHR, textStatus, errorThrown) {}, 17608 success: function(data, textStatus, jqXHR) {}, 17609 global: true, 17610 ifModified: false, 17611 username: null, 17612 password: null, 17613 type: 'GET' 17614 }, 17615 callback: {} 17616 }, opt); 17617 17618 var instant = ($.isArray(items) || typeof items == 'string') ? true : false; 17619 17620 items = $.isArray(items) ? items : new Array(); 17621 17622 if (typeof args[0] == 'string') items[0] = args[0]; 17623 17624 if (version_compare($.fn.jquery, '1.8', '>=')) { 17625 var iLB = new iLightBox($(this), options, items, instant); 17626 return { 17627 close: function() { 17628 iLB.closeAction(); 17629 }, 17630 fullscreen: function() { 17631 iLB.fullScreenAction(); 17632 }, 17633 moveNext: function() { 17634 iLB.moveTo('next'); 17635 }, 17636 movePrev: function() { 17637 iLB.moveTo('prev'); 17638 }, 17639 goTo: function(index) { 17640 iLB.goTo(index); 17641 }, 17642 refresh: function() { 17643 iLB.refresh(); 17644 }, 17645 reposition: function() { 17646 (arguments.length > 0) ? iLB.repositionPhoto(true): iLB.repositionPhoto(); 17647 }, 17648 setOption: function(options) { 17649 iLB.setOption(options); 17650 }, 17651 destroy: function() { 17652 iLB.closeAction(); 17653 iLB.dispatchItemsEvents(); 17654 } 17655 }; 17656 } else { 17657 throw "The jQuery version that was loaded is too old. iLightBox requires jQuery 1.8+"; 17658 } 17659 17660 }; 17661 17662 17663 $.iLightBox = function() { 17664 return $.fn.iLightBox(arguments[0], arguments[1]); 17665 }; 17666 17667 function getScrollXY() { 17668 var scrOfX = 0, 17669 scrOfY = 0; 17670 if (typeof(window.pageYOffset) == 'number') { 17671 //Netscape compliant 17672 scrOfY = window.pageYOffset; 17673 scrOfX = window.pageXOffset; 17674 } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) { 17675 //DOM compliant 17676 scrOfY = document.body.scrollTop; 17677 scrOfX = document.body.scrollLeft; 17678 } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) { 17679 //IE6 standards compliant mode 17680 scrOfY = document.documentElement.scrollTop; 17681 scrOfX = document.documentElement.scrollLeft; 17682 } 17683 return { 17684 x: scrOfX, 17685 y: scrOfY 17686 }; 17687 } 17688 17689 (function() { 17690 // add new event shortcuts 17691 $.each(("touchstart touchmove touchend " + 17692 "tap taphold " + 17693 "swipe swipeleft swiperight " + 17694 "scrollstart scrollstop").split(" "), function(i, name) { 17695 17696 $.fn[name] = function(fn) { 17697 return fn ? this.bind(name, fn) : this.trigger(name); 17698 }; 17699 17700 // jQuery < 1.8 17701 // if ($.attrFn) { 17702 // $.attrFn[name] = true; 17703 // } 17704 }); 17705 17706 var tapSettings = { 17707 startEvent: 'touchstart.iTap', 17708 endEvent: 'touchend.iTap' 17709 }; 17710 17711 // tap Event: 17712 $.event.special.itap = { 17713 setup: function() { 17714 17715 var self = this, 17716 $self = $(this), 17717 start, stop; 17718 17719 $self.bind(tapSettings.startEvent, function(event) { 17720 start = getScrollXY(); 17721 17722 $self.one(tapSettings.endEvent, function(event) { 17723 stop = getScrollXY(); 17724 17725 var orgEvent = event || window.event; 17726 event = $.event.fix(orgEvent); 17727 event.type = "itap"; 17728 17729 if ((start && stop) && (start.x == stop.x && start.y == stop.y))($.event.dispatch || $.event.handle).call(self, event); 17730 17731 start = stop = undefined; 17732 }); 17733 }); 17734 }, 17735 17736 teardown: function() { 17737 $(this).unbind(tapSettings.startEvent); 17738 } 17739 }; 17740 }()); 17741 17742 17743 //Fullscreen API 17744 (function() { 17745 fullScreenApi = { 17746 supportsFullScreen: false, 17747 isFullScreen: function() { 17748 return false;
17749 }, 17750 requestFullScreen: function() {}, 17751 cancelFullScreen: function() {}, 17752 fullScreenEventName: '', 17753 prefix: '' 17754 }, 17755 browserPrefixes = 'webkit moz o ms khtml'.split(' '); 17756 17757 // check for native support 17758 if (typeof document.cancelFullScreen != 'undefined') { 17759 fullScreenApi.supportsFullScreen = true; 17760 } else { 17761 // check for fullscreen support by vendor prefix 17762 for (var i = 0, il = browserPrefixes.length; i < il; i++) { 17763 fullScreenApi.prefix = browserPrefixes[i]; 17764 17765 if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') { 17766 fullScreenApi.supportsFullScreen = true; 17767 17768 break; 17769 } 17770 } 17771 } 17772 17773 // update methods to do something useful 17774 if (fullScreenApi.supportsFullScreen) { 17775 fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange'; 17776 17777 fullScreenApi.isFullScreen = function() { 17778 switch (this.prefix) { 17779 case '': 17780 return document.fullScreen; 17781 case 'webkit': 17782 return document.webkitIsFullScreen; 17783 default: 17784 return document[this.prefix + 'FullScreen']; 17785 } 17786 } 17787 fullScreenApi.requestFullScreen = function(el) { 17788 return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen'](); 17789 } 17790 fullScreenApi.cancelFullScreen = function(el) { 17791 return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen'](); 17792 } 17793 } 17794 }()); 17795 17796 // Browser detect 17797 (function() { 17798 function uaMatch(ua) { 17799 ua = ua.toLowerCase(); 17800 17801 var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || 17802 /(webkit)[ \/]([\w.]+)/.exec(ua) || 17803 /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || 17804 /(msie) ([\w.]+)/.exec(ua) || 17805 ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; 17806 17807 return { 17808 browser: match[1] || "", 17809 version: match[2] || "0" 17810 }; 17811 } 17812 17813 var matched = uaMatch(navigator.userAgent); 17814 browser = {}; 17815 17816 if (matched.browser) { 17817 browser[matched.browser] = true; 17818 browser.version = matched.version; 17819 } 17820 17821 // Chrome is Webkit, but Webkit is also Safari. 17822 if (browser.chrome) { 17823 browser.webkit = true; 17824 } else if (browser.webkit) { 17825 browser.safari = true; 17826 } 17827 }()); 17828 17829 // Feature detects 17830 (function() { 17831 var prefixes = ['', 'webkit', 'moz', 'ms', 'o']; 17832 var el = document.createElement('div'); 17833 17834 function testProp(prop) { 17835 for (var p = 0, pl = prefixes.length; p < pl; p++) { 17836 var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop; 17837 if (el.style[prefixedProp] !== undefined) { 17838 return prefixedProp; 17839 } 17840 } 17841 } 17842 17843 // Global support indicators 17844 transform = testProp('transform') || ''; 17845 gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : ''; 17846 }()); 17847 17848 17849 /* 17850 PluginDetect v0.7.9 17851 www.pinlady.net/PluginDetect/license/ 17852 [ getVersion onWindowLoaded BetterIE ] 17853 [ Flash QuickTime Shockwave ] 17854 */ 17855 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;
17855d++){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);
17855d.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)}
17855c.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;
17855if(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(); 17856 17857 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)}; 17858 17859 17860 /* 17861 jQuery hashchange event v1.3 17862 https://github.com/cowboy/jquery-hashchange 17863 Copyright (c) 2010 "Cowboy" Ben Alman 17864 Dual licensed under the MIT and GPL licenses. 17865 */ 17866 (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= 17867 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|| 17868 "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;
17868a!==d&&(b.title=k.title,b.open(),e&&b.write('<script>document.domain="'+e+'"\x3c/script>'),b.close(),c.location.hash=a)}}();return h}()})(); 17869 17870 if (!Array.prototype.filter) { 17871 Array.prototype.filter = function(fun /*, thisp */ ) { 17872 "use strict"; 17873 17874 if (this == null) 17875 throw new TypeError(); 17876 17877 var t = Object(this); 17878 var len = t.length >>> 0; 17879 if (typeof fun != "function") 17880 throw new TypeError(); 17881 17882 var res = []; 17883 var thisp = arguments[1]; 17884 for (var i = 0; i < len; i++) { 17885 if (i in t) { 17886 var val = t[i]; // in case fun mutates this 17887 if (fun.call(thisp, val, i, t)) 17888 res.push(val); 17889 } 17890 } 17891 17892 return res; 17893 }; 17894 } 17895 17896 if (!Array.prototype.indexOf) { 17897 Array.prototype.indexOf = function(searchElement, fromIndex) { 17898 var k; 17899 17900 if (this == null) { 17901 throw new TypeError('"this" is null or not defined'); 17902 } 17903 17904 var O = Object(this); 17905 17906 var len = O.length >>> 0; 17907 17908 if (len === 0) { 17909 return -1; 17910 } 17911 17912 var n = +fromIndex || 0; 17913 17914 if (abs(n) === Infinity) { 17915 n = 0; 17916 } 17917 17918 if (n >= len) { 17919 return -1; 17920 } 17921 17922 k = max(n >= 0 ? n : len - abs(n), 0); 17923 17924 while (k < len) { 17925 var kValue; 17926 if (k in O && O[k] === searchElement) { 17927 return k; 17928 } 17929 k++; 17930 } 17931 return -1; 17932 }; 17933 } 17934 17935 if (!Array.prototype.lastIndexOf) { 17936 Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/ ) { 17937 "use strict"; 17938 17939 if (this == null) 17940 throw new TypeError(); 17941 17942 var t = Object(this); 17943 var len = t.length >>> 0; 17944 if (len === 0) 17945 return -1; 17946 17947 var n = len; 17948 if (arguments.length > 1) { 17949 n = Number(arguments[1]); 17950 if (n != n) 17951 n = 0; 17952 else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) 17953 n = (n > 0 || -1) * floor(abs(n)); 17954 } 17955 17956 var k = n >= 0 ? min(n, len - 1) : len - abs(n); 17957 17958 for (; k >= 0; k--) { 17959 if (k in t && t[k] === searchElement) 17960 return k; 17961 } 17962 return -1; 17963 }; 17964 } 17965})(jQuery, this); 17966 17967/*! 17968 * lightgallery | 2.5.0 | June 13th 2022 17969 * http://www.lightgalleryjs.com/ 17970 * Copyright (c) 2020 Sachin Neravath; 17971 * @license GPLv3 17972 */ 17973 17974(function (global, factory) { 17975 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 17976 typeof define === 'function' && define.amd ? define(factory) : 17977 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lightGallery = factory()); 17978}(this, (function () { 'use strict'; 17979 17980 /*! ***************************************************************************** 17981 Copyright (c) Microsoft Corporation. 17982 17983 Permission to use, copy, modify, and/or distribute this software for any 17984 purpose with or without fee is hereby granted. 17985 17986 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 17987 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 17988 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 17989 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17990 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 17991 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17992 PERFORMANCE OF THIS SOFTWARE. 17993 ***************************************************************************** */ 17994 17995 var __assign = function() { 17996 __assign = Object.assign || function __assign(t) { 17997 for (var s, i = 1, n = arguments.length; i < n; i++) { 17998 s = arguments[i]; 17999 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 18000 } 18001 return t; 18002 }; 18003 return __assign.apply(this, arguments); 18004 }; 18005 18006 function __spreadArrays() { 18007 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 18008 for (var r = Array(s), k = 0, i = 0; i < il; i++) 18009 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 18010 r[k] = a[j]; 18011 return r; 18012 } 18013 18014 /** 18015 * List of lightGallery events 18016 * All events should be documented here 18017 * Below interfaces are used to build the website documentations 18018 * */ 18019 var lGEvents = { 18020 afterAppendSlide: 'lgAfterAppendSlide', 18021 init: 'lgInit', 18022 hasVideo: 'lgHasVideo', 18023 containerResize: 'lgContainerResize', 18024 updateSlides: 'lgUpdateSlides', 18025 afterAppendSubHtml: 'lgAfterAppendSubHtml', 18026 beforeOpen: 'lgBeforeOpen', 18027 afterOpen: 'lgAfterOpen', 18028 slideItemLoad: 'lgSlideItemLoad', 18029 beforeSlide: 'lgBeforeSlide', 18030 afterSlide: 'lgAfterSlide', 18031 posterClick: 'lgPosterClick', 18032 dragStart: 'lgDragStart', 18033 dragMove: 'lgDragMove', 18034 dragEnd: 'lgDragEnd', 18035 beforeNextSlide: 'lgBeforeNextSlide', 18036 beforePrevSlide: 'lgBeforePrevSlide', 18037 beforeClose: 'lgBeforeClose', 18038 afterClose: 'lgAfterClose', 18039 rotateLeft: 'lgRotateLeft', 18040 rotateRight: 'lgRotateRight', 18041 flipHorizontal: 'lgFlipHorizontal', 18042 flipVertical: 'lgFlipVertical', 18043 autoplay: 'lgAutoplay', 18044 autoplayStart: 'lgAutoplayStart', 18045 autoplayStop: 'lgAutoplayStop', 18046 }; 18047 18048 var lightGalleryCoreSettings = { 18049 mode: 'lg-slide', 18050 easing: 'ease', 18051 speed: 400, 18052 licenseKey: '0000-0000-000-0000', 18053 height: '100%', 18054 width: '100%', 18055 addClass: '', 18056 startClass: 'lg-start-zoom', 18057 backdropDuration: 300, 18058 container: '', 18059 startAnimationDuration: 400, 18060 zoomFromOrigin: true, 18061 hideBarsDelay: 0, 18062 showBarsAfter: 10000, 18063 slideDelay: 0, 18064 supportLegacyBrowser: true, 18065 allowMediaOverlap: false, 18066 videoMaxSize: '1280-720', 18067 loadYouTubePoster: true, 18068 defaultCaptionHeight: 0, 18069 ariaLabelledby: '', 18070 ariaDescribedby: '', 18071 resetScrollPosition: true, 18072 hideScrollbar: false, 18073 closable: true, 18074 swipeToClose: true, 18075 closeOnTap: true, 18076 showCloseIcon: true, 18077 showMaximizeIcon: false, 18078 loop: true, 18079 escKey: true, 18080 keyPress: true, 18081 trapFocus: true, 18082 controls: true, 18083 slideEndAnimation: true, 18084 hideControlOnEnd: false,
vendor: 17,869 bytes, lines 18085-18704
18085 mousewheel: false, 18086 getCaptionFromTitleOrAlt: true, 18087 appendSubHtmlTo: '.lg-sub-html', 18088 subHtmlSelectorRelative: false, 18089 preload: 2, 18090 numberOfSlideItemsInDom: 10, 18091 selector: '', 18092 selectWithin: '', 18093 nextHtml: '', 18094 prevHtml: '', 18095 index: 0, 18096 iframeWidth: '100%', 18097 iframeHeight: '100%', 18098 iframeMaxWidth: '100%', 18099 iframeMaxHeight: '100%', 18100 download: true, 18101 counter: true, 18102 appendCounterTo: '.lg-toolbar', 18103 swipeThreshold: 50, 18104 enableSwipe: true, 18105 enableDrag: true, 18106 dynamic: false, 18107 dynamicEl: [], 18108 extraProps: [], 18109 exThumbImage: '', 18110 isMobile: undefined, 18111 mobileSettings: { 18112 controls: false, 18113 showCloseIcon: false, 18114 download: false, 18115 }, 18116 plugins: [], 18117 strings: { 18118 closeGallery: 'Close gallery', 18119 toggleMaximize: 'Toggle maximize', 18120 previousSlide: 'Previous slide', 18121 nextSlide: 'Next slide', 18122 download: 'Download', 18123 playVideo: 'Play video', 18124 }, 18125 }; 18126 18127 function initLgPolyfills() { 18128 (function () { 18129 if (typeof window.CustomEvent === 'function') 18130 return false; 18131 function CustomEvent(event, params) { 18132 params = params || { 18133 bubbles: false, 18134 cancelable: false, 18135 detail: null, 18136 }; 18137 var evt = document.createEvent('CustomEvent'); 18138 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); 18139 return evt; 18140 } 18141 window.CustomEvent = CustomEvent; 18142 })(); 18143 (function () { 18144 if (!Element.prototype.matches) { 18145 Element.prototype.matches = 18146 Element.prototype.msMatchesSelector || 18147 Element.prototype.webkitMatchesSelector; 18148 } 18149 })(); 18150 } 18151 var lgQuery = /** @class */ (function () { 18152 function lgQuery(selector) { 18153 this.cssVenderPrefixes = [ 18154 'TransitionDuration', 18155 'TransitionTimingFunction', 18156 'Transform', 18157 'Transition', 18158 ]; 18159 this.selector = this._getSelector(selector); 18160 this.firstElement = this._getFirstEl(); 18161 return this; 18162 } 18163 lgQuery.generateUUID = function () { 18164 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 18165 var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8; 18166 return v.toString(16); 18167 }); 18168 }; 18169 lgQuery.prototype._getSelector = function (selector, context) { 18170 if (context === void 0) { context = document; } 18171 if (typeof selector !== 'string') { 18172 return selector; 18173 } 18174 context = context || document; 18175 var fl = selector.substring(0, 1); 18176 if (fl === '#') { 18177 return context.querySelector(selector); 18178 } 18179 else { 18180 return context.querySelectorAll(selector); 18181 } 18182 }; 18183 lgQuery.prototype._each = function (func) { 18184 if (!this.selector) { 18185 return this; 18186 } 18187 if (this.selector.length !== undefined) { 18188 [].forEach.call(this.selector, func); 18189 } 18190 else { 18191 func(this.selector, 0); 18192 } 18193 return this; 18194 }; 18195 lgQuery.prototype._setCssVendorPrefix = function (el, cssProperty, value) { 18196 // prettier-ignore 18197 var property = cssProperty.replace(/-([a-z])/gi, function (s, group1) { 18198 return group1.toUpperCase(); 18199 }); 18200 if (this.cssVenderPrefixes.indexOf(property) !== -1) { 18201 el.style[property.charAt(0).toLowerCase() + property.slice(1)] = value; 18202 el.style['webkit' + property] = value; 18203 el.style['moz' + property] = value; 18204 el.style['ms' + property] = value; 18205 el.style['o' + property] = value; 18206 } 18207 else { 18208 el.style[property] = value; 18209 } 18210 }; 18211 lgQuery.prototype._getFirstEl = function () { 18212 if (this.selector && this.selector.length !== undefined) { 18213 return this.selector[0]; 18214 } 18215 else { 18216 return this.selector; 18217 } 18218 }; 18219 lgQuery.prototype.isEventMatched = function (event, eventName) { 18220 var eventNamespace = eventName.split('.'); 18221 return event 18222 .split('.') 18223 .filter(function (e) { return e; }) 18224 .every(function (e) { 18225 return eventNamespace.indexOf(e) !== -1; 18226 }); 18227 }; 18228 lgQuery.prototype.attr = function (attr, value) { 18229 if (value === undefined) { 18230 if (!this.firstElement) { 18231 return ''; 18232 } 18233 return this.firstElement.getAttribute(attr); 18234 } 18235 this._each(function (el) { 18236 el.setAttribute(attr, value); 18237 }); 18238 return this; 18239 }; 18240 lgQuery.prototype.find = function (selector) { 18241 return $LG(this._getSelector(selector, this.selector)); 18242 }; 18243 lgQuery.prototype.first = function () { 18244 if (this.selector && this.selector.length !== undefined) { 18245 return $LG(this.selector[0]); 18246 } 18247 else { 18248 return $LG(this.selector); 18249 } 18250 }; 18251 lgQuery.prototype.eq = function (index) { 18252 return $LG(this.selector[index]); 18253 }; 18254 lgQuery.prototype.parent = function () { 18255 return $LG(this.selector.parentElement); 18256 }; 18257 lgQuery.prototype.get = function () { 18258 return this._getFirstEl(); 18259 }; 18260 lgQuery.prototype.removeAttr = function (attributes) { 18261 var attrs = attributes.split(' '); 18262 this._each(function (el) { 18263 attrs.forEach(function (attr) { return el.removeAttribute(attr); }); 18264 }); 18265 return this; 18266 }; 18267 lgQuery.prototype.wrap = function (className) { 18268 if (!this.firstElement) { 18269 return this; 18270 } 18271 var wrapper = document.createElement('div'); 18272 wrapper.className = className; 18273 this.firstElement.parentNode.insertBefore(wrapper, this.firstElement); 18274 this.firstElement.parentNode.removeChild(this.firstElement); 18275 wrapper.appendChild(this.firstElement); 18276 return this; 18277 }; 18278 lgQuery.prototype.addClass = function (classNames) { 18279 if (classNames === void 0) { classNames = ''; } 18280 this._each(function (el) { 18281 // IE doesn't support multiple arguments 18282 classNames.split(' ').forEach(function (className) { 18283 if (className) { 18284 el.classList.add(className); 18285 } 18286 }); 18287 }); 18288 return this; 18289 }; 18290 lgQuery.prototype.removeClass = function (classNames) { 18291 this._each(function (el) { 18292 // IE doesn't support multiple arguments 18293 classNames.split(' ').forEach(function (className) { 18294 if (className) { 18295 el.classList.remove(className); 18296 } 18297 }); 18298 }); 18299 return this; 18300 }; 18301 lgQuery.prototype.hasClass = function (className) { 18302 if (!this.firstElement) { 18303 return false; 18304 } 18305 return this.firstElement.classList.contains(className); 18306 }; 18307 lgQuery.prototype.hasAttribute = function (attribute) { 18308 if (!this.firstElement) { 18309 return false; 18310 } 18311 return this.firstElement.hasAttribute(attribute); 18312 }; 18313 lgQuery.prototype.toggleClass = function (className) { 18314 if (!this.firstElement) { 18315 return this; 18316 } 18317 if (this.hasClass(className)) { 18318 this.removeClass(className); 18319 } 18320 else { 18321 this.addClass(className); 18322 } 18323 return this; 18324 }; 18325 lgQuery.prototype.css = function (property, value) { 18326 var _this = this; 18327 this._each(function (el) { 18328 _this._setCssVendorPrefix(el, property, value); 18329 }); 18330 return this; 18331 }; 18332 // Need to pass separate namespaces for separate elements 18333 lgQuery.prototype.on = function (events, listener) { 18334 var _this = this; 18335 if (!this.selector) { 18336 return this; 18337 } 18338 events.split(' ').forEach(function (event) { 18339 if (!Array.isArray(lgQuery.eventListeners[event])) { 18340 lgQuery.eventListeners[event] = []; 18341 } 18342 lgQuery.eventListeners[event].push(listener); 18343 _this.selector.addEventListener(event.split('.')[0], listener); 18344 }); 18345 return this; 18346 }; 18347 // @todo - test this 18348 lgQuery.prototype.once = function (event, listener) { 18349 var _this = this; 18350 this.on(event, function () { 18351 _this.off(event); 18352 listener(event); 18353 }); 18354 return this; 18355 }; 18356 lgQuery.prototype.off = function (event) { 18357 var _this = this; 18358 if (!this.selector) { 18359 return this; 18360 } 18361 Object.keys(lgQuery.eventListeners).forEach(function (eventName) { 18362 if (_this.isEventMatched(event, eventName)) { 18363 lgQuery.eventListeners[eventName].forEach(function (listener) { 18364 _this.selector.removeEventListener(eventName.split('.')[0], listener); 18365 }); 18366 lgQuery.eventListeners[eventName] = []; 18367 } 18368 }); 18369 return this; 18370 }; 18371 lgQuery.prototype.trigger = function (event, detail) { 18372 if (!this.firstElement) { 18373 return this; 18374 } 18375 var customEvent = new CustomEvent(event.split('.')[0], { 18376 detail: detail || null, 18377 }); 18378 this.firstElement.dispatchEvent(customEvent); 18379 return this; 18380 }; 18381 // Does not support IE 18382 lgQuery.prototype.load = function (url) { 18383 var _this = this; 18384 fetch(url) 18385 .then(function (res) { return res.text(); }) 18386 .then(function (html) { 18387 _this.selector.innerHTML = html; 18388 }); 18389 return this; 18390 }; 18391 lgQuery.prototype.html = function (html) { 18392 if (html === undefined) { 18393 if (!this.firstElement) { 18394 return ''; 18395 } 18396 return this.firstElement.innerHTML; 18397 } 18398 this._each(function (el) { 18399 el.innerHTML = html; 18400 }); 18401 return this; 18402 }; 18403 lgQuery.prototype.append = function (html) { 18404 this._each(function (el) { 18405 if (typeof html === 'string') { 18406 el.insertAdjacentHTML('beforeend', html); 18407 } 18408 else { 18409 el.appendChild(html); 18410 } 18411 }); 18412 return this; 18413 }; 18414 lgQuery.prototype.prepend = function (html) { 18415 this._each(function (el) { 18416 el.insertAdjacentHTML('afterbegin', html); 18417 }); 18418 return this; 18419 }; 18420 lgQuery.prototype.remove = function () { 18421 this._each(function (el) { 18422 el.parentNode.removeChild(el); 18423 }); 18424 return this; 18425 }; 18426 lgQuery.prototype.empty = function () { 18427 this._each(function (el) { 18428 el.innerHTML = ''; 18429 }); 18430 return this; 18431 }; 18432 lgQuery.prototype.scrollTop = function (scrollTop) { 18433 if (scrollTop !== undefined) { 18434 document.body.scrollTop = scrollTop; 18435 document.documentElement.scrollTop = scrollTop; 18436 return this; 18437 } 18438 else { 18439 return (window.pageYOffset || 18440 document.documentElement.scrollTop || 18441 document.body.scrollTop || 18442 0); 18443 } 18444 }; 18445 lgQuery.prototype.scrollLeft = function (scrollLeft) { 18446 if (scrollLeft !== undefined) { 18447 document.body.scrollLeft = scrollLeft; 18448 document.documentElement.scrollLeft = scrollLeft; 18449 return this; 18450 } 18451 else { 18452 return (window.pageXOffset || 18453 document.documentElement.scrollLeft || 18454 document.body.scrollLeft || 18455 0); 18456 } 18457 }; 18458 lgQuery.prototype.offset = function () { 18459 if (!this.firstElement) { 18460 return { 18461 left: 0, 18462 top: 0, 18463 }; 18464 } 18465 var rect = this.firstElement.getBoundingClientRect(); 18466 var bodyMarginLeft = $LG('body').style().marginLeft; 18467 // Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value 18468 return { 18469 left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(), 18470 top: rect.top + this.scrollTop(), 18471 }; 18472 }; 18473 lgQuery.prototype.style = function () { 18474 if (!this.firstElement) { 18475 return {}; 18476 } 18477 return (this.firstElement.currentStyle || 18478 window.getComputedStyle(this.firstElement)); 18479 }; 18480 // Width without padding and border even if box-sizing is used. 18481 lgQuery.prototype.width = function () { 18482 var style = this.style(); 18483 return (this.firstElement.clientWidth - 18484 parseFloat(style.paddingLeft) - 18485 parseFloat(style.paddingRight)); 18486 }; 18487 // Height without padding and border even if box-sizing is used. 18488 lgQuery.prototype.height = function () { 18489 var style = this.style(); 18490 return (this.firstElement.clientHeight - 18491 parseFloat(style.paddingTop) - 18492 parseFloat(style.paddingBottom)); 18493 }; 18494 lgQuery.eventListeners = {}; 18495 return lgQuery; 18496 }()); 18497 function $LG(selector) { 18498 initLgPolyfills(); 18499 return new lgQuery(selector); 18500 } 18501 18502 var defaultDynamicOptions = [ 18503 'src', 18504 'sources', 18505 'subHtml', 18506 'subHtmlUrl', 18507 'html', 18508 'video', 18509 'poster', 18510 'slideName', 18511 'responsive', 18512 'srcset', 18513 'sizes', 18514 'iframe', 18515 'downloadUrl', 18516 'download', 18517 'width', 18518 'facebookShareUrl', 18519 'tweetText', 18520 'iframeTitle', 18521 'twitterShareUrl', 18522 'pinterestShareUrl', 18523 'pinterestText', 18524 'fbHtml', 18525 'disqusIdentifier', 18526 'disqusUrl', 18527 ]; 18528 // Convert html data-attribute to camalcase 18529 function convertToData(attr) { 18530 // FInd a way for lgsize 18531 if (attr === 'href') { 18532 return 'src'; 18533 } 18534 attr = attr.replace('data-', ''); 18535 attr = attr.charAt(0).toLowerCase() + attr.slice(1); 18536 attr = attr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); 18537 return attr; 18538 } 18539 var utils = { 18540 /** 18541 * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option 18542 */ 18543 //Uncode edit ##START## 18544 getSize: function (el, container, spacing, defaultLgSize, galleryItem) { 18545 // getSize: function (el, container, spacing, defaultLgSize) { 18546 //Uncode edit ##END## 18547 if (spacing === void 0) { spacing = 0; } 18548 var LGel = $LG(el); 18549 var lgSize = LGel.attr('data-lg-size') || defaultLgSize; 18550 //Uncode edit ##START## 18551 if ( typeof galleryItem.size && galleryItem.size != null ) { 18552 lgSize = galleryItem.size; 18553 } 18554 //Uncode edit ##END## 18555 if (!lgSize) { 18556 return; 18557 } 18558 var isResponsiveSizes = lgSize.split(','); 18559 // if at-least two viewport sizes are available 18560 if (isResponsiveSizes[1]) { 18561 var wWidth = window.innerWidth; 18562 for (var i = 0; i < isResponsiveSizes.length; i++) { 18563 var size_1 = isResponsiveSizes[i]; 18564 var responsiveWidth = parseInt(size_1.split('-')[2], 10); 18565 if (responsiveWidth > wWidth) { 18566 lgSize = size_1; 18567 break; 18568 } 18569 // take last item as last option 18570 if (i === isResponsiveSizes.length - 1) { 18571 lgSize = size_1; 18572 } 18573 } 18574 } 18575 var size = lgSize.split('-'); 18576 var width = parseInt(size[0], 10); 18577 var height = parseInt(size[1], 10); 18578 var cWidth = container.width(); 18579 var cHeight = container.height() - spacing; 18580 var maxWidth = Math.min(cWidth, width); 18581 var maxHeight = Math.min(cHeight, height); 18582 var ratio = Math.min(maxWidth / width, maxHeight / height); 18583 return { width: width * ratio, height: height * ratio }; 18584 }, 18585 /** 18586 * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option 18587 * @param {jQuery Element} 18588 * @returns {String} Transform CSS string 18589 */ 18590 getTransform: function (el, container, top, bottom, imageSize) { 18591 if (!imageSize) { 18592 return; 18593 } 18594 var LGel = $LG(el).find('img').first(); 18595 if (!LGel.get()) { 18596 return; 18597 } 18598 var containerRect = container.get().getBoundingClientRect(); 18599 var wWidth = containerRect.width; 18600 // using innerWidth to include mobile safari bottom bar 18601 var wHeight = container.height() - (top + bottom); 18602 var elWidth = LGel.width(); 18603 var elHeight = LGel.height(); 18604 var elStyle = LGel.style(); 18605 var x = (wWidth - elWidth) / 2 - 18606 LGel.offset().left + 18607 (parseFloat(elStyle.paddingLeft) || 0) + 18608 (parseFloat(elStyle.borderLeft) || 0) + 18609 $LG(window).scrollLeft() + 18610 containerRect.left; 18611 var y = (wHeight - elHeight) / 2 - 18612 LGel.offset().top + 18613 (parseFloat(elStyle.paddingTop) || 0) + 18614 (parseFloat(elStyle.borderTop) || 0) + 18615 $LG(window).scrollTop() + 18616 top; 18617 var scX = elWidth / imageSize.width; 18618 var scY = elHeight / imageSize.height; 18619 var transform = 'translate3d(' + 18620 (x *= -1) + 18621 'px, ' + 18622 (y *= -1) + 18623 'px, 0) scale3d(' + 18624 scX + 18625 ', ' + 18626 scY + 18627 ', 1)'; 18628 return transform; 18629 }, 18630 getIframeMarkup: function (iframeWidth, iframeHeight, iframeMaxWidth, iframeMaxHeight, src, iframeTitle) { 18631 var title = iframeTitle ? 'title="' + iframeTitle + '"' : ''; 18632 return "<div class=\"lg-video-cont lg-has-iframe\" style=\"width:" + iframeWidth + "; max-width:" + iframeMaxWidth + "; height: " + iframeHeight + "; max-height:" + iframeMaxHeight + "\">\n <iframe class=\"lg-object\" frameborder=\"0\" " + title + " src=\"" + src + "\" allowfullscreen=\"true\"></iframe>\n </div>"; 18633 }, 18634 getImgMarkup: function (index, src, altAttr, srcset, sizes, sources) { 18635 var srcsetAttr = srcset ? "srcset=\"" + srcset + "\"" : ''; 18636 var sizesAttr = sizes ? "sizes=\"" + sizes + "\"" : ''; 18637 var imgMarkup = "<img " + altAttr + " " + srcsetAttr + " " + sizesAttr + " class=\"lg-object lg-image\" data-index=\"" + index + "\" src=\"" + src + "\" />"; 18638 var sourceTag = ''; 18639 if (sources) { 18640 var sourceObj = typeof sources === 'string' ? JSON.parse(sources) : sources; 18641 sourceTag = sourceObj.map(function (source) { 18642 var attrs = ''; 18643 Object.keys(source).forEach(function (key) { 18644 // Do not remove the first space as it is required to separate the attributes 18645 attrs += " " + key + "=\"" + source[key] + "\""; 18646 }); 18647 return "<source " + attrs + "></source>"; 18648 }); 18649 } 18650 return "" + sourceTag + imgMarkup; 18651 }, 18652 // Get src from responsive src 18653 getResponsiveSrc: function (srcItms) { 18654 var rsWidth = []; 18655 var rsSrc = []; 18656 var src = ''; 18657 for (var i = 0; i < srcItms.length; i++) { 18658 var _src = srcItms[i].split(' '); 18659 // Manage empty space 18660 if (_src[0] === '') { 18661 _src.splice(0, 1); 18662 } 18663 rsSrc.push(_src[0]); 18664 rsWidth.push(_src[1]); 18665 } 18666 var wWidth = window.innerWidth; 18667 for (var j = 0; j < rsWidth.length; j++) { 18668 if (parseInt(rsWidth[j], 10) > wWidth) { 18669 src = rsSrc[j]; 18670 break; 18671 } 18672 } 18673 return src; 18674 }, 18675 isImageLoaded: function (img) { 18676 if (!img) 18677 return false; 18678 // During the onload event, IE correctly identifies any images that 18679 // werenât downloaded as not complete. Others should too. Gecko-based 18680 // browsers act like NS4 in that they report this incorrectly. 18681 if (!img.complete) { 18682 return false; 18683 } 18684 // However, they do have two very useful properties: naturalWidth and 18685 // naturalHeight. These give the true size of the image. If it failed 18686 // to load, either of these should be zero. 18687 if (img.naturalWidth === 0) { 18688 return false; 18689 } 18690 // No other way of checking: assume itâs ok. 18691 return true; 18692 }, 18693 getVideoPosterMarkup: function (_poster, dummyImg, videoContStyle, playVideoString, _isVideo) { 18694 var videoClass = ''; 18695 if (_isVideo && _isVideo.youtube) { 18696 videoClass = 'lg-has-youtube'; 18697 } 18698 else if (_isVideo && _isVideo.vimeo) { 18699 videoClass = 'lg-has-vimeo'; 18700 } 18701 else { 18702 videoClass = 'lg-has-html5'; 18703 } 18704 return "<div class=\"lg-video-cont " + videoClass + "\" style=\"" + videoContStyle + "\">\n <div class=\"lg-video-play-button\">
18704\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>"; 18705 }, 18706 getFocusableElements: function (container) { 18707 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])'); 18708 var visibleElements = [].filter.call(elements, function (element) { 18709 var style = window.getComputedStyle(element); 18710 return style.display !== 'none' && style.visibility !== 'hidden'; 18711 }); 18712 return visibleElements; 18713 }, 18714 /** 18715 * @desc Create dynamic elements array from gallery items when dynamic option is false 18716 * It helps to avoid frequent DOM interaction 18717 * and avoid multiple checks for dynamic elments 18718 * 18719 * @returns {Array} dynamicEl 18720 */ 18721 getDynamicOptions: function (items, extraProps, getCaptionFromTitleOrAlt, exThumbImage) { 18722 var dynamicElements = []; 18723 var availableDynamicOptions = __spreadArrays(defaultDynamicOptions, extraProps); 18724 [].forEach.call(items, function (item) { 18725 var dynamicEl = {}; 18726 for (var i = 0; i < item.attributes.length; i++) { 18727 var attr = item.attributes[i]; 18728 if (attr.specified) { 18729 var dynamicAttr = convertToData(attr.name); 18730 var label = ''; 18731 if (availableDynamicOptions.indexOf(dynamicAttr) > -1) { 18732 label = dynamicAttr; 18733 } 18734 if (label) { 18735 dynamicEl[label] = attr.value; 18736 } 18737 } 18738 } 18739 var currentItem = $LG(item); 18740 var alt = currentItem.find('img').first().attr('alt') || currentItem.attr('data-alt'); 18741 var title = currentItem.attr('title'); 18742 //Uncode edit ##START## 18743 // var thumb = exThumbImage 18744 var thumb = exThumbImage && currentItem.attr(exThumbImage) 18745 //Uncode edit ##END## 18746 ? currentItem.attr(exThumbImage) 18747 : currentItem.find('img').first().attr('src'); 18748 dynamicEl.thumb = thumb; 18749 //Uncode edit ##START## 18750 if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) { 18751 // dynamicEl.subHtml = title || alt || ''; 18752 dynamicEl.subHtml = title || ''; 18753 } 18754 // dynamicEl.alt = alt || title || ''; 18755 dynamicEl.alt = alt || title; 18756 var inlineType = currentItem.attr('data-type'); 18757 dynamicEl.type = inlineType; 18758 //Uncode edit ##END## 18759 dynamicElements.push(dynamicEl); 18760 }); 18761 return dynamicElements; 18762 }, 18763 isMobile: function () { 18764 return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); 18765 }, 18766 /** 18767 * @desc Check the given src is video 18768 * @param {String} src 18769 * @return {Object} video type 18770 * Ex:{ youtube : ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] } 18771 * 18772 * @todo - this information can be moved to dynamicEl to avoid frequent calls 18773 */ 18774 isVideo: function (src, isHTML5VIdeo, index) { 18775 if (!src || src.match(/\.(mp4|m4v|ogg|webm)$/) ) { 18776 if (isHTML5VIdeo) { 18777 return { 18778 html5: true, 18779 }; 18780 } 18781 else { 18782 console.warn('lightGallery :- data-src is not provided on slide item ' + 18783 (index + 1) + 18784 '. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/'); 18785 return; 18786 } 18787 } 18788 var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)([\&|?][\S]*)*/i); 18789 var vimeo = src.match(/\/\/(?:www\.)?(?:player\.)?vimeo.com\/(?:video\/)?([0-9a-z\-_]+)(.*)?/i); 18790 var wistia = src.match(/https?:\/\/(.+)?(wistia\.com|wi\.st)\/(medias|embed)\/([0-9a-z\-_]+)(.*)/); 18791 if (youtube) { 18792 return { 18793 youtube: youtube, 18794 }; 18795 } 18796 else if (vimeo) { 18797 return { 18798 vimeo: vimeo, 18799 }; 18800 } 18801 else if (wistia) { 18802 return { 18803 wistia: wistia, 18804 }; 18805 } 18806 }, 18807 }; 18808 18809 // @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio 18810 // @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html 18811 // Unique id for each gallery 18812 var lgId = 0; 18813 var LightGallery = /** @class */ (function () { 18814 function LightGallery(element, options) { 18815 this.lgOpened = false;
vendor: 26,259 bytes, lines 18816-19495
18816 this.index = 0; 18817 // lightGallery modules 18818 this.plugins = []; 18819 // false when lightGallery load first slide content; 18820 this.lGalleryOn = false; 18821 // True when a slide animation is in progress 18822 this.lgBusy = false; 18823 this.currentItemsInDom = []; 18824 // Scroll top value before lightGallery is opened 18825 this.prevScrollTop = 0; 18826 this.bodyPaddingRight = 0; 18827 this.isDummyImageRemoved = false; 18828 this.dragOrSwipeEnabled = false; 18829 this.mediaContainerPosition = { 18830 top: 0, 18831 bottom: 0, 18832 }; 18833 if (!element) { 18834 return this; 18835 } 18836 lgId++; 18837 this.lgId = lgId; 18838 this.el = element; 18839 this.LGel = $LG(element); 18840 this.generateSettings(options); 18841 this.buildModules(); 18842 // When using dynamic mode, ensure dynamicEl is an array 18843 if (this.settings.dynamic && 18844 this.settings.dynamicEl !== undefined && 18845 !Array.isArray(this.settings.dynamicEl)) { 18846 throw 'When using dynamic mode, you must also define dynamicEl as an Array.'; 18847 } 18848 this.galleryItems = this.getItems(); 18849 this.normalizeSettings(); 18850 // Gallery items 18851 this.init(); 18852 //Uncode edit ##START## 18853 // this.validateLicense(); 18854 //Uncode edit ##END## 18855 return this; 18856 } 18857 LightGallery.prototype.generateSettings = function (options) { 18858 // lightGallery settings 18859 this.settings = __assign(__assign({}, lightGalleryCoreSettings), options); 18860 if (this.settings.isMobile && 18861 typeof this.settings.isMobile === 'function' 18862 ? this.settings.isMobile() 18863 : utils.isMobile()) { 18864 var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings); 18865 this.settings = __assign(__assign({}, this.settings), mobileSettings); 18866 } 18867 }; 18868 LightGallery.prototype.normalizeSettings = function () { 18869 if (this.settings.slideEndAnimation) { 18870 this.settings.hideControlOnEnd = false; 18871 } 18872 if (!this.settings.closable) { 18873 this.settings.swipeToClose = false; 18874 } 18875 // And reset it on close to get the correct value next time 18876 this.zoomFromOrigin = this.settings.zoomFromOrigin; 18877 // At the moment, Zoom from image doesn't support dynamic options 18878 // @todo add zoomFromOrigin support for dynamic images 18879 if (this.settings.dynamic) { 18880 this.zoomFromOrigin = false; 18881 } 18882 if (!this.settings.container) { 18883 this.settings.container = document.body; 18884 } 18885 // settings.preload should not be grater than $item.length 18886 this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length); 18887 }; 18888 LightGallery.prototype.init = function () { 18889 var _this = this; 18890 this.addSlideVideoInfo(this.galleryItems); 18891 this.buildStructure(); 18892 this.LGel.trigger(lGEvents.init, { 18893 instance: this, 18894 }); 18895 if (this.settings.keyPress) { 18896 this.keyPress(); 18897 } 18898 setTimeout(function () { 18899 _this.enableDrag(); 18900 _this.enableSwipe(); 18901 _this.triggerPosterClick(); 18902 }, 50); 18903 this.arrow(); 18904 if (this.settings.mousewheel) { 18905 this.mousewheel(); 18906 } 18907 if (!this.settings.dynamic) { 18908 this.openGalleryOnItemClick(); 18909 } 18910 }; 18911 LightGallery.prototype.openGalleryOnItemClick = function () { 18912 var _this = this; 18913 var _loop_1 = function (index) { 18914 var element = this_1.items[index]; 18915 var $element = $LG(element); 18916 // Using different namespace for click because click event should not unbind if selector is same object('this') 18917 // @todo manage all event listners - should have namespace that represent element 18918 var uuid = lgQuery.generateUUID(); 18919 $element 18920 .attr('data-lg-id', uuid) 18921 .on("click.lgcustom-item-" + uuid, function (e) { 18922 e.preventDefault(); 18923 var currentItemIndex = _this.settings.index || index; 18924 _this.openGallery(currentItemIndex, element); 18925 }); 18926 }; 18927 var this_1 = this; 18928 // Using for loop instead of using bubbling as the items can be any html element. 18929 for (var index = 0; index < this.items.length; index++) { 18930 _loop_1(index); 18931 } 18932 }; 18933 /** 18934 * Module constructor 18935 * Modules are build incrementally. 18936 * Gallery should be opened only once all the modules are initialized. 18937 * use moduleBuildTimeout to make sure this 18938 */ 18939 LightGallery.prototype.buildModules = function () { 18940 var _this = this; 18941 this.settings.plugins.forEach(function (plugin) { 18942 _this.plugins.push(new plugin(_this, $LG)); 18943 }); 18944 }; 18945 LightGallery.prototype.validateLicense = function () { 18946 if (!this.settings.licenseKey) { 18947 console.warn('Please provide a valid license key'); 18948 } 18949 else if (this.settings.licenseKey === '0000-0000-000-0000') { 18950 console.warn("lightGallery: " + this.settings.licenseKey + " license key is not valid for production use"); 18951 } 18952 }; 18953 LightGallery.prototype.getSlideItem = function (index) { 18954 return $LG(this.getSlideItemId(index)); 18955 }; 18956 LightGallery.prototype.getSlideItemId = function (index) { 18957 return "#lg-item-" + this.lgId + "-" + index; 18958 }; 18959 LightGallery.prototype.getIdName = function (id) { 18960 return id + "-" + this.lgId; 18961 }; 18962 LightGallery.prototype.getElementById = function (id) { 18963 return $LG("#" + this.getIdName(id)); 18964 }; 18965 LightGallery.prototype.manageSingleSlideClassName = function () { 18966 if (this.galleryItems.length < 2) { 18967 this.outer.addClass('lg-single-item'); 18968 } 18969 else { 18970 this.outer.removeClass('lg-single-item'); 18971 } 18972 }; 18973 LightGallery.prototype.buildStructure = function () { 18974 var _this = this; 18975 var container = this.$container && this.$container.get(); 18976 if (container) { 18977 return; 18978 } 18979 var controls = ''; 18980 var subHtmlCont = ''; 18981 // Create controls 18982 if (this.settings.controls) { 18983 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>"; 18984 } 18985 if (this.settings.appendSubHtmlTo !== '.lg-item') { 18986 subHtmlCont = 18987 '<div class="lg-sub-html" role="status" aria-live="polite"></div>'; 18988 } 18989 var addClasses = ''; 18990 if (this.settings.allowMediaOverlap) { 18991 // Do not remove space before last single quote 18992 addClasses += 'lg-media-overlap '; 18993 } 18994 var ariaLabelledby = this.settings.ariaLabelledby 18995 ? 'aria-labelledby="' + this.settings.ariaLabelledby + '"' 18996 : ''; 18997 var ariaDescribedby = this.settings.ariaDescribedby 18998 ? 'aria-describedby="' + this.settings.ariaDescribedby + '"' 18999 : ''; 19000 var containerClassName = "lg-container " + this.settings.addClass + " " + (document.body !== this.settings.container ? 'lg-inline' : ''); 19001 var closeIcon = this.settings.closable && this.settings.showCloseIcon 19002 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['closeGallery'] + "\" id=\"" + this.getIdName('lg-close') + "\" class=\"lg-close lg-icon\"></button>" 19003 : ''; 19004 var maximizeIcon = this.settings.showMaximizeIcon 19005 ? "<button type=\"button\" aria-label=\"" + this.settings.strings['toggleMaximize'] + "\" id=\"" + this.getIdName('lg-maximize') + "\" class=\"lg-maximize lg-icon\"></button>" 19006 : ''; 19007 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' 19008 ? subHtmlCont 19009 : '') + "\n <div id=\"" + this.getIdName('lg-components') + "\" class=\"lg-components\">\n " + (this.settings.appendSubHtmlTo === '.lg-sub-html' 19010 ? subHtmlCont 19011 : '') + "\n </div>\n </div>\n </div>\n "; 19012 $LG(this.settings.container).append(template); 19013 if (document.body !== this.settings.container) { 19014 $LG(this.settings.container).css('position', 'relative'); 19015 } 19016 this.outer = this.getElementById('lg-outer'); 19017 this.$lgComponents = this.getElementById('lg-components'); 19018 this.$backdrop = this.getElementById('lg-backdrop'); 19019 this.$container = this.getElementById('lg-container'); 19020 this.$inner = this.getElementById('lg-inner'); 19021 this.$content = this.getElementById('lg-content'); 19022 this.$toolbar = this.getElementById('lg-toolbar'); 19023 this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms'); 19024 var outerClassNames = this.settings.mode + " "; 19025 this.manageSingleSlideClassName(); 19026 if (this.settings.enableDrag) { 19027 outerClassNames += 'lg-grab '; 19028 } 19029 this.outer.addClass(outerClassNames); 19030 this.$inner.css('transition-timing-function', this.settings.easing); 19031 this.$inner.css('transition-duration', this.settings.speed + 'ms'); 19032 if (this.settings.download) { 19033 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>"); 19034 } 19035 this.counter(); 19036 $LG(window).on("resize.lg.global" + this.lgId + " orientationchange.lg.global" + this.lgId, function () { 19037 _this.refreshOnResize(); 19038 }); 19039 this.hideBars(); 19040 this.manageCloseGallery(); 19041 this.toggleMaximize(); 19042 this.initModules(); 19043 }; 19044 LightGallery.prototype.refreshOnResize = function () { 19045 if (this.lgOpened) { 19046 var currentGalleryItem = this.galleryItems[this.index]; 19047 var __slideVideoInfo = currentGalleryItem.__slideVideoInfo; 19048 this.mediaContainerPosition = this.getMediaContainerPosition(); 19049 var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom; 19050 //Uncode edit ##START## 19051 this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 19052 // this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize); 19053 //Uncode edit ##END## 19054 if (__slideVideoInfo) { 19055 this.resizeVideoSlide(this.index, this.currentImageSize); 19056 } 19057 if (this.zoomFromOrigin && !this.isDummyImageRemoved) { 19058 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 19059 this.outer 19060 .find('.lg-current .lg-dummy-img') 19061 .first() 19062 .attr('style', imgStyle); 19063 } 19064 this.LGel.trigger(lGEvents.containerResize); 19065 } 19066 }; 19067 LightGallery.prototype.resizeVideoSlide = function (index, imageSize) { 19068 var lgVideoStyle = this.getVideoContStyle(imageSize); 19069 var currentSlide = this.getSlideItem(index); 19070 currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle); 19071 }; 19072 /** 19073 * Update slides dynamically. 19074 * Add, edit or delete slides dynamically when lightGallery is opened. 19075 * Modify the current gallery items and pass it via updateSlides method 19076 * @note 19077 * - Do not mutate existing lightGallery items directly. 19078 * - Always pass new list of gallery items 19079 * - You need to take care of thumbnails outside the gallery if any 19080 * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method. 19081 * @param items Gallery items 19082 * @param index After the update operation, which slide gallery should navigate to 19083 * @category lGPublicMethods 19084 * @example 19085 * const plugin = lightGallery(); 19086 * 19087 * // Adding slides dynamically 19088 * let galleryItems = [ 19089 * // Access existing lightGallery items 19090 * // galleryItems are automatically generated internally from the gallery HTML markup 19091 * // or directly from galleryItems when dynamic gallery is used 19092 * ...plugin.galleryItems, 19093 * ...[ 19094 * { 19095 * src: 'img/img-1.png', 19096 * thumb: 'img/thumb1.png', 19097 * }, 19098 * ], 19099 * ]; 19100 * plugin.updateSlides( 19101 * galleryItems, 19102 * plugin.index, 19103 * ); 19104 * 19105 * 19106 * // Remove slides dynamically 19107 * galleryItems = JSON.parse( 19108 * JSON.stringify(updateSlideInstance.galleryItems), 19109 * ); 19110 * galleryItems.shift(); 19111 * updateSlideInstance.updateSlides(galleryItems, 1); 19112 * @see <a href="/demos/update-slides/">Demo</a> 19113 */ 19114 LightGallery.prototype.updateSlides = function (items, index) { 19115 if (this.index > items.length - 1) { 19116 this.index = items.length - 1; 19117 } 19118 if (items.length === 1) { 19119 this.index = 0; 19120 } 19121 if (!items.length) { 19122 this.closeGallery(); 19123 return; 19124 } 19125 var currentSrc = this.galleryItems[index].src; 19126 this.galleryItems = items; 19127 this.updateControls(); 19128 this.$inner.empty(); 19129 this.currentItemsInDom = []; 19130 var _index = 0; 19131 // Find the current index based on source value of the slide 19132 this.galleryItems.some(function (galleryItem, itemIndex) { 19133 if (galleryItem.src === currentSrc) { 19134 _index = itemIndex; 19135 return true; 19136 } 19137 return false; 19138 }); 19139 this.currentItemsInDom = this.organizeSlideItems(_index, -1); 19140 this.loadContent(_index, true); 19141 this.getSlideItem(_index).addClass('lg-current'); 19142 this.index = _index; 19143 this.updateCurrentCounter(_index); 19144 this.LGel.trigger(lGEvents.updateSlides); 19145 }; 19146 // Get gallery items based on multiple conditions 19147 LightGallery.prototype.getItems = function () { 19148 // Gallery items 19149 this.items = []; 19150 if (!this.settings.dynamic) { 19151 if (this.settings.selector === 'this') { 19152 this.items.push(this.el); 19153 } 19154 else if (this.settings.selector) { 19155 if (typeof this.settings.selector === 'string') { 19156 if (this.settings.selectWithin) { 19157 var selectWithin = $LG(this.settings.selectWithin); 19158 this.items = selectWithin 19159 .find(this.settings.selector) 19160 .get(); 19161 } 19162 else { 19163 this.items = this.el.querySelectorAll(this.settings.selector); 19164 } 19165 } 19166 else { 19167 this.items = this.settings.selector; 19168 } 19169 } 19170 else { 19171 this.items = this.el.children; 19172 } 19173 return utils.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage); 19174 } 19175 else { 19176 return this.settings.dynamicEl || []; 19177 } 19178 }; 19179 LightGallery.prototype.shouldHideScrollbar = function () { 19180 return (this.settings.hideScrollbar && 19181 document.body === this.settings.container); 19182 }; 19183 LightGallery.prototype.hideScrollbar = function () { 19184 if (!this.shouldHideScrollbar()) { 19185 return; 19186 } 19187 this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight); 19188 var bodyRect = document.documentElement.getBoundingClientRect(); 19189 var scrollbarWidth = window.innerWidth - bodyRect.width; 19190 $LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px'); 19191 $LG(document.body).addClass('lg-overlay-open'); 19192 }; 19193 LightGallery.prototype.resetScrollBar = function () { 19194 if (!this.shouldHideScrollbar()) { 19195 return; 19196 } 19197 $LG(document.body).css('padding-right', this.bodyPaddingRight + 'px'); 19198 $LG(document.body).removeClass('lg-overlay-open'); 19199 }; 19200 /** 19201 * Open lightGallery. 19202 * Open gallery with specific slide by passing index of the slide as parameter. 19203 * @category lGPublicMethods 19204 * @param {Number} index - index of the slide 19205 * @param {HTMLElement} element - Which image lightGallery should zoom from 19206 * 19207 * @example 19208 * const $dynamicGallery = document.getElementById('dynamic-gallery-demo'); 19209 * const dynamicGallery = lightGallery($dynamicGallery, { 19210 * dynamic: true, 19211 * dynamicEl: [ 19212 * { 19213 * src: 'img/1.jpg', 19214 * thumb: 'img/thumb-1.jpg', 19215 * subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>', 19216 * }, 19217 * ... 19218 * ], 19219 * }); 19220 * $dynamicGallery.addEventListener('click', function () { 19221 * // Starts with third item.(Optional). 19222 * // This is useful if you want use dynamic mode with 19223 * // custom thumbnails (thumbnails outside gallery), 19224 * dynamicGallery.openGallery(2); 19225 * }); 19226 * 19227 */ 19228 LightGallery.prototype.openGallery = function (index, element) { 19229 var _this = this; 19230 if (index === void 0) { index = this.settings.index; } 19231 // prevent accidental double execution 19232 if (this.lgOpened) 19233 return; 19234 this.lgOpened = true; 19235 this.outer.removeClass('lg-hide-items'); 19236 this.hideScrollbar(); 19237 // Add display block, but still has opacity 0 19238 this.$container.addClass('lg-show'); 19239 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index); 19240 this.currentItemsInDom = itemsToBeInsertedToDom; 19241 var items = ''; 19242 itemsToBeInsertedToDom.forEach(function (item) { 19243 items = items + ("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 19244 }); 19245 this.$inner.append(items); 19246 this.addHtml(index); 19247 var transform = ''; 19248 this.mediaContainerPosition = this.getMediaContainerPosition(); 19249 var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 19250 if (!this.settings.allowMediaOverlap) { 19251 this.setMediaContainerPosition(top, bottom); 19252 } 19253 var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo; 19254 if (this.zoomFromOrigin && element) { 19255 //Uncode edit ##START## 19256 this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 19257 // this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize); 19258 //Uncode edit ##END## 19259 transform = utils.getTransform(element, this.outer, top, bottom, this.currentImageSize); 19260 } 19261 if (!this.zoomFromOrigin || !transform) { 19262 this.outer.addClass(this.settings.startClass); 19263 this.getSlideItem(index).removeClass('lg-complete'); 19264 } 19265 var timeout = this.settings.zoomFromOrigin 19266 ? 100 19267 : this.settings.backdropDuration; 19268 setTimeout(function () { 19269 _this.outer.addClass('lg-components-open'); 19270 }, timeout); 19271 this.index = index; 19272 //Uncode edit ##START## 19273 // this.LGel.trigger(lGEvents.beforeOpen); 19274 this.LGel.trigger(lGEvents.beforeOpen, { 19275 galleryItems: this.galleryItems, 19276 items: this.items, 19277 outer: this.outer, 19278 }); 19279 //Uncode edit ##END## 19280 // add class lg-current to remove initial transition 19281 this.getSlideItem(index).addClass('lg-current'); 19282 this.lGalleryOn = false; 19283 // Store the current scroll top value to scroll back after closing the gallery.. 19284 this.prevScrollTop = $LG(window).scrollTop(); 19285 setTimeout(function () { 19286 // Need to check both zoomFromOrigin and transform values as we need to set set the 19287 // default opening animation if user missed to add the lg-size attribute 19288 if (_this.zoomFromOrigin && transform) { 19289 var currentSlide_1 = _this.getSlideItem(index); 19290 currentSlide_1.css('transform', transform); 19291 setTimeout(function () { 19292 currentSlide_1 19293 .addClass('lg-start-progress lg-start-end-progress') 19294 .css('transition-duration', _this.settings.startAnimationDuration + 'ms'); 19295 _this.outer.addClass('lg-zoom-from-image'); 19296 }); 19297 setTimeout(function () { 19298 currentSlide_1.css('transform', 'translate3d(0, 0, 0)'); 19299 }, 100); 19300 } 19301 setTimeout(function () { 19302 _this.$backdrop.addClass('in'); 19303 _this.$container.addClass('lg-show-in'); 19304 }, 10); 19305 setTimeout(function () { 19306 if (_this.settings.trapFocus && 19307 document.body === _this.settings.container) { 19308 _this.trapFocus(); 19309 } 19310 }, _this.settings.backdropDuration + 50); 19311 // lg-visible class resets gallery opacity to 1 19312 if (!_this.zoomFromOrigin || !transform) { 19313 setTimeout(function () { 19314 _this.outer.addClass('lg-visible'); 19315 }, _this.settings.backdropDuration); 19316 } 19317 // initiate slide function 19318 _this.slide(index, false, false, false); 19319 _this.LGel.trigger(lGEvents.afterOpen); 19320 }); 19321 if (document.body === this.settings.container) { 19322 $LG('html').addClass('lg-on'); 19323 } 19324 }; 19325 /** 19326 * Note - Changing the position of the media on every slide transition creates a flickering effect. 19327 * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption. 19328 * if you have dynamic captions for each media, 19329 * you can provide an appropriate height for the captions via allowMediaOverlap option 19330 */ 19331 LightGallery.prototype.getMediaContainerPosition = function () { 19332 if (this.settings.allowMediaOverlap) { 19333 return { 19334 top: 0, 19335 bottom: 0, 19336 }; 19337 } 19338 var top = this.$toolbar.get().clientHeight || 0; 19339 var subHtml = this.outer.find('.lg-components .lg-sub-html').get(); 19340 var captionHeight = this.settings.defaultCaptionHeight || 19341 (subHtml && subHtml.clientHeight) || 19342 0; 19343 var thumbContainer = this.outer.find('.lg-thumb-outer').get(); 19344 var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0; 19345 var bottom = thumbHeight + captionHeight; 19346 //Uncode edit ##START## 19347 bottom = bottom < 55 ? 55 : bottom; 19348 //Uncode edit ##END## 19349 return { 19350 top: top, 19351 bottom: bottom, 19352 }; 19353 }; 19354 LightGallery.prototype.setMediaContainerPosition = function (top, bottom) { 19355 if (top === void 0) { top = 0; } 19356 if (bottom === void 0) { bottom = 0; } 19357 this.$content.css('top', top + 'px').css('bottom', bottom + 'px'); 19358 }; 19359 LightGallery.prototype.hideBars = function () { 19360 var _this = this; 19361 // Hide controllers if mouse doesn't move for some period 19362 setTimeout(function () { 19363 _this.outer.removeClass('lg-hide-items'); 19364 if (_this.settings.hideBarsDelay > 0) { 19365 _this.outer.on('mousemove.lg click.lg touchstart.lg', function () { 19366 _this.outer.removeClass('lg-hide-items'); 19367 clearTimeout(_this.hideBarTimeout); 19368 // Timeout will be cleared on each slide movement also 19369 _this.hideBarTimeout = setTimeout(function () { 19370 _this.outer.addClass('lg-hide-items'); 19371 }, _this.settings.hideBarsDelay); 19372 }); 19373 _this.outer.trigger('mousemove.lg'); 19374 } 19375 }, this.settings.showBarsAfter); 19376 }; 19377 LightGallery.prototype.initPictureFill = function ($img) { 19378 if (this.settings.supportLegacyBrowser) { 19379 try { 19380 picturefill({ 19381 elements: [$img.get()], 19382 }); 19383 } 19384 catch (e) { 19385 console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.'); 19386 } 19387 } 19388 }; 19389 /** 19390 * @desc Create image counter 19391 * Ex: 1/10 19392 */ 19393 LightGallery.prototype.counter = function () { 19394 if (this.settings.counter) { 19395 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>"; 19396 this.outer.find(this.settings.appendCounterTo).append(counterHtml); 19397 } 19398 }; 19399 /** 19400 * @desc add sub-html into the slide 19401 * @param {Number} index - index of the slide 19402 */ 19403 LightGallery.prototype.addHtml = function (index) { 19404 var subHtml; 19405 var subHtmlUrl; 19406 if (this.galleryItems[index].subHtmlUrl) { 19407 subHtmlUrl = this.galleryItems[index].subHtmlUrl; 19408 } 19409 else { 19410 subHtml = this.galleryItems[index].subHtml; 19411 } 19412 if (!subHtmlUrl) { 19413 if (subHtml) { 19414 // get first letter of sub-html 19415 // if first letter starts with . or # get the html form the jQuery object 19416 var fL = subHtml.substring(0, 1); 19417 if (fL === '.' || fL === '#') { 19418 if (this.settings.subHtmlSelectorRelative && 19419 !this.settings.dynamic) { 19420 subHtml = $LG(this.items) 19421 .eq(index) 19422 .find(subHtml) 19423 .first() 19424 .html(); 19425 } 19426 else { 19427 subHtml = $LG(subHtml).first().html(); 19428 } 19429 } 19430 } 19431 else { 19432 subHtml = ''; 19433 } 19434 } 19435 if (this.settings.appendSubHtmlTo !== '.lg-item') { 19436 if (subHtmlUrl) { 19437 this.outer.find('.lg-sub-html').load(subHtmlUrl); 19438 } 19439 else { 19440 this.outer.find('.lg-sub-html').html(subHtml); 19441 } 19442 } 19443 else { 19444 var currentSlide = $LG(this.getSlideItemId(index)); 19445 if (subHtmlUrl) { 19446 currentSlide.load(subHtmlUrl); 19447 } 19448 else { 19449 currentSlide.append("<div class=\"lg-sub-html\">" + subHtml + "</div>"); 19450 } 19451 } 19452 // Add lg-empty-html class if title doesn't exist 19453 if (typeof subHtml !== 'undefined' && subHtml !== null) { 19454 if (subHtml === '') { 19455 this.outer 19456 .find(this.settings.appendSubHtmlTo) 19457 .addClass('lg-empty-html'); 19458 } 19459 else { 19460 this.outer 19461 .find(this.settings.appendSubHtmlTo) 19462 .removeClass('lg-empty-html'); 19463 } 19464 } 19465 this.LGel.trigger(lGEvents.afterAppendSubHtml, { 19466 index: index, 19467 }); 19468 }; 19469 /** 19470 * @desc Preload slides 19471 * @param {Number} index - index of the slide 19472 * @todo preload not working for the first slide, Also, should work for the first and last slide as well 19473 */ 19474 LightGallery.prototype.preload = function (index) { 19475 for (var i = 1; i <= this.settings.preload; i++) { 19476 if (i >= this.galleryItems.length - index) { 19477 break; 19478 } 19479 this.loadContent(index + i, false); 19480 } 19481 for (var j = 1; j <= this.settings.preload; j++) { 19482 if (index - j < 0) { 19483 break; 19484 } 19485 this.loadContent(index - j, false); 19486 } 19487 }; 19488 LightGallery.prototype.getDummyImgStyles = function (imageSize) { 19489 if (!imageSize) 19490 return ''; 19491 return "width:" + imageSize.width + "px;\n margin-left: -" + imageSize.width / 2 + "px;\n margin-top: -" + imageSize.height / 2 + "px;\n height:" + imageSize.height + "px"; 19492 }; 19493 LightGallery.prototype.getVideoContStyle = function (imageSize) { 19494 if (!imageSize) 19495 return '';
19496 return "width:" + imageSize.width + "px;\n height:" + imageSize.height + "px"; 19497 }; 19498 LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) { 19499 var $currentItem; 19500 if (!this.settings.dynamic) { 19501 $currentItem = $LG(this.items).eq(index); 19502 } 19503 if ($currentItem) { 19504 var _dummyImgSrc = void 0; 19505 if (!this.settings.exThumbImage) { 19506 _dummyImgSrc = $currentItem.find('img').first().attr('src'); 19507 } 19508 else { 19509 _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage); 19510 } 19511 if (!_dummyImgSrc) 19512 return ''; 19513 var imgStyle = this.getDummyImgStyles(this.currentImageSize); 19514 var dummyImgContent = "<img " + alt + " style=\"" + imgStyle + "\" class=\"lg-dummy-img\" src=\"" + _dummyImgSrc + "\" />"; 19515 $currentSlide.addClass('lg-first-slide'); 19516 this.outer.addClass('lg-first-slide-loading'); 19517 return dummyImgContent; 19518 } 19519 return ''; 19520 }; 19521 LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) { 19522 var currentGalleryItem = this.galleryItems[index]; 19523 var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 19524 // Use the thumbnail as dummy image which will be resized to actual image size and 19525 // displayed on top of actual image 19526 var imgContent = ''; 19527 var altAttr = alt ? 'alt="' + alt + '"' : ''; 19528 if (this.isFirstSlideWithZoomAnimation()) { 19529 imgContent = this.getDummyImageContent($currentSlide, index, altAttr); 19530 } 19531 else { 19532 imgContent = utils.getImgMarkup(index, src, altAttr, srcset, sizes, sources); 19533 } 19534 var imgMarkup = "<picture class=\"lg-img-wrap\"> " + imgContent + "</picture>"; 19535 $currentSlide.prepend(imgMarkup); 19536 }; 19537 LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) { 19538 var mediaObject = $slide.find('.lg-object').first(); 19539 if (utils.isImageLoaded(mediaObject.get()) || 19540 isHTML5VideoWithoutPoster) { 19541 onLoad(); 19542 } 19543 else { 19544 mediaObject.on('load.lg error.lg', function () { 19545 onLoad && onLoad(); 19546 }); 19547 mediaObject.on('error.lg', function () { 19548 onError && onError(); 19549 }); 19550 } 19551 }; 19552 /** 19553 * 19554 * @param $el Current slide item 19555 * @param index 19556 * @param delay Delay is 0 except first time 19557 * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin 19558 * @param isFirstSlide 19559 */ 19560 LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) { 19561 var _this = this; 19562 //Uncode edit ##START## 19563 var $item = _this.galleryItems[index], 19564 type = $item.type; 19565 19566 if ( typeof $item.src !== 'undefined' ) { 19567 var inline_id = $item.src.replace('#', ''), 19568 $inline = document.getElementById(inline_id), 19569 inline_html; 19570 19571 if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) { 19572 inline_html = $inline.innerHTML; 19573 } else { 19574 inline_html = ''; 19575 } 19576 } 19577 //Uncode edit ##END## 19578 this.onSlideObjectLoad(currentSlide, true, function () { 19579 _this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide); 19580 }, function () { 19581 currentSlide.addClass('lg-complete lg-complete_'); 19582 //Uncode edit ##START## 19583 // currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 19584 if ( inline_html !== '' ) { 19585 currentSlide.html(inline_html); 19586 } else { 19587 currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>'); 19588 } 19589 //Uncode edit ##END## 19590 }); 19591 }; 19592 LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) { 19593 var _this = this; 19594 var currentGalleryItem = this.galleryItems[index]; 19595 // Adding delay for video slides without poster for better performance and user experience 19596 // Videos should start playing once once the gallery is completely loaded 19597 var _speed = isFirstSlide &&
vendor: 3,676 bytes, lines 19598-19686
19598 this.getSlideType(currentGalleryItem) === 'video' && 19599 !currentGalleryItem.poster 19600 ? speed 19601 : 0; 19602 setTimeout(function () { 19603 $currentSlide.addClass('lg-complete lg-complete_'); 19604 _this.LGel.trigger(lGEvents.slideItemLoad, { 19605 index: index, 19606 delay: delay || 0, 19607 isFirstSlide: isFirstSlide, 19608 }); 19609 }, _speed); 19610 }; 19611 LightGallery.prototype.isFirstSlideWithZoomAnimation = function () { 19612 return !!(!this.lGalleryOn && 19613 this.zoomFromOrigin && 19614 this.currentImageSize); 19615 }; 19616 // Add video slideInfo 19617 LightGallery.prototype.addSlideVideoInfo = function (items) { 19618 var _this = this; 19619 items.forEach(function (element, index) { 19620 element.__slideVideoInfo = utils.isVideo(element.src, !!element.video, index); 19621 if (element.__slideVideoInfo && 19622 _this.settings.loadYouTubePoster && 19623 !element.poster && 19624 element.__slideVideoInfo.youtube) { 19625 element.poster = "//img.youtube.com/vi/" + element.__slideVideoInfo.youtube[1] + "/maxresdefault.jpg"; 19626 } 19627 }); 19628 }; 19629 /** 19630 * Load slide content into slide. 19631 * This is used to load content into slides that is not visible too 19632 * @param {Number} index - index of the slide. 19633 * @param {Boolean} rec - if true call loadcontent() function again. 19634 */ 19635 LightGallery.prototype.loadContent = function (index, rec) { 19636 var _this = this; 19637 var currentGalleryItem = this.galleryItems[index]; 19638 var $currentSlide = $LG(this.getSlideItemId(index)); 19639 var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources; 19640 var src = currentGalleryItem.src; 19641 var video = currentGalleryItem.video; 19642 var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video; 19643 if (currentGalleryItem.responsive) { 19644 var srcDyItms = currentGalleryItem.responsive.split(','); 19645 src = utils.getResponsiveSrc(srcDyItms) || src; 19646 } 19647 var videoInfo = currentGalleryItem.__slideVideoInfo; 19648 var lgVideoStyle = ''; 19649 var iframe = !!currentGalleryItem.iframe; 19650 var isFirstSlide = !this.lGalleryOn; 19651 // delay for adding complete class. it is 0 except first time. 19652 var delay = 0; 19653 if (isFirstSlide) { 19654 if (this.zoomFromOrigin && this.currentImageSize) { 19655 delay = this.settings.startAnimationDuration + 10; 19656 } 19657 else { 19658 delay = this.settings.backdropDuration + 10; 19659 } 19660 } 19661 if (!$currentSlide.hasClass('lg-loaded')) { 19662 if (videoInfo) { 19663 var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom; 19664 //Uncode edit ##START## 19665 var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 19666 // var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize); 19667 //Uncode edit ##END## 19668 lgVideoStyle = this.getVideoContStyle(videoSize); 19669 } 19670 if (iframe) { 19671 var markup = utils.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle); 19672 $currentSlide.prepend(markup); 19673 } 19674 else if (poster) { 19675 var dummyImg = ''; 19676 var hasStartAnimation = isFirstSlide && 19677 this.zoomFromOrigin && 19678 this.currentImageSize; 19679 if (hasStartAnimation) { 19680 dummyImg = this.getDummyImageContent($currentSlide, index, ''); 19681 } 19682 var markup = utils.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo); 19683 $currentSlide.prepend(markup); 19684 } 19685 //Uncode edit ##START## 19686 // else if (videoInfo) {
19687 else if (videoInfo || this.getSlideType(currentGalleryItem) === 'audio') { 19688 if (! _html5Video) { 19689 var markup = "<div class=\"lg-video-cont \" style=\"" + lgVideoStyle + "\"></div>"; 19690 } 19691 //Uncode edit ##END## 19692 $currentSlide.prepend(markup); 19693 } 19694 else { 19695 //Uncode edit ##START## 19696 var $item = _this.galleryItems[index], 19697 type = $item.type; 19698 19699 if ( typeof $item.src !== 'undefined' ) { 19700 var inline_id = $item.src.replace('#', ''), 19701 $inline = document.getElementById(inline_id), 19702 inline_html; 19703 19704 if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) { 19705 inline_html = $inline.innerHTML; 19706 } else { 19707 inline_html = ''; 19708 } 19709 } 19710 if ( inline_html !== '' ) { 19711 $currentSlide.html(inline_html); 19712 } else { 19713 this.setImgMarkup(src, $currentSlide, index); 19714 if (srcset || sources) { 19715 var $img = $currentSlide.find('.lg-object'); 19716 this.initPictureFill($img); 19717 } 19718 } 19719 /*this.setImgMarkup(src, $currentSlide, index); 19720 if (srcset || sources) { 19721 var $img = $currentSlide.find('.lg-object'); 19722 this.initPictureFill($img); 19723 }*/ 19724 //Uncode edit ##END## 19725 } 19726 if (poster || videoInfo) { 19727 this.LGel.trigger(lGEvents.hasVideo, { 19728 index: index, 19729 src: src, 19730 html5Video: _html5Video, 19731 hasPoster: !!poster, 19732 }); 19733 } 19734 this.LGel.trigger(lGEvents.afterAppendSlide, { index: index }); 19735 if (this.lGalleryOn && 19736 this.settings.appendSubHtmlTo === '.lg-item') { 19737 this.addHtml(index); 19738 } 19739 } 19740 // For first time add some delay for displaying the start animation. 19741 var _speed = 0; 19742 // Do not change the delay value because it is required for zoom plugin. 19743 // If gallery opened from direct url (hash) speed value should be 0 19744 if (delay && !$LG(document.body).hasClass('lg-from-hash')) { 19745 _speed = delay; 19746 } 19747 // Only for first slide and zoomFromOrigin is enabled 19748 if (this.isFirstSlideWithZoomAnimation()) { 19749 setTimeout(function () { 19750 $currentSlide 19751 .removeClass('lg-start-end-progress lg-start-progress') 19752 .removeAttr('style'); 19753 }, this.settings.startAnimationDuration + 100); 19754 if (!$currentSlide.hasClass('lg-loaded')) { 19755 setTimeout(function () { 19756 if (_this.getSlideType(currentGalleryItem) === 'image') { 19757 var alt = currentGalleryItem.alt; 19758 var altAttr = alt ? 'alt="' + alt + '"' : ''; 19759 $currentSlide 19760 .find('.lg-img-wrap') 19761 .append(utils.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources)); 19762 if (srcset || sources) { 19763 var $img = $currentSlide.find('.lg-object'); 19764 _this.initPictureFill($img); 19765 } 19766 } 19767 if (_this.getSlideType(currentGalleryItem) === 'image' || 19768 (_this.getSlideType(currentGalleryItem) === 'video' && 19769 poster)) { 19770 _this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false); 19771 // load remaining slides once the slide is completely loaded 19772 _this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () { 19773 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 19774 }, function () { 19775 _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed); 19776 }); 19777 } 19778 }, this.settings.startAnimationDuration + 100); 19779 } 19780 } 19781 // SLide content has been added to dom 19782 $currentSlide.addClass('lg-loaded'); 19783 if (!this.isFirstSlideWithZoomAnimation() || 19784 (this.getSlideType(currentGalleryItem) === 'video' && !poster)) { 19785 //Uncode edit ##START## 19786 // this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster)); 19787 this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!( (videoInfo && videoInfo.html5 && !poster) || this.get
vendor: 31,133 bytes, lines 19787-20711
19787SlideType(currentGalleryItem) === 'audio')); 19788 //Uncode edit ##END## 19789 } 19790 // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling 19791 if ((!this.zoomFromOrigin || !this.currentImageSize) && 19792 $currentSlide.hasClass('lg-complete_') && 19793 !this.lGalleryOn) { 19794 setTimeout(function () { 19795 $currentSlide.addClass('lg-complete'); 19796 }, this.settings.backdropDuration); 19797 } 19798 // Content loaded 19799 // Need to set lGalleryOn before calling preload function 19800 this.lGalleryOn = true; 19801 if (rec === true) { 19802 if (!$currentSlide.hasClass('lg-complete_')) { 19803 $currentSlide 19804 .find('.lg-object') 19805 .first() 19806 .on('load.lg error.lg', function () { 19807 _this.preload(index); 19808 }); 19809 } 19810 else { 19811 this.preload(index); 19812 } 19813 } 19814 }; 19815 /** 19816 * @desc Remove dummy image content and load next slides 19817 * Called only for the first time if zoomFromOrigin animation is enabled 19818 * @param index 19819 * @param $currentSlide 19820 * @param speed 19821 */ 19822 LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) { 19823 var _this = this; 19824 setTimeout(function () { 19825 $currentSlide.find('.lg-dummy-img').remove(); 19826 $currentSlide.removeClass('lg-first-slide'); 19827 _this.outer.removeClass('lg-first-slide-loading'); 19828 _this.isDummyImageRemoved = true; 19829 _this.preload(index); 19830 }, speed + 300); 19831 }; 19832 LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) { 19833 var _this = this; 19834 if (numberOfItems === void 0) { numberOfItems = 0; } 19835 var itemsToBeInsertedToDom = []; 19836 // Minimum 2 items should be there 19837 var possibleNumberOfItems = Math.max(numberOfItems, 3); 19838 possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length); 19839 var prevIndexItem = "lg-item-" + this.lgId + "-" + prevIndex; 19840 if (this.galleryItems.length <= 3) { 19841 this.galleryItems.forEach(function (_element, index) { 19842 itemsToBeInsertedToDom.push("lg-item-" + _this.lgId + "-" + index); 19843 }); 19844 return itemsToBeInsertedToDom; 19845 } 19846 if (index < (this.galleryItems.length - 1) / 2) { 19847 for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) { 19848 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 19849 } 19850 var numberOfExistingItems = itemsToBeInsertedToDom.length; 19851 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 19852 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index + idx + 1)); 19853 } 19854 } 19855 else { 19856 for (var idx = index; idx <= this.galleryItems.length - 1 && 19857 idx < index + possibleNumberOfItems / 2; idx++) { 19858 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx); 19859 } 19860 var numberOfExistingItems = itemsToBeInsertedToDom.length; 19861 for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) { 19862 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index - idx - 1)); 19863 } 19864 } 19865 if (this.settings.loop) { 19866 if (index === this.galleryItems.length - 1) { 19867 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + 0); 19868 } 19869 else if (index === 0) { 19870 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (this.galleryItems.length - 1)); 19871 } 19872 } 19873 if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) { 19874 itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + prevIndex); 19875 } 19876 return itemsToBeInsertedToDom; 19877 }; 19878 LightGallery.prototype.organizeSlideItems = function (index, prevIndex) { 19879 var _this = this; 19880 var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom); 19881 itemsToBeInsertedToDom.forEach(function (item) { 19882 if (_this.currentItemsInDom.indexOf(item) === -1) { 19883 _this.$inner.append("<div id=\"" + item + "\" class=\"lg-item\"></div>"); 19884 } 19885 }); 19886 this.currentItemsInDom.forEach(function (item) { 19887 if (itemsToBeInsertedToDom.indexOf(item) === -1) { 19888 $LG("#" + item).remove(); 19889 } 19890 }); 19891 return itemsToBeInsertedToDom; 19892 }; 19893 /** 19894 * Get previous index of the slide 19895 */ 19896 LightGallery.prototype.getPreviousSlideIndex = function () { 19897 var prevIndex = 0; 19898 try { 19899 var currentItemId = this.outer 19900 .find('.lg-current') 19901 .first() 19902 .attr('id'); 19903 prevIndex = parseInt(currentItemId.split('-')[3]) || 0; 19904 } 19905 catch (error) { 19906 prevIndex = 0; 19907 } 19908 return prevIndex; 19909 }; 19910 LightGallery.prototype.setDownloadValue = function (index) { 19911 if (this.settings.download) { 19912 var currentGalleryItem = this.galleryItems[index]; 19913 var hideDownloadBtn = currentGalleryItem.downloadUrl === false || 19914 currentGalleryItem.downloadUrl === 'false'; 19915 if (hideDownloadBtn) { 19916 this.outer.addClass('lg-hide-download'); 19917 } 19918 else { 19919 var $download = this.getElementById('lg-download'); 19920 this.outer.removeClass('lg-hide-download'); 19921 $download.attr('href', currentGalleryItem.downloadUrl || 19922 currentGalleryItem.src); 19923 if (currentGalleryItem.download) { 19924 //Uncode edit ##START## 19925 if ( typeof currentGalleryItem.video !== 'undefined' && currentGalleryItem.video ) { 19926 var currentVideo = JSON.parse( currentGalleryItem.video ), 19927 download_name = currentVideo.source[0].src; 19928 $download.attr('href', download_name).removeAttr('download'); 19929 } else { 19930 var download_url = currentGalleryItem.downloadUrl || currentGalleryItem.src, 19931 download_name = download_url.substring(download_url.lastIndexOf('/')+1); 19932 $download.attr('download', download_name); 19933 } 19934 // $download.attr('download', currentGalleryItem.download); 19935 //Uncode edit ##END## 19936 } 19937 } 19938 } 19939 }; 19940 LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) { 19941 var _this = this; 19942 if (this.lGalleryOn) { 19943 previousSlideItem.addClass('lg-slide-progress'); 19944 } 19945 setTimeout(function () { 19946 // remove all transitions 19947 _this.outer.addClass('lg-no-trans'); 19948 _this.outer 19949 .find('.lg-item') 19950 .removeClass('lg-prev-slide lg-next-slide'); 19951 if (direction === 'prev') { 19952 //prevslide 19953 currentSlideItem.addClass('lg-prev-slide'); 19954 previousSlideItem.addClass('lg-next-slide'); 19955 } 19956 else { 19957 // next slide 19958 currentSlideItem.addClass('lg-next-slide'); 19959 previousSlideItem.addClass('lg-prev-slide'); 19960 } 19961 // give 50 ms for browser to add/remove class 19962 setTimeout(function () { 19963 _this.outer.find('.lg-item').removeClass('lg-current'); 19964 currentSlideItem.addClass('lg-current'); 19965 // reset all transitions 19966 _this.outer.removeClass('lg-no-trans'); 19967 }, 50); 19968 }, this.lGalleryOn ? this.settings.slideDelay : 0); 19969 }; 19970 /** 19971 * Goto a specific slide. 19972 * @param {Number} index - index of the slide 19973 * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag 19974 * @param {Boolean} fromThumb - true if slide function called via thumbnail click 19975 * @param {String} direction - Direction of the slide(next/prev) 19976 * @category lGPublicMethods 19977 * @example 19978 * const plugin = lightGallery(); 19979 * // to go to 3rd slide 19980 * plugin.slide(2); 19981 * 19982 */ 19983 LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) { 19984 var _this = this; 19985 var prevIndex = this.getPreviousSlideIndex(); 19986 this.currentItemsInDom = this.organizeSlideItems(index, prevIndex); 19987 // Prevent multiple call, Required for hsh plugin 19988 if (this.lGalleryOn && prevIndex === index) { 19989 return; 19990 } 19991 var numberOfGalleryItems = this.galleryItems.length; 19992 if (!this.lgBusy) { 19993 if (this.settings.counter) { 19994 this.updateCurrentCounter(index); 19995 } 19996 var currentSlideItem = this.getSlideItem(index); 19997 var previousSlideItem_1 = this.getSlideItem(prevIndex); 19998 var currentGalleryItem = this.galleryItems[index]; 19999 var videoInfo = currentGalleryItem.__slideVideoInfo; 20000 this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem)); 20001 this.setDownloadValue(index); 20002 if (videoInfo) { 20003 var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom; 20004 //Uncode edit ##START## 20005 var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]); 20006 // var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize); 20007 //Uncode edit ##END## 20008 this.resizeVideoSlide(index, videoSize); 20009 } 20010 this.LGel.trigger(lGEvents.beforeSlide, { 20011 prevIndex: prevIndex, 20012 index: index, 20013 fromTouch: !!fromTouch, 20014 fromThumb: !!fromThumb, 20015 //Uncode edit ##START## 20016 currentSlide: currentSlideItem, 20017 previousSlide: previousSlideItem_1, 20018 info: currentGalleryItem, 20019 item: this.items[index] 20020 //Uncode edit ##END## 20021 }); 20022 this.lgBusy = true; 20023 clearTimeout(this.hideBarTimeout); 20024 this.arrowDisable(index); 20025 if (!direction) { 20026 if (index < prevIndex) { 20027 direction = 'prev'; 20028 } 20029 else if (index > prevIndex) { 20030 direction = 'next'; 20031 } 20032 } 20033 if (!fromTouch) { 20034 this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1); 20035 } 20036 else { 20037 this.outer 20038 .find('.lg-item') 20039 .removeClass('lg-prev-slide lg-current lg-next-slide'); 20040 var touchPrev = void 0; 20041 var touchNext = void 0; 20042 if (numberOfGalleryItems > 2) { 20043 touchPrev = index - 1; 20044 touchNext = index + 1; 20045 if (index === 0 && prevIndex === numberOfGalleryItems - 1) { 20046 // next slide 20047 touchNext = 0; 20048 touchPrev = numberOfGalleryItems - 1; 20049 } 20050 else if (index === numberOfGalleryItems - 1 && 20051 prevIndex === 0) { 20052 // prev slide 20053 touchNext = 0; 20054 touchPrev = numberOfGalleryItems - 1; 20055 } 20056 } 20057 else { 20058 touchPrev = 0; 20059 touchNext = 1; 20060 } 20061 if (direction === 'prev') { 20062 this.getSlideItem(touchNext).addClass('lg-next-slide'); 20063 } 20064 else { 20065 this.getSlideItem(touchPrev).addClass('lg-prev-slide'); 20066 } 20067 currentSlideItem.addClass('lg-current'); 20068 } 20069 // Do not put load content in set timeout as it needs to load immediately when the gallery is opened 20070 if (!this.lGalleryOn) { 20071 this.loadContent(index, true); 20072 } 20073 else { 20074 setTimeout(function () { 20075 _this.loadContent(index, true); 20076 // Add title if this.settings.appendSubHtmlTo === lg-sub-html 20077 if (_this.settings.appendSubHtmlTo !== '.lg-item') { 20078 _this.addHtml(index); 20079 } 20080 }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay)); 20081 } 20082 setTimeout(function () { 20083 _this.lgBusy = false; 20084 previousSlideItem_1.removeClass('lg-slide-progress'); 20085 _this.LGel.trigger(lGEvents.afterSlide, { 20086 prevIndex: prevIndex, 20087 index: index, 20088 fromTouch: fromTouch, 20089 fromThumb: fromThumb, 20090 }); 20091 }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay)); 20092 } 20093 this.index = index; 20094 }; 20095 LightGallery.prototype.updateCurrentCounter = function (index) { 20096 this.getElementById('lg-counter-current').html(index + 1 + ''); 20097 }; 20098 LightGallery.prototype.updateCounterTotal = function () { 20099 this.getElementById('lg-counter-all').html(this.galleryItems.length + ''); 20100 }; 20101 LightGallery.prototype.getSlideType = function (item) { 20102 if (item.__slideVideoInfo) { 20103 return 'video'; 20104 } 20105 else if (item.iframe) { 20106 return 'iframe'; 20107 } 20108 //Uncode edit ##START## 20109 else if (typeof item.src !== '' && item.src.search(/.mp3|.m4a/i) > -1) { 20110 return 'audio'; 20111 } 20112 //Uncode edit ##END## 20113 else { 20114 return 'image'; 20115 } 20116 }; 20117 LightGallery.prototype.touchMove = function (startCoords, endCoords, e) { 20118 var distanceX = endCoords.pageX - startCoords.pageX; 20119 var distanceY = endCoords.pageY - startCoords.pageY; 20120 var allowSwipe = false; 20121 if (this.swipeDirection) { 20122 allowSwipe = true; 20123 } 20124 else { 20125 if (Math.abs(distanceX) > 15) { 20126 this.swipeDirection = 'horizontal'; 20127 allowSwipe = true; 20128 } 20129 else if (Math.abs(distanceY) > 15) { 20130 this.swipeDirection = 'vertical'; 20131 allowSwipe = true; 20132 } 20133 } 20134 if (!allowSwipe) { 20135 return; 20136 } 20137 var $currentSlide = this.getSlideItem(this.index); 20138 if (this.swipeDirection === 'horizontal') { 20139 e === null || e === void 0 ? void 0 : e.preventDefault(); 20140 // reset opacity and transition duration 20141 this.outer.addClass('lg-dragging'); 20142 // move current slide 20143 this.setTranslate($currentSlide, distanceX, 0); 20144 // move next and prev slide with current slide 20145 var width = $currentSlide.get().offsetWidth; 20146 var slideWidthAmount = (width * 15) / 100; 20147 var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100); 20148 this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0); 20149 this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0); 20150 } 20151 else if (this.swipeDirection === 'vertical') { 20152 if (this.settings.swipeToClose) { 20153 e === null || e === void 0 ? void 0 : e.preventDefault(); 20154 this.$container.addClass('lg-dragging-vertical'); 20155 var opacity = 1 - Math.abs(distanceY) / window.innerHeight; 20156 this.$backdrop.css('opacity', opacity); 20157 var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2); 20158 this.setTranslate($currentSlide, 0, distanceY, scale, scale); 20159 if (Math.abs(distanceY) > 100) { 20160 this.outer 20161 .addClass('lg-hide-items') 20162 .removeClass('lg-components-open'); 20163 } 20164 } 20165 } 20166 }; 20167 LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) { 20168 var _this = this; 20169 var distance; 20170 // keep slide animation for any mode while dragg/swipe 20171 if (this.settings.mode !== 'lg-slide') { 20172 this.outer.addClass('lg-slide'); 20173 } 20174 // set transition duration 20175 setTimeout(function () { 20176 _this.$container.removeClass('lg-dragging-vertical'); 20177 _this.outer 20178 .removeClass('lg-dragging lg-hide-items') 20179 .addClass('lg-components-open'); 20180 var triggerClick = true; 20181 if (_this.swipeDirection === 'horizontal') { 20182 distance = endCoords.pageX - startCoords.pageX; 20183 var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX); 20184 if (distance < 0 && 20185 distanceAbs > _this.settings.swipeThreshold) { 20186 _this.goToNextSlide(true); 20187 triggerClick = false; 20188 } 20189 else if (distance > 0 && 20190 distanceAbs > _this.settings.swipeThreshold) { 20191 _this.goToPrevSlide(true); 20192 triggerClick = false; 20193 } 20194 } 20195 else if (_this.swipeDirection === 'vertical') { 20196 distance = Math.abs(endCoords.pageY - startCoords.pageY); 20197 if (_this.settings.closable && 20198 _this.settings.swipeToClose && 20199 distance > 100) { 20200 _this.closeGallery(); 20201 return; 20202 } 20203 else { 20204 _this.$backdrop.css('opacity', 1); 20205 } 20206 } 20207 _this.outer.find('.lg-item').removeAttr('style'); 20208 if (triggerClick && 20209 Math.abs(endCoords.pageX - startCoords.pageX) < 5) { 20210 // Trigger click if distance is less than 5 pix 20211 var target = $LG(event.target); 20212 if (_this.isPosterElement(target)) { 20213 _this.LGel.trigger(lGEvents.posterClick); 20214 } 20215 } 20216 _this.swipeDirection = undefined; 20217 }); 20218 // remove slide class once drag/swipe is completed if mode is not slide 20219 setTimeout(function () { 20220 if (!_this.outer.hasClass('lg-dragging') && 20221 _this.settings.mode !== 'lg-slide') { 20222 _this.outer.removeClass('lg-slide'); 20223 } 20224 }, this.settings.speed + 100); 20225 }; 20226 LightGallery.prototype.enableSwipe = function () { 20227 var _this = this; 20228 var startCoords = {}; 20229 var endCoords = {}; 20230 var isMoved = false; 20231 var isSwiping = false; 20232 if (this.settings.enableSwipe) { 20233 this.$inner.on('touchstart.lg', function (e) { 20234 _this.dragOrSwipeEnabled = true; 20235 var $item = _this.getSlideItem(_this.index); 20236 if (($LG(e.target).hasClass('lg-item') || 20237 $item.get().contains(e.target)) && 20238 !_this.outer.hasClass('lg-zoomed') && 20239 !_this.lgBusy && 20240 e.targetTouches.length === 1) { 20241 isSwiping = true; 20242 _this.touchAction = 'swipe'; 20243 _this.manageSwipeClass(); 20244 startCoords = { 20245 pageX: e.targetTouches[0].pageX, 20246 pageY: e.targetTouches[0].pageY, 20247 }; 20248 } 20249 }); 20250 this.$inner.on('touchmove.lg', function (e) { 20251 if (isSwiping && 20252 _this.touchAction === 'swipe' && 20253 e.targetTouches.length === 1) { 20254 endCoords = { 20255 pageX: e.targetTouches[0].pageX, 20256 pageY: e.targetTouches[0].pageY, 20257 }; 20258 _this.touchMove(startCoords, endCoords, e); 20259 isMoved = true; 20260 } 20261 }); 20262 this.$inner.on('touchend.lg', function (event) { 20263 if (_this.touchAction === 'swipe') { 20264 if (isMoved) { 20265 isMoved = false; 20266 _this.touchEnd(endCoords, startCoords, event); 20267 } 20268 else if (isSwiping) { 20269 var target = $LG(event.target); 20270 if (_this.isPosterElement(target)) { 20271 _this.LGel.trigger(lGEvents.posterClick); 20272 } 20273 } 20274 _this.touchAction = undefined; 20275 isSwiping = false; 20276 } 20277 }); 20278 } 20279 }; 20280 LightGallery.prototype.enableDrag = function () { 20281 var _this = this; 20282 var startCoords = {}; 20283 var endCoords = {}; 20284 var isDraging = false; 20285 var isMoved = false; 20286 if (this.settings.enableDrag) { 20287 this.outer.on('mousedown.lg', function (e) { 20288 _this.dragOrSwipeEnabled = true; 20289 var $item = _this.getSlideItem(_this.index); 20290 if ($LG(e.target).hasClass('lg-item') || 20291 $item.get().contains(e.target)) { 20292 if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) { 20293 e.preventDefault(); 20294 if (!_this.lgBusy) { 20295 _this.manageSwipeClass(); 20296 startCoords = { 20297 pageX: e.pageX, 20298 pageY: e.pageY, 20299 }; 20300 isDraging = true; 20301 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 20302 _this.outer.get().scrollLeft += 1; 20303 _this.outer.get().scrollLeft -= 1; 20304 // * 20305 _this.outer 20306 .removeClass('lg-grab') 20307 .addClass('lg-grabbing'); 20308 _this.LGel.trigger(lGEvents.dragStart); 20309 } 20310 } 20311 } 20312 }); 20313 $LG(window).on("mousemove.lg.global" + this.lgId, function (e) { 20314 if (isDraging && _this.lgOpened) { 20315 isMoved = true; 20316 endCoords = { 20317 pageX: e.pageX, 20318 pageY: e.pageY, 20319 }; 20320 _this.touchMove(startCoords, endCoords); 20321 _this.LGel.trigger(lGEvents.dragMove); 20322 } 20323 }); 20324 $LG(window).on("mouseup.lg.global" + this.lgId, function (event) { 20325 if (!_this.lgOpened) { 20326 return; 20327 } 20328 var target = $LG(event.target); 20329 if (isMoved) { 20330 isMoved = false; 20331 _this.touchEnd(endCoords, startCoords, event); 20332 _this.LGel.trigger(lGEvents.dragEnd); 20333 } 20334 else if (_this.isPosterElement(target)) { 20335 _this.LGel.trigger(lGEvents.posterClick); 20336 } 20337 // Prevent execution on click 20338 if (isDraging) { 20339 isDraging = false; 20340 _this.outer.removeClass('lg-grabbing').addClass('lg-grab'); 20341 } 20342 }); 20343 } 20344 }; 20345 LightGallery.prototype.triggerPosterClick = function () { 20346 var _this = this; 20347 this.$inner.on('click.lg', function (event) { 20348 if (!_this.dragOrSwipeEnabled && 20349 _this.isPosterElement($LG(event.target))) { 20350 _this.LGel.trigger(lGEvents.posterClick); 20351 } 20352 }); 20353 }; 20354 LightGallery.prototype.manageSwipeClass = function () { 20355 var _touchNext = this.index + 1; 20356 var _touchPrev = this.index - 1; 20357 if (this.settings.loop && this.galleryItems.length > 2) { 20358 if (this.index === 0) { 20359 _touchPrev = this.galleryItems.length - 1; 20360 } 20361 else if (this.index === this.galleryItems.length - 1) { 20362 _touchNext = 0; 20363 } 20364 } 20365 this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide'); 20366 if (_touchPrev > -1) { 20367 this.getSlideItem(_touchPrev).addClass('lg-prev-slide'); 20368 } 20369 this.getSlideItem(_touchNext).addClass('lg-next-slide'); 20370 }; 20371 /** 20372 * Go to next slide 20373 * @param {Boolean} fromTouch - true if slide function called via touch event 20374 * @category lGPublicMethods 20375 * @example 20376 * const plugin = lightGallery(); 20377 * plugin.goToNextSlide(); 20378 * @see <a href="/demos/methods/">Demo</a> 20379 */ 20380 LightGallery.prototype.goToNextSlide = function (fromTouch) { 20381 var _this = this; 20382 var _loop = this.settings.loop; 20383 if (fromTouch && this.galleryItems.length < 3) { 20384 _loop = false; 20385 } 20386 if (!this.lgBusy) { 20387 if (this.index + 1 < this.galleryItems.length) { 20388 this.index++; 20389 this.LGel.trigger(lGEvents.beforeNextSlide, { 20390 index: this.index, 20391 }); 20392 this.slide(this.index, !!fromTouch, false, 'next'); 20393 } 20394 else { 20395 if (_loop) { 20396 this.index = 0; 20397 this.LGel.trigger(lGEvents.beforeNextSlide, { 20398 index: this.index, 20399 }); 20400 this.slide(this.index, !!fromTouch, false, 'next'); 20401 } 20402 else if (this.settings.slideEndAnimation && !fromTouch) { 20403 this.outer.addClass('lg-right-end'); 20404 setTimeout(function () { 20405 _this.outer.removeClass('lg-right-end'); 20406 }, 400); 20407 } 20408 } 20409 } 20410 }; 20411 /** 20412 * Go to previous slides 20413 * @param {Boolean} fromTouch - true if slide function called via touch event 20414 * @category lGPublicMethods 20415 * @example 20416 * const plugin = lightGallery({}); 20417 * plugin.goToPrevSlide(); 20418 * @see <a href="/demos/methods/">Demo</a> 20419 * 20420 */ 20421 LightGallery.prototype.goToPrevSlide = function (fromTouch) { 20422 var _this = this; 20423 var _loop = this.settings.loop; 20424 if (fromTouch && this.galleryItems.length < 3) { 20425 _loop = false; 20426 } 20427 if (!this.lgBusy) { 20428 if (this.index > 0) { 20429 this.index--; 20430 this.LGel.trigger(lGEvents.beforePrevSlide, { 20431 index: this.index, 20432 fromTouch: fromTouch, 20433 }); 20434 this.slide(this.index, !!fromTouch, false, 'prev'); 20435 } 20436 else { 20437 if (_loop) { 20438 this.index = this.galleryItems.length - 1; 20439 this.LGel.trigger(lGEvents.beforePrevSlide, { 20440 index: this.index, 20441 fromTouch: fromTouch, 20442 }); 20443 this.slide(this.index, !!fromTouch, false, 'prev'); 20444 } 20445 else if (this.settings.slideEndAnimation && !fromTouch) { 20446 this.outer.addClass('lg-left-end'); 20447 setTimeout(function () { 20448 _this.outer.removeClass('lg-left-end'); 20449 }, 400); 20450 } 20451 } 20452 } 20453 }; 20454 LightGallery.prototype.keyPress = function () { 20455 var _this = this; 20456 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 20457 if (_this.lgOpened && 20458 _this.settings.escKey === true && 20459 e.keyCode === 27) { 20460 e.preventDefault(); 20461 if (_this.settings.allowMediaOverlap && 20462 _this.outer.hasClass('lg-can-toggle') && 20463 _this.outer.hasClass('lg-components-open')) { 20464 _this.outer.removeClass('lg-components-open'); 20465 } 20466 else { 20467 _this.closeGallery(); 20468 } 20469 } 20470 if (_this.lgOpened && _this.galleryItems.length > 1) { 20471 if (e.keyCode === 37) { 20472 e.preventDefault(); 20473 _this.goToPrevSlide(); 20474 } 20475 if (e.keyCode === 39) { 20476 e.preventDefault(); 20477 _this.goToNextSlide(); 20478 } 20479 } 20480 }); 20481 }; 20482 LightGallery.prototype.arrow = function () { 20483 var _this = this; 20484 this.getElementById('lg-prev').on('click.lg', function () { 20485 _this.goToPrevSlide(); 20486 }); 20487 this.getElementById('lg-next').on('click.lg', function () { 20488 _this.goToNextSlide(); 20489 }); 20490 }; 20491 LightGallery.prototype.arrowDisable = function (index) { 20492 // Disable arrows if settings.hideControlOnEnd is true 20493 if (!this.settings.loop && this.settings.hideControlOnEnd) { 20494 var $prev = this.getElementById('lg-prev'); 20495 var $next = this.getElementById('lg-next'); 20496 if (index + 1 === this.galleryItems.length) { 20497 $next.attr('disabled', 'disabled').addClass('disabled'); 20498 } 20499 else { 20500 $next.removeAttr('disabled').removeClass('disabled'); 20501 } 20502 if (index === 0) { 20503 $prev.attr('disabled', 'disabled').addClass('disabled'); 20504 } 20505 else { 20506 $prev.removeAttr('disabled').removeClass('disabled'); 20507 } 20508 } 20509 }; 20510 LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) { 20511 if (scaleX === void 0) { scaleX = 1; } 20512 if (scaleY === void 0) { scaleY = 1; } 20513 $el.css('transform', 'translate3d(' + 20514 xValue + 20515 'px, ' + 20516 yValue + 20517 'px, 0px) scale3d(' + 20518 scaleX + 20519 ', ' + 20520 scaleY + 20521 ', 1)'); 20522 }; 20523 LightGallery.prototype.mousewheel = function () { 20524 var _this = this; 20525 var lastCall = 0; 20526 this.outer.on('wheel.lg', function (e) { 20527 if (!e.deltaY || _this.galleryItems.length < 2) { 20528 return; 20529 } 20530 e.preventDefault(); 20531 var now = new Date().getTime(); 20532 if (now - lastCall < 1000) { 20533 return; 20534 } 20535 lastCall = now; 20536 if (e.deltaY > 0) { 20537 _this.goToNextSlide(); 20538 } 20539 else if (e.deltaY < 0) { 20540 _this.goToPrevSlide(); 20541 } 20542 }); 20543 }; 20544 LightGallery.prototype.isSlideElement = function (target) { 20545 return (target.hasClass('lg-outer') || 20546 target.hasClass('lg-item') || 20547 target.hasClass('lg-img-wrap')); 20548 }; 20549 LightGallery.prototype.isPosterElement = function (target) { 20550 var playButton = this.getSlideItem(this.index) 20551 .find('.lg-video-play-button') 20552 .get(); 20553 return (target.hasClass('lg-video-poster') || 20554 target.hasClass('lg-video-play-button') || 20555 (playButton && playButton.contains(target.get()))); 20556 }; 20557 /** 20558 * Maximize minimize inline gallery. 20559 * @category lGPublicMethods 20560 */ 20561 LightGallery.prototype.toggleMaximize = function () { 20562 var _this = this; 20563 this.getElementById('lg-maximize').on('click.lg', function () { 20564 _this.$container.toggleClass('lg-inline'); 20565 _this.refreshOnResize(); 20566 }); 20567 }; 20568 LightGallery.prototype.invalidateItems = function () { 20569 for (var index = 0; index < this.items.length; index++) { 20570 var element = this.items[index]; 20571 var $element = $LG(element); 20572 $element.off("click.lgcustom-item-" + $element.attr('data-lg-id')); 20573 } 20574 }; 20575 LightGallery.prototype.trapFocus = function () { 20576 var _this = this; 20577 this.$container.get().focus({ 20578 preventScroll: true, 20579 }); 20580 $LG(window).on("keydown.lg.global" + this.lgId, function (e) { 20581 if (!_this.lgOpened) { 20582 return; 20583 } 20584 var isTabPressed = e.key === 'Tab' || e.keyCode === 9; 20585 if (!isTabPressed) { 20586 return; 20587 } 20588 var focusableEls = utils.getFocusableElements(_this.$container.get()); 20589 var firstFocusableEl = focusableEls[0]; 20590 var lastFocusableEl = focusableEls[focusableEls.length - 1]; 20591 if (e.shiftKey) { 20592 if (document.activeElement === firstFocusableEl) { 20593 lastFocusableEl.focus(); 20594 e.preventDefault(); 20595 } 20596 } 20597 else { 20598 if (document.activeElement === lastFocusableEl) { 20599 firstFocusableEl.focus(); 20600 e.preventDefault(); 20601 } 20602 } 20603 }); 20604 }; 20605 LightGallery.prototype.manageCloseGallery = function () { 20606 var _this = this; 20607 if (!this.settings.closable) 20608 return; 20609 var mousedown = false; 20610 this.getElementById('lg-close').on('click.lg', function () { 20611 _this.closeGallery(); 20612 }); 20613 if (this.settings.closeOnTap) { 20614 // If you drag the slide and release outside gallery gets close on chrome 20615 // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer 20616 this.outer.on('mousedown.lg', function (e) { 20617 var target = $LG(e.target); 20618 if (_this.isSlideElement(target)) { 20619 mousedown = true; 20620 } 20621 else { 20622 mousedown = false; 20623 } 20624 }); 20625 this.outer.on('mousemove.lg', function () { 20626 mousedown = false; 20627 }); 20628 this.outer.on('mouseup.lg', function (e) { 20629 var target = $LG(e.target); 20630 if (_this.isSlideElement(target) && mousedown) { 20631 if (!_this.outer.hasClass('lg-dragging')) { 20632 _this.closeGallery(); 20633 } 20634 } 20635 }); 20636 } 20637 }; 20638 /** 20639 * Close lightGallery if it is opened. 20640 * 20641 * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery 20642 * @return returns the estimated time to close gallery completely including the close animation duration 20643 * @category lGPublicMethods 20644 * @example 20645 * const plugin = lightGallery(); 20646 * plugin.closeGallery(); 20647 * 20648 */ 20649 LightGallery.prototype.closeGallery = function (force) { 20650 var _this = this; 20651 if (!this.lgOpened || (!this.settings.closable && !force)) { 20652 return 0; 20653 } 20654 this.LGel.trigger(lGEvents.beforeClose); 20655 if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) { 20656 $LG(window).scrollTop(this.prevScrollTop); 20657 } 20658 var currentItem = this.items[this.index]; 20659 var transform; 20660 if (this.zoomFromOrigin && currentItem) { 20661 var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom; 20662 var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster; 20663 //Uncode edit ##START## 20664 var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize, this.galleryItems[this.index]); 20665 // var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize); 20666 //Uncode edit ##END## 20667 transform = utils.getTransform(currentItem, this.outer, top_4, bottom, imageSize); 20668 } 20669 if (this.zoomFromOrigin && transform) { 20670 this.outer.addClass('lg-closing lg-zoom-from-image'); 20671 this.getSlideItem(this.index) 20672 .addClass('lg-start-end-progress') 20673 .css('transition-duration', this.settings.startAnimationDuration + 'ms') 20674 .css('transform', transform); 20675 } 20676 else { 20677 this.outer.addClass('lg-hide-items'); 20678 // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true 20679 // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts 20680 this.outer.removeClass('lg-zoom-from-image'); 20681 } 20682 // Unbind all events added by lightGallery 20683 // @todo 20684 //this.$el.off('.lg.tm'); 20685 this.destroyModules(); 20686 this.lGalleryOn = false; 20687 this.isDummyImageRemoved = false; 20688 this.zoomFromOrigin = this.settings.zoomFromOrigin; 20689 clearTimeout(this.hideBarTimeout); 20690 this.hideBarTimeout = false; 20691 $LG('html').removeClass('lg-on'); 20692 this.outer.removeClass('lg-visible lg-components-open'); 20693 // Resetting opacity to 0 isd required as vertical swipe to close function adds inline opacity. 20694 this.$backdrop.removeClass('in').css('opacity', 0); 20695 var removeTimeout = this.zoomFromOrigin && transform 20696 ? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration) 20697 : this.settings.backdropDuration; 20698 this.$container.removeClass('lg-show-in'); 20699 // Once the closign animation is completed and gallery is invisible 20700 setTimeout(function () { 20701 if (_this.zoomFromOrigin && transform) { 20702 _this.outer.removeClass('lg-zoom-from-image'); 20703 } 20704 _this.$container.removeClass('lg-show'); 20705 // Reset scrollbar 20706 _this.resetScrollBar(); 20707 // Need to remove inline opacity as it is used in the stylesheet as well 20708 _this.$backdrop 20709 .removeAttr('style') 20710 .css('transition-duration', _this.settings.backdropDuration + 'ms'); 20711 _this.outer.removeClass("lg-closing " + _this.settings.startClass);
vendor: 6,259 bytes, lines 20712-20915
20712 _this.getSlideItem(_this.index).removeClass('lg-start-end-progress'); 20713 _this.$inner.empty(); 20714 if (_this.lgOpened) { 20715 _this.LGel.trigger(lGEvents.afterClose, { 20716 instance: _this, 20717 }); 20718 } 20719 if (_this.$container.get()) { 20720 _this.$container.get().blur(); 20721 } 20722 _this.lgOpened = false; 20723 }, removeTimeout + 100); 20724 return removeTimeout + 100; 20725 }; 20726 LightGallery.prototype.initModules = function () { 20727 this.plugins.forEach(function (module) { 20728 try { 20729 module.init(); 20730 } 20731 catch (err) { 20732 console.warn("lightGallery:- make sure lightGallery module is properly initiated"); 20733 } 20734 }); 20735 }; 20736 LightGallery.prototype.destroyModules = function (destroy) { 20737 this.plugins.forEach(function (module) { 20738 try { 20739 if (destroy) { 20740 module.destroy(); 20741 } 20742 else { 20743 module.closeGallery && module.closeGallery(); 20744 } 20745 } 20746 catch (err) { 20747 console.warn("lightGallery:- make sure lightGallery module is properly destroyed"); 20748 } 20749 }); 20750 }; 20751 /** 20752 * Refresh lightGallery with new set of children. 20753 * 20754 * @description This is useful to update the gallery when the child elements are changed without calling destroy method. 20755 * 20756 * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery 20757 * @see <a href="/demos/dynamic-mode/">Demo</a> 20758 * @category lGPublicMethods 20759 * @example 20760 * const plugin = lightGallery(); 20761 * // Delete or add children, then call 20762 * plugin.refresh(); 20763 * 20764 */ 20765 LightGallery.prototype.refresh = function (galleryItems) { 20766 if (!this.settings.dynamic) { 20767 this.invalidateItems(); 20768 } 20769 if (galleryItems) { 20770 this.galleryItems = galleryItems; 20771 } 20772 else { 20773 this.galleryItems = this.getItems(); 20774 } 20775 this.updateControls(); 20776 this.openGalleryOnItemClick(); 20777 this.LGel.trigger(lGEvents.updateSlides); 20778 }; 20779 LightGallery.prototype.updateControls = function () { 20780 this.addSlideVideoInfo(this.galleryItems); 20781 this.updateCounterTotal(); 20782 this.manageSingleSlideClassName(); 20783 }; 20784 /** 20785 * Destroy lightGallery. 20786 * Destroy lightGallery and its plugin instances completely 20787 * 20788 * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance. 20789 * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed. 20790 * You can use refresh method most of the times. 20791 * @category lGPublicMethods 20792 * @example 20793 * const plugin = lightGallery(); 20794 * plugin.destroy(); 20795 * 20796 */ 20797 LightGallery.prototype.destroy = function () { 20798 var _this = this; 20799 var closeTimeout = this.closeGallery(true); 20800 setTimeout(function () { 20801 _this.destroyModules(true); 20802 if (!_this.settings.dynamic) { 20803 _this.invalidateItems(); 20804 } 20805 $LG(window).off(".lg.global" + _this.lgId); 20806 _this.LGel.off('.lg'); 20807 _this.$container.remove(); 20808 }, closeTimeout); 20809 return closeTimeout; 20810 }; 20811 return LightGallery; 20812 }()); 20813 20814 function lightGallery(el, options) { 20815 return new LightGallery(el, options); 20816 } 20817 20818 return lightGallery; 20819 20820}))); 20821 20822/*! 20823 * lightgallery | 2.5.0 | June 13th 2022 20824 * http://www.lightgalleryjs.com/ 20825 * Copyright (c) 2020 Sachin Neravath; 20826 * @license GPLv3 20827 */ 20828 20829(function (global, factory) { 20830 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 20831 typeof define === 'function' && define.amd ? define(factory) : 20832 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgZoom = factory()); 20833}(this, (function () { 'use strict'; 20834 20835 /*! ***************************************************************************** 20836 Copyright (c) Microsoft Corporation. 20837 20838 Permission to use, copy, modify, and/or distribute this software for any 20839 purpose with or without fee is hereby granted. 20840 20841 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 20842 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 20843 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 20844 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20845 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20846 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20847 PERFORMANCE OF THIS SOFTWARE. 20848 ***************************************************************************** */ 20849 20850 var __assign = function() { 20851 __assign = Object.assign || function __assign(t) { 20852 for (var s, i = 1, n = arguments.length; i < n; i++) { 20853 s = arguments[i]; 20854 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 20855 } 20856 return t; 20857 }; 20858 return __assign.apply(this, arguments); 20859 }; 20860 20861 var zoomSettings = { 20862 scale: 1, 20863 zoom: true, 20864 actualSize: true, 20865 showZoomInOutIcons: false, 20866 actualSizeIcons: { 20867 zoomIn: 'lg-zoom-in', 20868 zoomOut: 'lg-zoom-out', 20869 }, 20870 enableZoomAfter: 300, 20871 zoomPluginStrings: { 20872 zoomIn: 'Zoom in', 20873 zoomOut: 'Zoom out', 20874 viewActualSize: 'View actual size', 20875 }, 20876 }; 20877 20878 /** 20879 * List of lightGallery events 20880 * All events should be documented here 20881 * Below interfaces are used to build the website documentations 20882 * */ 20883 var lGEvents = { 20884 afterAppendSlide: 'lgAfterAppendSlide', 20885 init: 'lgInit', 20886 hasVideo: 'lgHasVideo', 20887 containerResize: 'lgContainerResize', 20888 updateSlides: 'lgUpdateSlides', 20889 afterAppendSubHtml: 'lgAfterAppendSubHtml', 20890 beforeOpen: 'lgBeforeOpen', 20891 afterOpen: 'lgAfterOpen', 20892 slideItemLoad: 'lgSlideItemLoad', 20893 beforeSlide: 'lgBeforeSlide', 20894 afterSlide: 'lgAfterSlide', 20895 posterClick: 'lgPosterClick', 20896 dragStart: 'lgDragStart', 20897 dragMove: 'lgDragMove', 20898 dragEnd: 'lgDragEnd', 20899 beforeNextSlide: 'lgBeforeNextSlide', 20900 beforePrevSlide: 'lgBeforePrevSlide', 20901 beforeClose: 'lgBeforeClose', 20902 afterClose: 'lgAfterClose', 20903 rotateLeft: 'lgRotateLeft', 20904 rotateRight: 'lgRotateRight', 20905 flipHorizontal: 'lgFlipHorizontal', 20906 flipVertical: 'lgFlipVertical', 20907 autoplay: 'lgAutoplay', 20908 autoplayStart: 'lgAutoplayStart', 20909 autoplayStop: 'lgAutoplayStop', 20910 }; 20911 20912 var Zoom = /** @class */ (function () { 20913 function Zoom(instance, $LG) { 20914 // get lightGallery core plugin instance 20915 this.core = instance;
20916 this.$LG = $LG; 20917 this.settings = __assign(__assign({}, zoomSettings), this.core.settings); 20918 return this; 20919 } 20920 // Append Zoom controls. Actual size, Zoom-in, Zoom-out 20921 Zoom.prototype.buildTemplates = function () { 20922 var zoomIcons = this.settings.showZoomInOutIcons 20923 ? "<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>" 20924 : ''; 20925 if (this.settings.actualSize) { 20926 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>"; 20927 } 20928 this.core.outer.addClass('lg-use-transition-for-zoom'); 20929 this.core.$toolbar.first().append(zoomIcons); 20930 }; 20931 /** 20932 * @desc Enable zoom option only once the image is completely loaded 20933 * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted 20934 * 20935 * Zoom styles are defined under lg-zoomable CSS class. 20936 */ 20937 Zoom.prototype.enableZoom = function (event) { 20938 var _this = this; 20939 // delay will be 0 except first time 20940 var _speed = this.settings.enableZoomAfter + event.detail.delay; 20941 // set _speed value 0 if gallery opened from direct url and if it is first slide 20942 if (this.$LG('body').first().hasClass('lg-from-hash') && 20943 event.detail.delay) { 20944 // will execute only once 20945 _speed = 0; 20946 } 20947 else { 20948 // Remove lg-from-hash to enable starting animation. 20949 this.$LG('body').first().removeClass('lg-from-hash'); 20950 } 20951 this.zoomableTimeout = setTimeout(function () { 20952 if (!_this.isImageSlide()) { 20953 return; 20954 } 20955 _this.core.getSlideItem(event.detail.index).addClass('lg-zoomable'); 20956 if (event.detail.index === _this.core.index) { 20957 _this.setZoomEssentials(); 20958 } 20959 }, _speed + 30); 20960 }; 20961 Zoom.prototype.enableZoomOnSlideItemLoad = function () { 20962 // Add zoomable class 20963 this.core.LGel.on(lGEvents.slideItemLoad + ".zoom", this.enableZoom.bind(this)); 20964 }; 20965 Zoom.prototype.getModifier = function (rotateValue, axis, el) { 20966 var originalRotate = rotateValue; 20967 rotateValue = Math.abs(rotateValue); 20968 var transformValues = this.getCurrentTransform(el); 20969 if (!transformValues) { 20970 return 1; 20971 } 20972 var modifier = 1; 20973 if (axis === 'X') { 20974 var flipHorizontalValue = Math.sign(parseFloat(transformValues[0])); 20975 if (rotateValue === 0 || rotateValue === 180) { 20976 modifier = 1; 20977 } 20978 else if (rotateValue === 90) { 20979 if ((originalRotate === -90 && flipHorizontalValue === 1) || 20980 (originalRotate === 90 && flipHorizontalValue === -1)) { 20981 modifier = -1; 20982 } 20983 else { 20984 modifier = 1; 20985 } 20986 } 20987 modifier = modifier * flipHorizontalValue; 20988 } 20989 else { 20990 var flipVerticalValue = Math.sign(parseFloat(transformValues[3])); 20991 if (rotateValue === 0 || rotateValue === 180) { 20992 modifier = 1; 20993 } 20994 else if (rotateValue === 90) { 20995 var sinX = parseFloat(transformValues[1]); 20996 var sinMinusX = parseFloat(transformValues[2]); 20997 modifier = Math.sign(sinX * sinMinusX * originalRotate * flipVerticalValue); 20998 } 20999 modifier = modifier * flipVerticalValue; 21000 } 21001 return modifier; 21002 }; 21003 Zoom.prototype.getImageSize = function ($image, rotateValue, axis) { 21004 var imageSizes = { 21005 y: 'offsetHeight', 21006 x: 'offsetWidth', 21007 }; 21008 if (Math.abs(rotateValue) === 90) { 21009 // Swap axis 21010 if (axis === 'x') { 21011 axis = 'y'; 21012 } 21013 else { 21014 axis = 'x'; 21015 } 21016 } 21017 return $image[imageSizes[axis]]; 21018 }; 21019 Zoom.prototype.getDragCords = function (e, rotateValue) { 21020 if (rotateValue === 90) { 21021 return { 21022 x: e.pageY, 21023 y: e.pageX, 21024 }; 21025 } 21026 else { 21027 return { 21028 x: e.pageX, 21029 y: e.pageY, 21030 }; 21031 } 21032 }; 21033 Zoom.prototype.getSwipeCords = function (e, rotateValue) { 21034 var x = e.targetTouches[0].pageX; 21035 var y = e.targetTouches[0].pageY; 21036 if (rotateValue === 90) { 21037 return { 21038 x: y, 21039 y: x, 21040 }; 21041 } 21042 else { 21043 return { 21044 x: x, 21045 y: y, 21046 }; 21047 } 21048 }; 21049 Zoom.prototype.getDragAllowedAxises = function (rotateValue, scale) { 21050 scale = scale || this.scale || 1; 21051 var allowY = this.imageYSize * scale > this.containerRect.height; 21052 var allowX = this.imageXSize * scale > this.containerRect.width; 21053 if (rotateValue === 90) { 21054 return { 21055 allowX: allowY, 21056 allowY: allowX, 21057 }; 21058 } 21059 else { 21060 return { 21061 allowX: allowX, 21062 allowY: allowY, 21063 }; 21064 } 21065 }; 21066 /** 21067 * 21068 * @param {Element} el 21069 * @return matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0); 21070 * Get the current transform value 21071 */ 21072 Zoom.prototype.getCurrentTransform = function (el) { 21073 if (!el) { 21074 return; 21075 } 21076 var st = window.getComputedStyle(el, null); 21077 var tm = st.getPropertyValue('-webkit-transform') || 21078 st.getPropertyValue('-moz-transform') || 21079 st.getPropertyValue('-ms-transform') || 21080 st.getPropertyValue('-o-transform') || 21081 st.getPropertyValue('transform') || 21082 'none'; 21083 if (tm !== 'none') { 21084 return tm.split('(')[1].split(')')[0].split(','); 21085 } 21086 return; 21087 }; 21088 Zoom.prototype.getCurrentRotation = function (el) { 21089 if (!el) { 21090 return 0; 21091 } 21092 var values = this.getCurrentTransform(el); 21093 if (values) { 21094 return Math.round(Math.atan2(parseFloat(values[1]), parseFloat(values[0])) * 21095 (180 / Math.PI)); 21096 // If you want rotate in 360 21097 //return (angle < 0 ? angle + 360 : angle); 21098 } 21099 return 0; 21100 }; 21101 Zoom.prototype.setZoomEssentials = function () { 21102 var $image = this.core 21103 .getSlideItem(this.core.index) 21104 .find('.lg-image') 21105 .first(); 21106 var rotateEl = this.core 21107 .getSlideItem(this.core.index) 21108 .find('.lg-img-rotate') 21109 .first() 21110 .get(); 21111 this.rotateValue = this.getCurrentRotation(rotateEl); 21112 this.imageYSize = this.getImageSize($image.get(), this.rotateValue, 'y'); 21113 this.imageXSize = this.getImageSize($image.get(), this.rotateValue, 'x'); 21114 this.containerRect = this.core.outer.get().getBoundingClientRect(); 21115 this.modifierX = this.getModifier(this.rotateValue, 'X', rotateEl); 21116 this.modifierY = this.getModifier(this.rotateValue, 'Y', rotateEl); 21117 }; 21118 /** 21119 * @desc Image zoom 21120 * Translate the wrap and scale the image to get better user experience 21121 * 21122 * @param {String} scale - Zoom decrement/increment value 21123 */ 21124 Zoom.prototype.zoomImage = function (scale) { 21125 // Find offset manually to avoid issue after zoom 21126 var offsetX = (this.containerRect.width - this.imageXSize) / 2 + 21127 this.containerRect.left; 21128 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 21129 var topBottomSpacing = Math.abs(top - bottom) / 2; 21130 var offsetY = (this.containerRect.height - 21131 this.imageYSize - 21132 topBottomSpacing * this.modifierX) / 21133 2 + 21134 this.scrollTop + 21135 this.containerRect.top; 21136 var originalX; 21137 var originalY; 21138 if (scale === 1) { 21139 this.positionChanged = false;
21140 } 21141 var dragAllowedAxises = this.getDragAllowedAxises(Math.abs(this.rotateValue), scale); 21142 var allowY = dragAllowedAxises.allowY, allowX = dragAllowedAxises.allowX; 21143 if (this.positionChanged) { 21144 originalX = this.left / (this.scale - 1); 21145 originalY = this.top / (this.scale - 1); 21146 this.pageX = Math.abs(originalX) + offsetX; 21147 this.pageY = Math.abs(originalY) + offsetY; 21148 this.positionChanged = false; 21149 } 21150 var possibleSwipeCords = this.getPossibleSwipeDragCords(this.rotateValue, scale); 21151 var _x = offsetX - this.pageX; 21152 var _y = offsetY - this.pageY; 21153 var x = (scale - 1) * _x; 21154 var y = (scale - 1) * _y; 21155 if (allowX) { 21156 if (this.isBeyondPossibleLeft(x, possibleSwipeCords.minX)) { 21157 x = possibleSwipeCords.minX; 21158 } 21159 else if (this.isBeyondPossibleRight(x, possibleSwipeCords.maxX)) { 21160 x = possibleSwipeCords.maxX; 21161 } 21162 } 21163 else { 21164 if (scale > 1) { 21165 if (x < possibleSwipeCords.minX) { 21166 x = possibleSwipeCords.minX; 21167 } 21168 else if (x > possibleSwipeCords.maxX) { 21169 x = possibleSwipeCords.maxX; 21170 } 21171 } 21172 }
21173 if (allowY) { 21174 if (this.isBeyondPossibleTop(y, possibleSwipeCords.minY)) { 21175 y = possibleSwipeCords.minY; 21176 } 21177 else if (this.isBeyondPossibleBottom(y, possibleSwipeCords.maxY)) { 21178 y = possibleSwipeCords.maxY; 21179 } 21180 } 21181 else { 21182 // If the translate value based on index of beyond the viewport, utilize the available space to prevent image being cut out 21183 if (scale > 1) { 21184 //If image goes beyond viewport top, use the minim possible translate value 21185 if (y < possibleSwipeCords.minY) { 21186 y = possibleSwipeCords.minY; 21187 } 21188 else if (y > possibleSwipeCords.maxY) { 21189 y = possibleSwipeCords.maxY; 21190 } 21191 } 21192 } 21193 this.setZoomStyles({ 21194 x: x, 21195 y: y, 21196 scale: scale, 21197 }); 21198 }; 21199 /** 21200 * @desc apply scale3d to image and translate to image wrap 21201 * @param {style} X,Y and scale 21202 */ 21203 Zoom.prototype.setZoomStyles = function (style) { 21204 var $image = this.core 21205 .getSlideItem(this.core.index) 21206 .find('.lg-image') 21207 .first(); 21208 var $dummyImage = this.core.outer 21209 .find('.lg-current .lg-dummy-img') 21210 .first(); 21211 var $imageWrap = $image.parent(); 21212 this.scale = style.scale; 21213 $image.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 21214 $dummyImage.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)'); 21215 var transform = 'translate3d(' + style.x + 'px, ' + style.y + 'px, 0)'; 21216 $imageWrap.css('transform', transform); 21217 this.left = style.x; 21218 this.top = style.y; 21219 }; 21220 /** 21221 * @param index - Index of the current slide 21222 * @param event - event will be available only if the function is called on clicking/taping the imags 21223 */ 21224 Zoom.prototype.setActualSize = function (index, event) { 21225 var _this = this; 21226 // Allow zoom only on image 21227 if (!this.isImageSlide() || 21228 this.core.outer.hasClass('lg-first-slide-loading')) { 21229 return; 21230 } 21231 var scale = this.getCurrentImageActualSizeScale(); 21232 if (this.core.outer.hasClass('lg-zoomed')) { 21233 this.scale = 1; 21234 } 21235 else { 21236 this.scale = this.getScale(scale); 21237 } 21238 this.setPageCords(event); 21239 this.beginZoom(this.scale); 21240 this.zoomImage(this.scale); 21241 setTimeout(function () { 21242 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 21243 }, 10); 21244 }; 21245 Zoom.prototype.getNaturalWidth = function (index) { 21246 var $image = this.core.getSlideItem(index).find('.lg-image').first(); 21247 var naturalWidth = this.core.galleryItems[index].width; 21248 return naturalWidth 21249 ? parseFloat(naturalWidth) 21250 : $image.get().naturalWidth; 21251 }; 21252 Zoom.prototype.getActualSizeScale = function (naturalWidth, width) { 21253 var _scale; 21254 var scale;
21255 if (naturalWidth > width) { 21256 _scale = naturalWidth / width; 21257 scale = _scale || 2; 21258 } 21259 else { 21260 scale = 1; 21261 } 21262 return scale; 21263 }; 21264 Zoom.prototype.getCurrentImageActualSizeScale = function () { 21265 var $image = this.core 21266 .getSlideItem(this.core.index) 21267 .find('.lg-image') 21268 .first(); 21269 var width = $image.get().offsetWidth; 21270 var naturalWidth = this.getNaturalWidth(this.core.index) || width; 21271 return this.getActualSizeScale(naturalWidth, width); 21272 }; 21273 Zoom.prototype.getPageCords = function (event) { 21274 var cords = {}; 21275 if (event) { 21276 cords.x = event.pageX || event.targetTouches[0].pageX; 21277 cords.y = event.pageY || event.targetTouches[0].pageY; 21278 } 21279 else { 21280 var containerRect = this.core.outer.get().getBoundingClientRect(); 21281 cords.x = containerRect.width / 2 + containerRect.left; 21282 cords.y = 21283 containerRect.height / 2 + this.scrollTop + containerRect.top; 21284 } 21285 return cords; 21286 }; 21287 Zoom.prototype.setPageCords = function (event) { 21288 var pageCords = this.getPageCords(event); 21289 this.pageX = pageCords.x; 21290 this.pageY = pageCords.y; 21291 }; 21292 // If true, zoomed - in else zoomed out 21293 Zoom.prototype.beginZoom = function (scale) { 21294 this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 21295 if (scale > 1) { 21296 this.core.outer.addClass('lg-zoomed'); 21297 var $actualSize = this.core.getElementById('lg-actual-size'); 21298 $actualSize 21299 .removeClass(this.settings.actualSizeIcons.zoomIn) 21300 .addClass(this.settings.actualSizeIcons.zoomOut); 21301 } 21302 else { 21303 this.resetZoom(); 21304 } 21305 return scale > 1; 21306 }; 21307 Zoom.prototype.getScale = function (scale) { 21308 var actualSizeScale = this.getCurrentImageActualSizeScale(); 21309 if (scale < 1) { 21310 scale = 1; 21311 } 21312 else if (scale > actualSizeScale) { 21313 scale = actualSizeScale; 21314 } 21315 return scale; 21316 }; 21317 Zoom.prototype.init = function () { 21318 var _this = this; 21319 if (!this.settings.zoom) { 21320 return; 21321 } 21322 this.buildTemplates(); 21323 this.enableZoomOnSlideItemLoad(); 21324 var tapped = null; 21325 this.core.outer.on('dblclick.lg', function (event) { 21326 if (!_this.$LG(event.target).hasClass('lg-image')) { 21327 return; 21328 } 21329 _this.setActualSize(_this.core.index, event); 21330 }); 21331 this.core.outer.on('touchstart.lg', function (event) { 21332 var $target = _this.$LG(event.target); 21333 if (event.targetTouches.length === 1 && 21334 $target.hasClass('lg-image')) { 21335 if (!tapped) { 21336 tapped = setTimeout(function () { 21337 tapped = null; 21338 }, 300); 21339 } 21340 else { 21341 clearTimeout(tapped); 21342 tapped = null; 21343 event.preventDefault(); 21344 _this.setActualSize(_this.core.index, event); 21345 } 21346 } 21347 }); 21348 // Update zoom on resize and orientationchange 21349 this.core.LGel.on(lGEvents.containerResize + ".zoom " + lGEvents.rotateRight + ".zoom " + lGEvents.rotateLeft + ".zoom " + lGEvents.flipHorizontal + ".zoom " + lGEvents.flipVertical + ".zoom", function () { 21350 if (!_this.core.lgOpened || !_this.isImageSlide()) 21351 return; 21352 _this.setPageCords(); 21353 _this.setZoomEssentials(); 21354 _this.zoomImage(_this.scale); 21355 }); 21356 // Update zoom on resize and orientationchange 21357 this.$LG(window).on("scroll.lg.zoom.global" + this.core.lgId, function () { 21358 if (!_this.core.lgOpened) 21359 return; 21360 _this.scrollTop = _this.$LG(window).scrollTop(); 21361 }); 21362 this.core.getElementById('lg-zoom-out').on('click.lg', function () { 21363 if (_this.core.outer.find('.lg-current .lg-image').get()) { 21364 _this.scale -= _this.settings.scale; 21365 _this.scale = _this.getScale(_this.scale); 21366 _this.beginZoom(_this.scale); 21367 _this.zoomImage(_this.scale); 21368 } 21369 }); 21370 this.core.getElementById('lg-zoom-in').on('click.lg', function () { 21371 _this.zoomIn(); 21372 }); 21373 this.core.getElementById('lg-actual-size').on('click.lg', function () { 21374 _this.setActualSize(_this.core.index); 21375 }); 21376 this.core.LGel.on(lGEvents.beforeOpen + ".zoom", function () { 21377 _this.core.outer.find('.lg-item').removeClass('lg-zoomable'); 21378 }); 21379 this.core.LGel.on(lGEvents.afterOpen + ".zoom", function () { 21380 _this.scrollTop = _this.$LG(window).scrollTop(); 21381 // Set the initial value center 21382 _this.pageX = _this.core.outer.width() / 2;
21383 _this.pageY = _this.core.outer.height() / 2 + _this.scrollTop; 21384 _this.scale = 1; 21385 }); 21386 // Reset zoom on slide change 21387 this.core.LGel.on(lGEvents.afterSlide + ".zoom", function (event) { 21388 var prevIndex = event.detail.prevIndex; 21389 _this.scale = 1; 21390 _this.positionChanged = false; 21391 _this.resetZoom(prevIndex); 21392 if (_this.isImageSlide()) { 21393 _this.setZoomEssentials(); 21394 } 21395 }); 21396 // Drag option after zoom 21397 this.zoomDrag(); 21398 this.pinchZoom(); 21399 this.zoomSwipe(); 21400 // Store the zoomable timeout value just to clear it while closing 21401 this.zoomableTimeout = false; 21402 this.positionChanged = false; 21403 }; 21404 Zoom.prototype.zoomIn = function (scale) { 21405 // Allow zoom only on image 21406 if (!this.isImageSlide()) { 21407 return; 21408 } 21409 if (scale) { 21410 this.scale = scale; 21411 } 21412 else { 21413 this.scale += this.settings.scale; 21414 } 21415 this.scale = this.getScale(this.scale); 21416 this.beginZoom(this.scale); 21417 this.zoomImage(this.scale); 21418 }; 21419 // Reset zoom effect 21420 Zoom.prototype.resetZoom = function (index) { 21421 this.core.outer.removeClass('lg-zoomed lg-zoom-drag-transition'); 21422 var $actualSize = this.core.getElementById('lg-actual-size'); 21423 var $item = this.core.getSlideItem(index !== undefined ? index : this.core.index); 21424 $actualSize 21425 .removeClass(this.settings.actualSizeIcons.zoomOut) 21426 .addClass(this.settings.actualSizeIcons.zoomIn); 21427 $item.find('.lg-img-wrap').first().removeAttr('style'); 21428 $item.find('.lg-image').first().removeAttr('style'); 21429 this.scale = 1; 21430 this.left = 0; 21431 this.top = 0; 21432 // Reset pagx pagy values to center 21433 this.setPageCords(); 21434 }; 21435 Zoom.prototype.getTouchDistance = function (e) { 21436 return Math.sqrt((e.targetTouches[0].pageX - e.targetTouches[1].pageX) * 21437 (e.targetTouches[0].pageX - e.targetTouches[1].pageX) + 21438 (e.targetTouches[0].pageY - e.targetTouches[1].pageY) * 21439 (e.targetTouches[0].pageY - e.targetTouches[1].pageY)); 21440 }; 21441 Zoom.prototype.pinchZoom = function () { 21442 var _this = this; 21443 var startDist = 0; 21444 var pinchStarted = false; 21445 var initScale = 1; 21446 var $item = this.core.getSlideItem(this.core.index); 21447 this.core.$inner.on('touchstart.lg', function (e) { 21448 $item = _this.core.getSlideItem(_this.core.index); 21449 if (!_this.isImageSlide()) { 21450 return; 21451 } 21452 if (e.targetTouches.length === 2 && 21453 !_this.core.outer.hasClass('lg-first-slide-loading') && 21454 (_this.$LG(e.target).hasClass('lg-item') || 21455 $item.get().contains(e.target))) { 21456 initScale = _this.scale || 1; 21457 _this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging'); 21458 _this.core.touchAction = 'pinch'; 21459 startDist = _this.getTouchDistance(e); 21460 } 21461 }); 21462 this.core.$inner.on('touchmove.lg', function (e) { 21463 if (e.targetTouches.length === 2 && 21464 _this.core.touchAction === 'pinch' && 21465 (_this.$LG(e.target).hasClass('lg-item') || 21466 $item.get().contains(e.target))) { 21467 e.preventDefault(); 21468 var endDist = _this.getTouchDistance(e); 21469 var distance = startDist - endDist; 21470 if (!pinchStarted && Math.abs(distance) > 5) { 21471 pinchStarted = true; 21472 } 21473 if (pinchStarted) { 21474 _this.scale = Math.max(1, initScale + -distance * 0.008); 21475 _this.zoomImage(_this.scale); 21476 } 21477 } 21478 }); 21479 this.core.$inner.on('touchend.lg', function (e) { 21480 if (_this.core.touchAction === 'pinch' && 21481 (_this.$LG(e.target).hasClass('lg-item') || 21482 $item.get().contains(e.target))) { 21483 pinchStarted = false; 21484 startDist = 0; 21485 if (_this.scale <= 1) { 21486 _this.resetZoom(); 21487 } 21488 else { 21489 _this.scale = _this.getScale(_this.scale); 21490 _this.zoomImage(_this.scale); 21491 _this.core.outer.addClass('lg-zoomed'); 21492 } 21493 _this.core.touchAction = undefined; 21494 } 21495 }); 21496 }; 21497 Zoom.prototype.touchendZoom = function (startCoords, endCoords, allowX, allowY, touchDuration, rotateValue) { 21498 var distanceXnew = endCoords.x - startCoords.x; 21499 var distanceYnew = endCoords.y - startCoords.y; 21500 var speedX = Math.abs(distanceXnew) / touchDuration + 1; 21501 var speedY = Math.abs(distanceYnew) / touchDuration + 1; 21502 if (speedX > 2) { 21503 speedX += 1; 21504 } 21505 if (speedY > 2) { 21506 speedY += 1; 21507 } 21508 distanceXnew = distanceXnew * speedX; 21509 distanceYnew = distanceYnew * speedY; 21510 var _LGel = this.core 21511 .getSlideItem(this.core.index) 21512 .find('.lg-img-wrap') 21513 .first(); 21514 var distance = {}; 21515 distance.x = this.left + distanceXnew * this.modifierX; 21516 distance.y = this.top + distanceYnew * this.modifierY; 21517 var possibleSwipeCords = this.getPossibleSwipeDragCords(rotateValue); 21518 if (Math.abs(distanceXnew) > 15 || Math.abs(distanceYnew) > 15) { 21519 if (allowY) { 21520 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 21521 distance.y = possibleSwipeCords.minY; 21522 } 21523 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 21524 distance.y = possibleSwipeCords.maxY; 21525 } 21526 } 21527 if (allowX) { 21528 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 21529 distance.x = possibleSwipeCords.minX; 21530 } 21531 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 21532 distance.x = possibleSwipeCords.maxX; 21533 } 21534 } 21535 if (allowY) { 21536 this.top = distance.y; 21537 } 21538 else { 21539 distance.y = this.top; 21540 } 21541 if (allowX) { 21542 this.left = distance.x; 21543 } 21544 else { 21545 distance.x = this.left; 21546 } 21547 this.setZoomSwipeStyles(_LGel, distance); 21548 this.positionChanged = true; 21549 } 21550 }; 21551 Zoom.prototype.getZoomSwipeCords = function (startCoords, endCoords, allowX, allowY, possibleSwipeCords) { 21552 var distance = {}; 21553 if (allowY) { 21554 distance.y = 21555 this.top + (endCoords.y - startCoords.y) * this.modifierY; 21556 if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) { 21557 var diffMinY = possibleSwipeCords.minY - distance.y; 21558 distance.y = possibleSwipeCords.minY - diffMinY / 6; 21559 } 21560 else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) { 21561 var diffMaxY = distance.y - possibleSwipeCords.maxY; 21562 distance.y = possibleSwipeCords.maxY + diffMaxY / 6; 21563 } 21564 } 21565 else { 21566 distance.y = this.top; 21567 }
21568 if (allowX) { 21569 distance.x = 21570 this.left + (endCoords.x - startCoords.x) * this.modifierX; 21571 if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) { 21572 var diffMinX = possibleSwipeCords.minX - distance.x; 21573 distance.x = possibleSwipeCords.minX - diffMinX / 6; 21574 } 21575 else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) { 21576 var difMaxX = distance.x - possibleSwipeCords.maxX; 21577 distance.x = possibleSwipeCords.maxX + difMaxX / 6; 21578 } 21579 } 21580 else { 21581 distance.x = this.left; 21582 } 21583 return distance; 21584 }; 21585 Zoom.prototype.isBeyondPossibleLeft = function (x, minX) { 21586 return x >= minX; 21587 }; 21588 Zoom.prototype.isBeyondPossibleRight = function (x, maxX) { 21589 return x <= maxX; 21590 }; 21591 Zoom.prototype.isBeyondPossibleTop = function (y, minY) { 21592 return y >= minY; 21593 }; 21594 Zoom.prototype.isBeyondPossibleBottom = function (y, maxY) { 21595 return y <= maxY; 21596 }; 21597 Zoom.prototype.isImageSlide = function () { 21598 var currentItem = this.core.galleryItems[this.core.index]; 21599 return this.core.getSlideType(currentItem) === 'image'; 21600 }; 21601 Zoom.prototype.getPossibleSwipeDragCords = function (rotateValue, scale) { 21602 var dataScale = scale || this.scale || 1; 21603 var elDataScale = Math.abs(dataScale); 21604 var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom; 21605 var topBottomSpacing = Math.abs(top - bottom) / 2; 21606 var minY = (this.imageYSize - this.containerRect.height) / 2 + 21607 topBottomSpacing * this.modifierX; 21608 var maxY = this.containerRect.height - this.imageYSize * elDataScale + minY; 21609 var minX = (this.imageXSize - this.containerRect.width) / 2; 21610 var maxX = this.containerRect.width - this.imageXSize * elDataScale + minX; 21611 var possibleSwipeCords = { 21612 minY: minY, 21613 maxY: maxY, 21614 minX: minX, 21615 maxX: maxX, 21616 }; 21617 if (Math.abs(rotateValue) === 90) { 21618 possibleSwipeCords = { 21619 minY: minX, 21620 maxY: maxX, 21621 minX: minY, 21622 maxX: maxY, 21623 }; 21624 } 21625 return possibleSwipeCords; 21626 }; 21627 Zoom.prototype.setZoomSwipeStyles = function (LGel, distance) { 21628 LGel.css('transform', 'translate3d(' + distance.x + 'px, ' + distance.y + 'px, 0)'); 21629 }; 21630 Zoom.prototype.zoomSwipe = function () { 21631 var _this = this; 21632 var startCoords = {}; 21633 var endCoords = {}; 21634 var isMoved = false; 21635 // Allow x direction drag 21636 var allowX = false; 21637 // Allow Y direction drag 21638 var allowY = false; 21639 var startTime = new Date(); 21640 var endTime = new Date(); 21641 var possibleSwipeCords; 21642 var _LGel; 21643 var $item = this.core.getSlideItem(this.core.index); 21644 this.core.$inner.on('touchstart.lg', function (e) { 21645 // Allow zoom only on image 21646 if (!_this.isImageSlide()) { 21647 return; 21648 } 21649 $item = _this.core.getSlideItem(_this.core.index); 21650 if ((_this.$LG(e.target).hasClass('lg-item') || 21651 $item.get().contains(e.target)) && 21652 e.targetTouches.length === 1 && 21653 _this.core.outer.hasClass('lg-zoomed')) { 21654 e.preventDefault(); 21655 startTime = new Date(); 21656 _this.core.touchAction = 'zoomSwipe'; 21657 _LGel = _this.core 21658 .getSlideItem(_this.core.index) 21659 .find('.lg-img-wrap') 21660 .first(); 21661 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 21662 allowY = dragAllowedAxises.allowY; 21663 allowX = dragAllowedAxises.allowX; 21664 if (allowX || allowY) { 21665 startCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 21666 } 21667 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 21668 // reset opacity and transition duration 21669 _this.core.outer.addClass('lg-zoom-dragging lg-zoom-drag-transition'); 21670 } 21671 }); 21672 this.core.$inner.on('touchmove.lg', function (e) { 21673 if (e.targetTouches.length === 1 && 21674 _this.core.touchAction === 'zoomSwipe' && 21675 (_this.$LG(e.target).hasClass('lg-item') || 21676 $item.get().contains(e.target))) { 21677 e.preventDefault(); 21678 _this.core.touchAction = 'zoomSwipe'; 21679 endCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue)); 21680 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 21681 if (Math.abs(endCoords.x - startCoords.x) > 15 || 21682 Math.abs(endCoords.y - startCoords.y) > 15) { 21683 isMoved = true; 21684 _this.setZoomSwipeStyles(_LGel, distance); 21685 } 21686 } 21687 }); 21688 this.core.$inner.on('touchend.lg', function (e) { 21689 if (_this.core.touchAction === 'zoomSwipe' && 21690 (_this.$LG(e.target).hasClass('lg-item') || 21691 $item.get().contains(e.target))) { 21692 _this.core.touchAction = undefined; 21693 _this.core.outer.removeClass('lg-zoom-dragging'); 21694 if (!isMoved) { 21695 return; 21696 } 21697 isMoved = false;
21698 endTime = new Date(); 21699 var touchDuration = endTime.valueOf() - startTime.valueOf(); 21700 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 21701 } 21702 }); 21703 }; 21704 Zoom.prototype.zoomDrag = function () { 21705 var _this = this; 21706 var startCoords = {}; 21707 var endCoords = {}; 21708 var isDragging = false; 21709 var isMoved = false; 21710 // Allow x direction drag 21711 var allowX = false; 21712 // Allow Y direction drag 21713 var allowY = false; 21714 var startTime; 21715 var endTime; 21716 var possibleSwipeCords; 21717 var _LGel; 21718 this.core.outer.on('mousedown.lg.zoom', function (e) { 21719 // Allow zoom only on image 21720 if (!_this.isImageSlide()) { 21721 return; 21722 } 21723 var $item = _this.core.getSlideItem(_this.core.index); 21724 if (_this.$LG(e.target).hasClass('lg-item') || 21725 $item.get().contains(e.target)) { 21726 startTime = new Date(); 21727 _LGel = _this.core 21728 .getSlideItem(_this.core.index) 21729 .find('.lg-img-wrap') 21730 .first(); 21731 var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue)); 21732 allowY = dragAllowedAxises.allowY; 21733 allowX = dragAllowedAxises.allowX; 21734 if (_this.core.outer.hasClass('lg-zoomed')) { 21735 if (_this.$LG(e.target).hasClass('lg-object') && 21736 (allowX || allowY)) { 21737 e.preventDefault(); 21738 startCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 21739 possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue); 21740 isDragging = true; 21741 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 21742 _this.core.outer.get().scrollLeft += 1; 21743 _this.core.outer.get().scrollLeft -= 1; 21744 _this.core.outer 21745 .removeClass('lg-grab') 21746 .addClass('lg-grabbing lg-zoom-drag-transition lg-zoom-dragging'); 21747 // reset opacity and transition duration 21748 } 21749 } 21750 } 21751 }); 21752 this.$LG(window).on("mousemove.lg.zoom.global" + this.core.lgId, function (e) { 21753 if (isDragging) { 21754 isMoved = true; 21755 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 21756 var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords); 21757 _this.setZoomSwipeStyles(_LGel, distance); 21758 } 21759 }); 21760 this.$LG(window).on("mouseup.lg.zoom.global" + this.core.lgId, function (e) { 21761 if (isDragging) { 21762 endTime = new Date(); 21763 isDragging = false; 21764 _this.core.outer.removeClass('lg-zoom-dragging'); 21765 // Fix for chrome mouse move on click 21766 if (isMoved && 21767 (startCoords.x !== endCoords.x || 21768 startCoords.y !== endCoords.y)) { 21769 endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue)); 21770 var touchDuration = endTime.valueOf() - startTime.valueOf(); 21771 _this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue); 21772 } 21773 isMoved = false; 21774 } 21775 _this.core.outer.removeClass('lg-grabbing').addClass('lg-grab'); 21776 }); 21777 }; 21778 Zoom.prototype.closeGallery = function () { 21779 this.resetZoom(); 21780 }; 21781 Zoom.prototype.destroy = function () { 21782 // Unbind all events added by lightGallery zoom plugin 21783 this.$LG(window).off(".lg.zoom.global" + this.core.lgId); 21784 this.core.LGel.off('.lg.zoom'); 21785 this.core.LGel.off('.zoom'); 21786 clearTimeout(this.zoomableTimeout); 21787 this.zoomableTimeout = false; 21788 }; 21789 return Zoom; 21790 }()); 21791 21792 return Zoom; 21793 21794}))); 21795/*! 21796 * lightgallery | 2.5.0 | June 13th 2022 21797 * http://www.lightgalleryjs.com/ 21798 * Copyright (c) 2020 Sachin Neravath; 21799 * @license GPLv3 21800 */ 21801 21802(function (global, factory) { 21803 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21804 typeof define === 'function' && define.amd ? define(factory) : 21805 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgFullscreen = factory()); 21806}(this, (function () { 'use strict'; 21807 21808 /*! ***************************************************************************** 21809 Copyright (c) Microsoft Corporation. 21810 21811 Permission to use, copy, modify, and/or distribute this software for any 21812 purpose with or without fee is hereby granted. 21813 21814 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21815 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21816 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21817 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21818 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21819 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21820 PERFORMANCE OF THIS SOFTWARE. 21821 ***************************************************************************** */ 21822 21823 var __assign = function() { 21824 __assign = Object.assign || function __assign(t) { 21825 for (var s, i = 1, n = arguments.length; i < n; i++) { 21826 s = arguments[i]; 21827 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21828 } 21829 return t; 21830 }; 21831 return __assign.apply(this, arguments); 21832 }; 21833 21834 var fullscreenSettings = { 21835 fullScreen: true, 21836 fullscreenPluginStrings: { 21837 toggleFullscreen: 'Toggle Fullscreen', 21838 }, 21839 }; 21840 21841 var FullScreen = /** @class */ (function () { 21842 function FullScreen(instance, $LG) { 21843 // get lightGallery core plugin instance 21844 this.core = instance;
21845 this.$LG = $LG; 21846 // extend module default settings with lightGallery core settings 21847 this.settings = __assign(__assign({}, fullscreenSettings), this.core.settings); 21848 return this; 21849 } 21850 FullScreen.prototype.init = function () { 21851 var fullScreen = ''; 21852 if (this.settings.fullScreen) { 21853 // check for fullscreen browser support 21854 if (!document.fullscreenEnabled && 21855 !document.webkitFullscreenEnabled && 21856 !document.mozFullScreenEnabled && 21857 !document.msFullscreenEnabled) { 21858 return; 21859 } 21860 else { 21861 fullScreen = "<button type=\"button\" aria-label=\"" + this.settings.fullscreenPluginStrings['toggleFullscreen'] + "\" class=\"lg-fullscreen lg-icon\"></button>"; 21862 this.core.$toolbar.append(fullScreen); 21863 this.fullScreen(); 21864 } 21865 } 21866 }; 21867 FullScreen.prototype.isFullScreen = function () { 21868 return (document.fullscreenElement || 21869 document.mozFullScreenElement || 21870 document.webkitFullscreenElement || 21871 document.msFullscreenElement); 21872 }; 21873 FullScreen.prototype.requestFullscreen = function () { 21874 var el = document.documentElement; 21875 if (el.requestFullscreen) { 21876 el.requestFullscreen(); 21877 } 21878 else if (el.msRequestFullscreen) { 21879 el.msRequestFullscreen(); 21880 } 21881 else if (el.mozRequestFullScreen) { 21882 el.mozRequestFullScreen(); 21883 } 21884 else if (el.webkitRequestFullscreen) { 21885 el.webkitRequestFullscreen(); 21886 } 21887 }; 21888 FullScreen.prototype.exitFullscreen = function () { 21889 if (document.exitFullscreen) { 21890 document.exitFullscreen(); 21891 } 21892 else if (document.msExitFullscreen) { 21893 document.msExitFullscreen(); 21894 } 21895 else if (document.mozCancelFullScreen) { 21896 document.mozCancelFullScreen(); 21897 } 21898 else if (document.webkitExitFullscreen) { 21899 document.webkitExitFullscreen(); 21900 } 21901 }; 21902 // https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode 21903 FullScreen.prototype.fullScreen = function () { 21904 var _this = this; 21905 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 () { 21906 if (!_this.core.lgOpened) 21907 return; 21908 _this.core.outer.toggleClass('lg-fullscreen-on'); 21909 }); 21910 this.core.outer 21911 .find('.lg-fullscreen') 21912 .first() 21913 .on('click.lg', function () { 21914 if (_this.isFullScreen()) { 21915 _this.exitFullscreen(); 21916 } 21917 else { 21918 _this.requestFullscreen(); 21919 } 21920 }); 21921 }; 21922 FullScreen.prototype.closeGallery = function () { 21923 // exit from fullscreen if activated 21924 if (this.isFullScreen()) { 21925 this.exitFullscreen(); 21926 } 21927 }; 21928 FullScreen.prototype.destroy = function () { 21929 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); 21930 }; 21931 return FullScreen; 21932 }()); 21933 21934 return FullScreen; 21935 21936}))); 21937 21938/*! 21939 * lightgallery | 2.5.0 | June 13th 2022 21940 * http://www.lightgalleryjs.com/ 21941 * Copyright (c) 2020 Sachin Neravath; 21942 * @license GPLv3 21943 */ 21944 21945(function (global, factory) { 21946 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 21947 typeof define === 'function' && define.amd ? define(factory) : 21948 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgHash = factory()); 21949}(this, (function () { 'use strict'; 21950 21951 /*! ***************************************************************************** 21952 Copyright (c) Microsoft Corporation. 21953 21954 Permission to use, copy, modify, and/or distribute this software for any 21955 purpose with or without fee is hereby granted. 21956 21957 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 21958 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 21959 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 21960 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21961 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21962 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21963 PERFORMANCE OF THIS SOFTWARE. 21964 ***************************************************************************** */ 21965 21966 var __assign = function() { 21967 __assign = Object.assign || function __assign(t) { 21968 for (var s, i = 1, n = arguments.length; i < n; i++) { 21969 s = arguments[i]; 21970 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 21971 } 21972 return t; 21973 }; 21974 return __assign.apply(this, arguments); 21975 }; 21976 21977 /** 21978 * List of lightGallery events 21979 * All events should be documented here 21980 * Below interfaces are used to build the website documentations 21981 * */ 21982 var lGEvents = { 21983 afterAppendSlide: 'lgAfterAppendSlide', 21984 init: 'lgInit', 21985 hasVideo: 'lgHasVideo', 21986 containerResize: 'lgContainerResize', 21987 updateSlides: 'lgUpdateSlides', 21988 afterAppendSubHtml: 'lgAfterAppendSubHtml', 21989 beforeOpen: 'lgBeforeOpen', 21990 afterOpen: 'lgAfterOpen', 21991 slideItemLoad: 'lgSlideItemLoad', 21992 beforeSlide: 'lgBeforeSlide', 21993 afterSlide: 'lgAfterSlide', 21994 posterClick: 'lgPosterClick', 21995 dragStart: 'lgDragStart', 21996 dragMove: 'lgDragMove', 21997 dragEnd: 'lgDragEnd', 21998 beforeNextSlide: 'lgBeforeNextSlide', 21999 beforePrevSlide: 'lgBeforePrevSlide', 22000 beforeClose: 'lgBeforeClose', 22001 afterClose: 'lgAfterClose', 22002 rotateLeft: 'lgRotateLeft', 22003 rotateRight: 'lgRotateRight', 22004 flipHorizontal: 'lgFlipHorizontal', 22005 flipVertical: 'lgFlipVertical', 22006 autoplay: 'lgAutoplay', 22007 autoplayStart: 'lgAutoplayStart', 22008 autoplayStop: 'lgAutoplayStop', 22009 }; 22010 22011 var hashSettings = { 22012 hash: true, 22013 galleryId: '1', 22014 customSlideName: false, 22015 }; 22016 22017 var Hash = /** @class */ (function () { 22018 function Hash(instance, $LG) { 22019 // get lightGallery core plugin instance 22020 this.core = instance;
22021 this.$LG = $LG; 22022 // extend module default settings with lightGallery core settings 22023 this.settings = __assign(__assign({}, hashSettings), this.core.settings); 22024 return this; 22025 } 22026 Hash.prototype.init = function () { 22027 var _this = this; 22028 if (!this.settings.hash) { 22029 return; 22030 } 22031 this.oldHash = window.location.hash; 22032 setTimeout(function () { 22033 _this.buildFromHash(); 22034 }, 100); 22035 // Change hash value on after each slide transition 22036 this.core.LGel.on(lGEvents.afterSlide + ".hash", this.onAfterSlide.bind(this)); 22037 this.core.LGel.on(lGEvents.afterClose + ".hash", this.onCloseAfter.bind(this)); 22038 // Listen hash change and change the slide according to slide value 22039 this.$LG(window).on("hashchange.lg.hash.global" + this.core.lgId, this.onHashchange.bind(this)); 22040 }; 22041 Hash.prototype.onAfterSlide = function (event) { 22042 var slideName = this.core.galleryItems[event.detail.index].slideName; 22043 slideName = this.settings.customSlideName 22044 ? slideName || event.detail.index 22045 : event.detail.index; 22046 if (history.replaceState) { 22047 history.replaceState(null, '', window.location.pathname + 22048 window.location.search + 22049 '#lg=' + 22050 this.settings.galleryId + 22051 '&slide=' + 22052 slideName); 22053 } 22054 else { 22055 window.location.hash = 22056 'lg=' + this.settings.galleryId + '&slide=' + slideName; 22057 } 22058 }; 22059 /** 22060 * Get index of the slide from custom slideName. Has to be a public method. Used in hash plugin 22061 * @param {String} hash 22062 * @returns {Number} Index of the slide. 22063 */ 22064 Hash.prototype.getIndexFromUrl = function (hash) { 22065 if (hash === void 0) { hash = window.location.hash; } 22066 var slideName = hash.split('&slide=')[1]; 22067 var _idx = 0; 22068 if (this.settings.customSlideName) { 22069 for (var index = 0; index < this.core.galleryItems.length; index++) { 22070 var dynamicEl = this.core.galleryItems[index]; 22071 if (dynamicEl.slideName === slideName) { 22072 _idx = index; 22073 break; 22074 } 22075 } 22076 } 22077 else { 22078 _idx = parseInt(slideName, 10); 22079 } 22080 return isNaN(_idx) ? 0 : _idx; 22081 }; 22082 // Build Gallery if gallery id exist in the URL 22083 Hash.prototype.buildFromHash = function () { 22084 // if dynamic option is enabled execute immediately 22085 var _hash = window.location.hash; 22086 //Uncode edit ##START## 22087 // if (_hash.indexOf('lg=' + this.settings.galleryId) > 0) { 22088 if (_hash.indexOf('lg=' + this.settings.galleryId + '&') > 0) { 22089 //Uncode edit ##END## 22090 // This class is used to remove the initial animation if galleryId present in the URL 22091 this.$LG(document.body).addClass('lg-from-hash'); 22092 var index = this.getIndexFromUrl(_hash); 22093 this.core.openGallery(index); 22094 return true; 22095 } 22096 }; 22097 Hash.prototype.onCloseAfter = function () { 22098 // Reset to old hash value 22099 if (this.oldHash && 22100 this.oldHash.indexOf('lg=' + this.settings.galleryId) < 0) { 22101 if (history.replaceState) { 22102 history.replaceState(null, '', this.oldHash); 22103 } 22104 else { 22105 window.location.hash = this.oldHash; 22106 } 22107 } 22108 else { 22109 if (history.replaceState) { 22110 history.replaceState(null, document.title, window.location.pathname + window.location.search); 22111 } 22112 else { 22113 window.location.hash = ''; 22114 } 22115 } 22116 }; 22117 Hash.prototype.onHashchange = function () { 22118 if (!this.core.lgOpened) 22119 return; 22120 var _hash = window.location.hash; 22121 var index = this.getIndexFromUrl(_hash); 22122 // it galleryId doesn't exist in the url close the gallery 22123 if (_hash.indexOf('lg=' + this.settings.galleryId) > -1) { 22124 this.core.slide(index, false, false); 22125 } 22126 else if (this.core.lGalleryOn) { 22127 this.core.closeGallery(); 22128 } 22129 }; 22130 Hash.prototype.closeGallery = function () { 22131 if (this.settings.hash) { 22132 this.$LG(document.body).removeClass('lg-from-hash'); 22133 } 22134 }; 22135 Hash.prototype.destroy = function () { 22136 this.core.LGel.off('.lg.hash'); 22137 this.core.LGel.off('.hash'); 22138 this.$LG(window).off("hashchange.lg.hash.global" + this.core.lgId); 22139 }; 22140 return Hash; 22141 }()); 22142 22143 return Hash; 22144 22145}))); 22146/*! 22147 * lightgallery | 2.5.0 | June 13th 2022 22148 * http://www.lightgalleryjs.com/ 22149 * Copyright (c) 2020 Sachin Neravath; 22150 * @license GPLv3 22151 */ 22152 22153(function (global, factory) { 22154 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 22155 typeof define === 'function' && define.amd ? define(factory) : 22156 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgShare = factory()); 22157}(this, (function () { 'use strict'; 22158 22159 /*! ***************************************************************************** 22160 Copyright (c) Microsoft Corporation. 22161 22162 Permission to use, copy, modify, and/or distribute this software for any 22163 purpose with or without fee is hereby granted. 22164 22165 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 22166 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 22167 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 22168 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 22169 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 22170 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22171 PERFORMANCE OF THIS SOFTWARE. 22172 ***************************************************************************** */ 22173 22174 var __assign = function() { 22175 __assign = Object.assign || function __assign(t) { 22176 for (var s, i = 1, n = arguments.length; i < n; i++) { 22177 s = arguments[i]; 22178 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 22179 } 22180 return t; 22181 }; 22182 return __assign.apply(this, arguments); 22183 }; 22184 22185 function __spreadArrays() { 22186 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 22187 for (var r = Array(s), k = 0, i = 0; i < il; i++) 22188 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 22189 r[k] = a[j]; 22190 return r; 22191 } 22192 22193 var shareSettings = { 22194 share: true, 22195 facebook: true, 22196 facebookDropdownText: 'Facebook', 22197 twitter: true, 22198 twitterDropdownText: 'Twitter', 22199 pinterest: true, 22200 pinterestDropdownText: 'Pinterest', 22201 additionalShareOptions: [], 22202 sharePluginStrings: { share: 'Share' }, 22203 }; 22204 22205 function getFacebookShareLink(galleryItem) { 22206 var facebookBaseUrl = '//www.facebook.com/sharer/sharer.php?u='; 22207 return (facebookBaseUrl + 22208 encodeURIComponent(galleryItem.facebookShareUrl || window.location.href)); 22209 } 22210 22211 function getTwitterShareLink(galleryItem) { 22212 var twitterBaseUrl = '//twitter.com/intent/tweet?text='; 22213 var url = encodeURIComponent(galleryItem.twitterShareUrl || window.location.href); 22214 var text = galleryItem.tweetText;
22215 return twitterBaseUrl + text + '&url=' + url; 22216 } 22217 22218 function getPinterestShareLink(galleryItem) { 22219 var pinterestBaseUrl = 'http://www.pinterest.com/pin/create/button/?url='; 22220 var description = galleryItem.pinterestText; 22221 var media = encodeURIComponent(galleryItem.src); 22222 var url = encodeURIComponent(galleryItem.pinterestShareUrl || window.location.href); 22223 return (pinterestBaseUrl + 22224 url + 22225 '&media=' + 22226 media + 22227 '&description=' + 22228 description); 22229 } 22230 22231 /** 22232 * List of lightGallery events 22233 * All events should be documented here 22234 * Below interfaces are used to build the website documentations 22235 * */ 22236 var lGEvents = { 22237 afterAppendSlide: 'lgAfterAppendSlide', 22238 init: 'lgInit', 22239 hasVideo: 'lgHasVideo', 22240 containerResize: 'lgContainerResize', 22241 updateSlides: 'lgUpdateSlides', 22242 afterAppendSubHtml: 'lgAfterAppendSubHtml', 22243 beforeOpen: 'lgBeforeOpen', 22244 afterOpen: 'lgAfterOpen', 22245 slideItemLoad: 'lgSlideItemLoad', 22246 beforeSlide: 'lgBeforeSlide', 22247 afterSlide: 'lgAfterSlide', 22248 posterClick: 'lgPosterClick', 22249 dragStart: 'lgDragStart', 22250 dragMove: 'lgDragMove', 22251 dragEnd: 'lgDragEnd', 22252 beforeNextSlide: 'lgBeforeNextSlide', 22253 beforePrevSlide: 'lgBeforePrevSlide', 22254 beforeClose: 'lgBeforeClose', 22255 afterClose: 'lgAfterClose', 22256 rotateLeft: 'lgRotateLeft', 22257 rotateRight: 'lgRotateRight', 22258 flipHorizontal: 'lgFlipHorizontal', 22259 flipVertical: 'lgFlipVertical', 22260 autoplay: 'lgAutoplay', 22261 autoplayStart: 'lgAutoplayStart', 22262 autoplayStop: 'lgAutoplayStop', 22263 }; 22264 22265 var Share = /** @class */ (function () { 22266 function Share(instance) { 22267 this.shareOptions = []; 22268 // get lightGallery core plugin instance 22269 this.core = instance; 22270 // extend module default settings with lightGallery core settings 22271 this.settings = __assign(__assign({}, shareSettings), this.core.settings); 22272 return this; 22273 } 22274 Share.prototype.init = function () { 22275 if (!this.settings.share) { 22276 return; 22277 } 22278 this.shareOptions = __spreadArrays(this.getDefaultShareOptions(), this.settings.additionalShareOptions); 22279 this.setLgShareMarkup(); 22280 this.core.outer 22281 .find('.lg-share .lg-dropdown') 22282 .append(this.getShareListHtml()); 22283 this.core.LGel.on(lGEvents.afterSlide + ".share", this.onAfterSlide.bind(this)); 22284 }; 22285 Share.prototype.getShareListHtml = function () { 22286 var shareHtml = ''; 22287 this.shareOptions.forEach(function (shareOption) { 22288 shareHtml += shareOption.dropdownHTML; 22289 }); 22290 return shareHtml; 22291 }; 22292 Share.prototype.setLgShareMarkup = function () { 22293 var _this = this; 22294 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>"); 22295 this.core.outer.append('<div class="lg-dropdown-overlay"></div>'); 22296 var $shareButton = this.core.outer.find('.lg-share'); 22297 $shareButton.first().on('click.lg', function () { 22298 _this.core.outer.toggleClass('lg-dropdown-active'); 22299 if (_this.core.outer.hasClass('lg-dropdown-active')) { 22300 _this.core.outer.attr('aria-expanded', true); 22301 } 22302 else { 22303 _this.core.outer.attr('aria-expanded', false); 22304 } 22305 }); 22306 this.core.outer 22307 .find('.lg-dropdown-overlay') 22308 .first() 22309 .on('click.lg', function () { 22310 _this.core.outer.removeClass('lg-dropdown-active'); 22311 _this.core.outer.attr('aria-expanded', false); 22312 }); 22313 }; 22314 Share.prototype.onAfterSlide = function (event) { 22315 var _this = this; 22316 var index = event.detail.index; 22317 var currentItem = this.core.galleryItems[index]; 22318 setTimeout(function () { 22319 _this.shareOptions.forEach(function (shareOption) { 22320 var selector = shareOption.selector; 22321 _this.core.outer 22322 .find(selector) 22323 .attr('href', shareOption.generateLink(currentItem)); 22324 }); 22325 }, 100); 22326 }; 22327 Share.prototype.getShareListItemHTML = function (type, text) { 22328 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>"; 22329 }; 22330 Share.prototype.getDefaultShareOptions = function () { 22331 return __spreadArrays((this.settings.facebook 22332 ? [ 22333 { 22334 type: 'facebook', 22335 generateLink: getFacebookShareLink,
22336 dropdownHTML: this.getShareListItemHTML('facebook', this.settings.facebookDropdownText), 22337 selector: '.lg-share-facebook', 22338 }, 22339 ] 22340 : []), (this.settings.twitter 22341 ? [ 22342 { 22343 type: 'twitter', 22344 generateLink: getTwitterShareLink, 22345 dropdownHTML: this.getShareListItemHTML('twitter', this.settings.twitterDropdownText), 22346 selector: '.lg-share-twitter', 22347 }, 22348 ] 22349 : []), (this.settings.pinterest 22350 ? [ 22351 { 22352 type: 'pinterest', 22353 generateLink: getPinterestShareLink, 22354 dropdownHTML: this.getShareListItemHTML('pinterest', this.settings.pinterestDropdownText), 22355 selector: '.lg-share-pinterest', 22356 }, 22357 ] 22358 : [])); 22359 }; 22360 Share.prototype.destroy = function () { 22361 this.core.outer.find('.lg-dropdown-overlay').remove(); 22362 this.core.outer.find('.lg-share').remove(); 22363 this.core.LGel.off('.lg.share'); 22364 this.core.LGel.off('.share'); 22365 }; 22366 return Share; 22367 }()); 22368 22369 return Share; 22370 22371}))); 22372/*! 22373 * lightgallery | 2.5.0 | June 13th 2022 22374 * http://www.lightgalleryjs.com/ 22375 * Copyright (c) 2020 Sachin Neravath; 22376 * @license GPLv3 22377 */ 22378 22379(function (global, factory) { 22380 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 22381 typeof define === 'function' && define.amd ? define(factory) : 22382 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgThumbnail = factory()); 22383}(this, (function () { 'use strict'; 22384 22385 /*! ***************************************************************************** 22386 Copyright (c) Microsoft Corporation. 22387 22388 Permission to use, copy, modify, and/or distribute this software for any 22389 purpose with or without fee is hereby granted. 22390 22391 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 22392 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 22393 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 22394 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 22395 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 22396 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22397 PERFORMANCE OF THIS SOFTWARE. 22398 ***************************************************************************** */ 22399 22400 var __assign = function() { 22401 __assign = Object.assign || function __assign(t) { 22402 for (var s, i = 1, n = arguments.length; i < n; i++) { 22403 s = arguments[i]; 22404 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 22405 } 22406 return t; 22407 }; 22408 return __assign.apply(this, arguments); 22409 }; 22410 22411 var thumbnailsSettings = { 22412 thumbnail: true, 22413 animateThumb: true, 22414 currentPagerPosition: 'middle', 22415 alignThumbnails: 'middle', 22416 thumbWidth: 100, 22417 thumbHeight: '80px', 22418 thumbMargin: 5, 22419 appendThumbnailsTo: '.lg-components', 22420 toggleThumb: false, 22421 enableThumbDrag: true, 22422 enableThumbSwipe: true, 22423 thumbnailSwipeThreshold: 10, 22424 loadYouTubeThumbnail: true, 22425 youTubeThumbSize: 1, 22426 thumbnailPluginStrings: { 22427 toggleThumbnails: 'Toggle thumbnails', 22428 }, 22429 }; 22430 22431 /** 22432 * List of lightGallery events 22433 * All events should be documented here 22434 * Below interfaces are used to build the website documentations 22435 * */ 22436 var lGEvents = { 22437 afterAppendSlide: 'lgAfterAppendSlide', 22438 init: 'lgInit', 22439 hasVideo: 'lgHasVideo', 22440 containerResize: 'lgContainerResize', 22441 updateSlides: 'lgUpdateSlides', 22442 afterAppendSubHtml: 'lgAfterAppendSubHtml', 22443 beforeOpen: 'lgBeforeOpen', 22444 afterOpen: 'lgAfterOpen', 22445 slideItemLoad: 'lgSlideItemLoad', 22446 beforeSlide: 'lgBeforeSlide', 22447 afterSlide: 'lgAfterSlide', 22448 posterClick: 'lgPosterClick', 22449 dragStart: 'lgDragStart', 22450 dragMove: 'lgDragMove', 22451 dragEnd: 'lgDragEnd', 22452 beforeNextSlide: 'lgBeforeNextSlide', 22453 beforePrevSlide: 'lgBeforePrevSlide', 22454 beforeClose: 'lgBeforeClose', 22455 afterClose: 'lgAfterClose', 22456 rotateLeft: 'lgRotateLeft', 22457 rotateRight: 'lgRotateRight', 22458 flipHorizontal: 'lgFlipHorizontal', 22459 flipVertical: 'lgFlipVertical', 22460 autoplay: 'lgAutoplay', 22461 autoplayStart: 'lgAutoplayStart', 22462 autoplayStop: 'lgAutoplayStop', 22463 }; 22464 22465 var Thumbnail = /** @class */ (function () { 22466 function Thumbnail(instance, $LG) { 22467 this.thumbOuterWidth = 0; 22468 this.thumbTotalWidth = 0; 22469 this.translateX = 0; 22470 this.thumbClickable = false;
22471 // get lightGallery core plugin instance 22472 this.core = instance; 22473 this.$LG = $LG; 22474 return this; 22475 } 22476 Thumbnail.prototype.init = function () { 22477 // extend module default settings with lightGallery core settings 22478 this.settings = __assign(__assign({}, thumbnailsSettings), this.core.settings); 22479 this.thumbOuterWidth = 0; 22480 this.thumbTotalWidth = 22481 this.core.galleryItems.length * 22482 (this.settings.thumbWidth + this.settings.thumbMargin); 22483 // Thumbnail animation value 22484 this.translateX = 0; 22485 this.setAnimateThumbStyles(); 22486 if (!this.core.settings.allowMediaOverlap) { 22487 this.settings.toggleThumb = false; 22488 } 22489 if (this.settings.thumbnail) { 22490 this.build(); 22491 if (this.settings.animateThumb) { 22492 if (this.settings.enableThumbDrag) { 22493 this.enableThumbDrag(); 22494 } 22495 if (this.settings.enableThumbSwipe) { 22496 this.enableThumbSwipe(); 22497 } 22498 this.thumbClickable = false; 22499 } 22500 else { 22501 this.thumbClickable = true; 22502 } 22503 this.toggleThumbBar(); 22504 this.thumbKeyPress(); 22505 } 22506 }; 22507 Thumbnail.prototype.build = function () { 22508 var _this = this; 22509 this.setThumbMarkup(); 22510 this.manageActiveClassOnSlideChange(); 22511 this.$lgThumb.first().on('click.lg touchend.lg', function (e) { 22512 var $target = _this.$LG(e.target); 22513 if (!$target.hasAttribute('data-lg-item-id')) { 22514 return; 22515 } 22516 setTimeout(function () { 22517 // In IE9 and bellow touch does not support 22518 // Go to slide if browser does not support css transitions 22519 if (_this.thumbClickable && !_this.core.lgBusy) { 22520 var index = parseInt($target.attr('data-lg-item-id')); 22521 _this.core.slide(index, false, true, false); 22522 } 22523 }, 50); 22524 }); 22525 //Uncode edit ##START## 22526 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 22527 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 22528 //Uncode edit ##END## 22529 var index = event.detail.index; 22530 _this.animateThumb(index); 22531 }); 22532 //Uncode edit ##START## 22533 // this.core.LGel.on(lGEvents.beforeOpen + ".thumb", function () { 22534 this.core.LGel.on(lGEvents.beforeOpen, function () { 22535 //Uncode edit ##END## 22536 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 22537 }); 22538 //Uncode edit ##START## 22539 // this.core.LGel.on(lGEvents.updateSlides + ".thumb", function () { 22540 this.core.LGel.on(lGEvents.updateSlides, function () { 22541 //Uncode edit ##END## 22542 _this.rebuildThumbnails(); 22543 }); 22544 //Uncode edit ##START## 22545 // this.core.LGel.on(lGEvents.containerResize + ".thumb", function () { 22546 this.core.LGel.on(lGEvents.containerResize, function () { 22547 //Uncode edit ##END## 22548 if (!_this.core.lgOpened) 22549 return; 22550 setTimeout(function () { 22551 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 22552 _this.animateThumb(_this.core.index); 22553 _this.thumbOuterWidth = _this.core.outer.get().offsetWidth; 22554 }, 50); 22555 }); 22556 }; 22557 Thumbnail.prototype.setThumbMarkup = function () { 22558 var thumbOuterClassNames = 'lg-thumb-outer '; 22559 if (this.settings.alignThumbnails) { 22560 thumbOuterClassNames += "lg-thumb-align-" + this.settings.alignThumbnails; 22561 } 22562 var html = "<div class=\"" + thumbOuterClassNames + "\">\n <div class=\"lg-thumb lg-group\">\n </div>\n </div>"; 22563 this.core.outer.addClass('lg-has-thumb'); 22564 if (this.settings.appendThumbnailsTo === '.lg-components') { 22565 this.core.$lgComponents.append(html); 22566 } 22567 else { 22568 this.core.outer.append(html); 22569 } 22570 this.$thumbOuter = this.core.outer.find('.lg-thumb-outer').first(); 22571 this.$lgThumb = this.core.outer.find('.lg-thumb').first(); 22572 if (this.settings.animateThumb) { 22573 this.core.outer 22574 .find('.lg-thumb') 22575 .css('transition-duration', this.core.settings.speed + 'ms') 22576 .css('width', this.thumbTotalWidth + 'px') 22577 .css('position', 'relative'); 22578 } 22579 this.setThumbItemHtml(this.core.galleryItems); 22580 }; 22581 Thumbnail.prototype.enableThumbDrag = function () { 22582 var _this = this; 22583 var thumbDragUtils = { 22584 cords: { 22585 startX: 0, 22586 endX: 0, 22587 }, 22588 isMoved: false, 22589 newTranslateX: 0, 22590 startTime: new Date(), 22591 endTime: new Date(), 22592 touchMoveTime: 0, 22593 }; 22594 var isDragging = false;
22595 this.$thumbOuter.addClass('lg-grab'); 22596 this.core.outer 22597 .find('.lg-thumb') 22598 .first() 22599 .on('mousedown.lg.thumb', function (e) { 22600 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 22601 // execute only on .lg-object 22602 e.preventDefault(); 22603 thumbDragUtils.cords.startX = e.pageX; 22604 thumbDragUtils.startTime = new Date(); 22605 _this.thumbClickable = false; 22606 isDragging = true; 22607 // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 22608 _this.core.outer.get().scrollLeft += 1; 22609 _this.core.outer.get().scrollLeft -= 1; 22610 // * 22611 _this.$thumbOuter 22612 .removeClass('lg-grab') 22613 .addClass('lg-grabbing'); 22614 } 22615 }); 22616 this.$LG(window).on("mousemove.lg.thumb.global" + this.core.lgId, function (e) { 22617 if (!_this.core.lgOpened) 22618 return; 22619 if (isDragging) { 22620 thumbDragUtils.cords.endX = e.pageX; 22621 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 22622 } 22623 }); 22624 this.$LG(window).on("mouseup.lg.thumb.global" + this.core.lgId, function () { 22625 if (!_this.core.lgOpened) 22626 return; 22627 if (thumbDragUtils.isMoved) { 22628 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 22629 } 22630 else { 22631 _this.thumbClickable = true; 22632 } 22633 if (isDragging) { 22634 isDragging = false; 22635 _this.$thumbOuter.removeClass('lg-grabbing').addClass('lg-grab'); 22636 } 22637 }); 22638 }; 22639 Thumbnail.prototype.enableThumbSwipe = function () { 22640 var _this = this; 22641 var thumbDragUtils = { 22642 cords: { 22643 startX: 0, 22644 endX: 0, 22645 }, 22646 isMoved: false, 22647 newTranslateX: 0, 22648 startTime: new Date(), 22649 endTime: new Date(), 22650 touchMoveTime: 0, 22651 }; 22652 this.$lgThumb.on('touchstart.lg', function (e) { 22653 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 22654 e.preventDefault(); 22655 thumbDragUtils.cords.startX = e.targetTouches[0].pageX; 22656 _this.thumbClickable = false; 22657 thumbDragUtils.startTime = new Date(); 22658 } 22659 }); 22660 this.$lgThumb.on('touchmove.lg', function (e) { 22661 if (_this.thumbTotalWidth > _this.thumbOuterWidth) { 22662 e.preventDefault(); 22663 thumbDragUtils.cords.endX = e.targetTouches[0].pageX; 22664 thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils); 22665 } 22666 }); 22667 this.$lgThumb.on('touchend.lg', function () { 22668 if (thumbDragUtils.isMoved) { 22669 thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils); 22670 } 22671 else { 22672 _this.thumbClickable = true; 22673 } 22674 }); 22675 }; 22676 // Rebuild thumbnails 22677 Thumbnail.prototype.rebuildThumbnails = function () { 22678 var _this = this; 22679 // Remove transitions 22680 this.$thumbOuter.addClass('lg-rebuilding-thumbnails'); 22681 setTimeout(function () { 22682 _this.thumbTotalWidth = 22683 _this.core.galleryItems.length * 22684 (_this.settings.thumbWidth + _this.settings.thumbMargin); 22685 _this.$lgThumb.css('width', _this.thumbTotalWidth + 'px'); 22686 _this.$lgThumb.empty(); 22687 _this.setThumbItemHtml(_this.core.galleryItems); 22688 _this.animateThumb(_this.core.index); 22689 }, 50); 22690 setTimeout(function () { 22691 _this.$thumbOuter.removeClass('lg-rebuilding-thumbnails'); 22692 }, 200); 22693 }; 22694 // @ts-check 22695 Thumbnail.prototype.setTranslate = function (value) { 22696 this.$lgThumb.css('transform', 'translate3d(-' + value + 'px, 0px, 0px)'); 22697 }; 22698 Thumbnail.prototype.getPossibleTransformX = function (left) { 22699 if (left > this.thumbTotalWidth - this.thumbOuterWidth) { 22700 left = this.thumbTotalWidth - this.thumbOuterWidth; 22701 } 22702 if (left < 0) { 22703 left = 0; 22704 } 22705 return left; 22706 }; 22707 Thumbnail.prototype.animateThumb = function (index) { 22708 this.$lgThumb.css('transition-duration', this.core.settings.speed + 'ms'); 22709 if (this.settings.animateThumb) { 22710 var position = 0; 22711 switch (this.settings.currentPagerPosition) { 22712 case 'left': 22713 position = 0; 22714 break; 22715 case 'middle': 22716 position = 22717 this.thumbOuterWidth / 2 - this.settings.thumbWidth / 2; 22718 break; 22719 case 'right': 22720 position = this.thumbOuterWidth - this.settings.thumbWidth; 22721 } 22722 this.translateX = 22723 (this.settings.thumbWidth + this.settings.thumbMargin) * index - 22724 1 - 22725 position; 22726 if (this.translateX > this.thumbTotalWidth - this.thumbOuterWidth) { 22727 this.translateX = this.thumbTotalWidth - this.thumbOuterWidth; 22728 } 22729 if (this.translateX < 0) { 22730 this.translateX = 0; 22731 } 22732 this.setTranslate(this.translateX); 22733 } 22734 };
22735 Thumbnail.prototype.onThumbTouchMove = function (thumbDragUtils) { 22736 thumbDragUtils.newTranslateX = this.translateX; 22737 thumbDragUtils.isMoved = true; 22738 thumbDragUtils.touchMoveTime = new Date().valueOf(); 22739 thumbDragUtils.newTranslateX -= 22740 thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 22741 thumbDragUtils.newTranslateX = this.getPossibleTransformX(thumbDragUtils.newTranslateX); 22742 // move current slide 22743 this.setTranslate(thumbDragUtils.newTranslateX); 22744 this.$thumbOuter.addClass('lg-dragging'); 22745 return thumbDragUtils; 22746 }; 22747 Thumbnail.prototype.onThumbTouchEnd = function (thumbDragUtils) { 22748 thumbDragUtils.isMoved = false; 22749 thumbDragUtils.endTime = new Date(); 22750 this.$thumbOuter.removeClass('lg-dragging'); 22751 var touchDuration = thumbDragUtils.endTime.valueOf() - 22752 thumbDragUtils.startTime.valueOf(); 22753 var distanceXnew = thumbDragUtils.cords.endX - thumbDragUtils.cords.startX; 22754 var speedX = Math.abs(distanceXnew) / touchDuration; 22755 // Some magical numbers 22756 // Can be improved 22757 if (speedX > 0.15 && 22758 thumbDragUtils.endTime.valueOf() - thumbDragUtils.touchMoveTime < 30) { 22759 speedX += 1; 22760 if (speedX > 2) { 22761 speedX += 1; 22762 } 22763 speedX = 22764 speedX + 22765 speedX * (Math.abs(distanceXnew) / this.thumbOuterWidth); 22766 this.$lgThumb.css('transition-duration', Math.min(speedX - 1, 2) + 'settings'); 22767 distanceXnew = distanceXnew * speedX; 22768 this.translateX = this.getPossibleTransformX(this.translateX - distanceXnew); 22769 this.setTranslate(this.translateX); 22770 } 22771 else { 22772 this.translateX = thumbDragUtils.newTranslateX; 22773 } 22774 if (Math.abs(thumbDragUtils.cords.endX - thumbDragUtils.cords.startX) < 22775 this.settings.thumbnailSwipeThreshold) { 22776 this.thumbClickable = true; 22777 } 22778 return thumbDragUtils; 22779 }; 22780 Thumbnail.prototype.getThumbHtml = function (thumb, index, alt) { 22781 var slideVideoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 22782 var thumbImg, 22783 altTh = this.core.galleryItems[index].subHtml, 22784 altApp = ''; 22785 if (slideVideoInfo.youtube) { 22786 if (this.settings.loadYouTubeThumbnail) { 22787 thumbImg = 22788 '//img.youtube.com/vi/' + 22789 slideVideoInfo.youtube[1] + 22790 '/' + 22791 this.settings.youTubeThumbSize + 22792 '.jpg'; 22793 } 22794 else { 22795 thumbImg = thumb; 22796 } 22797 } 22798 else { 22799 thumbImg = thumb; 22800 } 22801 22802 if ( altTh ) { 22803 altTh = altTh.replace(/<\/?[^>]+(>|$)/g, ""); 22804 altApp = 'alt=\"' + altTh + ' \" '; 22805 } else if ( typeof alt !== 'undefined' ) { 22806 altApp = 'alt=\"' + alt + ' \" '; 22807 } 22808 22809 if ( thumbImg ) { 22810 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 + "\" " + altApp + "src=\"" + thumbImg + "\" />\n </div>"; 22811 } else { 22812 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 </div>"; 22813 } 22814 }; 22815 Thumbnail.prototype.getThumbItemHtml = function (items) { 22816 var thumbList = ''; 22817 for (var i = 0; i < items.length; i++) { 22818 thumbList += this.getThumbHtml(items[i].thumb, i, items[i].alt); 22819 } 22820 return thumbList; 22821 }; 22822 Thumbnail.prototype.setThumbItemHtml = function (items) { 22823 var thumbList = this.getThumbItemHtml(items); 22824 this.$lgThumb.html(thumbList); 22825 }; 22826 Thumbnail.prototype.setAnimateThumbStyles = function () { 22827 if (this.settings.animateThumb) { 22828 this.core.outer.addClass('lg-animate-thumb'); 22829 } 22830 }; 22831 // Manage thumbnail active calss
22832 Thumbnail.prototype.manageActiveClassOnSlideChange = function () { 22833 var _this = this; 22834 // manage active class for thumbnail 22835 //Uncode edit ##START## 22836 // this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) { 22837 this.core.LGel.on(lGEvents.beforeSlide, function (event) { 22838 //Uncode edit ##END## 22839 var $thumb = _this.core.outer.find('.lg-thumb-item'); 22840 var index = event.detail.index; 22841 $thumb.removeClass('active'); 22842 $thumb.eq(index).addClass('active'); 22843 }); 22844 }; 22845 // Toggle thumbnail bar 22846 Thumbnail.prototype.toggleThumbBar = function () { 22847 var _this = this; 22848 if (this.settings.toggleThumb) { 22849 this.core.outer.addClass('lg-can-toggle'); 22850 this.core.$toolbar.append('<button type="button" aria-label="' + 22851 this.settings.thumbnailPluginStrings['toggleThumbnails'] + 22852 '" class="lg-toggle-thumb lg-icon"></button>'); 22853 this.core.outer 22854 .find('.lg-toggle-thumb') 22855 .first() 22856 .on('click.lg', function () { 22857 _this.core.outer.toggleClass('lg-components-open'); 22858 }); 22859 } 22860 }; 22861 Thumbnail.prototype.thumbKeyPress = function () { 22862 var _this = this; 22863 this.$LG(window).on("keydown.lg.thumb.global" + this.core.lgId, function (e) { 22864 if (!_this.core.lgOpened || !_this.settings.toggleThumb) 22865 return; 22866 if (e.keyCode === 38) { 22867 e.preventDefault(); 22868 _this.core.outer.addClass('lg-components-open'); 22869 } 22870 else if (e.keyCode === 40) { 22871 e.preventDefault(); 22872 _this.core.outer.removeClass('lg-components-open'); 22873 } 22874 }); 22875 }; 22876 Thumbnail.prototype.destroy = function () { 22877 if (this.settings.thumbnail) { 22878 this.$LG(window).off(".lg.thumb.global" + this.core.lgId); 22879 this.core.LGel.off('.lg.thumb'); 22880 this.core.LGel.off('.thumb'); 22881 this.$thumbOuter.remove(); 22882 this.core.outer.removeClass('lg-has-thumb'); 22883 } 22884 }; 22885 return Thumbnail; 22886 }()); 22887 22888 return Thumbnail; 22889 22890}))); 22891/*! 22892 * lightgallery | 2.5.0 | June 13th 2022 22893 * http://www.lightgalleryjs.com/ 22894 * Copyright (c) 2020 Sachin Neravath; 22895 * @license GPLv3 22896 */ 22897 22898(function (global, factory) { 22899 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 22900 typeof define === 'function' && define.amd ? define(factory) : 22901 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgVideo = factory()); 22902}(this, (function () { 'use strict'; 22903 22904 /*! ***************************************************************************** 22905 Copyright (c) Microsoft Corporation. 22906 22907 Permission to use, copy, modify, and/or distribute this software for any 22908 purpose with or without fee is hereby granted. 22909 22910 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 22911 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 22912 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 22913 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 22914 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 22915 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22916 PERFORMANCE OF THIS SOFTWARE. 22917 ***************************************************************************** */ 22918 22919 var __assign = function() { 22920 __assign = Object.assign || function __assign(t) { 22921 for (var s, i = 1, n = arguments.length; i < n; i++) { 22922 s = arguments[i]; 22923 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 22924 } 22925 return t; 22926 }; 22927 return __assign.apply(this, arguments); 22928 }; 22929 22930 var videoSettings = { 22931 autoplayFirstVideo: true, 22932 youTubePlayerParams: false, 22933 vimeoPlayerParams: false, 22934 wistiaPlayerParams: false, 22935 gotoNextSlideOnVideoEnd: true, 22936 autoplayVideoOnSlide: false, 22937 videojs: false, 22938 videojsTheme: '', 22939 videojsOptions: {}, 22940 }; 22941 22942 /** 22943 * List of lightGallery events 22944 * All events should be documented here 22945 * Below interfaces are used to build the website documentations 22946 * */ 22947 var lGEvents = { 22948 afterAppendSlide: 'lgAfterAppendSlide', 22949 init: 'lgInit', 22950 hasVideo: 'lgHasVideo', 22951 containerResize: 'lgContainerResize', 22952 updateSlides: 'lgUpdateSlides', 22953 afterAppendSubHtml: 'lgAfterAppendSubHtml', 22954 beforeOpen: 'lgBeforeOpen', 22955 afterOpen: 'lgAfterOpen', 22956 slideItemLoad: 'lgSlideItemLoad', 22957 beforeSlide: 'lgBeforeSlide', 22958 afterSlide: 'lgAfterSlide', 22959 posterClick: 'lgPosterClick', 22960 dragStart: 'lgDragStart', 22961 dragMove: 'lgDragMove', 22962 dragEnd: 'lgDragEnd', 22963 beforeNextSlide: 'lgBeforeNextSlide', 22964 beforePrevSlide: 'lgBeforePrevSlide', 22965 beforeClose: 'lgBeforeClose', 22966 afterClose: 'lgAfterClose', 22967 rotateLeft: 'lgRotateLeft', 22968 rotateRight: 'lgRotateRight', 22969 flipHorizontal: 'lgFlipHorizontal', 22970 flipVertical: 'lgFlipVertical', 22971 autoplay: 'lgAutoplay', 22972 autoplayStart: 'lgAutoplayStart', 22973 autoplayStop: 'lgAutoplayStop', 22974 }; 22975 22976 var param = function (obj) { 22977 return Object.keys(obj) 22978 .map(function (k) { 22979 return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]); 22980 }) 22981 .join('&'); 22982 }; 22983 var getVimeoURLParams = function (defaultParams, videoInfo) { 22984 if (!videoInfo || !videoInfo.vimeo) 22985 return '';
22986 var urlParams = videoInfo.vimeo[2] || ''; 22987 var defaultPlayerParams = defaultParams && Object.keys(defaultParams).length !== 0 22988 ? '&' + param(defaultParams) 22989 : ''; 22990 // Support private video 22991 var urlWithHash = videoInfo.vimeo[0].split('/').pop() || ''; 22992 var urlWithHashWithParams = urlWithHash.split('?')[0] || ''; 22993 var hash = urlWithHashWithParams.split('#')[0]; 22994 var isPrivate = videoInfo.vimeo[1] !== hash; 22995 if (isPrivate) { 22996 urlParams = urlParams.replace("/" + hash, ''); 22997 } 22998 urlParams = 22999 urlParams[0] == '?' ? '&' + urlParams.slice(1) : urlParams || ''; 23000 // For vimeo last params gets priority if duplicates found 23001 // Uncode edit ##START## 23002 var vimeoPlayerParams = '?autoplay=0'; 23003 if ( videoInfo.autoplay !== '' ) { 23004 vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' ); 23005 vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay(&|$)'), '$1$2' ); 23006 } else { 23007 if ( typeof SiteParameters !== 'undefined' && typeof SiteParameters.vimeoPlayerParams !== 'undefined' && SiteParameters.vimeoPlayerParams !== '' ) { 23008 vimeoPlayerParams = SiteParameters.vimeoPlayerParams; 23009 } 23010 } 23011 if ( videoInfo.muted !== '' ) { 23012 vimeoPlayerParams += '&muted=' + (videoInfo.muted === 'yes'); 23013 } else { 23014 if ( urlParams.indexOf('muted=') < 0 && vimeoPlayerParams.indexOf('muted=') < 0 ) { 23015 vimeoPlayerParams += '&muted=1'; 23016 } 23017 } 23018 // var vimeoPlayerParams = "?autoplay=0&muted=1" + (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 23019 vimeoPlayerParams += (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams; 23020 // Uncode edit ##END## 23021 return vimeoPlayerParams; 23022 }; 23023 23024 /** 23025 * Video module for lightGallery 23026 * Supports HTML5, YouTube, Vimeo, wistia videos 23027 * 23028 * 23029 * @ref Wistia 23030 * https://wistia.com/support/integrations/wordpress(How to get url) 23031 * https://wistia.com/support/developers/embed-options#using-embed-options 23032 * https://wistia.com/support/developers/player-api 23033 * https://wistia.com/support/developers/construct-an-embed-code 23034 * http://jsfiddle.net/xvnm7xLm/ 23035 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video 23036 * https://wistia.com/support/embed-and-share/sharing-videos 23037 * https://private-sharing.wistia.com/medias/mwhrulrucj 23038 * 23039 * @ref Youtube 23040 * https://developers.google.com/youtube/player_parameters#enablejsapi 23041 * https://developers.google.com/youtube/iframe_api_reference 23042 * https://developer.chrome.com/blog/autoplay/#iframe-delegation 23043 * 23044 * @ref Vimeo 23045 * https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url 23046 * https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode 23047 * https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters 23048 */ 23049 var Video = /** @class */ (function () { 23050 function Video(instance) { 23051 // get lightGallery core plugin instance 23052 this.core = instance; 23053 this.settings = __assign(__assign({}, videoSettings), this.core.settings); 23054 return this; 23055 } 23056 Video.prototype.init = function () { 23057 var _this = this; 23058 /** 23059 * Event triggered when video url found without poster 23060 * Append video HTML 23061 * Play if autoplayFirstVideo is true 23062 */ 23063 this.core.LGel.on(lGEvents.hasVideo + ".video", this.onHasVideo.bind(this)); 23064 this.core.LGel.on(lGEvents.posterClick + ".video", function () { 23065 var $el = _this.core.getSlideItem(_this.core.index); 23066 _this.loadVideoOnPosterClick($el); 23067 }); 23068 this.core.LGel.on(lGEvents.slideItemLoad + ".video", this.onSlideItemLoad.bind(this)); 23069 // @desc fired immediately before each slide transition. 23070 this.core.LGel.on(lGEvents.beforeSlide + ".video", this.onBeforeSlide.bind(this)); 23071 // @desc fired immediately after each slide transition. 23072 this.core.LGel.on(lGEvents.afterSlide + ".video", this.onAfterSlide.bind(this)); 23073 }; 23074 /** 23075 * @desc Event triggered when a slide is completely loaded 23076 * 23077 * @param {Event} event - lightGalley custom event 23078 */ 23079 Video.prototype.onSlideItemLoad = function (event) { 23080 var _this = this; 23081 var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index; 23082 // Should check the active slide as well as user may have moved to different slide before the first slide is loaded 23083 if (this.settings.autoplayFirstVideo && 23084 isFirstSlide && 23085 index === this.core.index) { 23086 // Delay is just for the transition effect on video load 23087 setTimeout(function () { 23088 _this.loadAndPlayVideo(index); 23089 }, 200); 23090 } 23091 // Should not call on first slide. should check only if the slide is active 23092 if (!isFirstSlide && 23093 this.settings.autoplayVideoOnSlide && 23094 index === this.core.index) { 23095 setTimeout(function () { 23096 _this.loadAndPlayVideo(index); 23097 }, 500); 23098 } 23099 }; 23100 /** 23101 * @desc Event triggered when video url or poster found 23102 * Append video HTML is poster is not given 23103 * Play if autoplayFirstVideo is true 23104 * 23105 * @param {Event} event - Javascript Event object. 23106 */ 23107 Video.prototype.onHasVideo = function (event) { 23108 var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster; 23109 if (!hasPoster) { 23110 // All functions are called separately if poster exist in loadVideoOnPosterClick function 23111 this.appendVideos(this.core.getSlideItem(index), { 23112 src: src, 23113 addClass: 'lg-object', 23114 index: index, 23115 html5Video: html5Video, 23116 // Uncode edit ##START## 23117 autoplay: event.target.getAttribute('data-lb-autoplay'), 23118 muted: event.target.getAttribute('data-lb-muted'), 23119 // Uncode edit ##END## 23120 }); 23121 // Automatically navigate to next slide once video reaches the end. 23122 this.gotoNextSlideOnVideoEnd(src, index); 23123 } 23124 }; 23125 /** 23126 * @desc fired immediately before each slide transition. 23127 * Pause the previous video 23128 * Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos. 23129 * 23130 * @param {Event} event - Javascript Event object. 23131 * @param {number} prevIndex - Previous index of the slide. 23132 * @param {number} index - Current index of the slide 23133 */ 23134 Video.prototype.onBeforeSlide = function (event) { 23135 if (this.core.lGalleryOn) { 23136 var prevIndex = event.detail.prevIndex; 23137 this.pauseVideo(prevIndex); 23138 } 23139 // Uncode edit ##START## 23140 var _a = event.detail, index = _a.index; 23141 var $slide = this.core.getSlideItem(index); 23142
23143 var iframe = $slide.selector.querySelector('iframe'); 23144 if ( iframe != null ) { 23145 23146 var data_play = iframe.getAttribute('data-autoplay'); 23147 if ( typeof data_play !== 'undefined' && data_play === '1' ) { 23148 this.loadAndPlayVideo(index); 23149 23150 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}, 23151 $videoElement = this.core.getSlideItem(index).find('.lg-video-object').first(); 23152 if (videoInfo.vimeo) { 23153 var vimeoPlayer = new Vimeo.Player($videoElement.get()); 23154 vimeoPlayer.on('play', function () { 23155 vimeoPlayer.setCurrentTime(0); 23156 }); 23157 } else if ( videoInfo.youtube ) { 23158 try { 23159 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"seekTo\",\"args\":[0, true]}", '*'); 23160 } 23161 catch (e) { 23162 console.warn(e); 23163 } 23164 } 23165 } 23166 } 23167 // Uncode edit ##END## 23168 }; 23169 /** 23170 * @desc fired immediately after each slide transition. 23171 * Play video if autoplayVideoOnSlide option is enabled. 23172 * 23173 * @param {Event} event - Javascript Event object. 23174 * @param {number} prevIndex - Previous index of the slide. 23175 * @param {number} index - Current index of the slide 23176 * @todo should check on onSlideLoad as well if video is not loaded on after slide 23177 */ 23178 Video.prototype.onAfterSlide = function (event) { 23179 var _this = this; 23180 var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex; 23181 // Do not call on first slide 23182 var $slide = this.core.getSlideItem(index); 23183 if (this.settings.autoplayVideoOnSlide && index !== prevIndex) { 23184 if ($slide.hasClass('lg-complete')) { 23185 setTimeout(function () { 23186 _this.loadAndPlayVideo(index); 23187 }, 100); 23188 } 23189 } 23190 }; 23191 Video.prototype.loadAndPlayVideo = function (index) { 23192 var $slide = this.core.getSlideItem(index); 23193 var currentGalleryItem = this.core.galleryItems[index]; 23194 if (currentGalleryItem.poster) { 23195 this.loadVideoOnPosterClick($slide, true); 23196 } 23197 else { 23198 //Uncode edit ##START## 23199 // this.playVideo(index); 23200 var iframe = $slide.selector.querySelector('iframe'); 23201 if ( iframe != null ) { 23202 var data_play = iframe.getAttribute('data-autoplay'); 23203 if ( typeof data_play !== 'undefined' ) { 23204 if ( data_play === '1' && this.core.index == index ) { 23205 this.playVideo(index); 23206 } else { 23207 this.pauseVideo(index); 23208 } 23209 } 23210 } 23211 //Uncode edit ##END## 23212 } 23213 }; 23214 /** 23215 * Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 23216 * @param {number} index - Index of the slide 23217 */ 23218 Video.prototype.playVideo = function (index) { 23219 this.controlVideo(index, 'play'); 23220 }; 23221 /** 23222 * Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide. 23223 * @param {number} index - Index of the slide 23224 */ 23225 Video.prototype.pauseVideo = function (index) { 23226 this.controlVideo(index, 'pause'); 23227 }; 23228 // Uncode edit ##START## 23229 //Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) { 23230 Video.prototype.getVideoHtml = function (src, addClass, index, html5Video, autoplay, muted) { 23231 // Uncode edit ##END## 23232 var video = ''; 23233 var videoInfo = this.core.galleryItems[index] 23234 .__slideVideoInfo || {}; 23235 var currentGalleryItem = this.core.galleryItems[index]; 23236 var videoTitle = currentGalleryItem.title || currentGalleryItem.alt; 23237 videoTitle = videoTitle ? 'title="' + videoTitle + '"' : ''; 23238 var commonIframeProps = "allowtransparency=\"true\"\n frameborder=\"0\"\n scrolling=\"no\"\n allowfullscreen\n mozallowfullscreen\n webkitallowfullscreen\n oallowfullscreen\n msallowfullscreen"; 23239 if (videoInfo.youtube) { 23240 var videoId = 'lg-youtube' + index; 23241 var slideUrlParams = videoInfo.youtube[2] 23242 ? videoInfo.youtube[2] + '&' 23243 : ''; 23244 // For youtube first parms gets priority if duplicates found 23245 // Uncode edit ##START## 23246 // var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&autoplay=0&mute=1&enablejsapi=1"; 23247 var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&enablejsapi=1"; 23248 if ( ( slideUrlParams.indexOf('autoplay=') < 0 && youTubePlayerParams.indexOf('autoplay=') < 0 ) ) { 23249 youTubePlayerParams += '&autoplay=0'; 23250 } 23251 if ( slideUrlParams.indexOf('mute=') < 0 && youTubePlayerParams.indexOf('mute=') < 0 ) { 23252 youTubePlayerParams += '&mute=1'; 23253 } 23254 var data_video = ''; 23255 if ( autoplay !== '' ) { 23256 //youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1autoplay=' + (autoplay === 'yes' ? 1 : 0) + '$3' ); 23257 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' ); 23258 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay'), '$1' ); 23259 data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"'; 23260 } 23261 // if ( muted !== '' ) { 23262 // youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1mute=' + (muted === 'yes' ? 1 : 0) + '$3' ); 23263 // } 23264 youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1$3' ); 23265 23266 youTubePlayerParams = youTubePlayerParams.replace('??', '?'); 23267 // Uncode edit ##END## 23268 var playerParams = youTubePlayerParams + 23269 (this.settings.youTubePlayerParams 23270 ? '&' + param(this.settings.youTubePlayerParams) 23271 : ''); 23272 // Uncode edit ##START## 23273 // 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>"; 23274 var nocookie = typeof SiteParameters.uncode_nocookie !== 'undefined' ? SiteParameters.uncode_nocookie : ''; 23275 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>"; 23276 var tag = document.createElement('script'); 23277 tag.src = "//www.youtube.com/player_api"; 23278 var firstScriptTag = document.getElementsByTagName('script')[0]; 23279 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 23280 23281 // Replace the 'ytplayer' element with an <iframe> and 23282 // YouTube player after the API code downloads. 23283 var ytIframeplayer, 23284 setMute = muted === 'yes' ? 0 : 100; 23285 window.onYouTubePlayerAPIReady = function() { 23286 ytIframeplayer = new YT.Player(videoId, { 23287 videoId: videoInfo.youtube[1], 23288 events: { 23289 'onReady': function (event) { 23290 event.target.setVolume(setMute); 23291 } 23292 } 23293 }); 23294 } 23295 // Uncode edit ##END## 23296 } 23297 else if (videoInfo.vimeo) { 23298 var videoId = 'lg-vimeo' + index; 23299 // Uncode edit ##START## 23300 videoInfo.autoplay = autoplay; 23301 videoInfo.muted = muted; 23302 // Uncode edit ##END## 23303 var playerParams = getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo); 23304 // Uncode edit ##START## 23305 // 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>"; 23306 var data_video = ''; 23307 if ( autoplay !== '' ) { 23308 data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"'; 23309 } 23310 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>"; 23311 // Uncode edit ##END## 23312 } 23313 else if (videoInfo.wistia) { 23314 var wistiaId = 'lg-wistia' + index; 23315 var playerParams = param(this.settings.wistiaPlayerParams); 23316 playerParams = playerParams ? '?' + playerParams : ''; 23317 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>"; 23318 } 23319 else if (videoInfo.html5) { 23320 var html5VideoMarkup = ''; 23321 for (var i = 0; i < html5Video.source.length; i++) { 23322 html5VideoMarkup += "<source src=\"" + html5Video.source[i].src + "\" type=\"" + html5Video.source[i].type + "\">"; 23323 } 23324 if (html5Video.tracks) { 23325 var _loop_1 = function (i) { 23326 var trackAttributes = ''; 23327 var track = html5Video.tracks[i]; 23328 Object.keys(track || {}
23328).forEach(function (key) { 23329 trackAttributes += key + "=\"" + track[key] + "\" "; 23330 }); 23331 html5VideoMarkup += "<track " + trackAttributes + ">"; 23332 }; 23333 for (var i = 0; i < html5Video.tracks.length; i++) { 23334 _loop_1(i); 23335 } 23336 } 23337 var html5VideoAttrs_1 = ''; 23338 var videoAttributes_1 = html5Video.attributes || {}; 23339 Object.keys(videoAttributes_1 || {}).forEach(function (key) { 23340 html5VideoAttrs_1 += key + "=\"" + videoAttributes_1[key] + "\" "; 23341 }); 23342 video = "<video class=\"lg-video-object lg-html5 " + (this.settings.videojs && this.settings.videojsTheme 23343 ? this.settings.videojsTheme + ' ' 23344 : '') + " " + (this.settings.videojs ? ' video-js' : '') + "\" " + html5VideoAttrs_1 + ">\n " + html5VideoMarkup + "\n Your browser does not support HTML5 video.\n </video>"; 23345 } 23346 return video; 23347 }; 23348 /** 23349 * @desc - Append videos to the slide 23350 * 23351 * @param {HTMLElement} el - slide element 23352 * @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo 23353 */ 23354 Video.prototype.appendVideos = function (el, videoParams) { 23355 var _a; 23356 // Uncode edit ##START## 23357 // var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video); 23358 var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video, videoParams.autoplay, videoParams.muted); 23359 // Uncode edit ##END## 23360 el.find('.lg-video-cont').append(videoHtml); 23361 var $videoElement = el.find('.lg-video-object').first(); 23362 if (videoParams.html5Video) { 23363 $videoElement.on('mousedown.lg.video', function (e) { 23364 e.stopPropagation(); 23365 }); 23366 } 23367 if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) { 23368 try { 23369 return videojs($videoElement.get(), this.settings.videojsOptions); 23370 } 23371 catch (e) { 23372 console.warn('lightGallery:- Make sure you have included videojs'); 23373 } 23374 } 23375 }; 23376 Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) { 23377 var _this = this; 23378 var $videoElement = this.core 23379 .getSlideItem(index) 23380 .find('.lg-video-object') 23381 .first(); 23382 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 23383 if (this.settings.gotoNextSlideOnVideoEnd) { 23384 if (videoInfo.html5) { 23385 $videoElement.on('ended', function () { 23386 _this.core.goToNextSlide(); 23387 }); 23388 } 23389 else if (videoInfo.vimeo) { 23390 try { 23391 // https://github.com/vimeo/player.js/#ended 23392 new Vimeo.Player($videoElement.get()).on('ended', function () { 23393 _this.core.goToNextSlide(); 23394 }); 23395 } 23396 catch (e) { 23397 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 23398 } 23399 } 23400 else if (videoInfo.wistia) { 23401 try { 23402 window._wq = window._wq || []; 23403 // @todo Event is gettign triggered multiple times 23404 window._wq.push({ 23405 id: $videoElement.attr('id'), 23406 onReady: function (video) { 23407 video.bind('end', function () { 23408 _this.core.goToNextSlide(); 23409 }); 23410 }, 23411 }); 23412 } 23413 catch (e) { 23414 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 23415 } 23416 } 23417 } 23418 }; 23419 Video.prototype.controlVideo = function (index, action) { 23420 var $videoElement = this.core 23421 .getSlideItem(index) 23422 .find('.lg-video-object') 23423 .first(); 23424 var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {}; 23425 if (!$videoElement.get()) 23426 return; 23427 if (videoInfo.youtube) { 23428 try { 23429 $videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"" + action + "Video\",\"args\":\"\"}", '*'); 23430 } 23431 catch (e) { 23432 console.warn("lightGallery:- " + e); 23433 } 23434 } 23435 else if (videoInfo.vimeo) { 23436 try { 23437 new Vimeo.Player($videoElement.get())[action](); 23438 } 23439 catch (e) { 23440 console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js'); 23441 } 23442 } 23443 else if (videoInfo.html5) { 23444 if (this.settings.videojs) { 23445 try { 23446 videojs($videoElement.get())[action](); 23447 } 23448 catch (e) { 23449 console.warn('lightGallery:- Make sure you have included videojs'); 23450 } 23451 } 23452 else { 23453 $videoElement.get()[action](); 23454 } 23455 } 23456 else if (videoInfo.wistia) { 23457 try { 23458 window._wq = window._wq || []; 23459 // @todo Find a way to destroy wistia player instance 23460 window._wq.push({ 23461 id: $videoElement.attr('id'), 23462 onReady: function (video) { 23463 video[action](); 23464 }, 23465 }); 23466 } 23467 catch (e) { 23468 console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js'); 23469 } 23470 } 23471 }; 23472 Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) { 23473 var _this = this; 23474 // check slide has poster 23475 if (!$el.hasClass('lg-video-loaded')) { 23476 // check already video element present
23477 if (!$el.hasClass('lg-has-video')) { 23478 $el.addClass('lg-has-video'); 23479 var _html = void 0; 23480 var _src = this.core.galleryItems[this.core.index].src; 23481 var video = this.core.galleryItems[this.core.index].video; 23482 if (video) { 23483 _html = 23484 typeof video === 'string' ? JSON.parse(video) : video; 23485 } 23486 var videoJsPlayer_1 = this.appendVideos($el, { 23487 src: _src, 23488 addClass: '', 23489 index: this.core.index, 23490 html5Video: _html, 23491 }); 23492 this.gotoNextSlideOnVideoEnd(_src, this.core.index); 23493 var $tempImg = $el.find('.lg-object').first().get(); 23494 // @todo make sure it is working 23495 $el.find('.lg-video-cont').first().append($tempImg); 23496 $el.addClass('lg-video-loading'); 23497 videoJsPlayer_1 && 23498 videoJsPlayer_1.ready(function () { 23499 videoJsPlayer_1.on('loadedmetadata', function () { 23500 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 23501 }); 23502 }); 23503 $el.find('.lg-video-object') 23504 .first() 23505 .on('load.lg error.lg loadedmetadata.lg', function () { 23506 setTimeout(function () { 23507 _this.onVideoLoadAfterPosterClick($el, _this.core.index); 23508 }, 50); 23509 }); 23510 } 23511 else { 23512 this.playVideo(this.core.index); 23513 } 23514 } 23515 else if (forcePlay) { 23516 this.playVideo(this.core.index); 23517 } 23518 }; 23519 Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) { 23520 $el.addClass('lg-video-loaded'); 23521 this.playVideo(index); 23522 }; 23523 Video.prototype.destroy = function () { 23524 this.core.LGel.off('.lg.video'); 23525 this.core.LGel.off('.video'); 23526 }; 23527 return Video; 23528 }()); 23529 23530 return Video; 23531 23532}))); 23533 23534 23535/*! @vimeo/player v2.17.1 | (c) 2022 Vimeo | MIT License | https://github.com/vimeo/player.js */ 23536!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:{}}
23536),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: 9,482 bytes, line 23536
23536var 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)}},{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: 11,908 bytes, lines 23536-24016
23536))}(),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}); 23537 23538/** 23539 * Owl carousel 23540 * @version 2.0.0-beta.3 23541 * @author Bartosz Wojciechowski 23542 * @license The MIT License (MIT) 23543 * @todo Lazy Load Icon 23544 * @todo prevent animationend bubling 23545 * @todo itemsScaleUp 23546 * @todo Test Zepto 23547 * @todo stagePadding calculate wrong active classes 23548 */ 23549;(function($, window, document, undefined) { 23550 23551 /** 23552 * Creates a carousel. 23553 * @class The Owl Carousel. 23554 * @public 23555 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 23556 * @param {Object} [options] - The options 23557 */ 23558 function Owl(element, options) { 23559 23560 /** 23561 * Current settings for the carousel. 23562 * @public 23563 */ 23564 this.settings = null; 23565 23566 /** 23567 * Current options set by the caller including defaults. 23568 * @public 23569 */ 23570 this.options = $.extend({}, Owl.Defaults, options); 23571 23572 /** 23573 * Plugin element. 23574 * @public 23575 */ 23576 this.$element = $(element); 23577 23578 /** 23579 * Proxied event handlers. 23580 * @protected 23581 */ 23582 this._handlers = {}; 23583 23584 /** 23585 * References to the running plugins of this carousel. 23586 * @protected 23587 */ 23588 this._plugins = {}; 23589 23590 /** 23591 * Currently suppressed events to prevent them from beeing retriggered. 23592 * @protected 23593 */ 23594 this._supress = {}; 23595 23596 /** 23597 * Absolute current position. 23598 * @protected 23599 */ 23600 this._current = null; 23601 23602 /** 23603 * Animation speed in milliseconds. 23604 * @protected 23605 */ 23606 this._speed = null; 23607 23608 /** 23609 * Coordinates of all items in pixel. 23610 * @todo The name of this member is missleading. 23611 * @protected 23612 */ 23613 this._coordinates = []; 23614 23615 /** 23616 * Current breakpoint. 23617 * @todo Real media queries would be nice. 23618 * @protected 23619 */ 23620 this._breakpoint = null; 23621 23622 /** 23623 * Current width of the plugin element. 23624 */ 23625 this._width = null; 23626 23627 /** 23628 * All real items. 23629 * @protected 23630 */ 23631 this._items = []; 23632 23633 /** 23634 * All cloned items. 23635 * @protected 23636 */ 23637 this._clones = []; 23638 23639 /** 23640 * Merge values of all items. 23641 * @todo Maybe this could be part of a plugin. 23642 * @protected 23643 */ 23644 this._mergers = []; 23645 23646 /** 23647 * Widths of all items. 23648 */ 23649 this._widths = []; 23650 23651 /** 23652 * Invalidated parts within the update process. 23653 * @protected 23654 */ 23655 this._invalidated = {}; 23656 23657 /** 23658 * Ordered list of workers for the update process. 23659 * @protected 23660 */ 23661 this._pipe = []; 23662 23663 /** 23664 * Current state information for the drag operation. 23665 * @todo #261 23666 * @protected 23667 */ 23668 this._drag = { 23669 time: null, 23670 target: null, 23671 pointer: null, 23672 stage: { 23673 start: null, 23674 current: null 23675 }, 23676 direction: null 23677 }; 23678 23679 /** 23680 * Current state information and their tags. 23681 * @type {Object} 23682 * @protected 23683 */ 23684 this._states = { 23685 current: {}, 23686 tags: { 23687 'initializing': [ 'busy' ], 23688 'animating': [ 'busy' ], 23689 'dragging': [ 'interacting' ] 23690 } 23691 }; 23692 23693 $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { 23694 this._handlers[handler] = $.proxy(this[handler], this); 23695 }, this)); 23696 23697 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 23698 this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] 23699 = new plugin(this); 23700 }, this)); 23701 23702 $.each(Owl.Workers, $.proxy(function(priority, worker) { 23703 this._pipe.push({ 23704 'filter': worker.filter, 23705 'run': $.proxy(worker.run, this) 23706 }); 23707 }, this)); 23708 23709 this.setup(); 23710 this.initialize(); 23711 } 23712 23713 /** 23714 * Default options for the carousel. 23715 * @public 23716 */ 23717 Owl.Defaults = { 23718 items: 3, 23719 loop: false, 23720 center: false, 23721 rewind: false, 23722 23723 mouseDrag: true, 23724 touchDrag: true, 23725 pullDrag: true, 23726 freeDrag: false, 23727 23728 margin: 0, 23729 stagePadding: 0, 23730 23731 merge: false, 23732 mergeFit: true, 23733 autoWidth: false, 23734 23735 startPosition: 0, 23736 rtl: false, 23737 23738 smartSpeed: 250, 23739 fluidSpeed: false, 23740 dragEndSpeed: false, 23741 23742 responsive: {}, 23743 responsiveRefreshRate: 200, 23744 responsiveBaseElement: window, 23745 23746 fallbackEasing: 'swing', 23747 23748 info: false, 23749 23750 nestedItemSelector: false, 23751 itemSelector: false, 23752 itemElement: 'div', 23753 stageElement: 'div', 23754 23755 refreshClass: 'owl-refresh', 23756 loadedClass: 'owl-loaded', 23757 loadingClass: 'owl-loading', 23758 rtlClass: 'owl-rtl', 23759 responsiveClass: 'owl-responsive', 23760 dragClass: 'owl-drag', 23761 itemClass: 'owl-item', 23762 stageClass: 'owl-stage', 23763 stageOuterClass: 'owl-stage-outer', 23764 grabClass: 'owl-grab' 23765 }; 23766 23767 /** 23768 * Enumeration for width. 23769 * @public 23770 * @readonly 23771 * @enum {String} 23772 */ 23773 Owl.Width = { 23774 Default: 'default', 23775 Inner: 'inner', 23776 Outer: 'outer' 23777 }; 23778 23779 /** 23780 * Enumeration for types. 23781 * @public 23782 * @readonly 23783 * @enum {String} 23784 */ 23785 Owl.Type = { 23786 Event: 'event', 23787 State: 'state' 23788 }; 23789 23790 /** 23791 * Contains all registered plugins. 23792 * @public 23793 */ 23794 Owl.Plugins = {}; 23795 23796 /** 23797 * List of workers involved in the update process. 23798 */ 23799 Owl.Workers = [ { 23800 filter: [ 'width', 'settings' ], 23801 run: function() { 23802 this._width = (this.$element.closest('.px-gutter').length) ? 12 * Math.ceil(this.$element.width() / 12) : this.$element.width(); 23803 //this._width = (UNCODE.isMobile) ? this.$element.width() : 12 * Math.ceil(this.$element.width() / 12); 23804 } 23805 }, { 23806 filter: [ 'width', 'items', 'settings' ], 23807 run: function(cache) { 23808 cache.current = this._items && this._items[this.relative(this._current)]; 23809 } 23810 }, { 23811 filter: [ 'items', 'settings' ], 23812 run: function() { 23813 this.$stage.children('.cloned').remove(); 23814 } 23815 }, { 23816 filter: [ 'width', 'items', 'settings' ], 23817 run: function(cache) { 23818 var margin = this.settings.margin || '', 23819 grid = !this.settings.autoWidth, 23820 rtl = this.settings.rtl, 23821 css = { 23822 'width': 'auto', 23823 'margin-left': rtl ? margin : '', 23824 'margin-right': rtl ? '' : margin 23825 }; 23826 23827 !grid && this.$stage.children().css(css); 23828 23829 cache.css = css; 23830 } 23831 }, { 23832 filter: [ 'width', 'items', 'settings' ], 23833 run: function(cache) { 23834 //UNCODE edit to fix Chrome stage padding issue 23835 var width = Math.round((this.width() / this.settings.items).toFixed(3) - this.settings.margin), 23836 merge = null, 23837 iterator = this._items.length, 23838 grid = !this.settings.autoWidth, 23839 widths = []; 23840 23841 cache.items = { 23842 merge: false, 23843 width: width 23844 }; 23845 23846 while (iterator--) { 23847 merge = this._mergers[iterator]; 23848 merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; 23849 23850 cache.items.merge = merge > 1 || cache.items.merge; 23851 23852 widths[iterator] = !grid ? this._items[iterator].width() : width * merge; 23853 } 23854 23855 this._widths = widths; 23856 } 23857 }, { 23858 filter: [ 'items', 'settings' ], 23859 run: function() { 23860 var clones = [], 23861 items = this._items, 23862 settings = this.settings, 23863 view = Math.max(settings.items * 2, 4), 23864 size = Math.ceil(items.length / 2) * 2, 23865 repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, 23866 append = '', 23867 prepend = ''; 23868 23869 repeat /= 2; 23870 23871 while (repeat--) { 23872 clones.push(this.normalize(clones.length / 2, true)); 23873 append = append + items[clones[clones.length - 1]][0].outerHTML; 23874 clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); 23875 prepend = items[clones[clones.length - 1]][0].outerHTML + prepend; 23876 } 23877 23878 this._clones = clones; 23879 23880 // var appendVideo = $(append).find('.uncode-video-container'); 23881 // if (appendVideo.length) { 23882 // appendVideo.attr('data-id', Math.round(Math.random() * 100000)); 23883 // } 23884 // var prependVideo = $(prepend).find('.uncode-video-container'); 23885 // if (prependVideo.length) { 23886 // prependVideo.attr('data-id', Math.round(Math.random() * 100000)); 23887 // } 23888 $(append).addClass('cloned').appendTo(this.$stage); 23889 $(prepend).addClass('cloned').prependTo(this.$stage); 23890 } 23891 }, { 23892 filter: [ 'width', 'items', 'settings' ], 23893 run: function() { 23894 var rtl = this.settings.rtl ? 1 : -1, 23895 size = this._clones.length + this._items.length, 23896 iterator = -1, 23897 previous = 0, 23898 current = 0, 23899 coordinates = []; 23900 23901 while (++iterator < size) { 23902 previous = coordinates[iterator - 1] || 0; 23903 current = this._widths[this.relative(iterator)] + this.settings.margin; 23904 coordinates.push(previous + current * rtl); 23905 } 23906 23907 this._coordinates = coordinates; 23908 } 23909 }, { 23910 filter: [ 'width', 'items', 'settings' ], 23911 run: function() { 23912 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 23913 padding = stagePadding, 23914 coordinates = this._coordinates, 23915 css = { 23916 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, 23917 'padding-left': padding || '', 23918 'padding-right': padding || '' 23919 }; 23920 23921 this.$stage.css(css); 23922 } 23923 }, { 23924 filter: [ 'width', 'items', 'settings' ], 23925 run: function(cache) { 23926 var iterator = this._coordinates.length, 23927 grid = !this.settings.autoWidth, 23928 items = this.$stage.children(); 23929 23930 if (grid && cache.items.merge) { 23931 while (iterator--) { 23932 cache.css.width = this._widths[this.relative(iterator)]; 23933 items.eq(iterator).css(cache.css); 23934 } 23935 } else if (grid) { 23936 cache.css.width = cache.items.width; 23937 items.css(cache.css); 23938 } 23939 } 23940 }, { 23941 filter: [ 'items' ], 23942 run: function() { 23943 this._coordinates.length < 1 && this.$stage.removeAttr('style'); 23944 } 23945 }, { 23946 filter: [ 'width', 'items', 'settings' ], 23947 run: function(cache) { 23948 cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; 23949 cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); 23950 this.reset(cache.current); 23951 } 23952 }, { 23953 filter: [ 'position' ], 23954 run: function() { 23955 this.animate(this.coordinates(this._current)); 23956 } 23957 }, { 23958 filter: [ 'width', 'position', 'items', 'settings' ], 23959 run: function() { 23960 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200, 23961 rtl = this.settings.rtl ? 1 : -1, 23962 padding = this.settings.stagePadding * 2, 23963 begin = this.coordinates(this.current()) + padding, 23964 end = begin + this.width() * rtl, 23965 inner, outer, matches = [], i, n; 23966 23967 for (i = 0, n = this._coordinates.length; i < n; i++) { 23968 inner = this._coordinates[i - 1] || 0; 23969 outer = Math.abs(this._coordinates[i]) + padding * rtl; 23970 23971 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 23972 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 23973 matches.push(i); 23974 } 23975 } 23976 23977 this.$stage.children('.active').removeClass('active'); 23978 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); 23979 23980 if (this.settings.center) { 23981 this.$stage.children('.center').removeClass('center'); 23982 this.$stage.children().eq(this.current()).addClass('center'); 23983 } 23984 } 23985 } ]; 23986 23987 /** 23988 * Initializes the carousel. 23989 * @protected 23990 */ 23991 Owl.prototype.initialize = function() { 23992 this.enter('initializing'); 23993 this.trigger('initialize'); 23994 23995 this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); 23996 23997 if (this.settings.autoWidth && !this.is('pre-loading')) { 23998 var imgs, nestedSelector, width; 23999 imgs = this.$element.find('img'); 24000 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 24001 width = this.$element.children(nestedSelector).width(); 24002 24003 if (imgs.length && width <= 0) { 24004 this.preloadAutoWidthImages(imgs); 24005 } 24006 } 24007 24008 this.$element.addClass(this.options.loadingClass); 24009 24010 // create stage 24011 this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>') 24012 .wrap('<div class="' + this.settings.stageOuterClass + '"/>'); 24013 24014 //UNCODE edit to exclude hidden items 24015 if ( this.settings.itemSelector ) { 24016 // append stage
24017 this.$element.prepend(this.$stage.parent()); 24018 // append content 24019 this.replace(this.$element.find(' > ' + this.settings.itemSelector).not(this.$stage.parent())); 24020 } else { 24021 // append stage 24022 this.$element.append(this.$stage.parent()); 24023 // append content 24024 this.replace(this.$element.children().not(this.$stage.parent())); 24025 } 24026 24027 // check visibility 24028 if (this.$element.is(':visible')) { 24029 // update view 24030 this.refresh(); 24031 } else { 24032 // invalidate width 24033 this.invalidate('width'); 24034 } 24035 24036 this.$element 24037 .removeClass(this.options.loadingClass) 24038 .addClass(this.options.loadedClass); 24039 24040 // register event handlers 24041 this.registerEventHandlers(); 24042 24043 this.leave('initializing'); 24044 this.trigger('initialized'); 24045 }; 24046 24047 /** 24048 * Setups the current settings. 24049 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 24050 * @todo Support for media queries by using `matchMedia` would be nice. 24051 * @public 24052 */ 24053 Owl.prototype.setup = function() { 24054 var viewport = this.viewport(), 24055 overwrites = this.options.responsive, 24056 match = -1, 24057 settings = null; 24058 24059 if (!overwrites) { 24060 settings = $.extend({}, this.options); 24061 } else { 24062 $.each(overwrites, function(breakpoint) { 24063 if (breakpoint <= viewport && breakpoint > match) { 24064 match = Number(breakpoint); 24065 } 24066 }); 24067 24068 settings = $.extend({}, this.options, overwrites[match]); 24069 delete settings.responsive; 24070 24071 // responsive class 24072 if (settings.responsiveClass) { 24073 this.$element.attr('class', 24074 this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) 24075 ); 24076 } 24077 } 24078 24079 if (this.settings === null || this._breakpoint !== match) { 24080 this.trigger('change', { property: { name: 'settings', value: settings } }); 24081 this._breakpoint = match; 24082 this.settings = settings; 24083 this.invalidate('settings'); 24084 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 24085 } 24086 }; 24087 24088 /** 24089 * Updates option logic if necessery. 24090 * @protected 24091 */ 24092 Owl.prototype.optionsLogic = function() { 24093 if (this.settings.autoWidth) { 24094 this.settings.stagePadding = false; 24095 this.settings.merge = false; 24096 } 24097 }; 24098 24099 /** 24100 * Prepares an item before add. 24101 * @todo Rename event parameter `content` to `item`. 24102 * @protected 24103 * @returns {jQuery|HTMLElement} - The item container. 24104 */ 24105 Owl.prototype.prepare = function(item, index) { 24106 var event = this.trigger('prepare', { content: item }); 24107 if (!event.data) { 24108 event.data = $('<' + this.settings.itemElement + '/>') 24109 .addClass(this.options.itemClass).attr('data-index', index + 1).append(item) 24110 } 24111 24112 this.trigger('prepared', { content: event.data }); 24113 24114 return event.data; 24115 }; 24116 24117 /** 24118 * Updates the view. 24119 * @public 24120 */ 24121 Owl.prototype.update = function() { 24122 var i = 0, 24123 n = this._pipe.length, 24124 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 24125 cache = {}; 24126 24127 while (i < n) { 24128 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 24129 this._pipe[i].run(cache); 24130 } 24131 i++; 24132 } 24133 24134 this._invalidated = {}; 24135 24136 !this.is('valid') && this.enter('valid'); 24137 }; 24138 24139 /** 24140 * Gets the width of the view. 24141 * @public 24142 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 24143 * @returns {Number} - The width of the view in pixel. 24144 */ 24145 Owl.prototype.width = function(dimension) { 24146 dimension = dimension || Owl.Width.Default; 24147 var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200; 24148 switch (dimension) { 24149 case Owl.Width.Inner: 24150 case Owl.Width.Outer: 24151 return this._width; 24152 default: 24153 return this._width - stagePadding * 2 + this.settings.margin; 24154 } 24155 }; 24156 24157 /** 24158 * Refreshes the carousel primarily for adaptive purposes. 24159 * @public 24160 */ 24161 Owl.prototype.refresh = function() { 24162 this.enter('refreshing'); 24163 this.trigger('refresh'); 24164 24165 this.setup(); 24166 24167 this.optionsLogic(); 24168 24169 this.$element.addClass(this.options.refreshClass); 24170 24171 this.update(); 24172 24173 this.$element.removeClass(this.options.refreshClass); 24174 24175 this.leave('refreshing'); 24176 this.trigger('refreshed'); 24177 }; 24178 24179 /** 24180 * Checks window `resize` event. 24181 * @protected 24182 */ 24183 Owl.prototype.onThrottledResize = function() { 24184 window.clearTimeout(this.resizeTimer); 24185 this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); 24186 }; 24187 24188 /** 24189 * Checks window `resize` event. 24190 * @protected 24191 */ 24192 Owl.prototype.onResize = function() { 24193 if (!this._items.length) { 24194 return false;
vendor: 46,301 bytes, lines 24195-25899
24195 } 24196 24197 if (this._width === this.$element.width()) { 24198 return false; 24199 } 24200 24201 if (!this.$element.is(':visible')) { 24202 return false; 24203 } 24204 24205 this.enter('resizing'); 24206 24207 if (this.trigger('resize').isDefaultPrevented()) { 24208 this.leave('resizing'); 24209 return false; 24210 } 24211 24212 this.invalidate('width'); 24213 24214 this.refresh(); 24215 24216 this.leave('resizing'); 24217 this.trigger('resized'); 24218 }; 24219 24220 /** 24221 * Registers event handlers. 24222 * @todo Check `msPointerEnabled` 24223 * @todo #261 24224 * @protected 24225 */ 24226 Owl.prototype.registerEventHandlers = function() { 24227 if ($.support.transition) { 24228 this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); 24229 } 24230 24231 if (this.settings.responsive !== false) { 24232 this.on(window, 'resize', this._handlers.onThrottledResize); 24233 } 24234 24235 if (this.settings.mouseDrag) { 24236 this.$element.addClass(this.options.dragClass); 24237 this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); 24238 this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); 24239 } 24240 24241 if (this.settings.touchDrag){ 24242 this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); 24243 this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); 24244 } 24245 }; 24246 24247 /** 24248 * Handles `touchstart` and `mousedown` events. 24249 * @todo Horizontal swipe threshold as option 24250 * @todo #261 24251 * @protected 24252 * @param {Event} event - The event arguments. 24253 */ 24254 Owl.prototype.onDragStart = function(event) { 24255 var stage = null; 24256 24257 if (event.which === 3) { 24258 return; 24259 } 24260 24261 if ($.support.transform) { 24262 stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); 24263 stage = { 24264 x: stage[stage.length === 16 ? 12 : 4], 24265 y: stage[stage.length === 16 ? 13 : 5] 24266 }; 24267 } else { 24268 stage = this.$stage.position(); 24269 stage = { 24270 x: this.settings.rtl ? 24271 stage.left + this.$stage.width() - this.width() + this.settings.margin : 24272 stage.left, 24273 y: stage.top 24274 }; 24275 } 24276 24277 if (this.is('animating')) { 24278 $.support.transform ? this.animate(stage.x) : this.$stage.stop() 24279 this.invalidate('position'); 24280 } 24281 24282 this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); 24283 24284 this.speed(0); 24285 24286 this._drag.time = new Date().getTime(); 24287 this._drag.target = $(event.target); 24288 this._drag.stage.start = stage; 24289 this._drag.stage.current = stage; 24290 this._drag.pointer = this.pointer(event); 24291 24292 $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); 24293 24294 $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { 24295 var delta = this.difference(this._drag.pointer, this.pointer(event)); 24296 24297 $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); 24298 24299 if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { 24300 return; 24301 } 24302 24303 event.preventDefault(); 24304 24305 this.enter('dragging'); 24306 this.trigger('drag'); 24307 }, this)); 24308 }; 24309 24310 /** 24311 * Handles the `touchmove` and `mousemove` events. 24312 * @todo #261 24313 * @protected 24314 * @param {Event} event - The event arguments. 24315 */ 24316 Owl.prototype.onDragMove = function(event) { 24317 var minimum = null, 24318 maximum = null, 24319 pull = null, 24320 delta = this.difference(this._drag.pointer, this.pointer(event)), 24321 stage = this.difference(this._drag.stage.start, delta); 24322 24323 if (!this.is('dragging')) { 24324 return; 24325 } 24326 24327 event.preventDefault(); 24328 24329 if (this.settings.loop) { 24330 minimum = this.coordinates(this.minimum()); 24331 maximum = this.coordinates(this.maximum() + 1) - minimum; 24332 stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; 24333 } else { 24334 minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 24335 maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 24336 pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; 24337 stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); 24338 } 24339 24340 this._drag.stage.current = stage; 24341 24342 this.animate(stage.x); 24343 }; 24344 24345 /** 24346 * Handles the `touchend` and `mouseup` events. 24347 * @todo #261 24348 * @todo Threshold for click event 24349 * @protected 24350 * @param {Event} event - The event arguments. 24351 */ 24352 Owl.prototype.onDragEnd = function(event) { 24353 var delta = this.difference(this._drag.pointer, this.pointer(event)), 24354 stage = this._drag.stage.current, 24355 direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; 24356 24357 $(document).off('.owl.core'); 24358 24359 this.$element.removeClass(this.options.grabClass); 24360 24361 if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { 24362 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 24363 this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); 24364 this.invalidate('position'); 24365 this.update(); 24366 24367 this._drag.direction = direction; 24368 24369 if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { 24370 this._drag.target.one('click.owl.core', function() { return false; }); 24371 } 24372 } 24373 24374 if (!this.is('dragging')) { 24375 return; 24376 } 24377 24378 this.leave('dragging'); 24379 this.trigger('dragged'); 24380 }; 24381 24382 /** 24383 * Gets absolute position of the closest item for a coordinate. 24384 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 24385 * @protected 24386 * @param {Number} coordinate - The coordinate in pixel. 24387 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. 24388 * @return {Number} - The absolute position of the closest item. 24389 */ 24390 Owl.prototype.closest = function(coordinate, direction) { 24391 var position = -1, 24392 pull = 30, 24393 width = this.width(), 24394 coordinates = this.coordinates(); 24395 24396 if (!this.settings.freeDrag) { 24397 // check closest item 24398 $.each(coordinates, $.proxy(function(index, value) { 24399 if (coordinate > value - pull && coordinate < value + pull) { 24400 position = index; 24401 } else if (this.op(coordinate, '<', value) 24402 && this.op(coordinate, '>', coordinates[index + 1] || value - width)) { 24403 position = direction === 'left' ? index + 1 : index; 24404 } 24405 return position === -1; 24406 }, this)); 24407 } 24408 24409 if (!this.settings.loop) { 24410 // non loop boundries 24411 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 24412 position = coordinate = this.minimum(); 24413 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 24414 position = coordinate = this.maximum(); 24415 } 24416 } 24417 24418 return position; 24419 }; 24420 24421 /** 24422 * Animates the stage. 24423 * @todo #270 24424 * @public 24425 * @param {Number} coordinate - The coordinate in pixels. 24426 */ 24427 Owl.prototype.animate = function(coordinate) { 24428 var animate = this.speed() > 0; 24429 24430 this.is('animating') && this.onTransitionEnd(); 24431 24432 if (animate) { 24433 this.enter('animating'); 24434 this.trigger('translate'); 24435 } 24436 24437 if ($.support.transform3d && $.support.transition) { 24438 this.$stage.css({ 24439 transform: 'translate3d(' + coordinate + 'px,0px,0px)', 24440 transition: (this.speed() / 1000) + 's' 24441 }); 24442 } else if (animate) { 24443 this.$stage.animate({ 24444 left: coordinate + 'px' 24445 }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); 24446 } else { 24447 this.$stage.css({ 24448 left: coordinate + 'px' 24449 }); 24450 } 24451 }; 24452 24453 /** 24454 * Checks whether the carousel is in a specific state or not. 24455 * @param {String} state - The state to check. 24456 * @returns {Boolean} - The flag which indicates if the carousel is busy. 24457 */ 24458 Owl.prototype.is = function(state) { 24459 return this._states.current[state] && this._states.current[state] > 0; 24460 }; 24461 24462 /** 24463 * Sets the absolute position of the current item. 24464 * @public 24465 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 24466 * @returns {Number} - The absolute position of the current item. 24467 */ 24468 Owl.prototype.current = function(position) { 24469 if (position === undefined) { 24470 return this._current; 24471 } 24472 24473 if (this._items.length === 0) { 24474 return undefined; 24475 } 24476 24477 position = this.normalize(position); 24478 24479 if (this._current !== position) { 24480 var event = this.trigger('change', { property: { name: 'position', value: position } }); 24481 24482 if (event.data !== undefined) { 24483 position = this.normalize(event.data); 24484 } 24485 24486 this._current = position; 24487 24488 this.invalidate('position'); 24489 24490 this.trigger('changed', { property: { name: 'position', value: this._current } }); 24491 } 24492 24493 return this._current; 24494 }; 24495 24496 /** 24497 * Invalidates the given part of the update routine. 24498 * @param {String} [part] - The part to invalidate. 24499 * @returns {Array.<String>} - The invalidated parts. 24500 */ 24501 Owl.prototype.invalidate = function(part) { 24502 if ($.type(part) === 'string') { 24503 this._invalidated[part] = true; 24504 this.is('valid') && this.leave('valid'); 24505 } 24506 return $.map(this._invalidated, function(v, i) { return i }); 24507 }; 24508 24509 /** 24510 * Resets the absolute position of the current item. 24511 * @public 24512 * @param {Number} position - The absolute position of the new item. 24513 */ 24514 Owl.prototype.reset = function(position) { 24515 position = this.normalize(position); 24516 24517 if (position === undefined) { 24518 return; 24519 } 24520 24521 this._speed = 0; 24522 this._current = position; 24523 24524 this.suppress([ 'translate', 'translated' ]); 24525 24526 this.animate(this.coordinates(position)); 24527 24528 this.release([ 'translate', 'translated' ]); 24529 }; 24530 24531 /** 24532 * Normalizes an absolute or a relative position of an item. 24533 * @public 24534 * @param {Number} position - The absolute or relative position to normalize. 24535 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 24536 * @returns {Number} - The normalized position. 24537 */ 24538 Owl.prototype.normalize = function(position, relative) { 24539 var n = this._items.length, 24540 m = relative ? 0 : this._clones.length; 24541 24542 if (!$.isNumeric(position) || n < 1) { 24543 position = undefined; 24544 } else if (position < 0 || position >= n + m) { 24545 position = ((position - m / 2) % n + n) % n + m / 2; 24546 } 24547 24548 return position; 24549 }; 24550 24551 /** 24552 * Converts an absolute position of an item into a relative one. 24553 * @public 24554 * @param {Number} position - The absolute position to convert. 24555 * @returns {Number} - The converted position. 24556 */ 24557 Owl.prototype.relative = function(position) { 24558 position -= this._clones.length / 2; 24559 return this.normalize(position, true); 24560 }; 24561 24562 /** 24563 * Gets the maximum position for the current item. 24564 * @public 24565 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 24566 * @returns {Number} 24567 */ 24568 Owl.prototype.maximum = function(relative) { 24569 var settings = this.settings, 24570 maximum = this._coordinates.length, 24571 boundary = Math.abs(this._coordinates[maximum - 1]) - this._width, 24572 i = -1, j; 24573 24574 if (settings.loop) { 24575 maximum = this._clones.length / 2 + this._items.length - 1; 24576 } else if (settings.autoWidth || settings.merge) { 24577 // binary search 24578 while (maximum - i > 1) { 24579 Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary 24580 ? i = j : maximum = j; 24581 } 24582 } else if (settings.center) { 24583 maximum = this._items.length - 1; 24584 } else { 24585 maximum = this._items.length - settings.items; 24586 } 24587 24588 if (relative) { 24589 maximum -= this._clones.length / 2; 24590 } 24591 24592 return Math.max(maximum, 0); 24593 }; 24594 24595 /** 24596 * Gets the minimum position for the current item. 24597 * @public 24598 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 24599 * @returns {Number} 24600 */ 24601 Owl.prototype.minimum = function(relative) { 24602 return relative ? 0 : this._clones.length / 2; 24603 }; 24604 24605 /** 24606 * Gets an item at the specified relative position. 24607 * @public 24608 * @param {Number} [position] - The relative position of the item. 24609 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 24610 */ 24611 Owl.prototype.items = function(position) { 24612 if (position === undefined) { 24613 return this._items.slice(); 24614 } 24615 24616 position = this.normalize(position, true); 24617 return this._items[position]; 24618 }; 24619 24620 /** 24621 * Gets an item at the specified relative position. 24622 * @public 24623 * @param {Number} [position] - The relative position of the item. 24624 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 24625 */ 24626 Owl.prototype.mergers = function(position) { 24627 if (position === undefined) { 24628 return this._mergers.slice(); 24629 } 24630 24631 position = this.normalize(position, true); 24632 return this._mergers[position]; 24633 }; 24634 24635 /** 24636 * Gets the absolute positions of clones for an item. 24637 * @public 24638 * @param {Number} [position] - The relative position of the item. 24639 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 24640 */ 24641 Owl.prototype.clones = function(position) { 24642 var odd = this._clones.length / 2, 24643 even = odd + this._items.length, 24644 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 24645 24646 if (position === undefined) { 24647 return $.map(this._clones, function(v, i) { return map(i) }); 24648 } 24649 24650 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 24651 }; 24652 24653 /** 24654 * Sets the current animation speed. 24655 * @public 24656 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 24657 * @returns {Number} - The current animation speed in milliseconds. 24658 */ 24659 Owl.prototype.speed = function(speed) { 24660 if (speed !== undefined) { 24661 this._speed = speed; 24662 } 24663 24664 return this._speed; 24665 }; 24666 24667 /** 24668 * Gets the coordinate of an item. 24669 * @todo The name of this method is missleanding. 24670 * @public 24671 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 24672 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 24673 */ 24674 Owl.prototype.coordinates = function(position) { 24675 var coordinate = null; 24676 24677 if (position === undefined) { 24678 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 24679 return this.coordinates(index); 24680 }, this)); 24681 } 24682 24683 if (this.settings.center) { 24684 coordinate = this._coordinates[position]; 24685 coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1); 24686 } else { 24687 coordinate = this._coordinates[position - 1] || 0; 24688 } 24689 24690 return coordinate; 24691 }; 24692 24693 /** 24694 * Calculates the speed for a translation. 24695 * @protected 24696 * @param {Number} from - The absolute position of the start item. 24697 * @param {Number} to - The absolute position of the target item. 24698 * @param {Number} [factor=undefined] - The time factor in milliseconds. 24699 * @returns {Number} - The time in milliseconds for the translation. 24700 */ 24701 Owl.prototype.duration = function(from, to, factor) { 24702 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 24703 }; 24704 24705 /** 24706 * Slides to the specified item. 24707 * @public 24708 * @param {Number} position - The position of the item. 24709 * @param {Number} [speed] - The time in milliseconds for the transition. 24710 */ 24711 Owl.prototype.to = function(position, speed) { 24712 var current = this.current(), 24713 revert = null, 24714 distance = position - this.relative(current), 24715 direction = (distance > 0) - (distance < 0), 24716 items = this._items.length, 24717 minimum = this.minimum(), 24718 maximum = this.maximum(); 24719 24720 if (this.settings.loop) { 24721 if (!this.settings.rewind && Math.abs(distance) > items / 2) { 24722 distance += direction * -1 * items; 24723 } 24724 24725 position = current + distance; 24726 revert = ((position - minimum) % items + items) % items + minimum; 24727 24728 if (revert !== position && revert - distance <= maximum && revert - distance > 0) { 24729 current = revert - distance; 24730 position = revert; 24731 this.reset(current); 24732 } 24733 } else if (this.settings.rewind) { 24734 maximum += 1; 24735 position = (position % maximum + maximum) % maximum; 24736 } else { 24737 position = Math.max(minimum, Math.min(maximum, position)); 24738 } 24739 24740 this.speed(this.duration(current, position, speed)); 24741 this.current(position); 24742 24743 if (this.$element.is(':visible')) { 24744 this.update(); 24745 } 24746 }; 24747 24748 /** 24749 * Slides to the next item. 24750 * @public 24751 * @param {Number} [speed] - The time in milliseconds for the transition. 24752 */ 24753 Owl.prototype.next = function(speed) { 24754 speed = speed || false; 24755 this.to(this.relative(this.current()) + 1, speed); 24756 }; 24757 24758 /** 24759 * Slides to the previous item. 24760 * @public 24761 * @param {Number} [speed] - The time in milliseconds for the transition. 24762 */ 24763 Owl.prototype.prev = function(speed) { 24764 speed = speed || false; 24765 this.to(this.relative(this.current()) - 1, speed); 24766 }; 24767 24768 /** 24769 * Handles the end of an animation. 24770 * @protected 24771 * @param {Event} event - The event arguments. 24772 */ 24773 Owl.prototype.onTransitionEnd = function(event) { 24774 24775 // if css2 animation then event object is undefined 24776 if (event !== undefined) { 24777 event.stopPropagation(); 24778 24779 // Catch only owl-stage transitionEnd event 24780 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 24781 return false; 24782 } 24783 } 24784 24785 this.leave('animating'); 24786 this.trigger('translated'); 24787 }; 24788 24789 /** 24790 * Gets viewport width. 24791 * @protected 24792 * @return {Number} - The width in pixel. 24793 */ 24794 Owl.prototype.viewport = function() { 24795 var width; 24796 if (this.options.responsiveBaseElement !== window) { 24797 width = $(this.options.responsiveBaseElement).width(); 24798 } else if (window.innerWidth) { 24799 width = window.innerWidth; 24800 } else if (document.documentElement && document.documentElement.clientWidth) { 24801 width = document.documentElement.clientWidth; 24802 } else { 24803 throw 'Can not detect viewport width.'; 24804 } 24805 24806 return width; 24807 }; 24808 24809 /** 24810 * Replaces the current content. 24811 * @public 24812 * @param {HTMLElement|jQuery|String} content - The new content. 24813 */ 24814 Owl.prototype.replace = function(content) { 24815 this.$stage.empty(); 24816 this._items = []; 24817 24818 if (content) { 24819 content = (content instanceof jQuery) ? content : $(content); 24820 } 24821 24822 if (this.settings.nestedItemSelector) { 24823 content = content.find('.' + this.settings.nestedItemSelector); 24824 } 24825 24826 content.filter(function() { 24827 return this.nodeType === 1; 24828 }).each($.proxy(function(index, item) { 24829 item = this.prepare(item, index); 24830 this.$stage.append(item); 24831 this._items.push(item); 24832 this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 24833 }, this)); 24834 24835 this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 24836 24837 this.invalidate('items'); 24838 }; 24839 24840 /** 24841 * Adds an item. 24842 * @todo Use `item` instead of `content` for the event arguments. 24843 * @public 24844 * @param {HTMLElement|jQuery|String} content - The item content to add. 24845 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 24846 */ 24847 Owl.prototype.add = function(content, position) { 24848 var current = this.relative(this._current); 24849 24850 position = position === undefined ? this._items.length : this.normalize(position, true); 24851 content = content instanceof jQuery ? content : $(content); 24852 24853 this.trigger('add', { content: content, position: position }); 24854 24855 content = this.prepare(content, this._items[current].index()); 24856 24857 if (this._items.length === 0 || position === this._items.length) { 24858 this._items.length === 0 && this.$stage.append(content); 24859 this._items.length !== 0 && this._items[position - 1].after(content); 24860 this._items.push(content); 24861 this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 24862 } else { 24863 this._items[position].before(content); 24864 this._items.splice(position, 0, content); 24865 this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1); 24866 } 24867 24868 this._items[current] && this.reset(this._items[current].index()); 24869 24870 this.invalidate('items'); 24871 24872 this.trigger('added', { content: content, position: position }); 24873 }; 24874 24875 /** 24876 * Removes an item by its position. 24877 * @todo Use `item` instead of `content` for the event arguments. 24878 * @public 24879 * @param {Number} position - The relative position of the item to remove. 24880 */ 24881 Owl.prototype.remove = function(position) { 24882 position = this.normalize(position, true); 24883 24884 if (position === undefined) { 24885 return; 24886 } 24887 24888 this.trigger('remove', { content: this._items[position], position: position }); 24889 24890 this._items[position].remove(); 24891 this._items.splice(position, 1); 24892 this._mergers.splice(position, 1); 24893 24894 this.invalidate('items'); 24895 24896 this.trigger('removed', { content: null, position: position }); 24897 }; 24898 24899 /** 24900 * Preloads images with auto width. 24901 * @todo Replace by a more generic approach 24902 * @protected 24903 */ 24904 Owl.prototype.preloadAutoWidthImages = function(images) { 24905 images.each($.proxy(function(i, element) { 24906 this.enter('pre-loading'); 24907 element = $(element); 24908 $(new Image()).one('load', $.proxy(function(e) { 24909 element.attr('src', e.target.src); 24910 element.css('opacity', 1); 24911 this.leave('pre-loading'); 24912 !this.is('pre-loading') && !this.is('initializing') && this.refresh(); 24913 }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina')); 24914 }, this)); 24915 }; 24916 24917 /** 24918 * Destroys the carousel. 24919 * @public 24920 */ 24921 Owl.prototype.destroy = function() { 24922 24923 this.$element.off('.owl.core'); 24924 this.$stage.off('.owl.core'); 24925 $(document).off('.owl.core'); 24926 24927 if (this.settings.responsive !== false) { 24928 window.clearTimeout(this.resizeTimer); 24929 this.off(window, 'resize', this._handlers.onThrottledResize); 24930 } 24931 24932 for (var i in this._plugins) { 24933 this._plugins[i].destroy(); 24934 } 24935 24936 this.$stage.children('.cloned').remove(); 24937 24938 this.$stage.unwrap(); 24939 this.$stage.children().contents().unwrap(); 24940 this.$stage.children().unwrap(); 24941 24942 this.$element 24943 .removeClass(this.options.refreshClass) 24944 .removeClass(this.options.loadingClass) 24945 .removeClass(this.options.loadedClass) 24946 .removeClass(this.options.rtlClass) 24947 .removeClass(this.options.dragClass) 24948 .removeClass(this.options.grabClass) 24949 .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) 24950 .removeData('owl.carousel'); 24951 }; 24952 24953 /** 24954 * Operators to calculate right-to-left and left-to-right. 24955 * @protected 24956 * @param {Number} [a] - The left side operand. 24957 * @param {String} [o] - The operator. 24958 * @param {Number} [b] - The right side operand. 24959 */ 24960 Owl.prototype.op = function(a, o, b) { 24961 var rtl = this.settings.rtl; 24962 switch (o) { 24963 case '<': 24964 return rtl ? a > b : a < b; 24965 case '>': 24966 return rtl ? a < b : a > b; 24967 case '>=': 24968 return rtl ? a <= b : a >= b; 24969 case '<=': 24970 return rtl ? a >= b : a <= b; 24971 default: 24972 break; 24973 } 24974 }; 24975 24976 /** 24977 * Attaches to an internal event. 24978 * @protected 24979 * @param {HTMLElement} element - The event source. 24980 * @param {String} event - The event name. 24981 * @param {Function} listener - The event handler to attach. 24982 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. 24983 */ 24984 Owl.prototype.on = function(element, event, listener, capture) { 24985 if (element.addEventListener) { 24986 element.addEventListener(event, listener, capture); 24987 } else if (element.attachEvent) { 24988 element.attachEvent('on' + event, listener); 24989 } 24990 }; 24991 24992 /** 24993 * Detaches from an internal event. 24994 * @protected 24995 * @param {HTMLElement} element - The event source. 24996 * @param {String} event - The event name. 24997 * @param {Function} listener - The attached event handler to detach. 24998 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 24999 */ 25000 Owl.prototype.off = function(element, event, listener, capture) { 25001 if (element.removeEventListener) { 25002 element.removeEventListener(event, listener, capture); 25003 } else if (element.detachEvent) { 25004 element.detachEvent('on' + event, listener); 25005 } 25006 }; 25007 25008 /** 25009 * Triggers a public event. 25010 * @todo Remove `status`, `relatedTarget` should be used instead. 25011 * @protected 25012 * @param {String} name - The event name. 25013 * @param {*} [data=null] - The event data. 25014 * @param {String} [namespace=carousel] - The event namespace. 25015 * @param {String} [state] - The state which is associated with the event. 25016 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. 25017 * @returns {Event} - The event arguments. 25018 */ 25019 Owl.prototype.trigger = function(name, data, namespace, state, enter) { 25020 var status = { 25021 item: { count: this._items.length, index: this.current() } 25022 }, handler = $.camelCase( 25023 $.grep([ 'on', name, namespace ], function(v) { return v }) 25024 .join('-').toLowerCase() 25025 ), event = $.Event( 25026 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 25027 $.extend({ relatedTarget: this }, status, data) 25028 ); 25029 25030 if (!this._supress[name]) { 25031 $.each(this._plugins, function(name, plugin) { 25032 if (plugin.onTrigger) { 25033 plugin.onTrigger(event); 25034 } 25035 }); 25036 25037 this.register({ type: Owl.Type.Event, name: name }); 25038 this.$element.trigger(event); 25039 25040 if (this.settings && typeof this.settings[handler] === 'function') { 25041 this.settings[handler].call(this, event); 25042 } 25043 } 25044 25045 return event; 25046 }; 25047 25048 /** 25049 * Enters a state. 25050 * @param name - The state name. 25051 */ 25052 Owl.prototype.enter = function(name) { 25053 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 25054 if (this._states.current[name] === undefined) { 25055 this._states.current[name] = 0; 25056 } 25057 25058 this._states.current[name]++; 25059 }, this)); 25060 }; 25061 25062 /** 25063 * Leaves a state. 25064 * @param name - The state name. 25065 */ 25066 Owl.prototype.leave = function(name) { 25067 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 25068 this._states.current[name]--; 25069 }, this)); 25070 }; 25071 25072 /** 25073 * Registers an event or state. 25074 * @public 25075 * @param {Object} object - The event or state to register. 25076 */ 25077 Owl.prototype.register = function(object) { 25078 if (object.type === Owl.Type.Event) { 25079 if (!$.event.special[object.name]) { 25080 $.event.special[object.name] = {}; 25081 } 25082 25083 if (!$.event.special[object.name].owl) { 25084 var _default = $.event.special[object.name]._default; 25085 $.event.special[object.name]._default = function(e) { 25086 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 25087 return _default.apply(this, arguments); 25088 } 25089 return e.namespace && e.namespace.indexOf('owl') > -1; 25090 }; 25091 $.event.special[object.name].owl = true; 25092 } 25093 } else if (object.type === Owl.Type.State) { 25094 if (!this._states.tags[object.name]) { 25095 this._states.tags[object.name] = object.tags; 25096 } else { 25097 this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); 25098 } 25099 25100 this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { 25101 return $.inArray(tag, this._states.tags[object.name]) === i; 25102 }, this)); 25103 } 25104 }; 25105 25106 /** 25107 * Suppresses events. 25108 * @protected 25109 * @param {Array.<String>} events - The events to suppress. 25110 */ 25111 Owl.prototype.suppress = function(events) { 25112 $.each(events, $.proxy(function(index, event) { 25113 this._supress[event] = true; 25114 }, this)); 25115 }; 25116 25117 /** 25118 * Releases suppressed events. 25119 * @protected 25120 * @param {Array.<String>} events - The events to release. 25121 */ 25122 Owl.prototype.release = function(events) { 25123 $.each(events, $.proxy(function(index, event) { 25124 delete this._supress[event]; 25125 }, this)); 25126 }; 25127 25128 /** 25129 * Gets unified pointer coordinates from event. 25130 * @todo #261 25131 * @protected 25132 * @param {Event} - The `mousedown` or `touchstart` event. 25133 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 25134 */ 25135 Owl.prototype.pointer = function(event) { 25136 var result = { x: null, y: null }; 25137 25138 event = event.originalEvent || event || window.event; 25139 25140 event = event.touches && event.touches.length ? 25141 event.touches[0] : event.changedTouches && event.changedTouches.length ? 25142 event.changedTouches[0] : event; 25143 25144 if (event.pageX) { 25145 result.x = event.pageX; 25146 result.y = event.pageY; 25147 } else { 25148 result.x = event.clientX; 25149 result.y = event.clientY; 25150 } 25151 25152 return result; 25153 }; 25154 25155 /** 25156 * Gets the difference of two vectors. 25157 * @todo #261 25158 * @protected 25159 * @param {Object} - The first vector. 25160 * @param {Object} - The second vector. 25161 * @returns {Object} - The difference. 25162 */ 25163 Owl.prototype.difference = function(first, second) { 25164 return { 25165 x: first.x - second.x, 25166 y: first.y - second.y 25167 }; 25168 }; 25169 25170 /** 25171 * The jQuery Plugin for the Owl Carousel 25172 * @todo Navigation plugin `next` and `prev` 25173 * @public 25174 */ 25175 $.fn.owlCarousel = function(option) { 25176 var args = Array.prototype.slice.call(arguments, 1); 25177 25178 return this.each(function() { 25179 var $this = $(this), 25180 data = $this.data('owl.carousel'); 25181 25182 if (!data) { 25183 data = new Owl(this, typeof option == 'object' && option); 25184 $this.data('owl.carousel', data); 25185 25186 $.each([ 25187 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' 25188 ], function(i, event) { 25189 data.register({ type: Owl.Type.Event, name: event }); 25190 data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { 25191 if (e.namespace && e.relatedTarget !== this) { 25192 this.suppress([ event ]); 25193 data[event].apply(this, [].slice.call(arguments, 1)); 25194 this.release([ event ]); 25195 } 25196 }, data)); 25197 }); 25198 } 25199 25200 if (typeof option == 'string' && option.charAt(0) !== '_') { 25201 data[option].apply(data, args); 25202 } 25203 }); 25204 }; 25205 25206 /** 25207 * The constructor for the jQuery Plugin 25208 * @public 25209 */ 25210 $.fn.owlCarousel.Constructor = Owl; 25211 25212})(window.Zepto || window.jQuery, window, document); 25213 25214/** 25215 * AutoRefresh Plugin 25216 * @version 2.0.0-beta.3 25217 * @author Artus Kolanowski 25218 * @license The MIT License (MIT) 25219 */ 25220;(function($, window, document, undefined) { 25221 25222 /** 25223 * Creates the auto refresh plugin. 25224 * @class The Auto Refresh Plugin 25225 * @param {Owl} carousel - The Owl Carousel 25226 */ 25227 var AutoRefresh = function(carousel) { 25228 /** 25229 * Reference to the core. 25230 * @protected 25231 * @type {Owl} 25232 */ 25233 this._core = carousel; 25234 25235 /** 25236 * Refresh interval. 25237 * @protected 25238 * @type {number} 25239 */ 25240 this._interval = null; 25241 25242 /** 25243 * Whether the element is currently visible or not. 25244 * @protected 25245 * @type {Boolean} 25246 */ 25247 this._visible = null; 25248 25249 /** 25250 * All event handlers. 25251 * @protected 25252 * @type {Object} 25253 */ 25254 this._handlers = { 25255 'initialized.owl.carousel': $.proxy(function(e) { 25256 if (e.namespace && this._core.settings.autoRefresh) { 25257 this.watch(); 25258 } 25259 }, this) 25260 }; 25261 25262 // set default options 25263 this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options); 25264 25265 // register event handlers 25266 this._core.$element.on(this._handlers); 25267 }; 25268 25269 /** 25270 * Default options. 25271 * @public 25272 */ 25273 AutoRefresh.Defaults = { 25274 autoRefresh: true, 25275 autoRefreshInterval: 500 25276 }; 25277 25278 /** 25279 * Watches the element. 25280 */ 25281 AutoRefresh.prototype.watch = function() { 25282 if (this._interval) { 25283 return; 25284 } 25285 25286 this._visible = this._core.$element.is(':visible'); 25287 this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval); 25288 }; 25289 25290 /** 25291 * Refreshes the element. 25292 */ 25293 AutoRefresh.prototype.refresh = function() { 25294 if (this._core.$element.is(':visible') === this._visible || this._core.$element.closest('.drop-menu').length) { 25295 return; 25296 } 25297 25298 this._visible = !this._visible; 25299 25300 this._core.$element.toggleClass('owl-hidden', !this._visible); 25301 25302 this._visible && (this._core.invalidate('width') && this._core.refresh()); 25303 }; 25304 25305 /** 25306 * Destroys the plugin. 25307 */ 25308 AutoRefresh.prototype.destroy = function() { 25309 var handler, property; 25310 25311 window.clearInterval(this._interval); 25312 25313 for (handler in this._handlers) { 25314 this._core.$element.off(handler, this._handlers[handler]); 25315 } 25316 for (property in Object.getOwnPropertyNames(this)) { 25317 typeof this[property] != 'function' && (this[property] = null); 25318 } 25319 }; 25320 25321 $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh; 25322 25323})(window.Zepto || window.jQuery, window, document); 25324 25325/** 25326 * Lazy Plugin 25327 * @version 2.0.0-beta.3 25328 * @author Bartosz Wojciechowski 25329 * @license The MIT License (MIT) 25330 */ 25331;(function($, window, document, undefined) { 25332 25333 /** 25334 * Creates the lazy plugin. 25335 * @class The Lazy Plugin 25336 * @param {Owl} carousel - The Owl Carousel 25337 */ 25338 var Lazy = function(carousel) { 25339 25340 /** 25341 * Reference to the core. 25342 * @protected 25343 * @type {Owl} 25344 */ 25345 this._core = carousel; 25346 25347 /** 25348 * Already loaded items. 25349 * @protected 25350 * @type {Array.<jQuery>} 25351 */ 25352 this._loaded = []; 25353 25354 /** 25355 * Event handlers. 25356 * @protected 25357 * @type {Object} 25358 */ 25359 this._handlers = { 25360 'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) { 25361 if (!e.namespace) { 25362 return; 25363 } 25364 25365 if (!this._core.settings || !this._core.settings.lazyLoad) { 25366 return; 25367 } 25368 25369 if ((e.property && e.property.name == 'position') || e.type == 'initialized') { 25370 var settings = this._core.settings, 25371 n = (settings.center && Math.ceil(settings.items / 2) || settings.items), 25372 i = ((settings.center && n * -1) || 0), 25373 position = ((e.property && e.property.value) || this._core.current()) + i, 25374 clones = this._core.clones().length, 25375 load = $.proxy(function(i, v) { this.load(v) }, this); 25376 25377 while (i++ < n) { 25378 this.load(clones / 2 + this._core.relative(position)); 25379 clones && $.each(this._core.clones(this._core.relative(position)), load); 25380 position++; 25381 } 25382 } 25383 }, this) 25384 }; 25385 25386 // set the default options 25387 this._core.options = $.extend({}, Lazy.Defaults, this._core.options); 25388 25389 // register event handler 25390 this._core.$element.on(this._handlers); 25391 } 25392 25393 /** 25394 * Default options. 25395 * @public 25396 */ 25397 Lazy.Defaults = { 25398 lazyLoad: false 25399 } 25400 25401 /** 25402 * Loads all resources of an item at the specified position. 25403 * @param {Number} position - The absolute position of the item. 25404 * @protected 25405 */ 25406 Lazy.prototype.load = function(position) { 25407 var $item = this._core.$stage.children().eq(position), 25408 $elements = $item && $item.find('.owl-lazy'); 25409 25410 if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { 25411 return; 25412 } 25413 25414 $elements.each($.proxy(function(index, element) { 25415 var $element = $(element), image, 25416 url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src'); 25417 25418 this._core.trigger('load', { element: $element, url: url }, 'lazy'); 25419 25420 if ($element.is('img')) { 25421 $element.one('load.owl.lazy', $.proxy(function() { 25422 $element.css('opacity', 1); 25423 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 25424 }, this)).attr('src', url); 25425 } else { 25426 image = new Image(); 25427 image.onload = $.proxy(function() { 25428 $element.css({ 25429 'background-image': 'url(' + url + ')', 25430 'opacity': '1' 25431 }); 25432 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 25433 }, this); 25434 image.src = url; 25435 } 25436 }, this)); 25437 25438 this._loaded.push($item.get(0)); 25439 } 25440 25441 /** 25442 * Destroys the plugin. 25443 * @public 25444 */ 25445 Lazy.prototype.destroy = function() { 25446 var handler, property; 25447 25448 for (handler in this.handlers) { 25449 this._core.$element.off(handler, this.handlers[handler]); 25450 } 25451 for (property in Object.getOwnPropertyNames(this)) { 25452 typeof this[property] != 'function' && (this[property] = null); 25453 } 25454 }; 25455 25456 $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; 25457 25458})(window.Zepto || window.jQuery, window, document); 25459 25460/** 25461 * AutoHeight Plugin 25462 * @version 2.0.0-beta.3 25463 * @author Bartosz Wojciechowski 25464 * @license The MIT License (MIT) 25465 */ 25466;(function($, window, document, undefined) { 25467 25468 /** 25469 * Creates the auto height plugin. 25470 * @class The Auto Height Plugin 25471 * @param {Owl} carousel - The Owl Carousel 25472 */ 25473 var AutoHeight = function(carousel) { 25474 /** 25475 * Reference to the core. 25476 * @protected 25477 * @type {Owl} 25478 */ 25479 this._core = carousel; 25480 25481 /** 25482 * All event handlers. 25483 * @protected 25484 * @type {Object} 25485 */ 25486 this._handlers = { 25487 'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) { 25488 if (e.namespace && this._core.settings.autoHeight) { 25489 this.update(); 25490 } 25491 }, this), 25492 'changed.owl.carousel': $.proxy(function(e) { 25493 if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){ 25494 this.update(); 25495 } 25496 }, this), 25497 'loaded.owl.lazy': $.proxy(function(e) { 25498 if (e.namespace && this._core.settings.autoHeight 25499 && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) { 25500 this.update(); 25501 } 25502 }, this) 25503 }; 25504 25505 // set default options 25506 this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); 25507 25508 // register event handlers 25509 this._core.$element.on(this._handlers); 25510 }; 25511 25512 /** 25513 * Default options. 25514 * @public 25515 */ 25516 AutoHeight.Defaults = { 25517 autoHeight: false, 25518 autoHeightClass: 'owl-height' 25519 }; 25520 25521 /** 25522 * Updates the view. 25523 */ 25524 AutoHeight.prototype.update = function() { 25525 var start = this._core._current, 25526 end = start + this._core.settings.items, 25527 visible = this._core.$stage.children().toArray().slice(start, end); 25528 heights = [], 25529 maxheight = 0; 25530 25531 $.each(visible, function(index, item) { 25532 heights.push($(item).height()); 25533 }); 25534 25535 maxheight = Math.max.apply(null, heights); 25536 25537 this._core.$stage.parent() 25538 .height(maxheight) 25539 .addClass(this._core.settings.autoHeightClass); 25540 }; 25541 25542 AutoHeight.prototype.destroy = function() { 25543 var handler, property; 25544 25545 for (handler in this._handlers) { 25546 this._core.$element.off(handler, this._handlers[handler]); 25547 } 25548 for (property in Object.getOwnPropertyNames(this)) { 25549 typeof this[property] != 'function' && (this[property] = null); 25550 } 25551 }; 25552 25553 $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; 25554 25555})(window.Zepto || window.jQuery, window, document); 25556 25557/** 25558 * Video Plugin 25559 * @version 2.0.0-beta.3 25560 * @author Bartosz Wojciechowski 25561 * @license The MIT License (MIT) 25562 */ 25563;(function($, window, document, undefined) { 25564 25565 /** 25566 * Creates the video plugin. 25567 * @class The Video Plugin 25568 * @param {Owl} carousel - The Owl Carousel 25569 */ 25570 var Video = function(carousel) { 25571 /** 25572 * Reference to the core. 25573 * @protected 25574 * @type {Owl} 25575 */ 25576 this._core = carousel; 25577 25578 /** 25579 * Cache all video URLs. 25580 * @protected 25581 * @type {Object} 25582 */ 25583 this._videos = {}; 25584 25585 /** 25586 * Current playing item. 25587 * @protected 25588 * @type {jQuery} 25589 */ 25590 this._playing = null; 25591 25592 /** 25593 * All event handlers. 25594 * @todo The cloned content removale is too late 25595 * @protected 25596 * @type {Object} 25597 */ 25598 this._handlers = { 25599 'initialized.owl.carousel': $.proxy(function(e) { 25600 if (e.namespace) { 25601 this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] }); 25602 } 25603 }, this), 25604 'resize.owl.carousel': $.proxy(function(e) { 25605 if (e.namespace && this._core.settings.video && this.isInFullScreen()) { 25606 e.preventDefault(); 25607 } 25608 }, this), 25609 'refreshed.owl.carousel': $.proxy(function(e) { 25610 if (e.namespace && this._core.is('resizing')) { 25611 this._core.$stage.find('.cloned .owl-video-frame').remove(); 25612 } 25613 }, this), 25614 'changed.owl.carousel': $.proxy(function(e) { 25615 if (e.namespace && e.property.name === 'position' && this._playing) { 25616 this.stop(); 25617 } 25618 }, this), 25619 'prepared.owl.carousel': $.proxy(function(e) { 25620 if (!e.namespace) { 25621 return; 25622 } 25623 25624 var $element = $(e.content).find('.owl-video'); 25625 25626 if ($element.length) { 25627 $element.css('display', 'none'); 25628 this.fetch($element, $(e.content)); 25629 } 25630 }, this) 25631 }; 25632 25633 // set default options 25634 this._core.options = $.extend({}, Video.Defaults, this._core.options); 25635 25636 // register event handlers 25637 this._core.$element.on(this._handlers); 25638 25639 this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 25640 this.play(e); 25641 }, this)); 25642 }; 25643 25644 /** 25645 * Default options. 25646 * @public 25647 */ 25648 Video.Defaults = { 25649 video: false, 25650 videoHeight: false, 25651 videoWidth: false 25652 }; 25653 25654 /** 25655 * Gets the video ID and the type (YouTube/Vimeo only). 25656 * @protected 25657 * @param {jQuery} target - The target containing the video data. 25658 * @param {jQuery} item - The item containing the video. 25659 */ 25660 Video.prototype.fetch = function(target, item) { 25661 var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube', 25662 id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'), 25663 width = target.attr('data-width') || this._core.settings.videoWidth, 25664 height = target.attr('data-height') || this._core.settings.videoHeight, 25665 url = target.attr('href'); 25666 25667 if (url) { 25668 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+)?/); 25669 25670 if (id[3].indexOf('youtu') > -1) { 25671 type = 'youtube'; 25672 } else if (id[3].indexOf('vimeo') > -1) { 25673 type = 'vimeo'; 25674 } else { 25675 throw new Error('Video URL not supported.'); 25676 } 25677 id = id[6]; 25678 } else { 25679 throw new Error('Missing video URL.'); 25680 } 25681 25682 this._videos[url] = { 25683 type: type, 25684 id: id, 25685 width: width, 25686 height: height 25687 }; 25688 25689 item.attr('data-video', url); 25690 25691 this.thumbnail(target, this._videos[url]); 25692 }; 25693 25694 /** 25695 * Creates video thumbnail. 25696 * @protected 25697 * @param {jQuery} target - The target containing the video data. 25698 * @param {Object} info - The video info object. 25699 * @see `fetch` 25700 */ 25701 Video.prototype.thumbnail = function(target, video) { 25702 var tnLink, 25703 icon, 25704 path, 25705 dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '', 25706 customTn = target.find('img'), 25707 srcType = 'src', 25708 lazyClass = '', 25709 settings = this._core.settings, 25710 create = function(path) { 25711 icon = '<div class="owl-video-play-icon"></div>'; 25712 25713 if (settings.lazyLoad) { 25714 tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>'; 25715 } else { 25716 tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>'; 25717 } 25718 target.after(tnLink); 25719 target.after(icon); 25720 }; 25721 25722 // wrap video content into owl-video-wrapper div 25723 target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>'); 25724 25725 if (this._core.settings.lazyLoad) { 25726 srcType = 'data-src'; 25727 lazyClass = 'owl-lazy'; 25728 } 25729 25730 // custom thumbnail 25731 if (customTn.length) { 25732 create(customTn.attr(srcType)); 25733 customTn.remove(); 25734 return false; 25735 } 25736 25737 if (video.type === 'youtube') { 25738 path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; 25739 create(path); 25740 } else if (video.type === 'vimeo') { 25741 $.ajax({ 25742 type: 'GET', 25743 url: '//vimeo.com/api/v2/video/' + video.id + '.json', 25744 jsonp: 'callback', 25745 dataType: 'jsonp', 25746 success: function(data) { 25747 path = data[0].thumbnail_large; 25748 create(path); 25749 } 25750 }); 25751 } 25752 }; 25753 25754 /** 25755 * Stops the current video. 25756 * @public 25757 */ 25758 Video.prototype.stop = function() { 25759 this._core.trigger('stop', null, 'video'); 25760 this._playing.find('.owl-video-frame').remove(); 25761 this._playing.removeClass('owl-video-playing'); 25762 this._playing = null; 25763 this._core.leave('playing'); 25764 this._core.trigger('stopped', null, 'video'); 25765 }; 25766 25767 /** 25768 * Starts the current video. 25769 * @public 25770 * @param {Event} event - The event arguments. 25771 */ 25772 Video.prototype.play = function(event) { 25773 var target = $(event.target), 25774 item = target.closest('.' + this._core.settings.itemClass), 25775 video = this._videos[item.attr('data-video')], 25776 width = video.width || '100%', 25777 height = video.height || this._core.$stage.height(), 25778 html; 25779 25780 if (this._playing) { 25781 return; 25782 } 25783 25784 this._core.enter('playing'); 25785 this._core.trigger('play', null, 'video'); 25786 25787 item = this._core.items(this._core.relative(item.index())); 25788 25789 this._core.reset(item.index()); 25790 25791 if (video.type === 'youtube') { 25792 html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' + 25793 video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>'; 25794 } else if (video.type === 'vimeo') { 25795 html = '<iframe src="//player.vimeo.com/video/' + video.id + 25796 '?autoplay=1" width="' + width + '" height="' + height + 25797 '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'; 25798 } 25799 25800 $('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video')); 25801 25802 this._playing = item.addClass('owl-video-playing'); 25803 }; 25804 25805 /** 25806 * Checks whether an video is currently in full screen mode or not. 25807 * @todo Bad style because looks like a readonly method but changes members. 25808 * @protected 25809 * @returns {Boolean} 25810 */ 25811 Video.prototype.isInFullScreen = function() { 25812 var element = document.fullscreenElement || document.mozFullScreenElement || 25813 document.webkitFullscreenElement; 25814 25815 return element && $(element).parent().hasClass('owl-video-frame'); 25816 }; 25817 25818 /** 25819 * Destroys the plugin. 25820 */ 25821 Video.prototype.destroy = function() { 25822 var handler, property; 25823 25824 this._core.$element.off('click.owl.video'); 25825 25826 for (handler in this._handlers) { 25827 this._core.$element.off(handler, this._handlers[handler]); 25828 } 25829 for (property in Object.getOwnPropertyNames(this)) { 25830 typeof this[property] != 'function' && (this[property] = null); 25831 } 25832 }; 25833 25834 $.fn.owlCarousel.Constructor.Plugins.Video = Video; 25835 25836})(window.Zepto || window.jQuery, window, document); 25837 25838/** 25839 * Animate Plugin 25840 * @version 2.0.0-beta.3 25841 * @author Bartosz Wojciechowski 25842 * @license The MIT License (MIT) 25843 */ 25844;(function($, window, document, undefined) { 25845 25846 /** 25847 * Creates the animate plugin. 25848 * @class The Navigation Plugin 25849 * @param {Owl} scope - The Owl Carousel 25850 */ 25851 var Animate = function(scope) { 25852 this.core = scope; 25853 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 25854 this.swapping = true; 25855 this.previous = undefined; 25856 this.next = undefined; 25857 25858 this.handlers = { 25859 'change.owl.carousel': $.proxy(function(e) { 25860 if (e.namespace && e.property.name == 'position') { 25861 this.previous = this.core.current(); 25862 this.next = e.property.value; 25863 } 25864 }, this), 25865 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 25866 if (e.namespace) { 25867 this.swapping = e.type == 'translated'; 25868 } 25869 }, this), 25870 'translate.owl.carousel': $.proxy(function(e) { 25871 if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 25872 this.swap(); 25873 } 25874 }, this) 25875 }; 25876 25877 this.core.$element.on(this.handlers); 25878 }; 25879 25880 /** 25881 * Default options. 25882 * @public 25883 */ 25884 Animate.Defaults = { 25885 animateOut: false, 25886 animateIn: false 25887 }; 25888 25889 /** 25890 * Toggles the animation classes whenever an translations starts. 25891 * @protected 25892 * @returns {Boolean|undefined} 25893 */ 25894 Animate.prototype.swap = function() { 25895 25896 if (this.core.settings.items !== 1) { 25897 return; 25898 } 25899
25900 if (!$.support.animation || !$.support.transition) { 25901 return; 25902 } 25903 25904 this.core.speed(0); 25905 25906 var left, 25907 clear = $.proxy(this.clear, this), 25908 previous = this.core.$stage.children().eq(this.previous), 25909 next = this.core.$stage.children().eq(this.next), 25910 incoming = this.core.settings.animateIn, 25911 outgoing = this.core.settings.animateOut; 25912 25913 if (this.core.current() === this.previous) { 25914 return; 25915 } 25916 25917 if (outgoing) { 25918 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 25919 previous.css( { 'left': left + 'px' } ) 25920 .addClass('animated owl-animated-out') 25921 .addClass(outgoing) 25922 .on($.support.animation.end, clear); 25923 } 25924 25925 if (incoming) { 25926 next.addClass('animated owl-animated-in') 25927 .addClass(incoming) 25928 .on($.support.animation.end, clear); 25929 } 25930 }; 25931 25932 Animate.prototype.clear = function(e) { 25933 if ($(e.target).hasClass('animated')) { 25934 $(e.target).css( { 'left': '' } ) 25935 .removeClass('animated owl-animated-out owl-animated-in') 25936 .removeClass(this.core.settings.animateIn) 25937 .removeClass(this.core.settings.animateOut); 25938 this.core.onTransitionEnd(); 25939 } 25940 }; 25941 25942 /** 25943 * Destroys the plugin. 25944 * @public 25945 */ 25946 Animate.prototype.destroy = function() { 25947 var handler, property; 25948 25949 for (handler in this.handlers) { 25950 this.core.$element.off(handler, this.handlers[handler]); 25951 } 25952 for (property in Object.getOwnPropertyNames(this)) { 25953 typeof this[property] != 'function' && (this[property] = null); 25954 } 25955 }; 25956 25957 $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; 25958 25959})(window.Zepto || window.jQuery, window, document); 25960 25961/** 25962 * Autoplay Plugin 25963 * @version 2.0.0-beta.3 25964 * @author Bartosz Wojciechowski 25965 * @author Artus Kolanowski 25966 * @license The MIT License (MIT) 25967 */ 25968;(function($, window, document, undefined) { 25969 25970 /** 25971 * Creates the autoplay plugin. 25972 * @class The Autoplay Plugin 25973 * @param {Owl} scope - The Owl Carousel 25974 */ 25975 var Autoplay = function(carousel) { 25976 /** 25977 * Reference to the core. 25978 * @protected 25979 * @type {Owl} 25980 */ 25981 this._core = carousel; 25982 25983 /** 25984 * The autoplay interval. 25985 * @type {Number} 25986 */ 25987 this._interval = null; 25988 25989 /** 25990 * Indicates whenever the autoplay is paused. 25991 * @type {Boolean} 25992 */ 25993 this._paused = false; 25994 25995 /** 25996 * All event handlers. 25997 * @protected 25998 * @type {Object} 25999 */ 26000 this._handlers = { 26001 'changed.owl.carousel': $.proxy(function(e) { 26002 if (e.namespace && e.property.name === 'settings') { 26003 if (this._core.settings.autoplay) { 26004 this.play(); 26005 } else { 26006 this.stop(); 26007 } 26008 } 26009 }, this), 26010 'initialized.owl.carousel': $.proxy(function(e) { 26011 if (e.namespace && this._core.settings.autoplay) { 26012 this.play(); 26013 } 26014 }, this), 26015 'play.owl.autoplay': $.proxy(function(e, t, s) { 26016 if (e.namespace) { 26017 this.play(t, s); 26018 } 26019 }, this), 26020 'stop.owl.autoplay': $.proxy(function(e) { 26021 if (e.namespace) { 26022 this.stop(); 26023 } 26024 }, this), 26025 'mouseover.owl.autoplay': $.proxy(function() { 26026 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 26027 this.pause(); 26028 } 26029 }, this), 26030 'mouseleave.owl.autoplay': $.proxy(function() { 26031 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 26032 this.play(); 26033 } 26034 }, this) 26035 }; 26036 26037 // register event handlers 26038 this._core.$element.on(this._handlers); 26039 26040 // set default options 26041 this._core.options = $.extend({}, Autoplay.Defaults, this._core.options); 26042 }; 26043 26044 /** 26045 * Default options. 26046 * @public 26047 */ 26048 Autoplay.Defaults = { 26049 autoplay: false, 26050 autoplayTimeout: 5000, 26051 autoplayHoverPause: false, 26052 autoplaySpeed: false 26053 }; 26054 26055 /** 26056 * Starts the autoplay. 26057 * @public 26058 * @param {Number} [timeout] - The interval before the next animation starts. 26059 * @param {Number} [speed] - The animation speed for the animations. 26060 */ 26061 Autoplay.prototype.play = function(timeout, speed) { 26062 this._paused = false; 26063 26064 if (this._core.is('rotating')) { 26065 return; 26066 } 26067 26068 this._core.enter('rotating'); 26069 26070 this._interval = window.setInterval($.proxy(function() { 26071 if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) { 26072 return; 26073 } 26074 this._core.next(speed || this._core.settings.autoplaySpeed); 26075 }, this), timeout || this._core.settings.autoplayTimeout); 26076 }; 26077 26078 /** 26079 * Stops the autoplay. 26080 * @public 26081 */ 26082 Autoplay.prototype.stop = function() { 26083 if (!this._core.is('rotating')) { 26084 return; 26085 } 26086 26087 window.clearInterval(this._interval); 26088 this._core.leave('rotating'); 26089 }; 26090 26091 /** 26092 * Stops the autoplay. 26093 * @public 26094 */ 26095 Autoplay.prototype.pause = function() { 26096 if (!this._core.is('rotating')) { 26097 return; 26098 } 26099 26100 this._paused = true; 26101 }; 26102 26103 /** 26104 * Destroys the plugin. 26105 */ 26106 Autoplay.prototype.destroy = function() { 26107 var handler, property; 26108 26109 this.stop(); 26110 26111 for (handler in this._handlers) { 26112 this._core.$element.off(handler, this._handlers[handler]); 26113 } 26114 for (property in Object.getOwnPropertyNames(this)) { 26115 typeof this[property] != 'function' && (this[property] = null); 26116 } 26117 }; 26118 26119 $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; 26120 26121})(window.Zepto || window.jQuery, window, document); 26122 26123/** 26124 * Navigation Plugin 26125 * @version 2.0.0-beta.3 26126 * @author Artus Kolanowski 26127 * @license The MIT License (MIT) 26128 */ 26129;(function($, window, document, undefined) { 26130 'use strict'; 26131 26132 /** 26133 * Creates the navigation plugin. 26134 * @class The Navigation Plugin 26135 * @param {Owl} carousel - The Owl Carousel. 26136 */ 26137 var Navigation = function(carousel) { 26138 /** 26139 * Reference to the core. 26140 * @protected 26141 * @type {Owl} 26142 */ 26143 this._core = carousel; 26144 26145 /** 26146 * Indicates whether the plugin is initialized or not. 26147 * @protected 26148 * @type {Boolean} 26149 */ 26150 this._initialized = false;
vendor: 14,134 bytes, lines 26151-26679
26151 26152 /** 26153 * The current paging indexes. 26154 * @protected 26155 * @type {Array} 26156 */ 26157 this._pages = []; 26158 26159 /** 26160 * All DOM elements of the user interface. 26161 * @protected 26162 * @type {Object} 26163 */ 26164 this._controls = {}; 26165 26166 /** 26167 * Markup for an indicator. 26168 * @protected 26169 * @type {Array.<String>} 26170 */ 26171 this._templates = []; 26172 26173 /** 26174 * The carousel element. 26175 * @type {jQuery} 26176 */ 26177 this.$element = this._core.$element; 26178 26179 /** 26180 * Overridden methods of the carousel. 26181 * @protected 26182 * @type {Object} 26183 */ 26184 this._overrides = { 26185 next: this._core.next, 26186 prev: this._core.prev, 26187 to: this._core.to 26188 }; 26189 26190 /** 26191 * All event handlers. 26192 * @protected 26193 * @type {Object} 26194 */ 26195 this._handlers = { 26196 'prepared.owl.carousel': $.proxy(function(e) { 26197 if (e.namespace && this._core.settings.dotsData) { 26198 this._templates.push('<div class="' + this._core.settings.dotClass + '">' + 26199 $(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot') + '</div>'); 26200 } 26201 }, this), 26202 'added.owl.carousel': $.proxy(function(e) { 26203 if (e.namespace && this._core.settings.dotsData) { 26204 this._templates.splice(e.position, 0, this._templates.pop()); 26205 } 26206 }, this), 26207 'remove.owl.carousel': $.proxy(function(e) { 26208 if (e.namespace && this._core.settings.dotsData) { 26209 this._templates.splice(e.position, 1); 26210 } 26211 }, this), 26212 'changed.owl.carousel': $.proxy(function(e) { 26213 if (e.namespace && e.property.name == 'position') { 26214 this.draw(); 26215 } 26216 }, this), 26217 'initialized.owl.carousel': $.proxy(function(e) { 26218 if (e.namespace && !this._initialized) { 26219 this._core.trigger('initialize', null, 'navigation'); 26220 this.initialize(); 26221 this.update(); 26222 this.draw(); 26223 this._initialized = true; 26224 this._core.trigger('initialized', null, 'navigation'); 26225 } 26226 }, this), 26227 'refreshed.owl.carousel': $.proxy(function(e) { 26228 if (e.namespace && this._initialized) { 26229 this._core.trigger('refresh', null, 'navigation'); 26230 this.update(); 26231 this.draw(); 26232 this._core.trigger('refreshed', null, 'navigation'); 26233 } 26234 }, this) 26235 }; 26236 26237 // set default options 26238 this._core.options = $.extend({}, Navigation.Defaults, this._core.options); 26239 26240 // register event handlers 26241 this.$element.on(this._handlers); 26242 }; 26243 26244 /** 26245 * Default options. 26246 * @public 26247 * @todo Rename `slideBy` to `navBy` 26248 */ 26249 Navigation.Defaults = { 26250 nav: false, 26251 navText: [ 'prev', 'next' ], 26252 navSpeed: false, 26253 navElement: 'button type="button"', 26254 navContainer: false, 26255 navContainerClass: 'owl-nav', 26256 navClass: [ 'owl-prev', 'owl-next' ], 26257 slideBy: 1, 26258 dotClass: 'owl-dot', 26259 dotsClass: 'owl-dots', 26260 dots: true, 26261 dotsEach: false, 26262 dotsData: false, 26263 dotsSpeed: false, 26264 dotsContainer: false 26265 }; 26266 26267 /** 26268 * Initializes the layout of the plugin and extends the carousel. 26269 * @protected 26270 */ 26271 Navigation.prototype.initialize = function() { 26272 var override, 26273 settings = this._core.settings; 26274 26275 // create DOM structure for relative navigation 26276 this._controls.$relative = (settings.navContainer ? $(settings.navContainer) 26277 : $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled'); 26278 26279 this._controls.$previous = $('<' + settings.navElement[0] + '>') 26280 .addClass(settings.navClass[0]) 26281 .html(settings.navText[0]) 26282 .prependTo(this._controls.$relative) 26283 .on('click', $.proxy(function(e) { 26284 this.prev(settings.navSpeed); 26285 }, this)); 26286 this._controls.$next = $('<' + settings.navElement[1] + '>') 26287 .addClass(settings.navClass[1]) 26288 .html(settings.navText[1]) 26289 .appendTo(this._controls.$relative) 26290 .on('click', $.proxy(function(e) { 26291 this.next(settings.navSpeed); 26292 }, this)); 26293 26294 // create DOM structure for absolute navigation 26295 if (!settings.dotsData) { 26296 this._templates = [ $('<button>') 26297 .addClass(settings.dotClass) 26298 .append($('<span>')) 26299 .prop('outerHTML') ]; 26300 } 26301 26302 this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer) 26303 : $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled'); 26304 26305 this._controls.$absolute.on('click', 'div, button', $.proxy(function(e) { 26306 var index = $(e.target).parent().is(this._controls.$absolute) 26307 ? $(e.target).index() : $(e.target).parent().index(); 26308 26309 e.preventDefault(); 26310 26311 this.to(index, settings.dotsSpeed); 26312 }, this)); 26313 26314 // override public methods of the carousel 26315 for (override in this._overrides) { 26316 this._core[override] = $.proxy(this[override], this); 26317 } 26318 }; 26319 26320 /** 26321 * Destroys the plugin. 26322 * @protected 26323 */ 26324 Navigation.prototype.destroy = function() { 26325 var handler, control, property, override; 26326 26327 for (handler in this._handlers) { 26328 this.$element.off(handler, this._handlers[handler]); 26329 } 26330 for (control in this._controls) { 26331 this._controls[control].remove(); 26332 } 26333 for (override in this.overides) { 26334 this._core[override] = this._overrides[override]; 26335 } 26336 for (property in Object.getOwnPropertyNames(this)) { 26337 typeof this[property] != 'function' && (this[property] = null); 26338 } 26339 }; 26340 26341 /** 26342 * Updates the internal state. 26343 * @protected 26344 */ 26345 Navigation.prototype.update = function() { 26346 var i, j, k, 26347 lower = this._core.clones().length / 2, 26348 upper = lower + this._core.items().length, 26349 maximum = this._core.maximum(true), 26350 settings = this._core.settings, 26351 size = settings.center || settings.autoWidth || settings.dotsData 26352 ? 1 : settings.dotsEach || settings.items; 26353 26354 if (settings.slideBy !== 'page') { 26355 settings.slideBy = Math.min(settings.slideBy, settings.items); 26356 } 26357 26358 if (settings.dots || settings.slideBy == 'page') { 26359 this._pages = []; 26360 26361 for (i = lower, j = 0, k = 0; i < upper; i++) { 26362 if (j >= size || j === 0) { 26363 this._pages.push({ 26364 start: Math.min(maximum, i - lower), 26365 end: i - lower + size - 1 26366 }); 26367 if (Math.min(maximum, i - lower) === maximum) { 26368 break; 26369 } 26370 j = 0, ++k; 26371 } 26372 j += this._core.mergers(this._core.relative(i)); 26373 } 26374 } 26375 }; 26376 26377 /** 26378 * Draws the user interface. 26379 * @todo The option `dotsData` wont work. 26380 * @protected 26381 */ 26382 Navigation.prototype.draw = function() { 26383 var difference, 26384 settings = this._core.settings, 26385 disabled = this._core.items().length <= settings.items, 26386 index = this._core.relative(this._core.current()), 26387 loop = settings.loop || settings.rewind; 26388 26389 this._controls.$relative.toggleClass('disabled', !settings.nav || disabled); 26390 26391 if (settings.nav) { 26392 this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true)); 26393 this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true)); 26394 } 26395 26396 this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled); 26397 26398 if (settings.dots) { 26399 difference = this._pages.length - this._controls.$absolute.children().length; 26400 26401 if (settings.dotsData && difference !== 0) { 26402 this._controls.$absolute.html(this._templates.join('')); 26403 } else if (difference > 0) { 26404 this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0])); 26405 } else if (difference < 0) { 26406 this._controls.$absolute.children().slice(difference).remove(); 26407 } 26408 26409 this._controls.$absolute.find('.active').removeClass('active'); 26410 this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 26411 } 26412 }; 26413 26414 /** 26415 * Extends event data. 26416 * @protected 26417 * @param {Event} event - The event object which gets thrown. 26418 */ 26419 Navigation.prototype.onTrigger = function(event) { 26420 var settings = this._core.settings; 26421 26422 event.page = { 26423 index: $.inArray(this.current(), this._pages), 26424 count: this._pages.length, 26425 size: settings && (settings.center || settings.autoWidth || settings.dotsData 26426 ? 1 : settings.dotsEach || settings.items) 26427 }; 26428 }; 26429 26430 /** 26431 * Gets the current page position of the carousel. 26432 * @protected 26433 * @returns {Number} 26434 */ 26435 Navigation.prototype.current = function() { 26436 var current = this._core.relative(this._core.current()); 26437 return $.grep(this._pages, $.proxy(function(page, index) { 26438 return page.start <= current && page.end >= current; 26439 }, this)).pop(); 26440 }; 26441 26442 /** 26443 * Gets the current succesor/predecessor position. 26444 * @protected 26445 * @returns {Number} 26446 */ 26447 Navigation.prototype.getPosition = function(successor) { 26448 var position, length, 26449 settings = this._core.settings; 26450 26451 if (settings.slideBy == 'page') { 26452 position = $.inArray(this.current(), this._pages); 26453 length = this._pages.length; 26454 successor ? ++position : --position; 26455 position = this._pages[((position % length) + length) % length].start; 26456 } else { 26457 position = this._core.relative(this._core.current()); 26458 length = this._core.items().length; 26459 successor ? position += settings.slideBy : position -= settings.slideBy; 26460 } 26461 26462 return position; 26463 }; 26464 26465 /** 26466 * Slides to the next item or page. 26467 * @public 26468 * @param {Number} [speed=false] - The time in milliseconds for the transition. 26469 */ 26470 Navigation.prototype.next = function(speed) { 26471 $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); 26472 }; 26473 26474 /** 26475 * Slides to the previous item or page. 26476 * @public 26477 * @param {Number} [speed=false] - The time in milliseconds for the transition. 26478 */ 26479 Navigation.prototype.prev = function(speed) { 26480 $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); 26481 }; 26482 26483 /** 26484 * Slides to the specified item or page. 26485 * @public 26486 * @param {Number} position - The position of the item or page. 26487 * @param {Number} [speed] - The time in milliseconds for the transition. 26488 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 26489 */ 26490 Navigation.prototype.to = function(position, speed, standard) { 26491 var length; 26492 26493 if (!standard) { 26494 length = this._pages.length; 26495 $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); 26496 } else { 26497 $.proxy(this._overrides.to, this._core)(position, speed); 26498 } 26499 }; 26500 26501 $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; 26502 26503})(window.Zepto || window.jQuery, window, document); 26504 26505/** 26506 * Hash Plugin 26507 * @version 2.0.0-beta.3 26508 * @author Artus Kolanowski 26509 * @license The MIT License (MIT) 26510 */ 26511;(function($, window, document, undefined) { 26512 'use strict'; 26513 26514 /** 26515 * Creates the hash plugin. 26516 * @class The Hash Plugin 26517 * @param {Owl} carousel - The Owl Carousel 26518 */ 26519 var Hash = function(carousel) { 26520 /** 26521 * Reference to the core. 26522 * @protected 26523 * @type {Owl} 26524 */ 26525 this._core = carousel; 26526 26527 /** 26528 * Hash index for the items. 26529 * @protected 26530 * @type {Object} 26531 */ 26532 this._hashes = {}; 26533 26534 /** 26535 * The carousel element. 26536 * @type {jQuery} 26537 */ 26538 this.$element = this._core.$element; 26539 26540 /** 26541 * All event handlers. 26542 * @protected 26543 * @type {Object} 26544 */ 26545 this._handlers = { 26546 'initialized.owl.carousel': $.proxy(function(e) { 26547 if (e.namespace && this._core.settings.startPosition === 'URLHash') { 26548 $(window).trigger('hashchange.owl.navigation'); 26549 } 26550 }, this), 26551 'prepared.owl.carousel': $.proxy(function(e) { 26552 if (e.namespace) { 26553 var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash'); 26554 26555 if (!hash) { 26556 return; 26557 } 26558 26559 this._hashes[hash] = e.content; 26560 } 26561 }, this), 26562 'changed.owl.carousel': $.proxy(function(e) { 26563 if (e.namespace && e.property.name === 'position') { 26564 var current = this._core.items(this._core.relative(this._core.current())), 26565 hash = $.map(this._hashes, function(item, hash) { 26566 return item === current ? hash : null; 26567 }).join(); 26568 26569 if (!hash || window.location.hash.slice(1) === hash) { 26570 return; 26571 } 26572 26573 window.location.hash = hash; 26574 } 26575 }, this) 26576 }; 26577 26578 // set default options 26579 this._core.options = $.extend({}, Hash.Defaults, this._core.options); 26580 26581 // register the event handlers 26582 this.$element.on(this._handlers); 26583 26584 // register event listener for hash navigation 26585 /*$(window).on('hashchange.owl.navigation', $.proxy(function(e) { 26586 var hash = window.location.hash.substring(1), 26587 items = this._core.$stage.children(), 26588 position = this._hashes[hash] && items.index(this._hashes[hash]); 26589 26590 if (position === undefined || position === this._core.current()) { 26591 return; 26592 } 26593 26594 this._core.to(this._core.relative(position), false, true); 26595 }, this));*/ 26596 }; 26597 26598 /** 26599 * Default options. 26600 * @public 26601 */ 26602 Hash.Defaults = { 26603 URLhashListener: false 26604 }; 26605 26606 /** 26607 * Destroys the plugin. 26608 * @public 26609 */ 26610 Hash.prototype.destroy = function() { 26611 var handler, property; 26612 26613 $(window).off('hashchange.owl.navigation'); 26614 26615 for (handler in this._handlers) { 26616 this._core.$element.off(handler, this._handlers[handler]); 26617 } 26618 for (property in Object.getOwnPropertyNames(this)) { 26619 typeof this[property] != 'function' && (this[property] = null); 26620 } 26621 }; 26622 26623 $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; 26624 26625})(window.Zepto || window.jQuery, window, document); 26626 26627/** 26628 * Support Plugin 26629 * 26630 * @version 2.0.0-beta.3 26631 * @author Vivid Planet Software GmbH 26632 * @author Artus Kolanowski 26633 * @license The MIT License (MIT) 26634 */ 26635;(function($, window, document, undefined) { 26636 26637 var style = $('<support>').get(0).style, 26638 prefixes = 'Webkit Moz O ms'.split(' '), 26639 events = { 26640 transition: { 26641 end: { 26642 WebkitTransition: 'webkitTransitionEnd', 26643 MozTransition: 'transitionend', 26644 OTransition: 'oTransitionEnd', 26645 transition: 'transitionend' 26646 } 26647 }, 26648 animation: { 26649 end: { 26650 WebkitAnimation: 'webkitAnimationEnd', 26651 MozAnimation: 'animationend', 26652 OAnimation: 'oAnimationEnd', 26653 animation: 'animationend' 26654 } 26655 } 26656 }, 26657 tests = { 26658 csstransforms: function() { 26659 return !!test('transform'); 26660 }, 26661 csstransforms3d: function() { 26662 return !!test('perspective'); 26663 }, 26664 csstransitions: function() { 26665 return !!test('transition'); 26666 }, 26667 cssanimations: function() { 26668 return !!test('animation'); 26669 } 26670 }; 26671 26672 function test(property, prefixed) { 26673 var result = false, 26674 upper = property.charAt(0).toUpperCase() + property.slice(1); 26675 26676 $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) { 26677 if (style[property] !== undefined) { 26678 result = prefixed ? property : true; 26679 return false;
26680 } 26681 }); 26682 26683 return result; 26684 } 26685 26686 function prefixed(property) { 26687 return test(property, true); 26688 } 26689 26690 if (tests.csstransitions()) { 26691 /* jshint -W053 */ 26692 $.support.transition = new String(prefixed('transition')) 26693 $.support.transition.end = events.transition.end[ $.support.transition ]; 26694 } 26695 26696 if (tests.cssanimations()) { 26697 /* jshint -W053 */ 26698 $.support.animation = new String(prefixed('animation')) 26699 $.support.animation.end = events.animation.end[ $.support.animation ]; 26700 } 26701 26702 if (tests.csstransforms()) { 26703 /* jshint -W053 */ 26704 $.support.transform = new String(prefixed('transform')); 26705 $.support.transform3d = tests.csstransforms3d(); 26706 } 26707 26708})(window.Zepto || window.jQuery, window, document); 26709 26710(function(window, document, undefined) { 26711 26712 /** 26713 * Find the absolute position of an element 26714 */ 26715 var absPos = function(element) { 26716 var offsetLeft, offsetTop; 26717 offsetLeft = offsetTop = 0; 26718 if (element.offsetParent) { 26719 do { 26720 offsetLeft += element.offsetLeft; 26721 offsetTop += element.offsetTop; 26722 } while (element = element.offsetParent); 26723 } 26724 return [offsetLeft, offsetTop]; 26725 }; 26726 26727 /** 26728 * @constructor Progress Circle class 26729 * @param params.canvas Canvas on which the circles will be drawn. 26730 * @param params.minRadius Inner radius of the innermost circle, in px. 26731 * @param params.arcWidth Width of each circle(to be more accurate, ring). 26732 * @param params.gapWidth Space between each circle. 26733 * @param params.centerX X coordinate of the center of circles. 26734 * @param params.centerY Y coordinate of the center of circles. 26735 * @param params.infoLineBaseAngle Base angle of the info line. 26736 * @param params.infoLineAngleInterval Angles between the info lines. 26737 */ 26738 var ProgressCircle = function(params) { 26739 this.canvas = params.canvas; 26740 this.minRadius = params.minRadius || 15; 26741 this.arcWidth = params.arcWidth || 5; 26742 this.gapWidth = params.gapWidth || 3; 26743 this.centerX = params.centerX || this.canvas.width / 2; 26744 this.centerY = params.centerY || this.canvas.height / 2;
26745 this.infoLineLength = params.infoLineLength || 60; 26746 this.horizLineLength = params.horizLineLength || 10; 26747 this.infoLineAngleInterval = params.infoLineAngleInterval || Math.PI / 8; 26748 this.infoLineBaseAngle = params.infoLineBaseAngle || Math.PI / 6; 26749 26750 this.context = this.canvas.getContext('2d'); 26751 26752 this.width = this.canvas.width; 26753 this.height = this.canvas.height; 26754 26755 this.circles = []; 26756 this.runningCount = 0; 26757 }; 26758 26759 ProgressCircle.prototype = { 26760 constructor: ProgressCircle, 26761 26762 /** 26763 * @method Adds an progress monitor entry. 26764 * @param params.fillColor Color to fill in the circle. 26765 * @param params.outlineColor Color to outline the circle. 26766 * @param params.progressListener Callback function to fetch the progress. 26767 * @param params.infoListener Callback function to fetch the info. 26768 * @returns this 26769 */ 26770 addEntry: function(params) { 26771 this.circles.push(new Circle({ 26772 canvas: this.canvas, 26773 context: this.context, 26774 centerX: this.centerX, 26775 centerY: this.centerY, 26776 innerRadius: this.minRadius + this.circles.length * 26777 (this.gapWidth + this.arcWidth), 26778 arcWidth: this.arcWidth,
26779 infoLineLength: this.infoLineLength, 26780 horizLineLength: this.horizLineLength, 26781 26782 id: this.circles.length, 26783 fillColor: params.fillColor, 26784 outlineColor: params.outlineColor, 26785 progressListener: params.progressListener, 26786 infoListener: params.infoListener, 26787 infoLineAngle: this.infoLineBaseAngle + 26788 this.circles.length * this.infoLineAngleInterval, 26789 })); 26790 26791 return this; 26792 }, 26793 26794 /** 26795 * @method Starts the monitor and updates with the given interval. 26796 * @param interval Interval between updates, in millisecond. 26797 * @returns this 26798 */ 26799 start: function(interval) { 26800 var self = this; 26801 this.timer = setInterval(function() { 26802 self._update(); 26803 }, interval || 33); 26804 26805 return this; 26806 }, 26807 26808 /** 26809 * @method Stop the animation. 26810 */ 26811 stop: function() { 26812 clearTimeout(this.timer); 26813 }, 26814 26815 /** 26816 * @private 26817 * @method Call update on each circle and redraw them. 26818 * @returns this 26819 */ 26820 _update: function() { 26821 this._clear(); 26822 this.circles.forEach(function(circle, idx, array) { 26823 circle.update(); 26824 }); 26825 26826 return this; 26827 }, 26828 26829 /** 26830 * @private 26831 * @method Clear the canvas. 26832 * @returns this 26833 */ 26834 _clear: function() { 26835 this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); 26836 26837 return this; 26838 }, 26839 26840 }; 26841 26842 /** 26843 * @private 26844 * @class Individual progress circle. 26845 * @param params.canvas Canvas on which the circle will be drawn. 26846 * @param params.context Context of the canvas. 26847 * @param params.innerRadius Inner radius of the circle, in px. 26848 * @param params.arcWidth Width of each arc(circle). 26849 * @param params.gapWidth Distance between each arc. 26850 * @param params.centerX X coordinate of the center of circles. 26851 * @param params.centerY Y coordinate of the center of circles. 26852 * @param params.fillColor Color to fill in the circle. 26853 * @param params.outlineColor Color to outline the circle. 26854 * @param params.progressListener Callback function to fetch the progress. 26855 * @param params.infoListener Callback function to fetch the info. 26856 * @param params.infoLineAngle Angle of info line. 26857 */ 26858 var Circle = function(params) { 26859 this.id = params.id; 26860 this.canvas = params.canvas; 26861 this.context = params.context; 26862 this.centerX = params.centerX; 26863 this.centerY = params.centerY; 26864 this.arcWidth = params.arcWidth; 26865 this.innerRadius = params.innerRadius || 0; 26866 this.fillColor = params.fillColor || '#fff'; 26867 this.outlineColor = params.outlineColor || this.fillColor; 26868 this.progressListener = params.progressListener;
26869 this.infoLineLength = params.infoLineLength || 250; 26870 this.horizLineLength = params.horizLineLength || 50; 26871 this.infoListener = params.infoListener; 26872 this.infoLineAngle = params.infoLineAngle; 26873 26874 this.outerRadius = this.innerRadius + this.arcWidth; 26875 26876 // If the info listener is not registered, then don't calculate 26877 // the related coordinates 26878 if (!this.infoListener) return; 26879 26880 // calculate the info-line turning points 26881 var angle = this.infoLineAngle, 26882 arcDistance = (this.innerRadius + this.outerRadius) / 2, 26883 26884 sinA = Math.sin(angle), 26885 cosA = Math.cos(angle); 26886 26887 this.infoLineStartX = this.centerX + sinA * arcDistance; 26888 this.infoLineStartY = this.centerY - cosA * arcDistance; 26889 26890 this.infoLineMidX = this.centerX + sinA * this.infoLineLength; 26891 this.infoLineMidY = this.centerY - cosA * this.infoLineLength; 26892 26893 this.infoLineEndX = this.infoLineMidX + 26894 (sinA < 0 ? -this.horizLineLength : this.horizLineLength); 26895 this.infoLineEndY = this.infoLineMidY; 26896 26897 var infoText = document.createElement('div'), 26898 style = infoText.style; 26899 26900 style.color = this.fillColor; 26901 style.position = 'absolute'; 26902 style.left = this.infoLineEndX + absPos(this.canvas)[0] + 'px'; 26903 // style.top will be calculated in the `drawInfo` method. Since 26904 // user may want to change the size of the font, so the top offset 26905 // must be updated in each loop. 26906 infoText.className = 'ProgressCircleInfo'; // For css styling 26907 infoText.id = 'progress_circle_info_' + this.id; 26908 document.body.appendChild(infoText); 26909 this.infoText = infoText; 26910 }; 26911 26912 Circle.prototype = { 26913 constructor: Circle, 26914 26915 update: function() { 26916 this.progress = this.progressListener(); 26917 this._draw(); 26918 26919 if (this.infoListener) { 26920 this.info = this.infoListener(); 26921 this._drawInfo(); 26922 } 26923 }, 26924 26925 /** 26926 * @private 26927 * @method Draw the circle on the canvas. 26928 * @returns this 26929 */ 26930 _draw: function() { 26931 var ctx = this.context, 26932 26933 ANGLE_OFFSET = -Math.PI / 2, 26934 26935 startAngle = 0 + ANGLE_OFFSET, 26936 endAngle= startAngle + this.progress * Math.PI * 2, 26937 26938 x = this.centerX, 26939 y = this.centerY, 26940 26941 innerRadius = this.innerRadius - this.arcWidth - 1, 26942 outerRadius = this.outerRadius - this.arcWidth - 1; 26943 26944 if ( innerRadius < 0 ) 26945 return; 26946 26947 ctx.fillStyle = this.fillColor; 26948 ctx.strokeStyle = this.outlineColor; 26949 26950 ctx.beginPath(); 26951 ctx.arc(x, y, innerRadius, startAngle, endAngle, false); 26952 ctx.arc(x, y, outerRadius, endAngle, startAngle, true); 26953 ctx.closePath(); 26954 ctx.stroke(); 26955 ctx.fill(); 26956 26957 return this; 26958 }, 26959 26960 /** 26961 * @private 26962 * @method Draw the info lines and info text. 26963 * @returns this 26964 */ 26965 _drawInfo: function() { 26966 26967 var pointList, lineHeight; 26968 26969 pointList = [ 26970 [this.infoLineStartX, this.infoLineStartY], 26971 [this.infoLineMidX, this.infoLineMidY], 26972 [this.infoLineEndX, this.infoLineEndY], 26973 ]; 26974 this._drawSegments(pointList, false); 26975 26976 this.infoText.innerHTML = this.info; 26977 26978 lineHeight = this.infoText.offsetHeight; 26979 this.infoText.style.top = this.infoLineEndY + 26980 absPos(this.canvas)[1] - lineHeight / 2 + 'px'; 26981 26982 return this; 26983 }, 26984 26985 /** 26986 * @private 26987 * @method Helper function to draw the segments 26988 * @param pointList An array of points in the form of [x, y]. 26989 * @param close Whether to connect the first and last point. 26990 */ 26991 _drawSegments: function(pointList, close) { 26992 var ctx = this.context; 26993 26994 ctx.beginPath(); 26995 ctx.moveTo(pointList[0][0], pointList[0][1]); 26996 for (var i = 1; i < pointList.length; ++i) { 26997 ctx.lineTo(pointList[i][0], pointList[i][1]); 26998 } 26999 27000 if (close) { 27001 ctx.closePath(); 27002 } 27003 ctx.stroke(); 27004 }, 27005 }; 27006 27007 window.ProgressCircle = ProgressCircle; 27008 27009})(window, document); 27010 27011 27012 27013 27014/* ========================================================= 27015 * jquery.vc_chart.js v1.0 27016 * ========================================================= 27017 * Copyright 2013 Wpbakery 27018 * 27019 * Jquery chart plugin for the Visual Composer. 27020 * ========================================================= */ 27021(function($){ 27022 /** 27023 * Pie chart animated. 27024 * @param element - DOM element 27025 * @param options - settings object. 27026 * @constructor 27027 */ 27028 var VcChart = function(element, options) { 27029 this.el = element; 27030 this.$el = $(this.el); 27031 var $this = this; 27032 $this.options = $.extend({ 27033 color: 'wpb_button', 27034 units: '', 27035 width: '', 27036 label_selector: '.vc_pie_chart_value', 27037 back_selector: '.vc_pie_chart_back', 27038 responsive: true 27039 }, options); 27040 $this.init(); 27041 }; 27042 VcChart.prototype = { 27043 constructor: VcChart, 27044 _progress_v: 0, 27045 animated: false, 27046 colors: { 27047 'wpb_button': 'rgba(247, 247, 247, 1)', 27048 'btn-primary': 'rgba(0, 136, 204, 1)', 27049 'btn-info': 'rgba(88, 185, 218, 1)', 27050 'btn-success': 'rgba(106, 177, 101, 1)', 27051 'btn-warning': 'rgba(255, 153, 0, 1)', 27052 'btn-danger': 'rgba(255, 103, 91, 1)', 27053 'btn-inverse': 'rgba(85, 85, 85, 1)' 27054 }, 27055 init: function() { 27056 this.setupColor(); 27057 this.value = this.$el.data('pie-value')/100; 27058 this.label_value = this.$el.data('pie-label-value') || this.$el.data('pie-value'); 27059 this.$wrapper = $('.vc_pie_wrapper', this.$el); 27060 this.$label = $(this.options.label_selector, this.$el); 27061 this.$back = $(this.options.back_selector, this.$el); 27062 this.$canvas = this.$el.find('canvas'); 27063 this.arcWidth = this.$el.data('pie-width') * 2; 27064 this.draw(); 27065 this.setWayPoint(); 27066 if(this.options.responsive === true) this.setResponsive(); 27067 if (UNCODE.isMobile) this._progress_v = this.value; 27068 }, 27069 setupColor: function() { 27070 // if(typeof this.colors[this.options.color] !== 'undefined') { 27071 // this.color = this.colors[this.options.color]; 27072 // } else if(typeof this.options.color === 'string' && this.options.color.match(/^rgba?\([^\)]+\)/)) { 27073 // this.color = this.options.color; 27074 // } else { 27075 // this.color = 'rgba(247, 247, 247, 0.2)'; 27076 // } 27077 if(typeof this.options.color !== 'undefined') { 27078 this.color = this.options.color; 27079 } else this.color = 'rgba(247, 247, 247, 0.2)'; 27080 27081 }, 27082 setResponsive: function() { 27083 var that = this; 27084 if (!UNCODE.isMobile) { 27085 $(window).resize(function(){ 27086 if(that.animated === true) that.circle.stop(); 27087 that.draw(true); 27088 }); 27089 } 27090 }, 27091 draw: function(redraw) { 27092 var w = this.$el.addClass('vc_ready').width() * 2, 27093 border_w = this.arcWidth, 27094 radius; 27095 if(!w) w = this.$el.parents(':visible').first().width()-2; 27096 //w = Math.round(w/100*80); 27097 //if (w < 250) w = 250; 27098 radius = w/2; 27099 this.$wrapper.css({"width" : (w / 2) + "px"}); 27100 this.$label.css({"width" : (w / 2), "height" : (w / 2), "line-height" : (w / 2)+"px"}); 27101 this.$back.css({"width" : (w / 2), "height" : (w / 2)}); 27102 this.$canvas.attr({"width" : w + "px", "height" : w + "px"}); 27103 this.$el.addClass('vc_ready'); 27104 this.circle = new ProgressCircle({ 27105 canvas: this.$canvas.get(0), 27106 minRadius: radius, 27107 arcWidth: border_w 27108 }); 27109 if(redraw === true && this.animated === true) { 27110 this._progress_v = this.value; 27111 this.circle.addEntry({ 27112 fillColor: this.color, 27113 progressListener: $.proxy(this.setProgress, this) 27114 }).start(); 27115 } 27116 }, 27117 setProgress: function() { 27118 if (this._progress_v >= this.value) { 27119 this.circle.stop(); 27120 this.animated = true; 27121 this.$label.html(this.label_value + this.options.units); 27122 return this._progress_v; 27123 } 27124 this._progress_v += 0.01; 27125 if (!isNaN(this.label_value)) { 27126 var label_value = this._progress_v/this.value*this.label_value; 27127 var val = Math.round(label_value) + this.options.units; 27128 this.$label.html(val); 27129 } else this.$label.html(this.label_value + this.options.units); 27130 return this._progress_v; 27131 }, 27132 animate: function() { 27133 if(this.animated !== true) { 27134 this.circle.addEntry({ 27135 fillColor: this.color, 27136 progressListener: $.proxy(this.setProgress, this) 27137 }).start(10); 27138 } 27139 }, 27140 setWayPoint: function() { 27141 if (typeof $.fn.waypoint !== 'undefined' && !UNCODE.isMobile) { 27142 this.$el.waypoint($.proxy(this.animate, this), { offset: '85%' }); 27143 } else { 27144 this.animate(); 27145 } 27146 } 27147 }; 27148 /** 27149 * jQuery plugin 27150 * @param option - object with settings 27151 * @return {*} 27152 */ 27153 $.fn.vcChat = function(option, value) { 27154 return this.each(function () { 27155 var $this = $(this), 27156 data = $this.data('vc_chart'), 27157 options = typeof option === 'object' ? option : { 27158 color: $this.data('pie-color'), 27159 units: $this.data('pie-units') 27160 }; 27161 if (typeof option == 'undefined') $this.data('vc_chart', (data = new VcChart(this, options))); 27162 if (typeof option == 'string') data[option](value); 27163 }); 27164 }; 27165 /** 27166 * Allows users to rewrite function inside theme. 27167 */ 27168 if ( typeof window['vc_pieChart'] !== 'function' ) { 27169 window.vc_pieChart = function() { 27170 $('.vc_pie_chart:visible:not(.vc_ready)').vcChat(); 27171 } 27172 } 27173 $(document).ready(function(){ 27174 !window.vc_iframe && vc_pieChart(); 27175 27176 /** 27177 * Tab and collapse integration. 27178 */ 27179 $('.nav-tabs a').on('shown.bs.tab', function(e){ 27180 var $cont = $(e.target).closest('.tab-container'), 27181 $active = $('.tab-pane.active', $cont); 27182 $('.vc_pie_chart:not(.vc_ready)', $active).vcChat(); 27183 }); 27184 27185 $('.panel-collapse').on('shown.bs.collapse', function (e) { 27186 $('.vc_pie_chart:not(.vc_ready)', e.target).vcChat(); 27187 }) 27188 }); 27189 27190})(window.jQuery); 27191 27192/* Progress bar 27193 ---------------------------------------------------------- */ 27194function uncode_progress_bar() { 27195 jQuery.each(jQuery('.vc_progress_bar'), function(index, val) { 27196 if (UNCODE.isUnmodalOpen && !val.closest('#unmodal-content')) { 27197 return; 27198 } 27199 if (!UNCODE.isMobile) { 27200 new Waypoint({ 27201 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 27202 element: val, 27203 handler: function() { 27204 var element = jQuery(this.element); 27205 element.find('.vc_single_bar').each(function(index) { 27206 var $this = jQuery(this), 27207 bar = $this.find('.vc_bar'), 27208 val = bar.data('percentage-value'); 27209 setTimeout(function() { 27210 bar.css({ 27211 "width": val + '%' 27212 }); 27213 }, index * 200); 27214 }); 27215 }, 27216 offset: '80%' 27217 }); 27218 } else { 27219 var element = jQuery(val); 27220 element.find('.vc_single_bar').each(function(index) { 27221 var $this = jQuery(this), 27222 bar = $this.find('.vc_bar'), 27223 val = bar.data('percentage-value'); 27224 setTimeout(function() { 27225 bar.css({ 27226 "width": val + '%' 27227 }); 27228 }, index * 200); 27229 }); 27230 } 27231 }); 27232}; 27233uncode_progress_bar(); 27234 27235/*! 27236 * jquery.counterup.js 1.0 27237 * 27238 * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal 27239 * Released under the GPL v2 License 27240 * 27241 * Date: Nov 26, 2013 27242 */ 27243(function($) { 27244 "use strict"; 27245 $.fn.counterUp = function(options) { 27246 // Defaults 27247 var settings = $.extend({ 27248 'time': 400, 27249 'delay': 10 27250 }, options); 27251 return this.each(function() { 27252 // Store the object 27253 var $this = $(this); 27254 var $settings = settings; 27255 var counterUpper = function() { 27256 var nums = []; 27257 var divisions = $settings.time / $settings.delay; 27258 var numReal = $this.attr('data-val'), 27259 num = numReal; 27260 var isComma = /[0-9]+,[0-9]+/.test(num); 27261 num = num.replace(/,/g, ''); 27262 var isInt = /^[0-9]+$/.test(num); 27263 var isFloat = /^[0-9]+\.[0-9]+$/.test(num); 27264 var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0; 27265 // Generate list of incremental numbers to display 27266 for (var i = divisions; i >= 1; i--) { 27267 // Preserve as int if input was int 27268 var newNum = parseInt(num / divisions * i); 27269 // Preserve float if input was float 27270 if (isFloat) { 27271 newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces); 27272 } 27273 // Preserve commas if input had commas 27274 if (isComma) { 27275 while (/(\d+)(\d{3})/.test(newNum.toString())) { 27276 newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2'); 27277 } 27278 } 27279 nums.unshift(newNum); 27280 } 27281 nums.push(numReal); 27282 $this.data('counterup-nums', nums); 27283 $this.text('0'); 27284 // Updates the number until we're done 27285 var f = function() { 27286 if ($this.data('counterup-nums') != null) { 27287 $this.text($this.data('counterup-nums').shift()); 27288 if ($this.data('counterup-nums').length) { 27289 setTimeout($this.data('counterup-func'), $settings.delay); 27290 } else { 27291 delete $this.data('counterup-nums'); 27292 $this.data('counterup-nums', null); 27293 $this.data('counterup-func', null); 27294 } 27295 } 27296 }; 27297 $this.data('counterup-func', f); 27298 // Start the count up 27299 setTimeout($this.data('counterup-func'), $settings.delay); 27300 }; 27301 // Perform counts when the element gets into view 27302 new Waypoint({ 27303 context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window, 27304 element: this, 27305 handler: function() { 27306 counterUpper(); 27307 if (!UNCODE.isUnmodalOpen) { 27308 this.destroy(); 27309 } 27310 }, 27311 offset: '100%' 27312 }); 27313 }); 27314 }; 27315})(jQuery); 27316 27317/*! 27318 * The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/) 27319 * Copyright (c) 2016 Edson Hilios 27320 * 27321 * Permission is hereby granted, free of charge, to any person obtaining a copy of 27322 * this software and associated documentation files (the "Software"), to deal in 27323 * the Software without restriction, including without limitation the rights to 27324 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 27325 * the Software, and to permit persons to whom the Software is furnished to do so, 27326 * subject to the following conditions: 27327 * 27328 * The above copyright notice and this permission notice shall be included in all 27329 * copies or substantial portions of the Software. 27330 * 27331 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27332 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 27333 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 27334 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 27335 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 27336 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27337 */ 27338(function(factory) { 27339 "use strict"; 27340 if (typeof define === "function" && define.amd) { 27341 define([ "jquery" ], factory); 27342 } else { 27343 factory(jQuery); 27344 } 27345})(function($) { 27346 "use strict"; 27347 var instances = [], matchers = [], defaultOptions = { 27348 precision: 100, 27349 elapse: false, 27350 defer: false 27351 }; 27352 matchers.push(/^[0-9]*$/.source); 27353 matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 27354 matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 27355 matchers = new RegExp(matchers.join("|")); 27356 function parseDateString(dateString) { 27357 if (dateString instanceof Date) { 27358 return dateString; 27359 } 27360 if (String(dateString).match(matchers)) { 27361 if (String(dateString).match(/^[0-9]*$/)) { 27362 dateString = Number(dateString); 27363 } 27364 if (String(dateString).match(/\-/)) { 27365 dateString = String(dateString).replace(/\-/g, "/"); 27366 } 27367 return new Date(dateString); 27368 } else { 27369 throw new Error("Couldn't cast `" + dateString + "` to a date object."); 27370 } 27371 } 27372 var DIRECTIVE_KEY_MAP = { 27373 Y: "years", 27374 m: "months", 27375 n: "daysToMonth", 27376 d: "daysToWeek", 27377 w: "weeks", 27378 W: "weeksToMonth", 27379 H: "hours", 27380 M: "minutes", 27381 S: "seconds", 27382 D: "totalDays", 27383 I: "totalHours", 27384 N: "totalMinutes", 27385 T: "totalSeconds" 27386 }; 27387 function escapedRegExp(str) { 27388 var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); 27389 return new RegExp(sanitize); 27390 } 27391 function strftime(offsetObject) { 27392 return function(format) { 27393 var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi); 27394 if (directives) { 27395 for (var i = 0, len = directives.length; i < len; ++i) { 27396 var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null; 27397 directive = directive[2]; 27398 if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) { 27399 value = DIRECTIVE_KEY_MAP[directive]; 27400 value = Number(offsetObject[value]); 27401 } 27402 if (value !== null) { 27403 if (modifier === "!") { 27404 value = pluralize(plural, value); 27405 } 27406 if (modifier === "") { 27407 if (value < 10) { 27408 value = "0" + value.toString(); 27409 } 27410 } 27411 format = format.replace(regexp, value.toString()); 27412 } 27413 } 27414 } 27415 format = format.replace(/%%/, "%"); 27416 return format; 27417 }; 27418 } 27419 function pluralize(format, count) { 27420 var plural = "s", singular = ""; 27421 if (format) { 27422 format = format.rep
vendor: 8,618 bytes, lines 27422-27566
27422lace(/(:|;|\s)/gi, "").split(/\,/); 27423 if (format.length === 1) { 27424 plural = format[0]; 27425 } else { 27426 singular = format[0]; 27427 plural = format[1]; 27428 } 27429 } 27430 if (Math.abs(count) > 1) { 27431 return plural; 27432 } else { 27433 return singular; 27434 } 27435 } 27436 var Countdown = function(el, finalDate, options) { 27437 this.el = el; 27438 this.$el = $(el); 27439 this.interval = null; 27440 this.offset = {}; 27441 this.options = $.extend({}, defaultOptions); 27442 this.instanceNumber = instances.length; 27443 instances.push(this); 27444 this.$el.data("countdown-instance", this.instanceNumber); 27445 if (options) { 27446 if (typeof options === "function") { 27447 this.$el.on("update.countdown", options); 27448 this.$el.on("stoped.countdown", options); 27449 this.$el.on("finish.countdown", options); 27450 } else { 27451 this.options = $.extend({}, defaultOptions, options); 27452 } 27453 } 27454 this.setFinalDate(finalDate); 27455 if (this.options.defer === false) { 27456 this.start(); 27457 } 27458 }; 27459 $.extend(Countdown.prototype, { 27460 start: function() { 27461 if (this.interval !== null) { 27462 clearInterval(this.interval); 27463 } 27464 var self = this; 27465 this.update(); 27466 this.interval = setInterval(function() { 27467 self.update.call(self); 27468 }, this.options.precision); 27469 }, 27470 stop: function() { 27471 clearInterval(this.interval); 27472 this.interval = null; 27473 this.dispatchEvent("stoped"); 27474 }, 27475 toggle: function() { 27476 if (this.interval) { 27477 this.stop(); 27478 } else { 27479 this.start(); 27480 } 27481 }, 27482 pause: function() { 27483 this.stop(); 27484 }, 27485 resume: function() { 27486 this.start(); 27487 }, 27488 remove: function() { 27489 this.stop.call(this); 27490 instances[this.instanceNumber] = null; 27491 delete this.$el.data().countdownInstance; 27492 }, 27493 setFinalDate: function(value) { 27494 this.finalDate = parseDateString(value); 27495 }, 27496 update: function() { 27497 if (this.$el.closest("html").length === 0) { 27498 this.remove(); 27499 return; 27500 } 27501 var hasEventsAttached = $._data(this.el, "events") !== undefined, now = new Date(), newTotalSecsLeft; 27502 newTotalSecsLeft = this.finalDate.getTime() - now.getTime(); 27503 newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3); 27504 newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft); 27505 if (this.totalSecsLeft === newTotalSecsLeft || !hasEventsAttached) { 27506 return; 27507 } else { 27508 this.totalSecsLeft = newTotalSecsLeft; 27509 } 27510 this.elapsed = now >= this.finalDate; 27511 this.offset = { 27512 seconds: this.totalSecsLeft % 60, 27513 minutes: Math.floor(this.totalSecsLeft / 60) % 60, 27514 hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24, 27515 days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 27516 daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 27517 daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368), 27518 weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7), 27519 weeksToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7) % 4, 27520 months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368), 27521 years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()), 27522 totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24), 27523 totalHours: Math.floor(this.totalSecsLeft / 60 / 60), 27524 totalMinutes: Math.floor(this.totalSecsLeft / 60), 27525 totalSeconds: this.totalSecsLeft 27526 }; 27527 if (!this.options.elapse && this.totalSecsLeft === 0) { 27528 this.stop(); 27529 this.dispatchEvent("finish"); 27530 } else { 27531 this.dispatchEvent("update"); 27532 } 27533 }, 27534 dispatchEvent: function(eventName) { 27535 var event = $.Event(eventName + ".countdown"); 27536 event.finalDate = this.finalDate; 27537 event.elapsed = this.elapsed; 27538 event.offset = $.extend({}, this.offset); 27539 event.strftime = strftime(this.offset); 27540 this.$el.trigger(event); 27541 } 27542 }); 27543 $.fn.countdown = function() { 27544 var argumentsArray = Array.prototype.slice.call(arguments, 0); 27545 return this.each(function() { 27546 var instanceNumber = $(this).data("countdown-instance"); 27547 if (instanceNumber !== undefined) { 27548 var instance = instances[instanceNumber], method = argumentsArray[0]; 27549 if (Countdown.prototype.hasOwnProperty(method)) { 27550 instance[method].apply(instance, argumentsArray.slice(1)); 27551 } else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) { 27552 instance.setFinalDate.call(instance, method); 27553 instance.start(); 27554 } else { 27555 $.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method)); 27556 } 27557 } else { 27558 new Countdown(this, argumentsArray[0], argumentsArray[1]); 27559 } 27560 }); 27561 }; 27562}); 27563 27564!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; 27565function getStyles(config){ 27566 // 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;
27566left: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+"}" 27567}; 27568 var ShareUtils; 27569 27570if ((!("classList" in document.documentElement)) && Object.defineProperty && typeof HTMLElement !== "undefined") { 27571 Object.defineProperty(HTMLElement.prototype, "classList", { 27572 get: function() { 27573 var ret, self, update; 27574 update = function(fn) { 27575 return function(value) { 27576 var classes, index; 27577 classes = self.className.split(/\s+/); 27578 index = classes.indexOf(value); 27579 fn(classes, index, value); 27580 self.className = classes.join(" "); 27581 }; 27582 }; 27583 self = this; 27584 ret = { 27585 add: update(function(classes, index, value) { 27586 ~index || classes.push(value); 27587 }), 27588 remove: update(function(classes, index) { 27589 ~index && classes.splice(index, 1); 27590 }), 27591 toggle: update(function(classes, index, value) { 27592 if (~index) { 27593 classes.splice(index, 1); 27594 } else { 27595 classes.push(value); 27596 } 27597 }), 27598 contains: function(value) { 27599 return !!~self.className.split(/\s+/).indexOf(value); 27600 }, 27601 item: function(i) { 27602 return self.className.split(/\s+/)[i] || null; 27603 } 27604 }; 27605 Object.defineProperty(ret, "length", { 27606 get: function() { 27607 return self.className.split(/\s+/).length; 27608 } 27609 }); 27610 return ret; 27611 } 27612 }); 27613} 27614 27615String.prototype.to_rfc3986 = function() { 27616 var tmp; 27617 tmp = encodeURIComponent(this); 27618 return tmp.replace(/[!'()*]/g, function(c) { 27619 return "%" + c.charCodeAt(0).toString(16); 27620 }); 27621}; 27622 27623ShareUtils = (function() { 27624 function ShareUtils() {} 27625 27626 ShareUtils.prototype.extend = function(to, from, overwrite) { 27627 var hasProp, prop; 27628 for (prop in from) { 27629 hasProp = to[prop] !== undefined; 27630 if (hasProp && typeof from[prop] === "object") { 27631 this.extend(to[prop], from[prop], overwrite); 27632 } else { 27633 if (overwrite || !hasProp) { 27634 to[prop] = from[prop]; 27635 } 27636 } 27637 } 27638 }; 27639 27640 ShareUtils.prototype.hide = function(el) { 27641 return el.style.display = "none"; 27642 }; 27643 27644 ShareUtils.prototype.show = function(el) { 27645 return el.style.display = "block"; 27646 }; 27647 27648 ShareUtils.prototype.has_class = function(el, class_name) { 27649 return el.classList.contains(class_name); 27650 }; 27651 27652 ShareUtils.prototype.add_class = function(el, class_name) { 27653 return el.classList.add(class_name); 27654 }; 27655 27656 ShareUtils.prototype.remove_class = function(el, class_name) { 27657 return el.classList.remove(class_name); 27658 }; 27659 27660 ShareUtils.prototype.is_encoded = function(str) { 27661 str = str.to_rfc3986(); 27662 return decodeURIComponent(str) !== str; 27663 }; 27664 27665 ShareUtils.prototype.encode = function(str) { 27666 if (typeof str === "undefined" || this.is_encoded(str)) { 27667 return str; 27668 } else { 27669 return str.to_rfc3986(); 27670 } 27671 }; 27672 27673 ShareUtils.prototype.popup = function(url, params) { 27674 var k, popup, qs, v; 27675 if (params == null) { 27676 params = {}; 27677 } 27678 popup = { 27679 width: 500, 27680 height: 350 27681 }; 27682 popup.top = (screen.height / 2) - (popup.height / 2); 27683 popup.left = (screen.width / 2) - (popup.width / 2); 27684 qs = ((function() { 27685 var _results; 27686 _results = []; 27687 for (k in params) { 27688 v = params[k]; 27689 _results.push("" + k + "=" + (this.encode(v))); 27690 } 27691 return _results; 27692 }).call(this)).join('&'); 27693 if (qs) { 27694 qs = "?" + qs; 27695 } 27696 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="
27696+ popup.width + ",height=" + popup.height); 27697 }; 27698 27699 return ShareUtils; 27700 27701})(); 27702var Share, 27703 __hasProp = {}.hasOwnProperty, 27704 __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; }; 27705 27706Share = (function(_super) { 27707 __extends(Share, _super); 27708 27709 function Share(element, options) { 27710 this.element = element; 27711 this.el = { 27712 head: document.getElementsByTagName('head')[0], 27713 body: document.getElementsByTagName('body')[0] 27714 }; 27715 this.config = { 27716 enabled_networks: 0, 27717 protocol: ['http', 'https'].indexOf(window.location.href.split(':')[0]) === -1 ? 'https://' : '//', 27718 url: window.location.href.replace("&", "%26"), 27719 caption: null, 27720 title: this.default_title(), 27721 image: this.default_image(), 27722 description: this.default_description(), 27723 ui: { 27724 flyout: 'top center', 27725 button_text: 'Share', 27726 button_font: true, 27727 icon_font: true 27728 }, 27729 networks: { 27730 twitter: { 27731 enabled: true, 27732 url: null, 27733 title: null, 27734 description: null 27735 }, 27736 facebook: { 27737 enabled: true, 27738 load_sdk: true, 27739 url: null, 27740 app_id: null, 27741 title: null, 27742 caption: null, 27743 description: null, 27744 image: null 27745 }, 27746 threads: { 27747 enabled: true, 27748 url: null, 27749 title: null, 27750 description: null 27751 }, 27752 bluesky: { 27753 enabled: true, 27754 url: null, 27755 title: null, 27756 description: null 27757 }, 27758 pinterest: { 27759 enabled: true, 27760 url: null, 27761 image: null, 27762 description: null 27763 }, 27764 reddit: { 27765 enabled: true, 27766 url: null, 27767 title: null 27768 }, 27769 linkedin: { 27770 enabled: true, 27771 url: null, 27772 title: null, 27773 description: null 27774 }, 27775 xing: { 27776 enabled: true, 27777 url: null, 27778 title: null, 27779 image: null, 27780 description: null 27781 }, 27782 whatsapp: { 27783 enabled: true, 27784 title: null, 27785 url: null 27786 }, 27787 email: { 27788 enabled: true, 27789 title: null, 27790 description: null, 27791 url: null 27792 } 27793 } 27794 }; 27795 this.setup(element, options); 27796 return this; 27797 } 27798 27799 Share.prototype.setup = function(element, opts) { 27800 var index, instance, instances, _i, _len; 27801 instances = document.querySelectorAll(element); 27802 this.extend(this.config, opts, true); 27803 this.set_global_configuration(); 27804 this.normalize_network_configuration(); 27805 if (this.config.ui.icon_font) { 27806 this.inject_icons(); 27807 } 27808 if (this.config.ui.button_font) { 27809 this.inject_fonts(); 27810 } 27811 if (this.config.networks.facebook.enabled && this.config.networks.facebook.load_sdk) { 27812 this.inject_facebook_sdk(); 27813 } 27814 for (index = _i = 0, _len = instances.length; _i < _len; index = ++_i) { 27815 instance = instances[index]; 27816 this.setup_instance(element, index); 27817 } 27818 }; 27819 27820 Share.prototype.setup_instance = function(element, index) { 27821 var button, instance, label, network, networks, _i, _len, _results, 27822 _this = this; 27823 instance = document.querySelectorAll(element)[index]; 27824 this.hide(instance); 27825 this.add_class(instance, "sharer-" + index); 27826 instance = document.querySelectorAll(element)[index]; 27827 this.inject_css(instance); 27828 this.inject_html(instance); 27829 this.show(instance); 27830 label = instance.getElementsByTagName("label")[0]; 27831 button = instance.getElementsByClassName("social")[0]; 27832 networks = instance.getElementsByTagName('li'); 27833 this.add_class(button, "networks-" + this.config.enabled_networks); 27834 label.addEventListener("click", function() { 27835 return _this.event_toggle(button); 27836 }); 27837 _this = this; 27838 _results = []; 27839 for (index = _i = 0, _len = networks.length; _i < _len; index = ++_i) { 27840 network = networks[index]; 27841 _results.push(network.addEventListener("click", function() { 27842 _this.event_network(instance, this); 27843 return _this.event_close(button); 27844 })); 27845 } 27846 return _results; 27847 }; 27848 27849 Share.prototype.event_toggle = function(button) { 27850 if (this.has_class(button, "active")) { 27851 return this.event_close(button); 27852 } else { 27853 return this.event_open(button); 27854 } 27855 }; 27856 27857 Share.prototype.event_open = function(button) { 27858 if (this.has_class(button, "load")) { 27859 this.remove_class(button, "load"); 27860 } 27861 return this.add_class(button, "active"); 27862 }; 27863 27864 Share.prototype.event_close = function(button) { 27865 return this.remove_class(button, "active"); 27866 }; 27867 27868 Share.prototype.event_network = function(instance, network) { 27869 var name; 27870 name = network.getAttribute("data-network"); 27871 this.hook("before", name, instance);
27872 this["network_" + name](); 27873 return this.hook("after", name, instance); 27874 }; 27875 27876 Share.prototype.open = function() { 27877 return this["public"]("open"); 27878 }; 27879 27880 Share.prototype.close = function() { 27881 return this["public"]("close"); 27882 }; 27883 27884 Share.prototype.toggle = function() { 27885 return this["public"]("toggle"); 27886 }; 27887 27888 Share.prototype["public"] = function(action) { 27889 var button, index, instance, _i, _len, _ref, _results; 27890 _ref = document.querySelectorAll(this.element); 27891 _results = []; 27892 for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { 27893 instance = _ref[index]; 27894 button = instance.getElementsByClassName("social")[0]; 27895 _results.push(this["event_" + action](button)); 27896 } 27897 return _results; 27898 }; 27899 27900 Share.prototype.network_facebook = function() { 27901 if (this.config.networks.facebook.load_sdk) { 27902 if (!window.FB) { 27903 return console.error("The Facebook JS SDK hasn't loaded yet."); 27904 } 27905 return FB.ui({ 27906 method: 'feed', 27907 name: this.config.networks.facebook.title, 27908 link: this.config.networks.facebook.url, 27909 picture: this.config.networks.facebook.image, 27910 caption: this.config.networks.facebook.caption, 27911 description: this.config.networks.facebook.description 27912 }); 27913 } else { 27914 return this.popup('https://www.facebook.com/sharer/sharer.php', { 27915 u: this.config.networks.facebook.url 27916 }); 27917 } 27918 }; 27919 27920 Share.prototype.network_threads = function() { 27921 return this.popup('https://threads.net/intent/post', { 27922 text: this.config.networks.threads.title, 27923 url: this.config.networks.threads.url 27924 }); 27925 }; 27926 27927 Share.prototype.network_bluesky = function() { 27928 return this.popup('https://bsky.app/intent/compose', { 27929 text: this.config.networks.bluesky.title + ' ' + this.config.networks.bluesky.url 27930 }); 27931 }; 27932 27933 Share.prototype.network_twitter = function() { 27934 return this.popup('https://twitter.com/intent/tweet', { 27935 text: this.config.networks.twitter.title, 27936 url: this.config.networks.twitter.url 27937 }); 27938 }; 27939 27940 Share.prototype.network_pinterest = function() { 27941 return this.popup('https://www.pinterest.com/pin/create/button', { 27942 url: this.config.networks.pinterest.url, 27943 media: this.config.networks.pinterest.image, 27944 description: this.config.networks.pinterest.description 27945 }); 27946 }; 27947 27948 Share.prototype.network_linkedin = function() { 27949 return this.popup('https://www.linkedin.com/shareArticle', { 27950 url: this.config.networks.linkedin.url, 27951 title: this.config.networks.linkedin.title, 27952 summary: this.config.networks.linkedin.description 27953 }); 27954 } 27955 27956 Share.prototype.network_xing = function() { 27957 return this.popup('https://www.xing.com/spi/shares/new', { 27958 url: this.config.networks.xing.url, 27959 image: this.config.networks.xing.image, 27960 title: this.config.networks.xing.title, 27961 summary: this.config.networks.xing.description 27962 }); 27963 } 27964 27965 Share.prototype.network_whatsapp = function() { 27966 return this.popup('https://api.whatsapp.com/send', { 27967 text: this.config.networks.whatsapp.title + '%20' + this.config.networks.whatsapp.url, 27968 }); 27969 } 27970 27971 Share.prototype.network_email = function() { 27972 return this.popup('mailto:', { 27973 subject: this.config.networks.email.title, 27974 body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description, 27975 }); 27976 }; 27977 27978 Share.prototype.inject_icons = function() { 27979 // return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css"); 27980 }; 27981 27982 Share.prototype.inject_fonts = function() { 27983 // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text); 27984 }; 27985 27986 Share.prototype.inject_stylesheet = function(url) { 27987 var link; 27988 if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) { 27989 link = document.createElement("link"); 27990 link.setAttribute("rel", "stylesheet"); 27991 link.setAttribute("href", url); 27992 return this.el.head.appendChild(link); 27993 } 27994 }; 27995 27996 Share.prototype.inject_css = function(instance) { 27997 var css, meta, selector, style; 27998 selector = "." + (instance.getAttribute('class').split(" ").join(".")); 27999 if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) { 28000 this.config.selector = selector; 28001 css = getStyles(this.config); 28002 style = document.createElement("style"); 28003 style.type = "text/css"; 28004 if (style.styleSheet) { 28005 style.styleSheet.cssText = css; 28006 } else { 28007 style.appendChild(document.createTextNode(css)); 28008 } 28009 this.el.head.appendChild(style); 28010 delete this.config.selector; 28011 meta = document.createElement("meta"); 28012 meta.setAttribute("name", "sharer" + selector); 28013 return this.el.head.appendChild(meta); 28014 } 28015 }; 28016 28017 Share.prototype.inject_html = function(instance) { 28018 // 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>"; 28019 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-threads' data-network='threads' 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-bluesky' data-network='bluesky' 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>"; 28020 }; 28021 28022 Share.prototype.inject_facebook_sdk = function() { 28023 var fb_root, script; 28024 if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) { 28025 script = document.createElement("script"); 28026 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')"; 28027 fb_root = document.createElement("div"); 28028 fb_root.id = "fb-root"; 28029 this.el.body.appendChild(fb_root); 28030 return this.el.body.appendChild(script); 28031 } 28032 }; 28033 28034 Share.prototype.hook = function(type, network, instance) { 28035 var fn, opts; 28036 fn = this.config.networks[network][type]; 28037 if (typeof fn === "function") { 28038 opts = fn.call(this.config.networks[network], instance); 28039 if (opts !== void 0) { 28040 opts = this.normalize_filter_config_updates(opts); 28041 this.extend(this.config.networks[network], opts, true); 28042 this.normalize_network_configuration(); 28043 } 28044 } 28045 }; 28046 28047 Share.prototype.default_title = function() { 28048 var content; 28049 if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) { 28050 return encodeURIComponent(content.getAttribute('content')); 28051 } else if (content = document.querySelector('title')) { 28052 return encodeURIComponent(content.innerText); 28053 } 28054 }; 28055 28056 Share.prototype.default_image = function() { 28057 var content; 28058 if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) { 28059 return content.getAttribute('content'); 28060 } 28061 }; 28062 28063 Share.prototype.default_description = function() { 28064 var content; 28065 if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) { 28066 return encodeURIComponent(content.getAttribute('content')); 28067 } else { 28068 return ''; 28069 } 28070 }; 28071 28072 Share.prototype.set_global_configuration = function() { 28073 var display, network, option, options, _ref, _results; 28074 _ref = this.config.networks; 28075 _results = []; 28076 for (network in _ref) { 28077 options = _ref[network]; 28078 for (option in options) { 28079 if (this.config.networks[network][option] == null) { 28080 this.config.networks[network][option] = this.config[option]; 28081 } 28082 } 28083 if (this.config.networks[network].enabled) { 28084 display = 'block'; 28085 this.config.enabled_networks += 1; 28086 } else { 28087 display = 'none'; 28088 } 28089 _results.push(this.config.networks[network].display = display); 28090 } 28091 return _results; 28092 }; 28093 28094 Share.prototype.normalize_network_configuration = function() { 28095 if (!this.config.networks.facebook.app_id) { 28096 this.config.networks.facebook.load_sdk = false;
28097 } 28098 if (!this.is_encoded(this.config.networks.twitter.description)) { 28099 this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description); 28100 } 28101 if (typeof this.config.networks.facebook.app_id === 'number') { 28102 return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString(); 28103 } 28104 }; 28105 28106 Share.prototype.normalize_filter_config_updates = function(opts) { 28107 if (this.config.networks.facebook.app_id !== opts.app_id) { 28108 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."); 28109 delete opts.app_id; 28110 } 28111 if (this.config.networks.facebook.load_sdk !== opts.load_sdk) { 28112 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."); 28113 delete opts.app_id; 28114 } 28115 return opts; 28116 }; 28117 28118 return Share; 28119 28120})(ShareUtils); 28121 return Share; 28122}); 28123 28124// Generated by CoffeeScript 1.9.2 28125 28126// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net 28127 28128(function() { 28129 var $, win; 28130 28131 $ = this.jQuery || window.jQuery; 28132 28133 win = $(window); 28134 28135 $.fn.stick_in_parent = function(opts) { 28136 var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class; 28137 if (opts == null) { 28138 opts = {}; 28139 } 28140 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; 28141 if (offset_top == null) { 28142 offset_top = 0; 28143 } 28144 if (parent_selector == null) { 28145 parent_selector = void 0; 28146 } 28147 if (inner_scrolling == null) { 28148 inner_scrolling = true; 28149 } 28150 if (sticky_class == null) { 28151 sticky_class = "is_stuck"; 28152 } 28153 doc = $(document); 28154 if (enable_bottoming == null) { 28155 enable_bottoming = true; 28156 } 28157 outer_width = function(el) { 28158 var _el, computed, w; 28159 if (window.getComputedStyle) { 28160 _el = el[0]; 28161 computed = window.getComputedStyle(el[0]); 28162 w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right")); 28163 if (computed.getPropertyValue("box-sizing") !== "border-box") { 28164 w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right")); 28165 } 28166 return w; 28167 } else { 28168 return el.outerWidth(true); 28169 } 28170 }; 28171 fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) { 28172 var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick; 28173 if (elm.data("sticky_kit")) { 28174 return; 28175 } 28176 elm.data("sticky_kit", true); 28177 last_scroll_height = doc.height(); 28178 parent = elm.parent(); 28179 if (parent_selector != null) { 28180 parent = parent.closest(parent_selector); 28181 } 28182 if (!parent.length) { 28183 throw "failed to find stick parent"; 28184 } 28185 fixed = false; 28186 bottomed = false; 28187 spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />"); 28188 if (spacer) { 28189 spacer.css('position', elm.css('position')); 28190 } 28191 recalc = function() { 28192 var border_top, padding_top, restore; 28193 if (detached) { 28194 return; 28195 } 28196 last_scroll_height = doc.height(); 28197 border_top = parseInt(parent.css("border-top-width"), 10); 28198 padding_top = parseInt(parent.css("padding-top"), 10); 28199 padding_bottom = parseInt(parent.css("padding-bottom"), 10); 28200 parent_top = parent.offset().top + border_top + padding_top; 28201 parent_height = parent.height(); 28202 if (fixed) { 28203 fixed = false;
vendor: 6,068 bytes, lines 28204-28398
28204 bottomed = false; 28205 if (manual_spacer == null) { 28206 elm.insertAfter(spacer); 28207 spacer.detach(); 28208 } 28209 elm.css({ 28210 position: "", 28211 top: "", 28212 width: "", 28213 bottom: "" 28214 }).removeClass(sticky_class); 28215 restore = true; 28216 } 28217 top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top; 28218 height = elm.outerHeight(true); 28219 el_float = elm.css("float"); 28220 if (spacer) { 28221 spacer.css({ 28222 width: outer_width(elm), 28223 height: height, 28224 display: elm.css("display"), 28225 "vertical-align": elm.css("vertical-align"), 28226 "float": el_float 28227 }); 28228 } 28229 if (restore) { 28230 return tick(); 28231 } 28232 }; 28233 recalc(); 28234 if (height === parent_height) { 28235 return; 28236 } 28237 last_pos = void 0; 28238 offset = offset_top; 28239 recalc_counter = recalc_every; 28240 tick = function() { 28241 var css, delta, recalced, scroll, will_bottom, win_height; 28242 if (detached) { 28243 return; 28244 } 28245 recalced = false; 28246 if (recalc_counter != null) { 28247 recalc_counter -= 1; 28248 if (recalc_counter <= 0) { 28249 recalc_counter = recalc_every; 28250 recalc(); 28251 recalced = true; 28252 } 28253 } 28254 if (!recalced && doc.height() !== last_scroll_height) { 28255 recalc(); 28256 recalced = true; 28257 } 28258 scroll = win.scrollTop(); 28259 if (last_pos != null) { 28260 delta = scroll - last_pos; 28261 } 28262 last_pos = scroll; 28263 if (fixed) { 28264 if (enable_bottoming) { 28265 will_bottom = scroll + height + offset > parent_height + parent_top; 28266 if (bottomed && !will_bottom) { 28267 bottomed = false; 28268 elm.css({ 28269 position: "fixed", 28270 bottom: "", 28271 top: offset 28272 }).trigger("sticky_kit:unbottom"); 28273 } 28274 } 28275 if (scroll < top) { 28276 fixed = false; 28277 offset = offset_top; 28278 if (manual_spacer == null) { 28279 if (el_float === "left" || el_float === "right") { 28280 elm.insertAfter(spacer); 28281 } 28282 spacer.detach(); 28283 } 28284 css = { 28285 position: "", 28286 width: "", 28287 top: "" 28288 }; 28289 elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick"); 28290 } 28291 if (inner_scrolling) { 28292 win_height = win.height(); 28293 if (height + offset_top > win_height) { 28294 if (!bottomed) { 28295 offset -= delta; 28296 offset = Math.max(win_height - height, offset); 28297 offset = Math.min(offset_top, offset); 28298 if (fixed) { 28299 elm.css({ 28300 top: offset + "px" 28301 }); 28302 } 28303 } 28304 } 28305 } 28306 } else { 28307 if (scroll > top) { 28308 fixed = true; 28309 css = { 28310 position: "fixed", 28311 top: offset 28312 }; 28313 css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px"; 28314 elm.css(css).addClass(sticky_class); 28315 if (manual_spacer == null) { 28316 elm.after(spacer); 28317 if (el_float === "left" || el_float === "right") { 28318 spacer.append(elm); 28319 } 28320 } 28321 elm.trigger("sticky_kit:stick"); 28322 } 28323 } 28324 if (fixed && enable_bottoming) { 28325 if (will_bottom == null) { 28326 will_bottom = scroll + height + offset > parent_height + parent_top; 28327 } 28328 if (!bottomed && will_bottom) { 28329 bottomed = true; 28330 if (parent.css("position") === "static") { 28331 parent.css({ 28332 position: "relative" 28333 }); 28334 } 28335 return elm.css({ 28336 position: "absolute", 28337 bottom: padding_bottom, 28338 top: "auto" 28339 }).trigger("sticky_kit:bottom"); 28340 } 28341 } 28342 }; 28343 recalc_and_tick = function() { 28344 recalc(); 28345 return tick(); 28346 }; 28347 detach = function() { 28348 detached = true; 28349 win.off("touchmove", tick); 28350 win.off("scroll", tick); 28351 win.off("resize", recalc_and_tick); 28352 $(document.body).off("sticky_kit:recalc", recalc_and_tick); 28353 elm.off("sticky_kit:detach", detach); 28354 elm.removeData("sticky_kit"); 28355 elm.css({ 28356 position: "", 28357 bottom: "", 28358 top: "", 28359 width: "" 28360 }); 28361 parent.position("position", ""); 28362 if (fixed) { 28363 if (manual_spacer == null) { 28364 if (el_float === "left" || el_float === "right") { 28365 elm.insertAfter(spacer); 28366 } 28367 spacer.remove(); 28368 } 28369 return elm.removeClass(sticky_class); 28370 } 28371 }; 28372 win.on("touchmove", tick); 28373 win.on("scroll", tick); 28374 win.on("resize", recalc_and_tick); 28375 $(document.body).on("sticky_kit:recalc", recalc_and_tick); 28376 elm.on("sticky_kit:detach", detach); 28377 return setTimeout(tick, 0); 28378 }; 28379 for (i = 0, len = this.length; i < len; i++) { 28380 elm = this[i]; 28381 fn($(elm)); 28382 } 28383 return this; 28384 }; 28385 28386}).call(this); 28387/* ========================================================================== 28388 * bootstrap-tab-history.js 28389 * Author: Michael Narayan <[email protected]> 28390 * Repository: https://github.com/mnarayan01/bootstrap-tab-history/ 28391 * ========================================================================== 28392 * Licensed under the Apache License, Version 2.0 (the "License"); you may 28393 * not use this file except in compliance with the License. You may obtain a 28394 * copy of the License at 28395 * 28396 * http://www.apache.org/licenses/LICENSE-2.0 28397 * 28398 * Unless required by applicable law or agreed to in writing, softw
28398are 28399 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 28400 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 28401 * License for the specific language governing permissions and limitations 28402 * under the License. 28403 * ========================================================================== */ 28404 28405/* ========================================================================== */ 28406/* JSHint directives */ 28407/* */ 28408/* global BootstrapTabHistory: true */ 28409/* */ 28410/* global document */ 28411/* global jQuery */ 28412/* global history */ 28413/* global window */ 28414/* ========================================================================== */ 28415 28416/** 28417 * Integrate [HTML5 history state tracking](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history) 28418 * with [`bootstrap/tab.js`](http://getbootstrap.com/javascript/#tabs). To enable tracking on a tab element, simply set 28419 * the `data-tab-history` attribute to true (or a string denoting a tab grouping). 28420 * 28421 * See the README for additional information. 28422 * 28423 * Functionality based upon bootstrap/tab.js v3.1.0; reference it when making any changes. 28424 */ 28425 28426BootstrapTabHistory = { 28427 options: { 28428 /** 28429 * When the anchor portion of the URI is used to activate a tab, scroll down to the given offset, rather than the 28430 * element with the given `id` attribute. Set to null to disable. Only relevant if showTabsBasedOnAnchor is true. 28431 * 28432 * May be overriden on a per-element basis by the attribute `data-tab-history-anchor-y-offset`. 28433 * 28434 * @public 28435 * @type {?number} 28436 */ 28437 defaultAnchorYOffset: 0, 28438 /** 28439 * Either 'push' or 'replace', for whether to use `history.pushState` or `history.replaceState`, resp. 28440 * 28441 * May be overriden on a per-element basis by the attribute `data-tab-history-changer`. 28442 * 28443 * @public 28444 * @type {string} 28445 */ 28446 defaultChanger: 'replace', 28447 /** 28448 * If true, update the URL in onShownTab in the calls to `history.pushState` and `history.replaceState`. Otherwise, 28449 * `null` is passed as the third parameter to these calls. 28450 * 28451 * May be overriden on a per-element basis by the attribute `data-tab-history-update-url`. 28452 * 28453 * @public 28454 * @type {boolean} 28455 */ 28456 defaultUpdateURL: false, 28457 /** 28458 * Should the anchor portion of the loaded URI be used to activate a single tab if no history was present on page 28459 * load. 28460 * 28461 * @public 28462 * @type {boolean} 28463 */ 28464 showTabsBasedOnAnchor: true 28465 } 28466}; 28467 28468(function () { 28469 'use strict'; 28470 28471 jQuery(function () { 28472 if(history && history.pushState && history.replaceState) { 28473 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 28474 28475 if(bootstrapTabHistory) { 28476 showTabsBasedOnState(bootstrapTabHistory); 28477 } else { 28478 showTabsBasedOnAnchor(); 28479 } 28480 28481 backfillHistoryState(); 28482 28483 jQuery(document).on('shown.bs.tab show.bs.collapse', onShownTab); 28484 jQuery(window).on('popstate', onPopState); 28485 } else { 28486 showTabsBasedOnAnchor(); 28487 } 28488 }); 28489 28490 /** 28491 * Used to prevent onShownTab from registering shown events that we triggered via showTabsBasedOnState. 28492 * 28493 * @type {boolean} 28494 */ 28495 var showingTabsBasedOnState = false; 28496 28497 /** 28498 * Used to update `history.state` to reflect the default active tabs on initial page load. This supports proper 28499 * `history.back` handling when `data-tab-history-update-url` is true. 28500 */ 28501 function backfillHistoryState() { 28502 var newState = null; 28503 28504 jQuery('li.active > [data-tab-history], .panel-title.active [data-tab-history]').each(function () {//edited by Uncode 28505 var $activeTabElement = jQuery(this); 28506 var selector = getTabSelector($activeTabElement); 28507 28508 if(selector) { 28509 var tabGroup = getTabGroup($activeTabElement); 28510 28511 if(tabGroup) { 28512 newState = createNewHistoryState(newState || history.state, tabGroup, selector); 28513 } 28514 } 28515 }); 28516 28517 if(newState) { 28518 history.replaceState(newState, '', null); 28519 } 28520 } 28521 28522 /** 28523 * Clone the existing state, ensure its bootstrapTabHistory attribute is an Object, and add the provided tabGroup to 28524 * said bootstrapTabHistory attribute. 28525 * 28526 * @param {?object} existingState 28527 * @param {!string} tabGroup 28528 * @param {!string} selector 28529 * @returns {!object} 28530 */ 28531 function createNewHistoryState(existingState, tabGroup, selector) { 28532 // Clone history.state and ensure it has a bootstrapTabHistory entry. 28533 var newState = jQuery.extend(true, {}, existingState, { 28534 bootstrapTabHistory: {} 28535 }); 28536 28537 newState.bootstrapTabHistory[tabGroup] = selector; 28538 28539 return newState; 28540 } 28541 28542 /** 28543 * @param {jQuery} $tab
28544 * @returns {?string} 28545 */ 28546 function getTabGroup($tab) { 28547 return parseTruthyAttributeValue($tab.data('tab-history')); 28548 } 28549 28550 /** 28551 * @param {jQuery} $tab 28552 * @returns {?string} 28553 */ 28554 function getTabSelector($tab) { 28555 return $tab.data('target') || $tab.attr('href'); 28556 } 28557 28558 /** 28559 * Receives the `shown.bs.tab` event. Updates `history.state` as appropriate. 28560 * 28561 * @param {jQuery.Event} shownEvt 28562 */ 28563 function onShownTab(shownEvt) { 28564 if(!showingTabsBasedOnState) { 28565 var $activatedTab = jQuery(shownEvt.target); 28566 if ( $activatedTab.hasClass('panel-collapse') ) 28567 $activatedTab = $activatedTab.closest('.panel').find('a'); 28568 var selector = getTabSelector($activatedTab); 28569 28570 if(selector) { 28571 var tabGroup = getTabGroup($activatedTab); 28572 28573 if(tabGroup) { 28574 var historyChanger = $activatedTab.data('tab-history-changer') || BootstrapTabHistory.options.defaultChanger; 28575 var newState = createNewHistoryState(history.state, tabGroup, selector); 28576 var updateURL = (function ($activatedTab) { 28577 if(selector[0] === '#') { 28578 var elementUpdateURLOption = parseTruthyAttributeValue($activatedTab.data('tab-history-update-url')); 28579 28580 if(elementUpdateURLOption === undefined) { 28581 return BootstrapTabHistory.options.defaultUpdateURL; 28582 } else { 28583 return elementUpdateURLOption; 28584 } 28585 } else { 28586 return false; 28587 } 28588 })($activatedTab); 28589 28590 switch(historyChanger) { 28591 case 'push': 28592 history.pushState(newState, '', updateURL ? selector : null); 28593 break; 28594 case 'replace': 28595 history.replaceState(newState, '', updateURL ? selector : null); 28596 break; 28597 default: 28598 throw new Error('Unknown tab-history-changer: ' + historyChanger); 28599 } 28600 } 28601 } 28602 } 28603 } 28604 28605 /** 28606 * Receives the `popstate` event. Shows tabs based on the value of `history.state` as appropriate. 28607 */ 28608 function onPopState() { 28609 var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory; 28610 28611 if(bootstrapTabHistory) { 28612 showTabsBasedOnState(bootstrapTabHistory); 28613 } 28614 } 28615 28616 /** 28617 * Returns the given value, _unless_ that value is an empty string, in which case `true` is returned. 28618 * 28619 * Rationale: HAML data attributes which are set to `true` are rendered as a blank string. 28620 * 28621 * @param {*} value 28622 * @returns {*} 28623 */ 28624 function parseTruthyAttributeValue(value) { 28625 if(value) { 28626 return value; 28627 } else if(value === '') { 28628 return true; 28629 } else { 28630 return value; 28631 } 28632 } 28633 28634 /** 28635 * Show tabs based upon the anchor component of `window.location`. 28636 */ 28637 function showTabsBasedOnAnchor() { 28638 if(BootstrapTabHistory.options.showTabsBasedOnAnchor) { 28639 var anchor = window.location && window.location.hash; 28640 28641 if(anchor) { 28642 var $tabElement = showTabForSelector(anchor); 28643 28644 if($tabElement && window.addEventListener && window.removeEventListener) { 28645 var anchorYOffset = (function ($tabElement) { 28646 var elementSetting = $tabElement.data('tab-history-anchor-y-offset'); 28647 28648 if(elementSetting === undefined) { 28649 return BootstrapTabHistory.options.defaultAnchorYOffset; 28650 } else { 28651 return elementSetting; 28652 } 28653 })($tabElement); 28654 28655 // HACK: This prevents scrolling to the tab on page load. This relies on the fact that we should never get 28656 // here on `history.forward`, `history.back`, or `location.reload`, since in all those situations the 28657 // `history.state` object should have been used (unless the browser did not support the modern History API). 28658 if(anchorYOffset || anchorYOffset === 0) { 28659 var scrollListener = function resetAnchorScroll () { 28660 window.removeEventListener('scroll', scrollListener); 28661 window.scrollTo(0, anchorYOffset); 28662 }; 28663 28664 window.addEventListener('scroll', scrollListener); 28665 } 28666 } 28667 } 28668 } 28669 } 28670 28671 /** 28672 * Show a tab which corresponds to the provided selector. 28673 * 28674 * @param {string} selector - A CSS selector. 28675 * @returns {?jQuery} - The tab which was found to show (even if said tab was already active). 28676 */ 28677 function showTabForSelector(selector) { 28678 var $tabElement = (function (selector) { 28679 var $ret = null; 28680 28681 jQuery('[data-toggle="tab"], [data-toggle="pill"], [data-toggle="collapse"]').each(function () { 28682 var $potentialTab = jQuery(this); 28683 28684 if(($potentialTab.attr('href') === selector || $potentialTab.data('target') === selector ) && getTabGroup($potentialTab)) { 28685 $ret = $potentialTab; 28686 return false;
vendor: 43,483 bytes, lines 28687-29903
28687 } else { 28688 return null; 28689 } 28690 }); 28691 28692 return $ret; 28693 })(selector); 28694 28695 if($tabElement) { 28696 if ( !$tabElement.parent().hasClass('active') ) { 28697 $tabElement.trigger('click'); 28698 } 28699 //$tabElement.tab('show'); 28700 } 28701 28702 return $tabElement; 28703 } 28704 28705 /** 28706 * Iterate through the provided set of tab tab groups, showing the tabs based on the stored selectors. 28707 * 28708 * @param {object} bootstrapTabHistory - Each of the values is passed to showTabForSelector; the keys are actually irrelevant. 28709 */ 28710 function showTabsBasedOnState(bootstrapTabHistory) { 28711 showingTabsBasedOnState = true; 28712 28713 try { 28714 for(var k in bootstrapTabHistory) { 28715 if(bootstrapTabHistory.hasOwnProperty(k)) { 28716 showTabForSelector(bootstrapTabHistory[k]); 28717 } 28718 } 28719 } finally { 28720 showingTabsBasedOnState = false; 28721 } 28722 } 28723})(); 28724 28725/*! 28726 * justifiedGallery - v3.8.1 28727 * http://miromannino.github.io/Justified-Gallery/ 28728 * Copyright (c) 2020 Miro Mannino 28729 * Licensed under the MIT license. 28730 */ 28731(function (factory) { 28732 if (typeof define === 'function' && define.amd) { 28733 // AMD. Register as an anonymous module. 28734 define(['jquery'], factory); 28735 } else if (typeof module === 'object' && module.exports) { 28736 // Node/CommonJS 28737 module.exports = function (root, jQuery) { 28738 if (jQuery === undefined) { 28739 // require('jQuery') returns a factory that requires window to 28740 // build a jQuery instance, we normalize how we use modules 28741 // that require this pattern but the window provided is a noop 28742 // if it's defined (how jquery works) 28743 if (typeof window !== 'undefined') { 28744 jQuery = require('jquery'); 28745 } 28746 else { 28747 jQuery = require('jquery')(root); 28748 } 28749 } 28750 factory(jQuery); 28751 return jQuery; 28752 }; 28753 } else { 28754 // Browser globals 28755 factory(jQuery); 28756 } 28757}(function ($) { 28758 28759 /** 28760 * Justified Gallery controller constructor 28761 * 28762 * @param $gallery the gallery to build 28763 * @param settings the settings (the defaults are in JustifiedGallery.defaults) 28764 * @constructor 28765 */ 28766 var JustifiedGallery = function ($gallery, settings) { 28767 28768 this.settings = settings; 28769 this.checkSettings(); 28770 28771 this.imgAnalyzerTimeout = null; 28772 this.entries = null; 28773 this.buildingRow = { 28774 entriesBuff: [], 28775 width: 0, 28776 height: 0, 28777 aspectRatio: 0 28778 }; 28779 this.lastFetchedEntry = null; 28780 this.lastAnalyzedIndex = -1; 28781 this.yield = { 28782 every: 2, // do a flush every n flushes (must be greater than 1) 28783 flushed: 0 // flushed rows without a yield 28784 }; 28785 this.border = settings.border >= 0 ? settings.border : settings.margins; 28786 this.maxRowHeight = this.retrieveMaxRowHeight(); 28787 this.suffixRanges = this.retrieveSuffixRanges(); 28788 this.offY = this.border; 28789 this.rows = 0; 28790 this.spinner = { 28791 phase: 0, 28792 timeSlot: 150, 28793 $el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'), 28794 intervalId: null 28795 }; 28796 this.scrollBarOn = false; 28797 this.checkWidthIntervalId = null; 28798 this.galleryWidth = $gallery.width(); 28799 this.$gallery = $gallery; 28800 28801 }; 28802 28803 /** @returns {String} the best suffix given the width and the height */ 28804 JustifiedGallery.prototype.getSuffix = function (width, height) { 28805 var longestSide, i; 28806 longestSide = (width > height) ? width : height; 28807 for (i = 0; i < this.suffixRanges.length; i++) { 28808 if (longestSide <= this.suffixRanges[i]) { 28809 return this.settings.sizeRangeSuffixes[this.suffixRanges[i]]; 28810 } 28811 } 28812 return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]]; 28813 }; 28814 28815 /** 28816 * Remove the suffix from the string 28817 * 28818 * @returns {string} a new string without the suffix 28819 */ 28820 JustifiedGallery.prototype.removeSuffix = function (str, suffix) { 28821 return str.substring(0, str.length - suffix.length); 28822 }; 28823 28824 /** 28825 * @returns {boolean} a boolean to say if the suffix is contained in the str or not 28826 */ 28827 JustifiedGallery.prototype.endsWith = function (str, suffix) { 28828 return str.indexOf(suffix, str.length - suffix.length) !== -1; 28829 }; 28830 28831 /** 28832 * Get the used suffix of a particular url 28833 * 28834 * @param str 28835 * @returns {String} return the used suffix 28836 */ 28837 JustifiedGallery.prototype.getUsedSuffix = function (str) { 28838 for (var si in this.settings.sizeRangeSuffixes) { 28839 if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) { 28840 if (this.settings.sizeRangeSuffixes[si].length === 0) continue; 28841 if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si]; 28842 } 28843 } 28844 return ''; 28845 }; 28846 28847 /** 28848 * Given an image src, with the width and the height, returns the new image src with the 28849 * best suffix to show the best quality thumbnail. 28850 * 28851 * @returns {String} the suffix to use 28852 */ 28853 JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight, image) { 28854 var newImageSrc; 28855 28856 if (this.settings.thumbnailPath) { 28857 newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image); 28858 } else { 28859 var matchRes = imageSrc.match(this.settings.extension); 28860 var ext = (matchRes !== null) ? matchRes[0] : ''; 28861 newImageSrc = imageSrc.replace(this.settings.extension, ''); 28862 newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc)); 28863 newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext; 28864 } 28865 28866 return newImageSrc; 28867 }; 28868 28869 /** 28870 * Shows the images that is in the given entry 28871 * 28872 * @param $entry the entry 28873 * @param callback the callback that is called when the show animation is finished 28874 */ 28875 JustifiedGallery.prototype.showImg = function ($entry, callback) { 28876 if (this.settings.cssAnimation) { 28877 $entry.addClass('jg-entry-visible'); 28878 if (callback) callback(); 28879 } else { 28880 $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 28881 $entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback); 28882 } 28883 }; 28884 28885 /** 28886 * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the 28887 * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src. 28888 * 28889 * @param $image the image to analyze 28890 * @returns {String} the extracted src 28891 */ 28892 JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) { 28893 var imageSrc = $image.data('safe-src'); 28894 var imageSrcLoc = 'data-safe-src'; 28895 // Begin Uncode edit 28896 if (typeof imageSrc === 'undefined') { 28897 var imageCurrentSrc = $image[0].currentSrc; 28898 if (imageCurrentSrc) { 28899 imageSrc = imageCurrentSrc; 28900 } else { 28901 imageSrc = $image.attr('src'); 28902 } 28903 imageSrcLoc = 'src'; 28904 } 28905 // End Uncode edit 28906 $image.data('jg.originalSrc', imageSrc); // this is saved for the destroy method 28907 $image.data('jg.src', imageSrc); // this will change overtime 28908 $image.data('jg.originalSrcLoc', imageSrcLoc); // this is saved for the destroy method 28909 return imageSrc; 28910 }; 28911 28912 /** @returns {jQuery} the image in the given entry */ 28913 JustifiedGallery.prototype.imgFromEntry = function ($entry) { 28914 var $img = $entry.find(this.settings.imgSelector); 28915 if ($img.length === 0) $img = $entry.find('.t-entry-visual-cont img');//hacked by Uncode 28916 return $img.length === 0 ? null : $img; 28917 }; 28918 28919 /** @returns {jQuery} the caption in the given entry */ 28920 JustifiedGallery.prototype.captionFromEntry = function ($entry) { 28921 var $caption = $entry.find('> .jg-caption'); 28922 return $caption.length === 0 ? null : $caption; 28923 }; 28924 28925 /** 28926 * Display the entry 28927 * 28928 * @param {jQuery} $entry the entry to display 28929 * @param {int} x the x position where the entry must be positioned 28930 * @param y the y position where the entry must be positioned 28931 * @param imgWidth the image width 28932 * @param imgHeight the image height 28933 * @param rowHeight the row height of the row that owns the entry 28934 */ 28935 JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) { 28936 $entry.width(imgWidth); 28937 $entry.height(Math.floor(rowHeight));//hacked by Uncode 28938 $entry.css('top', Math.floor(y));//hacked by Uncode 28939 $entry.css('left', x); 28940 28941 var $image = this.imgFromEntry($entry); 28942 if ($image !== null) { 28943 $image.css('width', imgWidth); 28944 $image.css('height', imgHeight); 28945 $image.css('margin-left', - imgWidth / 2); 28946 $image.css('margin-top', - imgHeight / 2); 28947 28948 // Image reloading for an high quality of thumbnails 28949 var imageSrc = $image.data('jg.src'); 28950 if (imageSrc) { 28951 imageSrc = this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]); 28952 28953 $image.one('error', function () { 28954 this.resetImgSrc($image); //revert to the original thumbnail 28955 }); 28956 28957 var loadNewImage = function () { 28958 // if (imageSrc !== newImageSrc) { 28959 $image.attr('src', imageSrc); 28960 // } 28961 }; 28962 28963 if ($entry.data('jg.loaded') === 'skipped' && imageSrc) { 28964 this.onImageEvent(imageSrc, (function() { 28965 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 28966 $entry.data('jg.loaded', true); 28967 }).bind(this)); 28968 } else { 28969 this.showImg($entry, loadNewImage); //load the new image after the fadeIn 28970 } 28971 28972 } 28973 28974 } else { 28975 this.showImg($entry); 28976 } 28977 28978 this.displayEntryCaption($entry); 28979 }; 28980 28981 /** 28982 * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt' 28983 * or the 'title' attributes. 28984 * 28985 * @param {jQuery} $entry the entry to process 28986 */ 28987 JustifiedGallery.prototype.displayEntryCaption = function ($entry) { 28988 var $image = this.imgFromEntry($entry); 28989 if ($image !== null && this.settings.captions) { 28990 var $imgCaption = this.captionFromEntry($entry); 28991 28992 // Create it if it doesn't exists 28993 if ($imgCaption === null) { 28994 var caption = $image.attr('alt'); 28995 if (!this.isValidCaption(caption)) caption = $entry.attr('title'); 28996 if (this.isValidCaption(caption)) { // Create only we found something 28997 $imgCaption = $('<div class="jg-caption">' + caption + '</div>'); 28998 $entry.append($imgCaption); 28999 $entry.data('jg.createdCaption', true); 29000 } 29001 } 29002 29003 // Create events (we check again the $imgCaption because it can be still inexistent) 29004 if ($imgCaption !== null) { 29005 if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity); 29006 this.addCaptionEventsHandlers($entry); 29007 } 29008 } else { 29009 this.removeCaptionEventsHandlers($entry); 29010 } 29011 }; 29012 29013 /** 29014 * Validates the caption 29015 * 29016 * @param caption The caption that should be validated 29017 * @return {boolean} Validation result 29018 */ 29019 JustifiedGallery.prototype.isValidCaption = function (caption) { 29020 return (typeof caption !== 'undefined' && caption.length > 0); 29021 }; 29022 29023 /** 29024 * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry. 29025 * It shows the caption using jQuery (or using CSS if it is configured so) 29026 * 29027 * @param {Event} eventObject the event object 29028 */ 29029 JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) { 29030 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 29031 if (this.settings.cssAnimation) { 29032 $caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden'); 29033 } else { 29034 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 29035 this.settings.captionSettings.visibleOpacity); 29036 } 29037 }; 29038 29039 /** 29040 * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry. 29041 * It hides the caption using jQuery (or using CSS if it is configured so) 29042 * 29043 * @param {Event} eventObject the event object 29044 */ 29045 JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) { 29046 var $caption = this.captionFromEntry($(eventObject.currentTarget)); 29047 if (this.settings.cssAnimation) { 29048 $caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden'); 29049 } else { 29050 $caption.stop().fadeTo(this.settings.captionSettings.animationDuration, 29051 this.settings.captionSettings.nonVisibleOpacity); 29052 } 29053 }; 29054 29055 /** 29056 * Add the handlers of the entry for the caption 29057 * 29058 * @param $entry the entry to modify 29059 */ 29060 JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) { 29061 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 29062 if (typeof captionMouseEvents === 'undefined') { 29063 captionMouseEvents = { 29064 mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this), 29065 mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this) 29066 }; 29067 $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter); 29068 $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave); 29069 $entry.data('jg.captionMouseEvents', captionMouseEvents); 29070 } 29071 }; 29072 29073 /** 29074 * Remove the handlers of the entry for the caption 29075 * 29076 * @param $entry the entry to modify 29077 */ 29078 JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) { 29079 var captionMouseEvents = $entry.data('jg.captionMouseEvents'); 29080 if (typeof captionMouseEvents !== 'undefined') { 29081 $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter); 29082 $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave); 29083 $entry.removeData('jg.captionMouseEvents'); 29084 } 29085 }; 29086 29087 /** 29088 * Clear the building row data to be used for a new row 29089 */ 29090 JustifiedGallery.prototype.clearBuildingRow = function () { 29091 this.buildingRow.entriesBuff = []; 29092 this.buildingRow.aspectRatio = 0; 29093 this.buildingRow.width = 0; 29094 }; 29095 29096 /** 29097 * Justify the building row, preparing it to 29098 * 29099 * @param isLastRow 29100 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 29101 * @returns a boolean to know if the row has been justified or not 29102 */ 29103 JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow, hiddenRow) { 29104 var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true; 29105 var minHeight = 0; 29106 var availableWidth = this.galleryWidth - 2 * this.border - ( 29107 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 29108 var rowHeight = Math.floor( availableWidth / this.buildingRow.aspectRatio );//hacked by Uncode 29109 var defaultRowHeight = this.settings.rowHeight; 29110 var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold; 29111 29112 //Skip the last row if we can't justify it and the lastRow == 'hide' 29113 if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) { 29114 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 29115 $entry = this.buildingRow.entriesBuff[i]; 29116 if (this.settings.cssAnimation) 29117 $entry.removeClass('jg-entry-visible'); 29118 else { 29119 $entry.stop().fadeTo(0, 0.1); 29120 $entry.find('> img, > a > img').fadeTo(0, 0); 29121 } 29122 } 29123 return -1; 29124 } 29125 29126 // With lastRow = nojustify, justify if is justificable (the images will not become too big) 29127 if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') { 29128 justify = false; 29129 29130 if (this.rows > 0) { 29131 defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows; 29132 justify = defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold; 29133 } 29134 } 29135 29136 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 29137 $entry = this.buildingRow.entriesBuff[i]; 29138 imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 29139 29140 if (justify) { 29141 newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio; 29142 newImgH = rowHeight; 29143 } else { 29144 newImgW = defaultRowHeight * imgAspectRatio; 29145 newImgH = defaultRowHeight; 29146 } 29147 29148 availableWidth -= Math.round(newImgW); 29149 $entry.data('jg.jwidth', Math.round(newImgW)); 29150 $entry.data('jg.jheight', Math.ceil(newImgH)); 29151 if (i === 0 || minHeight > newImgH) minHeight = newImgH; 29152 } 29153 29154 this.buildingRow.height = minHeight; 29155 return justify; 29156 }; 29157 29158 /** 29159 * Flush a row: justify it, modify the gallery height accordingly to the row height 29160 * 29161 * @param isLastRow 29162 * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row. 29163 */ 29164 JustifiedGallery.prototype.flushRow = function (isLastRow, hiddenRow) { 29165 var settings = this.settings; 29166 var $entry, buildingRowRes, offX = this.border, i; 29167 29168 buildingRowRes = this.prepareBuildingRow(isLastRow, hiddenRow); 29169 if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1)) { 29170 this.clearBuildingRow(); 29171 return; 29172 } 29173 29174 if (this.maxRowHeight) { 29175 if (this.maxRowHeight < this.buildingRow.height) this.buildingRow.height = this.maxRowHeight; 29176 } 29177 29178 //Align last (unjustified) row 29179 if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) { 29180 var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins; 29181 29182 for (i = 0; i < this.buildingRow.entriesBuff.length; i++) { 29183 $entry = this.buildingRow.entriesBuff[i]; 29184 availableWidth -= $entry.data('jg.jwidth'); 29185 } 29186 29187 if (settings.lastRow === 'center') 29188 offX += Math.round(availableWidth / 2); 29189 else if (settings.lastRow === 'right') 29190 offX += availableWidth; 29191 } 29192 29193 var lastEntryIdx = this.buildingRow.entriesBuff.length - 1; 29194 for (i = 0; i <= lastEntryIdx; i++) { 29195 $entry = this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i : i]; 29196 this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height); 29197 offX += $entry.data('jg.jwidth') + settings.margins; 29198 } 29199 29200 //Gallery Height 29201 this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border; 29202 this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight()); 29203 29204 if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) { 29205 //Ready for a new row 29206 this.offY += this.buildingRow.height + settings.margins; 29207 this.rows += 1; 29208 this.clearBuildingRow(); 29209 this.settings.triggerEvent.call(this, 'jg.rowflush'); 29210 } 29211 }; 29212 29213 29214 // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221 29215 var galleryPrevStaticHeight = 0; 29216 29217 JustifiedGallery.prototype.rememberGalleryHeight = function () { 29218 galleryPrevStaticHeight = this.$gallery.height(); 29219 this.$gallery.height(galleryPrevStaticHeight); 29220 }; 29221 29222 // grow only 29223 JustifiedGallery.prototype.setGalleryTempHeight = function (height) { 29224 galleryPrevStaticHeight = Math.max(height, galleryPrevStaticHeight); 29225 this.$gallery.height(galleryPrevStaticHeight); 29226 }; 29227 29228 JustifiedGallery.prototype.setGalleryFinalHeight = function (height) { 29229 galleryPrevStaticHeight = height; 29230 this.$gallery.height(height); 29231 }; 29232 29233 /** 29234 * Checks the width of the gallery container, to know if a new justification is needed 29235 */ 29236 JustifiedGallery.prototype.checkWidth = function () { 29237 this.checkWidthIntervalId = setInterval($.proxy(function () { 29238 29239 // if the gallery is not currently visible, abort. 29240 if (!this.$gallery.is(":visible")) return; 29241 29242 var galleryWidth = parseFloat(this.$gallery.width()); 29243 if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) { 29244 this.galleryWidth = galleryWidth; 29245 this.rewind(); 29246 29247 this.rememberGalleryHeight(); 29248 29249 // Restart to analyze 29250 this.startImgAnalyzer(true); 29251 } 29252 }, this), this.settings.refreshTime); 29253 }; 29254 29255 /** 29256 * @returns {boolean} a boolean saying if the spinner is active or not 29257 */ 29258 JustifiedGallery.prototype.isSpinnerActive = function () { 29259 return this.spinner.intervalId !== null; 29260 }; 29261 29262 /** 29263 * @returns {int} the spinner height 29264 */ 29265 JustifiedGallery.prototype.getSpinnerHeight = function () { 29266 return this.spinner.$el.innerHeight(); 29267 }; 29268 29269 /** 29270 * Stops the spinner animation and modify the gallery height to exclude the spinner 29271 */ 29272 JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () { 29273 clearInterval(this.spinner.intervalId); 29274 this.spinner.intervalId = null; 29275 this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight()); 29276 this.spinner.$el.detach(); 29277 }; 29278 29279 /** 29280 * Starts the spinner animation 29281 */ 29282 JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () { 29283 var spinnerContext = this.spinner; 29284 var $spinnerPoints = spinnerContext.$el.find('span'); 29285 clearInterval(spinnerContext.intervalId); 29286 this.$gallery.append(spinnerContext.$el); 29287 this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight()); 29288 spinnerContext.intervalId = setInterval(function () { 29289 if (spinnerContext.phase < $spinnerPoints.length) { 29290 $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1); 29291 } else { 29292 $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0); 29293 } 29294 spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2); 29295 }, spinnerContext.timeSlot); 29296 }; 29297 29298 /** 29299 * Rewind the image analysis to start from the first entry. 29300 */ 29301 JustifiedGallery.prototype.rewind = function () { 29302 this.lastFetchedEntry = null; 29303 this.lastAnalyzedIndex = -1; 29304 this.offY = this.border; 29305 this.rows = 0; 29306 this.clearBuildingRow(); 29307 }; 29308 29309 /** 29310 * @returns {String} `settings.selector` rejecting spinner element 29311 */ 29312 JustifiedGallery.prototype.getSelectorWithoutSpinner = function () { 29313 return this.settings.selector + ', div:not(.jg-spinner)'; 29314 }; 29315 29316 /** 29317 * @returns {Array} all entries matched by `settings.selector` 29318 */ 29319 JustifiedGallery.prototype.getAllEntries = function () { 29320 var selector = this.getSelectorWithoutSpinner(); 29321 return this.$gallery.children(selector).toArray(); 29322 }; 29323 29324 /** 29325 * Update the entries searching it from the justified gallery HTML element 29326 * 29327 * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered) 29328 * @returns {boolean} true if some entries has been founded 29329 */ 29330 JustifiedGallery.prototype.updateEntries = function (norewind) { 29331 var newEntries; 29332 29333 if (norewind && this.lastFetchedEntry != null) { 29334 var selector = this.getSelectorWithoutSpinner(); 29335 newEntries = $(this.lastFetchedEntry).nextAll(selector).toArray(); 29336 } else { 29337 this.entries = []; 29338 newEntries = this.getAllEntries(); 29339 } 29340 29341 if (newEntries.length > 0) { 29342 29343 // Sort or randomize 29344 if ($.isFunction(this.settings.sort)) { 29345 newEntries = this.sortArray(newEntries); 29346 } else if (this.settings.randomize) { 29347 newEntries = this.shuffleArray(newEntries); 29348 } 29349 this.lastFetchedEntry = newEntries[newEntries.length - 1]; 29350 29351 // Filter 29352 if (this.settings.filter) { 29353 newEntries = this.filterArray(newEntries); 29354 } else { 29355 this.resetFilters(newEntries); 29356 } 29357 29358 } 29359 29360 this.entries = this.entries.concat(newEntries); 29361 return true; 29362 }; 29363 29364 /** 29365 * Apply the entries order to the DOM, iterating the entries and appending the images 29366 * 29367 * @param entries the entries that has been modified and that must be re-ordered in the DOM 29368 */ 29369 JustifiedGallery.prototype.insertToGallery = function (entries) { 29370 var that = this; 29371 $.each(entries, function () { 29372 $(this).appendTo(that.$gallery); 29373 }); 29374 }; 29375 29376 /** 29377 * Shuffle the array using the Fisher-Yates shuffle algorithm 29378 * 29379 * @param a the array to shuffle 29380 * @return the shuffled array 29381 */ 29382 JustifiedGallery.prototype.shuffleArray = function (a) { 29383 var i, j, temp; 29384 for (i = a.length - 1; i > 0; i--) { 29385 j = Math.floor(Math.random() * (i + 1)); 29386 temp = a[i]; 29387 a[i] = a[j]; 29388 a[j] = temp; 29389 } 29390 this.insertToGallery(a); 29391 return a; 29392 }; 29393 29394 /** 29395 * Sort the array using settings.comparator as comparator 29396 * 29397 * @param a the array to sort (it is sorted) 29398 * @return the sorted array 29399 */ 29400 JustifiedGallery.prototype.sortArray = function (a) { 29401 a.sort(this.settings.sort); 29402 this.insertToGallery(a); 29403 return a; 29404 }; 29405 29406 /** 29407 * Reset the filters removing the 'jg-filtered' class from all the entries 29408 * 29409 * @param a the array to reset 29410 */ 29411 JustifiedGallery.prototype.resetFilters = function (a) { 29412 for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered'); 29413 }; 29414 29415 /** 29416 * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering. 29417 * 29418 * @param a the array to filter 29419 * @return the filtered array 29420 */ 29421 JustifiedGallery.prototype.filterArray = function (a) { 29422 var settings = this.settings; 29423 if ($.type(settings.filter) === 'string') { 29424 // Filter only keeping the entries passed in the string 29425 return a.filter(function (el) { 29426 var $el = $(el); 29427 if ($el.is(settings.filter)) { 29428 $el.removeClass('jg-filtered'); 29429 return true; 29430 } else { 29431 $el.addClass('jg-filtered').removeClass('jg-visible'); 29432 return false; 29433 } 29434 }); 29435 } else if ($.isFunction(settings.filter)) { 29436 // Filter using the passed function 29437 var filteredArr = a.filter(settings.filter); 29438 for (var i = 0; i < a.length; i++) { 29439 if (filteredArr.indexOf(a[i]) === -1) { 29440 $(a[i]).addClass('jg-filtered').removeClass('jg-visible'); 29441 } else { 29442 $(a[i]).removeClass('jg-filtered'); 29443 } 29444 } 29445 return filteredArr; 29446 } 29447 }; 29448 29449 /** 29450 * Revert the image src to the default value. 29451 */ 29452 JustifiedGallery.prototype.resetImgSrc = function ($img) { 29453 if ($img.data('jg.originalSrcLoc') === 'src') { 29454 $img.attr('src', $img.data('jg.originalSrc')); 29455 } else { 29456 $img.attr('src', ''); 29457 } 29458 }; 29459 29460 /** 29461 * Destroy the Justified Gallery instance. 29462 * 29463 * It clears all the css properties added in the style attributes. We doesn't backup the original 29464 * values for those css attributes, because it costs (performance) and because in general one 29465 * shouldn't use the style attribute for an uniform set of images (where we suppose the use of 29466 * classes). Creating a backup is also difficult because JG could be called multiple times and 29467 * with different style attributes. 29468 */ 29469 JustifiedGallery.prototype.destroy = function () { 29470 clearInterval(this.checkWidthIntervalId); 29471 this.stopImgAnalyzerStarter(); 29472 29473 // Get fresh entries list since filtered entries are absent in `this.entries` 29474 $.each(this.getAllEntries(), $.proxy(function (_, entry) { 29475 var $entry = $(entry); 29476 29477 // Reset entry style 29478 $entry.css('width', ''); 29479 $entry.css('height', ''); 29480 $entry.css('top', ''); 29481 $entry.css('left', ''); 29482 $entry.data('jg.loaded', undefined); 29483 $entry.removeClass('jg-entry jg-filtered jg-entry-visible'); 29484 29485 // Reset image style 29486 var $img = this.imgFromEntry($entry); 29487 if ($img) { 29488 $img.css('width', ''); 29489 $img.css('height', ''); 29490 $img.css('margin-left', ''); 29491 $img.css('margin-top', ''); 29492 this.resetImgSrc($img); 29493 $img.data('jg.originalSrc', undefined); 29494 $img.data('jg.originalSrcLoc', undefined); 29495 $img.data('jg.src', undefined); 29496 } 29497 29498 // Remove caption 29499 this.removeCaptionEventsHandlers($entry); 29500 var $caption = this.captionFromEntry($entry); 29501 if ($entry.data('jg.createdCaption')) { 29502 // remove also the caption element (if created by jg) 29503 $entry.data('jg.createdCaption', undefined); 29504 if ($caption !== null) $caption.remove(); 29505 } else { 29506 if ($caption !== null) $caption.fadeTo(0, 1); 29507 } 29508 29509 }, this)); 29510 29511 this.$gallery.css('height', ''); 29512 this.$gallery.removeClass('justified-gallery'); 29513 this.$gallery.data('jg.controller', undefined); 29514 this.settings.triggerEvent.call(this, 'jg.destroy'); 29515 }; 29516 29517 /** 29518 * Analyze the images and builds the rows. It returns if it found an image that is not loaded. 29519 * 29520 * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end 29521 */ 29522 JustifiedGallery.prototype.analyzeImages = function (isForResize) { 29523 for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) { 29524 var $entry = $(this.entries[i]); 29525 if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') { 29526 var availableWidth = this.galleryWidth - 2 * this.border - ( 29527 (this.buildingRow.entriesBuff.length - 1) * this.settings.margins); 29528 var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height'); 29529 29530 this.buildingRow.entriesBuff.push($entry); 29531 this.buildingRow.aspectRatio += imgAspectRatio; 29532 this.buildingRow.width += imgAspectRatio * this.settings.rowHeight; 29533 this.lastAnalyzedIndex = i; 29534 29535 if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) { 29536 this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 29537 29538 if (++this.yield.flushed >= this.yield.every) { 29539 this.startImgAnalyzer(isForResize); 29540 return; 29541 } 29542 } 29543 } else if ($entry.data('jg.loaded') !== 'error') { 29544 return; 29545 } 29546 } 29547 29548 // Last row flush (the row is not full) 29549 if (this.buildingRow.entriesBuff.length > 0) { 29550 this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount); 29551 } 29552 29553 if (this.isSpinnerActive()) { 29554 this.stopLoadingSpinnerAnimation(); 29555 } 29556 29557 /* Stop, if there is, the timeout to start the analyzeImages. 29558 This is because an image can be set loaded, and the timeout can be set, 29559 but this image can be analyzed yet. 29560 */ 29561 this.stopImgAnalyzerStarter(); 29562 29563 this.setGalleryFinalHeight(this.galleryHeightToSet); 29564 29565 //On complete callback 29566 this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete'); 29567 }; 29568 29569 /** 29570 * Stops any ImgAnalyzer starter (that has an assigned timeout) 29571 */ 29572 JustifiedGallery.prototype.stopImgAnalyzerStarter = function () { 29573 this.yield.flushed = 0; 29574 if (this.imgAnalyzerTimeout !== null) { 29575 clearTimeout(this.imgAnalyzerTimeout); 29576 this.imgAnalyzerTimeout = null; 29577 } 29578 }; 29579 29580 /** 29581 * Starts the image analyzer. It is not immediately called to let the browser to update the view 29582 * 29583 * @param isForResize specifies if the image analyzer must be called for resizing or not 29584 */ 29585 JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) { 29586 var that = this; 29587 this.stopImgAnalyzerStarter(); 29588 this.imgAnalyzerTimeout = setTimeout(function () { 29589 that.analyzeImages(isForResize); 29590 }, 0.001); // we can't start it immediately due to a IE different behaviour 29591 }; 29592 29593 /** 29594 * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property, 29595 * because some browsers, with a 404 set complete = true. 29596 * 29597 * @param imageSrc the image src to load 29598 * @param onLoad callback that is called when the image has been loaded 29599 * @param onError callback that is called in case of an error 29600 */ 29601 JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) { 29602 if (!onLoad && !onError) return; 29603 29604 var memImage = new Image(); 29605 var $memImage = $(memImage); 29606 if (onLoad) { 29607 $memImage.one('load', function () { 29608 $memImage.off('load error'); 29609 onLoad(memImage); 29610 }); 29611 } 29612 if (onError) { 29613 $memImage.one('error', function () { 29614 $memImage.off('load error'); 29615 onError(memImage); 29616 }); 29617 } 29618 memImage.src = imageSrc; 29619 }; 29620 29621 /** 29622 * Init of Justified Gallery controlled 29623 * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images) 29624 */ 29625 JustifiedGallery.prototype.init = function () { 29626 var imagesToLoad = false, skippedImages = false, that = this; 29627 $.each(this.entries, function (index, entry) { 29628 var $entry = $(entry); 29629 var $image = that.imgFromEntry($entry); 29630 29631 $entry.addClass('jg-entry'); 29632 29633 if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') { 29634 29635 // Link Rel global overwrite 29636 if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel); 29637 29638 // Link Target global overwrite 29639 if (that.settings.target !== null) $entry.attr('target', that.settings.target); 29640 29641 if ($image !== null) { 29642 29643 // Image src 29644 var imageSrc = that.extractImgSrcFromImage($image); 29645 29646 /* If we have the height and the width, we don't wait that the image is loaded, 29647 but we start directly with the justification */ 29648 if (that.settings.waitThumbnailsLoad === false || !imageSrc) { 29649 var width = parseFloat($image.attr('width')); 29650 var height = parseFloat($image.attr('height')); 29651 if ($image.prop('tagName') === 'svg') { 29652 width = parseFloat($image[0].getBBox().width); 29653 height = parseFloat($image[0].getBBox().height); 29654 } 29655 if (!isNaN(width) && !isNaN(height)) { 29656 $entry.data('jg.width', width); 29657 $entry.data('jg.height', height); 29658 $entry.data('jg.loaded', 'skipped'); 29659 skippedImages = true; 29660 that.startImgAnalyzer(false); 29661 return true; // continue 29662 } 29663 } 29664 29665 $entry.data('jg.loaded', false); 29666 imagesToLoad = true; 29667 29668 // Spinner start 29669 if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation(); 29670 29671 that.onImageEvent(imageSrc, function (loadImg) { // image loaded 29672 $entry.data('jg.width', loadImg.width); 29673 $entry.data('jg.height', loadImg.height); 29674 $entry.data('jg.loaded', true); 29675 that.startImgAnalyzer(false); 29676 }, function () { // image load error 29677 $entry.data('jg.loaded', 'error'); 29678 that.startImgAnalyzer(false); 29679 }); 29680 29681 } else { 29682 $entry.data('jg.loaded', true); 29683 $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1); 29684 $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1); 29685 } 29686 29687 } 29688 29689 }); 29690 29691 if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false); 29692 this.checkWidth(); 29693 }; 29694 29695 /** 29696 * Checks that it is a valid number. If a string is passed it is converted to a number 29697 * 29698 * @param settingContainer the object that contains the setting (to allow the conversion) 29699 * @param settingName the setting name 29700 */ 29701 JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) { 29702 if ($.type(settingContainer[settingName]) === 'string') { 29703 settingContainer[settingName] = parseFloat(settingContainer[settingName]); 29704 } 29705 29706 if ($.type(settingContainer[settingName]) === 'number') { 29707 if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName; 29708 } else { 29709 throw settingName + ' must be a number'; 29710 } 29711 }; 29712 29713 /** 29714 * Checks the sizeRangeSuffixes and, if necessary, converts 29715 * its keys from string (e.g. old settings with 'lt100') to int. 29716 */ 29717 JustifiedGallery.prototype.checkSizeRangesSuffixes = function () { 29718 if ($.type(this.settings.sizeRangeSuffixes) !== 'object') { 29719 throw 'sizeRangeSuffixes must be defined and must be an object'; 29720 } 29721 29722 var suffixRanges = []; 29723 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 29724 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx); 29725 } 29726 29727 var newSizeRngSuffixes = { 0: '' }; 29728 for (var i = 0; i < suffixRanges.length; i++) { 29729 if ($.type(suffixRanges[i]) === 'string') { 29730 try { 29731 var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10); 29732 newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 29733 } catch (e) { 29734 throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')'; 29735 } 29736 } else { 29737 newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]]; 29738 } 29739 } 29740 29741 this.settings.sizeRangeSuffixes = newSizeRngSuffixes; 29742 }; 29743 29744 /** 29745 * check and convert the maxRowHeight setting 29746 * requires rowHeight to be already set 29747 * TODO: should be always called when only rowHeight is changed 29748 * @return number or null 29749 */ 29750 JustifiedGallery.prototype.retrieveMaxRowHeight = function () { 29751 var newMaxRowHeight = null; 29752 var rowHeight = this.settings.rowHeight; 29753 29754 if ($.type(this.settings.maxRowHeight) === 'string') { 29755 if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) { 29756 newMaxRowHeight = rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100; 29757 } else { 29758 newMaxRowHeight = parseFloat(this.settings.maxRowHeight); 29759 } 29760 } else if ($.type(this.settings.maxRowHeight) === 'number') { 29761 newMaxRowHeight = this.settings.maxRowHeight; 29762 } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight == null) { 29763 return null; 29764 } else { 29765 throw 'maxRowHeight must be a number or a percentage'; 29766 } 29767 29768 // check if the converted value is not a number 29769 if (isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight'; 29770 29771 // check values, maxRowHeight must be >= rowHeight 29772 if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight; 29773 29774 return newMaxRowHeight; 29775 }; 29776 29777 /** 29778 * Checks the settings 29779 */ 29780 JustifiedGallery.prototype.checkSettings = function () { 29781 this.checkSizeRangesSuffixes(); 29782 29783 this.checkOrConvertNumber(this.settings, 'rowHeight'); 29784 this.checkOrConvertNumber(this.settings, 'margins'); 29785 this.checkOrConvertNumber(this.settings, 'border'); 29786 this.checkOrConvertNumber(this.settings, 'maxRowsCount'); 29787 29788 var lastRowModes = [ 29789 'justify', 29790 'nojustify', 29791 'left', 29792 'center', 29793 'right', 29794 'hide' 29795 ]; 29796 if (lastRowModes.indexOf(this.settings.lastRow) === -1) { 29797 throw 'lastRow must be one of: ' + lastRowModes.join(', '); 29798 } 29799 29800 this.checkOrConvertNumber(this.settings, 'justifyThreshold'); 29801 if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) { 29802 throw 'justifyThreshold must be in the interval [0,1]'; 29803 } 29804 if ($.type(this.settings.cssAnimation) !== 'boolean') { 29805 throw 'cssAnimation must be a boolean'; 29806 } 29807 29808 if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean'; 29809 this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration'); 29810 29811 this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity'); 29812 if (this.settings.captionSettings.visibleOpacity < 0 || 29813 this.settings.captionSettings.visibleOpacity > 1) { 29814 throw 'captionSettings.visibleOpacity must be in the interval [0, 1]'; 29815 } 29816 29817 this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity'); 29818 if (this.settings.captionSettings.nonVisibleOpacity < 0 || 29819 this.settings.captionSettings.nonVisibleOpacity > 1) { 29820 throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]'; 29821 } 29822 29823 this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration'); 29824 this.checkOrConvertNumber(this.settings, 'refreshTime'); 29825 this.checkOrConvertNumber(this.settings, 'refreshSensitivity'); 29826 if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean'; 29827 if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string'; 29828 29829 if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) { 29830 throw 'sort must be false or a comparison function'; 29831 } 29832 29833 if (this.settings.filter !== false && !$.isFunction(this.settings.filter) && 29834 $.type(this.settings.filter) !== 'string') { 29835 throw 'filter must be false, a string or a filter function'; 29836 } 29837 }; 29838 29839 /** 29840 * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned. 29841 * @returns {Array} sorted suffix ranges 29842 */ 29843 JustifiedGallery.prototype.retrieveSuffixRanges = function () { 29844 var suffixRanges = []; 29845 for (var rangeIdx in this.settings.sizeRangeSuffixes) { 29846 if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10)); 29847 } 29848 suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; }); 29849 return suffixRanges; 29850 }; 29851 29852 /** 29853 * Update the existing settings only changing some of them 29854 * 29855 * @param newSettings the new settings (or a subgroup of them) 29856 */ 29857 JustifiedGallery.prototype.updateSettings = function (newSettings) { 29858 // In this case Justified Gallery has been called again changing only some options 29859 this.settings = $.extend({}, this.settings, newSettings); 29860 this.checkSettings(); 29861 29862 // As reported in the settings: negative value = same as margins, 0 = disabled 29863 this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins; 29864 29865 this.maxRowHeight = this.retrieveMaxRowHeight(); 29866 this.suffixRanges = this.retrieveSuffixRanges(); 29867 }; 29868 29869 JustifiedGallery.prototype.defaults = { 29870 sizeRangeSuffixes: {}, /* e.g. Flickr configuration 29871 { 29872 100: '_t', // used when longest is less than 100px 29873 240: '_m', // used when longest is between 101px and 240px 29874 320: '_n', // ... 29875 500: '', 29876 640: '_z', 29877 1024: '_b' // used as else case because it is the last 29878 } 29879 */ 29880 thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the 29881 path relative to a specific thumbnail size. The function should accept respectively three arguments: 29882 current path, width and height */ 29883 rowHeight: 120, // required? required to be > 0? 29884 maxRowHeight: false, // false or negative value to deactivate. Positive number to express the value in pixels, 29885 // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height 29886 // can't exceed 3 * rowHeight) 29887 maxRowsCount: 0, // maximum number of rows to be displayed (0 = disabled) 29888 margins: 1, 29889 border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border 29890 29891 lastRow: 'nojustify', // ⦠which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide' 29892 29893 justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified 29894 * (i.e. lastRow setting is not considered) */ 29895 waitThumbnailsLoad: true, 29896 captions: true, 29897 cssAnimation: true, 29898 imagesAnimationDuration: 500, // ignored with css animations 29899 captionSettings: { // ignored with css animations 29900 animationDuration: 500, 29901 visibleOpacity: 0.7, 29902 nonVisibleOpacity: 0.0 29903 },
29904 rel: null, // rewrite the rel of each analyzed links 29905 target: null, // rewrite the target of all links 29906 extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image 29907 refreshTime: 200, // time interval (in ms) to check if the page changes its width 29908 refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery 29909 randomize: false, 29910 rtl: false, // right-to-left mode 29911 sort: false, /* 29912 - false: to do not sort 29913 - function: to sort them using the function as comparator (see Array.prototype.sort()) 29914 */ 29915 filter: false, /* 29916 - false, null or undefined: for a disabled filter 29917 - a string: an entry is kept if entry.is(filter string) returns true 29918 see jQuery's .is() function for further information 29919 - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise. 29920 It follows the specifications of the Array.prototype.filter() function of JavaScript. 29921 */ 29922 selector: 'a', // The selector that is used to know what are the entries of the gallery 29923 imgSelector: '> img, > a > img, > svg, > a > svg', // The selector that is used to know what are the images of each entry 29924 triggerEvent: function (event) { // This is called to trigger events, the default behavior is to call $.trigger 29925 this.$gallery.trigger(event); // Consider that 'this' is this set to the JustifiedGallery object, so it can 29926 } // access to fields such as $gallery, useful to trigger events with jQuery. 29927 }; 29928 29929 29930 /** 29931 * Justified Gallery plugin for jQuery 29932 * 29933 * Events 29934 * - jg.complete : called when all the gallery has been created 29935 * - jg.resize : called when the gallery has been resized 29936 * - jg.rowflush : when a new row appears 29937 * 29938 * @param arg the action (or the settings) passed when the plugin is called 29939 * @returns {*} the object itself 29940 */ 29941 $.fn.justifiedGallery = function (arg) { 29942 return this.each(function (index, gallery) { 29943 29944 var $gallery = $(gallery); 29945 $gallery.addClass('justified-gallery'); 29946 29947 var controller = $gallery.data('jg.controller'); 29948 if (typeof controller === 'undefined') { 29949 // Create controller and assign it to the object data 29950 if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') { 29951 if (arg === 'destroy') return; // Just a call to an unexisting object 29952 throw 'The argument must be an object'; 29953 } 29954 controller = new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg)); 29955 $gallery.data('jg.controller', controller); 29956 } else if (arg === 'norewind') { 29957 // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row 29958 // ... left to be more readable 29959 } else if (arg === 'destroy') { 29960 controller.destroy(); 29961 return; 29962 } else { 29963 // In this case Justified Gallery has been called again changing only some options 29964 controller.updateSettings(arg); 29965 controller.rewind(); 29966 } 29967 29968 // Update the entries list 29969 if (!controller.updateEntries(arg === 'norewind')) return; 29970 29971 // Init justified gallery 29972 controller.init(); 29973 29974 }); 29975 }; 29976 29977})); 29978 29979/*! 29980* Customized version of iScroll.js 0.0.1 29981* It fixes bugs affecting its integration with fullpage.js 29982*/ 29983/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */ 29984(function (window, document, Math) { 29985var rAF = window.requestAnimationFrame || 29986 window.webkitRequestAnimationFrame || 29987 window.mozRequestAnimationFrame || 29988 window.oRequestAnimationFrame || 29989 window.msRequestAnimationFrame || 29990 function (callback) { window.setTimeout(callback, 1000 / 60); }; 29991 29992var utils = (function () { 29993 var me = {}; 29994 29995 var _elementStyle = document.createElement('div').style; 29996 var _vendor = (function () { 29997 var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], 29998 transform, 29999 i = 0, 30000 l = vendors.length; 30001 30002 for ( ; i < l; i++ ) { 30003 transform = vendors[i] + 'ransform'; 30004 if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); 30005 } 30006 30007 return false;
30008 })(); 30009 30010 function _prefixStyle (style) { 30011 if ( _vendor === false ) return false; 30012 if ( _vendor === '' ) return style; 30013 return _vendor + style.charAt(0).toUpperCase() + style.substr(1); 30014 } 30015 30016 me.getTime = Date.now || function getTime () { return new Date().getTime(); }; 30017 30018 me.extend = function (target, obj) { 30019 for ( var i in obj ) { 30020 target[i] = obj[i]; 30021 } 30022 }; 30023 30024 me.addEvent = function (el, type, fn, capture) { 30025 el.addEventListener(type, fn, !!capture); 30026 }; 30027 30028 me.removeEvent = function (el, type, fn, capture) { 30029 el.removeEventListener(type, fn, !!capture); 30030 }; 30031 30032 me.prefixPointerEvent = function (pointerEvent) { 30033 return window.MSPointerEvent ? 30034 'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8): 30035 pointerEvent; 30036 }; 30037 30038 me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { 30039 var distance = current - start, 30040 speed = Math.abs(distance) / time, 30041 destination, 30042 duration; 30043 30044 deceleration = deceleration === undefined ? 0.0006 : deceleration; 30045 30046 destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); 30047 duration = speed / deceleration; 30048 30049 if ( destination < lowerMargin ) { 30050 destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; 30051 distance = Math.abs(destination - current); 30052 duration = distance / speed; 30053 } else if ( destination > 0 ) { 30054 destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; 30055 distance = Math.abs(current) + destination; 30056 duration = distance / speed; 30057 } 30058 30059 return { 30060 destination: Math.round(destination), 30061 duration: duration 30062 }; 30063 }; 30064 30065 var _transform = _prefixStyle('transform'); 30066 30067 me.extend(me, { 30068 hasTransform: _transform !== false, 30069 hasPerspective: _prefixStyle('perspective') in _elementStyle, 30070 hasTouch: 'ontouchstart' in window, 30071 hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed 30072 hasTransition: _prefixStyle('transition') in _elementStyle 30073 }); 30074 30075 /* 30076 This should find all Android browsers lower than build 535.19 (both stock browser and webview) 30077 - galaxy S2 is ok 30078 - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1` 30079 - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 30080 - galaxy S3 is badAndroid (stock brower, webview) 30081 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 30082 - galaxy S4 is badAndroid (stock brower, webview) 30083 `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30` 30084 - galaxy S5 is OK 30085 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 30086 - galaxy S6 is OK 30087 `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)` 30088 */ 30089 me.isBadAndroid = (function() { 30090 var appVersion = window.navigator.appVersion; 30091 // Android browser is not a chrome browser. 30092 if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) { 30093 var safariVersion = appVersion.match(/Safari\/(\d+.\d)/); 30094 if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) { 30095 return parseFloat(safariVersion[1]) < 535.19; 30096 } else { 30097 return true; 30098 } 30099 } else { 30100 return false; 30101 } 30102 })(); 30103 30104 me.extend(me.style = {}, { 30105 transform: _transform, 30106 transitionTimingFunction: _prefixStyle('transitionTimingFunction'), 30107 transitionDuration: _prefixStyle('transitionDuration'), 30108 transitionDelay: _prefixStyle('transitionDelay'), 30109 transformOrigin: _prefixStyle('transformOrigin') 30110 }); 30111 30112 me.hasClass = function (e, c) { 30113 var re = new RegExp("(^|\\s)" + c + "(\\s|$)"); 30114 return re.test(e.className); 30115 }; 30116 30117 me.addClass = function (e, c) { 30118 if ( me.hasClass(e, c) ) { 30119 return; 30120 } 30121 30122 var newclass = e.className.split(' '); 30123 newclass.push(c); 30124 e.className = newclass.join(' '); 30125 }; 30126 30127 me.removeClass = function (e, c) { 30128 if ( !me.hasClass(e, c) ) { 30129 return; 30130 } 30131 30132 var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g'); 30133 e.className = e.className.replace(re, ' '); 30134 }; 30135 30136 me.offset = function (el) { 30137 var left = -el.offsetLeft, 30138 top = -el.offsetTop; 30139 30140 // jshint -W084 30141 while (el = el.offsetParent) { 30142 left -= el.offsetLeft; 30143 top -= el.offsetTop; 30144 } 30145 // jshint +W084 30146 30147 return { 30148 left: left, 30149 top: top 30150 }; 30151 }; 30152 30153 me.preventDefaultException = function (el, exceptions) { 30154 for ( var i in exceptions ) { 30155 if ( exceptions[i].test(el[i]) ) { 30156 return true; 30157 } 30158 } 30159 30160 return false;
30161 }; 30162 30163 me.extend(me.eventType = {}, { 30164 touchstart: 1, 30165 touchmove: 1, 30166 touchend: 1, 30167 30168 mousedown: 2, 30169 mousemove: 2, 30170 mouseup: 2, 30171 30172 pointerdown: 3, 30173 pointermove: 3, 30174 pointerup: 3, 30175 30176 MSPointerDown: 3, 30177 MSPointerMove: 3, 30178 MSPointerUp: 3 30179 }); 30180 30181 me.extend(me.ease = {}, { 30182 quadratic: { 30183 style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', 30184 fn: function (k) { 30185 return k * ( 2 - k ); 30186 } 30187 }, 30188 circular: { 30189 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) 30190 fn: function (k) { 30191 return Math.sqrt( 1 - ( --k * k ) ); 30192 } 30193 }, 30194 back: { 30195 style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', 30196 fn: function (k) { 30197 var b = 4; 30198 return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; 30199 } 30200 }, 30201 bounce: { 30202 style: '', 30203 fn: function (k) { 30204 if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { 30205 return 7.5625 * k * k; 30206 } else if ( k < ( 2 / 2.75 ) ) { 30207 return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; 30208 } else if ( k < ( 2.5 / 2.75 ) ) { 30209 return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; 30210 } else { 30211 return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; 30212 } 30213 } 30214 }, 30215 elastic: { 30216 style: '', 30217 fn: function (k) { 30218 var f = 0.22, 30219 e = 0.4; 30220 30221 if ( k === 0 ) { return 0; } 30222 if ( k == 1 ) { return 1; } 30223 30224 return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); 30225 } 30226 } 30227 }); 30228 30229 me.tap = function (e, eventName) { 30230 var ev = document.createEvent('Event'); 30231 ev.initEvent(eventName, true, true); 30232 ev.pageX = e.pageX; 30233 ev.pageY = e.pageY; 30234 e.target.dispatchEvent(ev); 30235 }; 30236 30237 me.click = function (e) { 30238 var target = e.target, 30239 ev; 30240 30241 if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { 30242 // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent 30243 // initMouseEvent is deprecated. 30244 ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event'); 30245 ev.initEvent('click', true, true); 30246 ev.view = e.view || window; 30247 ev.detail = 1; 30248 ev.screenX = target.screenX || 0; 30249 ev.screenY = target.screenY || 0; 30250 ev.clientX = target.clientX || 0; 30251 ev.clientY = target.clientY || 0; 30252 ev.ctrlKey = !!e.ctrlKey; 30253 ev.altKey = !!e.altKey; 30254 ev.shiftKey = !!e.shiftKey; 30255 ev.metaKey = !!e.metaKey; 30256 ev.button = 0; 30257 ev.relatedTarget = null; 30258 ev._constructed = true; 30259 target.dispatchEvent(ev); 30260 } 30261 }; 30262 30263 return me; 30264})(); 30265function IScroll (el, options) { 30266 this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; 30267 this.scroller = this.wrapper.children[0]; 30268 this.scrollerStyle = this.scroller.style; // cache style for better performance 30269 30270 this.options = { 30271 30272 resizeScrollbars: true, 30273 30274 mouseWheelSpeed: 20, 30275 30276 snapThreshold: 0.334, 30277 30278// INSERT POINT: OPTIONS 30279 disablePointer : !utils.hasPointer, 30280 disableTouch : utils.hasPointer || !utils.hasTouch, 30281 disableMouse : utils.hasPointer || utils.hasTouch, 30282 startX: 0, 30283 startY: 0, 30284 scrollY: true, 30285 directionLockThreshold: 5, 30286 momentum: true, 30287 30288 bounce: true, 30289 bounceTime: 600, 30290 bounceEasing: '', 30291 30292 preventDefault: true, 30293 preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL)$/ }, 30294 30295 HWCompositing: true, 30296 useTransition: true, 30297 useTransform: true, 30298 bindToWrapper: typeof window.onmousedown === "undefined" 30299 }; 30300 30301 for ( var i in options ) { 30302 this.options[i] = options[i]; 30303 } 30304 30305 // Normalize options 30306 this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : ''; 30307 30308 this.options.useTransition = utils.hasTransition && this.options.useTransition; 30309 this.options.useTransform = utils.hasTransform && this.options.useTransform; 30310 30311 this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; 30312 this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; 30313 30314 // If you want eventPassthrough I have to lock one of the axes 30315 this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; 30316 this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; 30317 30318 // With eventPassthrough we also need lockDirection mechanism 30319 this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; 30320 this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; 30321 30322 this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; 30323 30324 this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; 30325 30326 if ( this.options.tap === true ) {
30327 this.options.tap = 'tap'; 30328 } 30329 30330 // https://github.com/cubiq/iscroll/issues/1029 30331 if (!this.options.useTransition && !this.options.useTransform) { 30332 if(!(/relative|absolute/i).test(this.scrollerStyle.position)) { 30333 this.scrollerStyle.position = "relative"; 30334 } 30335 } 30336 30337 if ( this.options.shrinkScrollbars == 'scale' ) { 30338 this.options.useTransition = false; 30339 } 30340 30341 this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1; 30342 30343// INSERT POINT: NORMALIZATION 30344 30345 // Some defaults 30346 this.x = 0; 30347 this.y = 0; 30348 this.directionX = 0; 30349 this.directionY = 0; 30350 this._events = {}; 30351 30352// INSERT POINT: DEFAULTS 30353 30354 this._init(); 30355 this.refresh(); 30356 30357 this.scrollTo(this.options.startX, this.options.startY); 30358 this.enable(); 30359} 30360 30361IScroll.prototype = { 30362 version: '5.2.0', 30363 30364 _init: function () { 30365 this._initEvents(); 30366 30367 if ( this.options.scrollbars || this.options.indicators ) { 30368 this._initIndicators(); 30369 } 30370 30371 if ( this.options.mouseWheel ) { 30372 this._initWheel(); 30373 } 30374 30375 if ( this.options.snap ) { 30376 this._initSnap(); 30377 } 30378 30379 if ( this.options.keyBindings ) { 30380 this._initKeys(); 30381 } 30382 30383// INSERT POINT: _init 30384 30385 }, 30386 30387 destroy: function () { 30388 this._initEvents(true); 30389 clearTimeout(this.resizeTimeout); 30390 this.resizeTimeout = null; 30391 this._execEvent('destroy'); 30392 }, 30393 30394 _transitionEnd: function (e) { 30395 if ( e.target != this.scroller || !this.isInTransition ) { 30396 return; 30397 } 30398 30399 this._transitionTime(); 30400 if ( !this.resetPosition(this.options.bounceTime) ) { 30401 this.isInTransition = false; 30402 this._execEvent('scrollEnd'); 30403 } 30404 }, 30405 30406 _start: function (e) { 30407 // React to left mouse button only 30408 if ( utils.eventType[e.type] != 1 ) { 30409 // for button property 30410 // http://unixpapa.com/js/mouse.html 30411 var button; 30412 if (!e.which) { 30413 /* IE case */ 30414 button = (e.button < 2) ? 0 : 30415 ((e.button == 4) ? 1 : 2); 30416 } else { 30417 /* All others */ 30418 button = e.button; 30419 } 30420 if ( button !== 0 ) { 30421 return; 30422 } 30423 } 30424 30425 if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { 30426 return; 30427 } 30428 30429 if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 30430 e.preventDefault(); 30431 } 30432 30433 var point = e.touches ? e.touches[0] : e, 30434 pos; 30435 30436 this.initiated = utils.eventType[e.type]; 30437 this.moved = false; 30438 this.distX = 0; 30439 this.distY = 0; 30440 this.directionX = 0; 30441 this.directionY = 0; 30442 this.directionLocked = 0; 30443 30444 this.startTime = utils.getTime(); 30445 30446 if ( this.options.useTransition && this.isInTransition ) { 30447 this._transitionTime(); 30448 this.isInTransition = false; 30449 pos = this.getComputedPosition(); 30450 this._translate(Math.round(pos.x), Math.round(pos.y)); 30451 this._execEvent('scrollEnd'); 30452 } else if ( !this.options.useTransition && this.isAnimating ) { 30453 this.isAnimating = false; 30454 this._execEvent('scrollEnd'); 30455 } 30456 30457 this.startX = this.x; 30458 this.startY = this.y; 30459 this.absStartX = this.x; 30460 this.absStartY = this.y; 30461 this.pointX = point.pageX; 30462 this.pointY = point.pageY; 30463 30464 this._execEvent('beforeScrollStart'); 30465 }, 30466 30467 _move: function (e) { 30468 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 30469 return; 30470 } 30471 30472 if ( this.options.preventDefault ) { // increases performance on Android? TODO: check! 30473 e.preventDefault(); 30474 } 30475 30476 var point = e.touches ? e.touches[0] : e, 30477 deltaX = point.pageX - this.pointX, 30478 deltaY = point.pageY - this.pointY, 30479 timestamp = utils.getTime(), 30480 newX, newY, 30481 absDistX, absDistY; 30482 30483 this.pointX = point.pageX; 30484 this.pointY = point.pageY; 30485 30486 this.distX += deltaX; 30487 this.distY += deltaY; 30488 absDistX = Math.abs(this.distX); 30489 absDistY = Math.abs(this.distY); 30490 30491 // We need to move at least 10 pixels for the scrolling to initiate 30492 if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { 30493 return; 30494 } 30495 30496 // If you are scrolling in one direction lock the other 30497 if ( !this.directionLocked && !this.options.freeScroll ) { 30498 if ( absDistX > absDistY + this.options.directionLockThreshold ) {
30499 this.directionLocked = 'h'; // lock horizontally 30500 } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { 30501 this.directionLocked = 'v'; // lock vertically 30502 } else { 30503 this.directionLocked = 'n'; // no lock 30504 } 30505 } 30506 30507 if ( this.directionLocked == 'h' ) { 30508 if ( this.options.eventPassthrough == 'vertical' ) { 30509 e.preventDefault(); 30510 } else if ( this.options.eventPassthrough == 'horizontal' ) { 30511 this.initiated = false; 30512 return; 30513 } 30514 30515 deltaY = 0; 30516 } else if ( this.directionLocked == 'v' ) { 30517 if ( this.options.eventPassthrough == 'horizontal' ) { 30518 e.preventDefault(); 30519 } else if ( this.options.eventPassthrough == 'vertical' ) { 30520 this.initiated = false; 30521 return; 30522 } 30523 30524 deltaX = 0; 30525 } 30526 30527 deltaX = this.hasHorizontalScroll ? deltaX : 0; 30528 deltaY = this.hasVerticalScroll ? deltaY : 0; 30529 30530 newX = this.x + deltaX; 30531 newY = this.y + deltaY; 30532 30533 // Slow down if outside of the boundaries 30534 if ( newX > 0 || newX < this.maxScrollX ) { 30535 newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; 30536 } 30537 if ( newY > 0 || newY < this.maxScrollY ) { 30538 newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; 30539 } 30540 30541 this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; 30542 this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; 30543 30544 if ( !this.moved ) { 30545 this._execEvent('scrollStart'); 30546 } 30547 30548 this.moved = true; 30549 30550 this._translate(newX, newY); 30551 30552/* REPLACE START: _move */ 30553 30554 if ( timestamp - this.startTime > 300 ) { 30555 this.startTime = timestamp; 30556 this.startX = this.x; 30557 this.startY = this.y; 30558 } 30559 30560/* REPLACE END: _move */ 30561 30562 }, 30563 30564 _end: function (e) { 30565 if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { 30566 return; 30567 } 30568 30569 if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { 30570 e.preventDefault(); 30571 } 30572 30573 var point = e.changedTouches ? e.changedTouches[0] : e, 30574 momentumX, 30575 momentumY, 30576 duration = utils.getTime() - this.startTime, 30577 newX = Math.round(this.x), 30578 newY = Math.round(this.y), 30579 distanceX = Math.abs(newX - this.startX), 30580 distanceY = Math.abs(newY - this.startY), 30581 time = 0, 30582 easing = ''; 30583 30584 this.isInTransition = 0; 30585 this.initiated = 0; 30586 this.endTime = utils.getTime(); 30587 30588 // reset if we are outside of the boundaries 30589 if ( this.resetPosition(this.options.bounceTime) ) { 30590 return; 30591 } 30592 30593 this.scrollTo(newX, newY); // ensures that the last position is rounded 30594 30595 // we scrolled less than 10 pixels 30596 if ( !this.moved ) { 30597 if ( this.options.tap ) { 30598 utils.tap(e, this.options.tap); 30599 } 30600 30601 if ( this.options.click ) { 30602 utils.click(e); 30603 } 30604 30605 this._execEvent('scrollCancel'); 30606 return; 30607 } 30608 30609 if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) { 30610 this._execEvent('flick'); 30611 return; 30612 } 30613 30614 // start momentum animation if needed 30615 if ( this.options.momentum && duration < 300 ) { 30616 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 }; 30617 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 }; 30618 newX = momentumX.destination; 30619 newY = momentumY.destination; 30620 time = Math.max(momentumX.duration, momentumY.duration); 30621 this.isInTransition = 1; 30622 } 30623 30624 30625 if ( this.options.snap ) { 30626 var snap = this._nearestSnap(newX, newY); 30627 this.currentPage = snap; 30628 time = this.options.snapSpeed || Math.max( 30629 Math.max( 30630 Math.min(Math.abs(newX - snap.x), 1000), 30631 Math.min(Math.abs(newY - snap.y), 1000) 30632 ), 300); 30633 newX = snap.x; 30634 newY = snap.y; 30635 30636 this.directionX = 0; 30637 this.directionY = 0; 30638 easing = this.options.bounceEasing; 30639 } 30640 30641// INSERT POINT: _end 30642 30643 if ( newX != this.x || newY != this.y ) { 30644 // change easing function when scroller goes out of the boundaries 30645 if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { 30646 easing = utils.ease.quadratic; 30647 } 30648 30649 this.scrollTo(newX, newY, time, easing); 30650 return; 30651 } 30652 30653 this._execEvent('scrollEnd'); 30654 }, 30655 30656 _resize: function () { 30657 var that = this; 30658 30659 clearTimeout(this.resizeTimeout); 30660 30661 this.resizeTimeout = setTimeout(function () { 30662 that.refresh(); 30663 }, this.options.resizePolling); 30664 }, 30665 30666 resetPosition: function (time) { 30667 var x = this.x, 30668 y = this.y; 30669 30670 time = time || 0; 30671 30672 if ( !this.hasHorizontalScroll || this.x > 0 ) { 30673 x = 0; 30674 } else if ( this.x < this.maxScrollX ) { 30675 x = this.maxScrollX; 30676 } 30677 30678 if ( !this.hasVerticalScroll || this.y > 0 ) { 30679 y = 0; 30680 } else if ( this.y < this.maxScrollY ) { 30681 y = this.maxScrollY; 30682 } 30683 30684 if ( x == this.x && y == this.y ) { 30685 return false;
30686 } 30687 30688 this.scrollTo(x, y, time, this.options.bounceEasing); 30689 30690 return true; 30691 }, 30692 30693 disable: function () { 30694 this.enabled = false; 30695 }, 30696 30697 enable: function () { 30698 this.enabled = true; 30699 }, 30700 30701 refresh: function () { 30702 var rf = this.wrapper.offsetHeight; // Force reflow 30703 30704 this.wrapperWidth = this.wrapper.clientWidth; 30705 this.wrapperHeight = this.wrapper.clientHeight; 30706 30707/* REPLACE START: refresh */ 30708 30709 this.scrollerWidth = this.scroller.offsetWidth; 30710 this.scrollerHeight = this.scroller.offsetHeight; 30711 30712 this.maxScrollX = this.wrapperWidth - this.scrollerWidth; 30713 this.maxScrollY = this.wrapperHeight - this.scrollerHeight; 30714 30715/* REPLACE END: refresh */ 30716 30717 this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; 30718 this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; 30719 30720 if ( !this.hasHorizontalScroll ) { 30721 this.maxScrollX = 0; 30722 this.scrollerWidth = this.wrapperWidth; 30723 } 30724 30725 if ( !this.hasVerticalScroll ) { 30726 this.maxScrollY = 0; 30727 this.scrollerHeight = this.wrapperHeight; 30728 } 30729 30730 this.endTime = 0; 30731 this.directionX = 0; 30732 this.directionY = 0; 30733 30734 this.wrapperOffset = utils.offset(this.wrapper); 30735 30736 this._execEvent('refresh'); 30737 30738 this.resetPosition(); 30739 30740// INSERT POINT: _refresh 30741 30742 }, 30743 30744 30745 on: function (type, fn) { 30746 if ( !this._events[type] ) { 30747 this._events[type] = []; 30748 } 30749 30750 this._events[type].push(fn); 30751 }, 30752 30753 off: function (type, fn) { 30754 if ( !this._events[type] ) { 30755 return; 30756 } 30757 30758 var index = this._events[type].indexOf(fn); 30759 30760 if ( index > -1 ) { 30761 this._events[type].splice(index, 1); 30762 } 30763 }, 30764 30765 _execEvent: function (type) { 30766 if ( !this._events[type] ) { 30767 return; 30768 } 30769 30770 var i = 0, 30771 l = this._events[type].length; 30772 30773 if ( !l ) { 30774 return; 30775 } 30776 30777 for ( ; i < l; i++ ) { 30778 this._events[type][i].apply(this, [].slice.call(arguments, 1)); 30779 } 30780 }, 30781 30782 scrollBy: function (x, y, time, easing) { 30783 x = this.x + x; 30784 y = this.y + y; 30785 time = time || 0; 30786 30787 this.scrollTo(x, y, time, easing); 30788 }, 30789 30790 scrollTo: function (x, y, time, easing) { 30791 easing = easing || utils.ease.circular; 30792 30793 this.isInTransition = this.options.useTransition && time > 0; 30794 var transitionType = this.options.useTransition && easing.style; 30795 if ( !time || transitionType ) { 30796 if(transitionType) { 30797 this._transitionTimingFunction(easing.style); 30798 this._transitionTime(time); 30799 } 30800 this._translate(x, y); 30801 } else { 30802 this._animate(x, y, time, easing.fn); 30803 } 30804 }, 30805 30806 scrollToElement: function (el, time, offsetX, offsetY, easing) { 30807 el = el.nodeType ? el : this.scroller.querySelector(el); 30808 30809 if ( !el ) { 30810 return; 30811 } 30812 30813 var pos = utils.offset(el); 30814 30815 pos.left -= this.wrapperOffset.left; 30816 pos.top -= this.wrapperOffset.top; 30817 30818 // if offsetX/Y are true we center the element to the screen 30819 if ( offsetX === true ) { 30820 offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); 30821 } 30822 if ( offsetY === true ) { 30823 offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); 30824 } 30825 30826 pos.left -= offsetX || 0; 30827 pos.top -= offsetY || 0; 30828 30829 pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; 30830 pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; 30831 30832 time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; 30833 30834 this.scrollTo(pos.left, pos.top, time, easing); 30835 }, 30836 30837 _transitionTime: function (time) { 30838 if (!this.options.useTransition) { 30839 return; 30840 } 30841 time = time || 0; 30842 var durationProp = utils.style.transitionDuration; 30843 if(!durationProp) { 30844 return; 30845 } 30846 30847 this.scrollerStyle[durationProp] = time + 'ms'; 30848 30849 if ( !time && utils.isBadAndroid ) { 30850 this.scrollerStyle[durationProp] = '0.0001ms'; 30851 // remove 0.0001ms 30852 var self = this; 30853 rAF(function() { 30854 if(self.scrollerStyle[durationProp] === '0.0001ms') { 30855 self.scrollerStyle[durationProp] = '0s'; 30856 } 30857 }); 30858 } 30859 30860 30861 if ( this.indicators ) { 30862 for ( var i = this.indicators.length; i--; ) { 30863 this.indicators[i].transitionTime(time); 30864 } 30865 } 30866 30867 30868// INSERT POINT: _transitionTime 30869 30870 }, 30871 30872 _transitionTimingFunction: function (easing) { 30873 this.scrollerStyle[utils.style.transitionTimingFunction] = easing; 30874 30875 30876 if ( this.indicators ) { 30877 for ( var i = this.indicators.length; i--; ) { 30878 this.indicators[i].transitionTimingFunction(easing); 30879 } 30880 } 30881 30882 30883// INSERT POINT: _transitionTimingFunction 30884 30885 }, 30886 30887 _translate: function (x, y) { 30888 //Uncode addition 30889 if ( (" " + this.wrapper.className + " ").replace(/[\n\t]/g, " ").indexOf(" no-scrolloverflow ") > -1 ) 30890 return false;
30891 30892 if ( this.options.useTransform ) { 30893 30894/* REPLACE START: _translate */ 30895 30896 this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ; 30897 30898/* REPLACE END: _translate */ 30899 30900 } else { 30901 x = Math.round(x); 30902 y = Math.round(y); 30903 this.scrollerStyle.left = x + 'px'; 30904 this.scrollerStyle.top = y + 'px'; 30905 } 30906 30907 this.x = x; 30908 this.y = y; 30909 30910 30911 if ( this.indicators ) { 30912 for ( var i = this.indicators.length; i--; ) { 30913 this.indicators[i].updatePosition(); 30914 } 30915 } 30916 30917 //Uncode addition 30918 var uncodevent = new CustomEvent('fp-slide-scroll'); 30919 window.dispatchEvent(uncodevent); 30920 30921// INSERT POINT: _translate 30922 30923 }, 30924 30925 _initEvents: function (remove) { 30926 var eventType = remove ? utils.removeEvent : utils.addEvent, 30927 target = this.options.bindToWrapper ? this.wrapper : window; 30928 30929 eventType(window, 'orientationchange', this); 30930 eventType(window, 'resize', this); 30931 30932 if ( this.options.click ) { 30933 eventType(this.wrapper, 'click', this, true); 30934 } 30935 30936 if ( !this.options.disableMouse ) { 30937 eventType(this.wrapper, 'mousedown', this); 30938 eventType(target, 'mousemove', this); 30939 eventType(target, 'mousecancel', this); 30940 eventType(target, 'mouseup', this); 30941 } 30942 30943 if ( utils.hasPointer && !this.options.disablePointer ) { 30944 eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); 30945 eventType(target, utils.prefixPointerEvent('pointermove'), this); 30946 eventType(target, utils.prefixPointerEvent('pointercancel'), this); 30947 eventType(target, utils.prefixPointerEvent('pointerup'), this); 30948 } 30949 30950 if ( utils.hasTouch && !this.options.disableTouch ) { 30951 eventType(this.wrapper, 'touchstart', this); 30952 eventType(target, 'touchmove', this); 30953 eventType(target, 'touchcancel', this); 30954 eventType(target, 'touchend', this); 30955 } 30956 30957 eventType(this.scroller, 'transitionend', this); 30958 eventType(this.scroller, 'webkitTransitionEnd', this); 30959 eventType(this.scroller, 'oTransitionEnd', this); 30960 eventType(this.scroller, 'MSTransitionEnd', this); 30961 }, 30962 30963 getComputedPosition: function () { 30964 var matrix = window.getComputedStyle(this.scroller, null), 30965 x, y; 30966 30967 if ( this.options.useTransform ) { 30968 matrix = matrix[utils.style.transform].split(')')[0].split(', '); 30969 x = +(matrix[12] || matrix[4]); 30970 y = +(matrix[13] || matrix[5]); 30971 } else { 30972 x = +matrix.left.replace(/[^-\d.]/g, ''); 30973 y = +matrix.top.replace(/[^-\d.]/g, ''); 30974 } 30975 30976 return { x: x, y: y }; 30977 }, 30978 _initIndicators: function () { 30979 var interactive = this.options.interactiveScrollbars, 30980 customStyle = typeof this.options.scrollbars != 'string', 30981 indicators = [], 30982 indicator; 30983 30984 var that = this; 30985 30986 this.indicators = []; 30987 30988 if ( this.options.scrollbars ) { 30989 // Vertical scrollbar 30990 if ( this.options.scrollY ) { 30991 indicator = { 30992 el: createDefaultScrollbar('v', interactive, this.options.scrollbars), 30993 interactive: interactive, 30994 defaultScrollbars: true, 30995 customStyle: customStyle, 30996 resize: this.options.resizeScrollbars, 30997 shrink: this.options.shrinkScrollbars, 30998 fade: this.options.fadeScrollbars, 30999 listenX: false 31000 }; 31001 31002 this.wrapper.appendChild(indicator.el); 31003 indicators.push(indicator); 31004 } 31005 31006 // Horizontal scrollbar 31007 if ( this.options.scrollX ) { 31008 indicator = { 31009 el: createDefaultScrollbar('h', interactive, this.options.scrollbars), 31010 interactive: interactive, 31011 defaultScrollbars: true, 31012 customStyle: customStyle, 31013 resize: this.options.resizeScrollbars, 31014 shrink: this.options.shrinkScrollbars, 31015 fade: this.options.fadeScrollbars, 31016 listenY: false 31017 }; 31018 31019 this.wrapper.appendChild(indicator.el); 31020 indicators.push(indicator); 31021 } 31022 } 31023 31024 if ( this.options.indicators ) { 31025 // TODO: check concat compatibility 31026 indicators = indicators.concat(this.options.indicators); 31027 } 31028 31029 for ( var i = indicators.length; i--; ) { 31030 this.indicators.push( new Indicator(this, indicators[i]) ); 31031 } 31032 31033 // TODO: check if we can use array.map (wide compatibility and performance issues) 31034 function _indicatorsMap (fn) { 31035 if (that.indicators) { 31036 for ( var i = that.indicators.length; i--; ) { 31037 fn.call(that.indicators[i]); 31038 } 31039 } 31040 } 31041 31042 if ( this.options.fadeScrollbars ) { 31043 this.on('scrollEnd', function () { 31044 _indicatorsMap(function () { 31045 this.fade(); 31046 }); 31047 }); 31048 31049 this.on('scrollCancel', function () { 31050 _indicatorsMap(function () { 31051 this.fade(); 31052 }); 31053 }); 31054 31055 this.on('scrollStart', function () { 31056 _indicatorsMap(function () { 31057 this.fade(1); 31058 }); 31059 }); 31060 31061 this.on('beforeScrollStart', function () { 31062 _indicatorsMap(function () { 31063 this.fade(1, true); 31064 }); 31065 }); 31066 } 31067 31068 31069 this.on('refresh', function () { 31070 _indicatorsMap(function () { 31071 this.refresh(); 31072 }); 31073 }); 31074 31075 this.on('destroy', function () { 31076 _indicatorsMap(function () { 31077 this.destroy(); 31078 }); 31079 31080 delete this.indicators; 31081 }); 31082 }, 31083 31084 _initWheel: function () { 31085 utils.addEvent(this.wrapper, 'wheel', this); 31086 utils.addEvent(this.wrapper, 'mousewheel', this); 31087 utils.addEvent(this.wrapper, 'DOMMouseScroll', this); 31088 31089 this.on('destroy', function () { 31090 clearTimeout(this.wheelTimeout); 31091 this.wheelTimeout = null; 31092 utils.removeEvent(this.wrapper, 'wheel', this); 31093 utils.removeEvent(this.wrapper, 'mousewheel', this); 31094 utils.removeEvent(this.wrapper, 'DOMMouseScroll', this); 31095 }); 31096 }, 31097 31098 _wheel: function (e) { 31099 if ( !this.enabled ) { 31100 return; 31101 } 31102 31103 var wheelDeltaX, wheelDeltaY, 31104 newX, newY, 31105 that = this; 31106 31107 if ( this.wheelTimeout === undefined ) { 31108 that._execEvent('scrollStart'); 31109 } 31110 31111 // Execute the scrollEnd event after 400ms the wheel stopped scrolling 31112 clearTimeout(this.wheelTimeout); 31113 this.wheelTimeout = setTimeout(function () { 31114 if(!that.options.snap) { 31115 that._execEvent('scrollEnd'); 31116 } 31117 that.wheelTimeout = undefined; 31118 }, 400); 31119 31120 if ( 'deltaX' in e ) { 31121 if (e.deltaMode === 1) { 31122 wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed; 31123 wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed; 31124 } else { 31125 wheelDeltaX = -e.deltaX; 31126 wheelDeltaY = -e.deltaY; 31127 } 31128 } else if ( 'wheelDeltaX' in e ) { 31129 wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed; 31130 wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed; 31131 } else if ( 'wheelDelta' in e ) { 31132 wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed; 31133 } else if ( 'detail' in e ) { 31134 wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed; 31135 } else { 31136 return; 31137 } 31138 31139 wheelDeltaX *= this.options.invertWheelDirection; 31140 wheelDeltaY *= this.options.invertWheelDirection; 31141 31142 if ( !this.hasVerticalScroll ) { 31143 wheelDeltaX = wheelDeltaY; 31144 wheelDeltaY = 0; 31145 } 31146 31147 if ( this.options.snap ) { 31148 newX = this.currentPage.pageX; 31149 newY = this.currentPage.pageY; 31150 31151 if ( wheelDeltaX > 0 ) { 31152 newX--; 31153 } else if ( wheelDeltaX < 0 ) { 31154 newX++; 31155 } 31156 31157 if ( wheelDeltaY > 0 ) { 31158 newY--; 31159 } else if ( wheelDeltaY < 0 ) { 31160 newY++; 31161 } 31162 31163 this.goToPage(newX, newY); 31164 31165 return; 31166 } 31167 31168 newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0); 31169 newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0); 31170 31171 this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0; 31172 this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0; 31173 31174 if ( newX > 0 ) { 31175 newX = 0; 31176 } else if ( newX < this.maxScrollX ) { 31177 newX = this.maxScrollX; 31178 } 31179 31180 if ( newY > 0 ) { 31181 newY = 0; 31182 } else if ( newY < this.maxScrollY ) { 31183 newY = this.maxScrollY; 31184 } 31185 31186 this.scrollTo(newX, newY, 0); 31187 31188// INSERT POINT: _wheel 31189 }, 31190 31191 _initSnap: function () { 31192 this.currentPage = {}; 31193 31194 if ( typeof this.options.snap == 'string' ) { 31195 this.options.snap = this.scroller.querySelectorAll(this.options.snap); 31196 } 31197 31198 this.on('refresh', function () { 31199 var i = 0, l, 31200 m = 0, n, 31201 cx, cy, 31202 x = 0, y,
31203 stepX = this.options.snapStepX || this.wrapperWidth, 31204 stepY = this.options.snapStepY || this.wrapperHeight, 31205 el; 31206 31207 this.pages = []; 31208 31209 if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) { 31210 return; 31211 } 31212 31213 if ( this.options.snap === true ) { 31214 cx = Math.round( stepX / 2 ); 31215 cy = Math.round( stepY / 2 ); 31216 31217 while ( x > -this.scrollerWidth ) { 31218 this.pages[i] = []; 31219 l = 0; 31220 y = 0; 31221 31222 while ( y > -this.scrollerHeight ) { 31223 this.pages[i][l] = { 31224 x: Math.max(x, this.maxScrollX), 31225 y: Math.max(y, this.maxScrollY), 31226 width: stepX, 31227 height: stepY, 31228 cx: x - cx, 31229 cy: y - cy 31230 }; 31231 31232 y -= stepY; 31233 l++; 31234 } 31235 31236 x -= stepX; 31237 i++; 31238 } 31239 } else { 31240 el = this.options.snap; 31241 l = el.length; 31242 n = -1; 31243 31244 for ( ; i < l; i++ ) { 31245 if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) { 31246 m = 0; 31247 n++; 31248 } 31249 31250 if ( !this.pages[m] ) { 31251 this.pages[m] = []; 31252 } 31253 31254 x = Math.max(-el[i].offsetLeft, this.maxScrollX); 31255 y = Math.max(-el[i].offsetTop, this.maxScrollY); 31256 cx = x - Math.round(el[i].offsetWidth / 2); 31257 cy = y - Math.round(el[i].offsetHeight / 2); 31258 31259 this.pages[m][n] = { 31260 x: x, 31261 y: y, 31262 width: el[i].offsetWidth, 31263 height: el[i].offsetHeight, 31264 cx: cx, 31265 cy: cy 31266 }; 31267 31268 if ( x > this.maxScrollX ) { 31269 m++; 31270 } 31271 } 31272 } 31273 31274 this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0); 31275 31276 // Update snap threshold if needed 31277 if ( this.options.snapThreshold % 1 === 0 ) { 31278 this.snapThresholdX = this.options.snapThreshold; 31279 this.snapThresholdY = this.options.snapThreshold; 31280 } else { 31281 this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold); 31282 this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold); 31283 } 31284 }); 31285 31286 this.on('flick', function () { 31287 var time = this.options.snapSpeed || Math.max( 31288 Math.max( 31289 Math.min(Math.abs(this.x - this.startX), 1000), 31290 Math.min(Math.abs(this.y - this.startY), 1000) 31291 ), 300); 31292 31293 this.goToPage( 31294 this.currentPage.pageX + this.directionX, 31295 this.currentPage.pageY + this.directionY, 31296 time 31297 ); 31298 }); 31299 }, 31300 31301 _nearestSnap: function (x, y) { 31302 if ( !this.pages.length ) { 31303 return { x: 0, y: 0, pageX: 0, pageY: 0 }; 31304 } 31305 31306 var i = 0, 31307 l = this.pages.length, 31308 m = 0; 31309 31310 // Check if we exceeded the snap threshold 31311 if ( Math.abs(x - this.absStartX) < this.snapThresholdX && 31312 Math.abs(y - this.absStartY) < this.snapThresholdY ) { 31313 return this.currentPage; 31314 } 31315 31316 if ( x > 0 ) { 31317 x = 0; 31318 } else if ( x < this.maxScrollX ) { 31319 x = this.maxScrollX; 31320 } 31321 31322 if ( y > 0 ) { 31323 y = 0; 31324 } else if ( y < this.maxScrollY ) { 31325 y = this.maxScrollY; 31326 } 31327 31328 for ( ; i < l; i++ ) { 31329 if ( x >= this.pages[i][0].cx ) { 31330 x = this.pages[i][0].x; 31331 break; 31332 } 31333 } 31334 31335 l = this.pages[i].length; 31336 31337 for ( ; m < l; m++ ) { 31338 if ( y >= this.pages[0][m].cy ) { 31339 y = this.pages[0][m].y; 31340 break; 31341 } 31342 } 31343 31344 if ( i == this.currentPage.pageX ) { 31345 i += this.directionX; 31346 31347 if ( i < 0 ) { 31348 i = 0; 31349 } else if ( i >= this.pages.length ) { 31350 i = this.pages.length - 1; 31351 } 31352 31353 x = this.pages[i][0].x; 31354 } 31355 31356 if ( m == this.currentPage.pageY ) { 31357 m += this.directionY; 31358 31359 if ( m < 0 ) { 31360 m = 0; 31361 } else if ( m >= this.pages[0].length ) { 31362 m = this.pages[0].length - 1; 31363 } 31364 31365 y = this.pages[0][m].y; 31366 } 31367 31368 return { 31369 x: x, 31370 y: y, 31371 pageX: i, 31372 pageY: m 31373 }; 31374 }, 31375 31376 goToPage: function (x, y, time, easing) { 31377 easing = easing || this.options.bounceEasing; 31378 31379 if ( x >= this.pages.length ) { 31380 x = this.pages.length - 1; 31381 } else if ( x < 0 ) { 31382 x = 0; 31383 } 31384 31385 if ( y >= this.pages[x].length ) { 31386 y = this.pages[x].length - 1; 31387 } else if ( y < 0 ) { 31388 y = 0; 31389 } 31390 31391 var posX = this.pages[x][y].x, 31392 posY = this.pages[x][y].y; 31393 31394 time = time === undefined ? this.options.snapSpeed || Math.max( 31395 Math.max( 31396 Math.min(Math.abs(posX - this.x), 1000), 31397 Math.min(Math.abs(posY - this.y), 1000) 31398 ), 300) : time; 31399 31400 this.currentPage = { 31401 x: posX, 31402 y: posY, 31403 pageX: x, 31404 pageY: y 31405 }; 31406 31407 this.scrollTo(posX, posY, time, easing); 31408 }, 31409 31410 next: function (time, easing) { 31411 var x = this.currentPage.pageX, 31412 y = this.currentPage.pageY; 31413 31414 x++; 31415 31416 if ( x >= this.pages.length && this.hasVerticalScroll ) { 31417 x = 0; 31418 y++; 31419 } 31420 31421 this.goToPage(x, y, time, easing); 31422 }, 31423 31424 prev: function (time, easing) { 31425 var x = this.currentPage.pageX, 31426 y = this.currentPage.pageY; 31427 31428 x--; 31429 31430 if ( x < 0 && this.hasVerticalScroll ) { 31431 x = 0; 31432 y--; 31433 } 31434 31435 this.goToPage(x, y, time, easing); 31436 }, 31437 31438 _initKeys: function (e) { 31439 // default key bindings 31440 var keys = { 31441 pageUp: 33, 31442 pageDown: 34, 31443 end: 35, 31444 home: 36, 31445 left: 37, 31446 up: 38, 31447 right: 39, 31448 down: 40 31449 }; 31450 var i; 31451 31452 // if you give me characters I give you keycode 31453 if ( typeof this.options.keyBindings == 'object' ) { 31454 for ( i in this.options.keyBindings ) { 31455 if ( typeof this.options.keyBindings[i] == 'string' ) { 31456 this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCo
31456deAt(0); 31457 } 31458 } 31459 } else { 31460 this.options.keyBindings = {}; 31461 } 31462 31463 for ( i in keys ) { 31464 this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i]; 31465 } 31466 31467 utils.addEvent(window, 'keydown', this); 31468 31469 this.on('destroy', function () { 31470 utils.removeEvent(window, 'keydown', this); 31471 }); 31472 }, 31473 31474 _key: function (e) { 31475 if ( !this.enabled ) { 31476 return; 31477 } 31478 31479 var snap = this.options.snap, // we are using this alot, better to cache it 31480 newX = snap ? this.currentPage.pageX : this.x, 31481 newY = snap ? this.currentPage.pageY : this.y, 31482 now = utils.getTime(), 31483 prevTime = this.keyTime || 0, 31484 acceleration = 0.250, 31485 pos; 31486 31487 if ( this.options.useTransition && this.isInTransition ) { 31488 pos = this.getComputedPosition(); 31489 31490 this._translate(Math.round(pos.x), Math.round(pos.y)); 31491 this.isInTransition = false; 31492 } 31493 31494 this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0; 31495 31496 switch ( e.keyCode ) { 31497 case this.options.keyBindings.pageUp: 31498 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 31499 newX += snap ? 1 : this.wrapperWidth; 31500 } else { 31501 newY += snap ? 1 : this.wrapperHeight; 31502 } 31503 break; 31504 case this.options.keyBindings.pageDown: 31505 if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { 31506 newX -= snap ? 1 : this.wrapperWidth; 31507 } else { 31508 newY -= snap ? 1 : this.wrapperHeight; 31509 } 31510 break; 31511 case this.options.keyBindings.end: 31512 newX = snap ? this.pages.length-1 : this.maxScrollX; 31513 newY = snap ? this.pages[0].length-1 : this.maxScrollY; 31514 break; 31515 case this.options.keyBindings.home: 31516 newX = 0; 31517 newY = 0; 31518 break; 31519 case this.options.keyBindings.left: 31520 newX += snap ? -1 : 5 + this.keyAcceleration>>0; 31521 break; 31522 case this.options.keyBindings.up: 31523 newY += snap ? 1 : 5 + this.keyAcceleration>>0; 31524 break; 31525 case this.options.keyBindings.right: 31526 newX -= snap ? -1 : 5 + this.keyAcceleration>>0; 31527 break; 31528 case this.options.keyBindings.down: 31529 newY -= snap ? 1 : 5 + this.keyAcceleration>>0; 31530 break; 31531 default: 31532 return; 31533 } 31534 31535 if ( snap ) { 31536 this.goToPage(newX, newY); 31537 return; 31538 } 31539 31540 if ( newX > 0 ) { 31541 newX = 0; 31542 this.keyAcceleration = 0; 31543 } else if ( newX < this.maxScrollX ) { 31544 newX = this.maxScrollX; 31545 this.keyAcceleration = 0; 31546 } 31547 31548 if ( newY > 0 ) { 31549 newY = 0; 31550 this.keyAcceleration = 0; 31551 } else if ( newY < this.maxScrollY ) { 31552 newY = this.maxScrollY; 31553 this.keyAcceleration = 0; 31554 } 31555 31556 this.scrollTo(newX, newY, 0); 31557 31558 this.keyTime = now; 31559 }, 31560 31561 _animate: function (destX, destY, duration, easingFn) { 31562 var that = this, 31563 startX = this.x, 31564 startY = this.y, 31565 startTime = utils.getTime(), 31566 destTime = startTime + duration; 31567 31568 function step () { 31569 var now = utils.getTime(), 31570 newX, newY, 31571 easing; 31572 31573 if ( now >= destTime ) { 31574 that.isAnimating = false; 31575 that._translate(destX, destY); 31576 31577 if ( !that.resetPosition(that.options.bounceTime) ) { 31578 that._execEvent('scrollEnd'); 31579 } 31580 31581 return; 31582 } 31583 31584 now = ( now - startTime ) / duration; 31585 easing = easingFn(now); 31586 newX = ( destX - startX ) * easing + startX; 31587 newY = ( destY - startY ) * easing + startY; 31588 that._translate(newX, newY); 31589 31590 if ( that.isAnimating ) { 31591 rAF(step); 31592 } 31593 } 31594 31595 this.isAnimating = true; 31596 step(); 31597 }, 31598 handleEvent: function (e) { 31599 switch ( e.type ) { 31600 case 'touchstart': 31601 case 'pointerdown': 31602 case 'MSPointerDown': 31603 case 'mousedown': 31604 this._start(e); 31605 break; 31606 case 'touchmove': 31607 case 'pointermove': 31608 case 'MSPointerMove': 31609 case 'mousemove': 31610 this._move(e); 31611 break; 31612 case 'touchend': 31613 case 'pointerup': 31614 case 'MSPointerUp': 31615 case 'mouseup': 31616 case 'touchcancel': 31617 case 'pointercancel': 31618 case 'MSPointerCancel': 31619 case 'mousecancel': 31620 this._end(e); 31621 break; 31622 case 'orientationchange': 31623 case 'resize': 31624 this._resize(); 31625 break; 31626 case 'transitionend': 31627 case 'webkitTransitionEnd': 31628 case 'oTransitionEnd': 31629 case 'MSTransitionEnd': 31630 this._transitionEnd(e); 31631 break; 31632 case 'wheel': 31633 case 'DOMMouseScroll': 31634 case 'mousewheel': 31635 this._wheel(e); 31636 break; 31637 case 'keydown': 31638 this._key(e); 31639 break; 31640 case 'click': 31641 if ( this.enabled && !e._constructed ) { 31642 e.preventDefault(); 31643 e.stopPropagation(); 31644 } 31645 break; 31646 } 31647 } 31648}; 31649function createDefaultScrollbar (direction, interactive, type) { 31650 var scrollbar = document.createElement('div'), 31651 indicator = document.createElement('div'); 31652 31653 if ( type === true ) { 31654 scrollbar.style.cssText = 'position:absolute;z-index:9999'; 31655 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'; 31656 } 31657 31658 indicator.className = 'iScrollIndicator'; 31659 31660 if ( direction == 'h' ) { 31661 if ( type === true ) { 31662 scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0'; 31663 indicator.style.height = '100%'; 31664 } 31665 scrollbar.className = 'iScrollHorizontalScrollbar'; 31666 } else { 31667 if ( type === true ) { 31668 scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px'; 31669 indicator.style.width = '100%'; 31670 } 31671 scrollbar.className = 'iScrollVerticalScrollbar'; 31672 } 31673 31674 scrollbar.style.cssText += ';overflow:hidden'; 31675 31676 if ( !interactive ) { 31677 scrollbar.style.pointerEvents = 'none'; 31678 } 31679 31680 scrollbar.appendChild(indicator); 31681 31682 return scrollbar; 31683} 31684 31685function Indicator (scroller, options) { 31686 this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; 31687 this.wrapperStyle = this.wrapper.style; 31688 this.indicator = this.wrapper.children[0]; 31689 this.indicatorStyle = this.indicator.style; 31690 this.scroller = scroller; 31691 31692 this.options = { 31693 listenX: true, 31694 listenY: true, 31695 interactive: false, 31696 resize: true, 31697 defaultScrollbars: false, 31698 shrink: false, 31699 fade: false, 31700 speedRatioX: 0, 31701 speedRatioY: 0 31702 }; 31703 31704 for ( var i in options ) { 31705 this.options[i] = options[i]; 31706 } 31707 31708 this.sizeRatioX = 1; 31709 this.sizeRatioY = 1; 31710 this.maxPosX = 0; 31711 this.maxPosY = 0; 31712 31713 if ( this.options.interactive ) { 31714 if ( !this.options.disableTouch ) { 31715 utils.addEvent(this.indicator, 'touchstart', this); 31716 utils.addEvent(window, 'touchend', this); 31717 } 31718 if ( !this.options.disablePointer ) { 31719 utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 31720 utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this); 31721 } 31722 if ( !this.options.disableMouse ) { 31723 utils.addEvent(this.indicator, 'mousedown', this); 31724 utils.addEvent(window, 'mouseup', this); 31725 } 31726 } 31727 31728 if ( this.options.fade ) { 31729 this.wrapperStyle[utils.style.transform] = this.scroller.translateZ; 31730 var durationProp = utils.style.transitionDuration; 31731 if(!durationProp) { 31732 return; 31733 } 31734 this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms'; 31735 // remove 0.0001ms 31736 var self = this; 31737 if(utils.isBadAndroid) { 31738 rAF(function() { 31739 if(self.wrapperStyle[durationProp] === '0.0001ms') { 31740 self.wrapperStyle[durationProp] = '0s'; 31741 } 31742 }); 31743 } 31744 this.wrapperStyle.opacity = '0'; 31745 } 31746} 31747 31748Indicator.prototype = { 31749 handleEvent: function (e) { 31750 switch ( e.type ) { 31751 case 'touchstart': 31752 case 'pointerdown': 31753 case 'MSPointerDown': 31754 case 'mousedown': 31755 this._start(e); 31756 break; 31757 case 'touchmove': 31758 case 'pointermove': 31759 case 'MSPointerMove': 31760 case 'mousemove': 31761 this._move(e); 31762 break; 31763 case 'touchend': 31764 case 'pointerup': 31765 case 'MSPointerUp': 31766 case 'mouseup': 31767 case 'touchcancel': 31768 case 'pointercancel': 31769 case 'MSPointerCancel': 31770 case 'mousecancel': 31771 this._end(e); 31772 break; 31773 } 31774 }, 31775 31776 destroy: function () { 31777 if ( this.options.fadeScrollbars ) { 31778 clearTimeout(this.fadeTimeout); 31779 this.fadeTimeout = null; 31780 } 31781 if ( this.options.interactive ) { 31782 utils.removeEvent(this.indicator, 'touchstart', this); 31783 utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); 31784 utils.removeEvent(this.indicator, 'mousedown', this); 31785 31786 utils.removeEvent(window, 'touchmove', this); 31787 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 31788 utils.removeEvent(window, 'mousemove', this); 31789 31790 utils.removeEvent(window, 'touchend', this); 31791 utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this); 31792 utils.removeEvent(window, 'mouseup', this); 31793 } 31794 31795 if ( this.options.defaultScrollbars ) { 31796 this.wrapper.parentNode.removeChild(this.wrapper); 31797 } 31798 }, 31799 31800 _start: function (e) { 31801 var point = e.touches ? e.touches[0] : e; 31802 31803 e.preventDefault(); 31804 e.stopPropagation(); 31805 31806 this.transitionTime(); 31807 31808 this.initiated = true; 31809 this.moved = false;
31810 this.lastPointX = point.pageX; 31811 this.lastPointY = point.pageY; 31812 31813 this.startTime = utils.getTime(); 31814 31815 if ( !this.options.disableTouch ) { 31816 utils.addEvent(window, 'touchmove', this); 31817 } 31818 if ( !this.options.disablePointer ) { 31819 utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this); 31820 } 31821 if ( !this.options.disableMouse ) { 31822 utils.addEvent(window, 'mousemove', this); 31823 } 31824 31825 this.scroller._execEvent('beforeScrollStart'); 31826 }, 31827 31828 _move: function (e) { 31829 var point = e.touches ? e.touches[0] : e, 31830 deltaX, deltaY, 31831 newX, newY, 31832 timestamp = utils.getTime(); 31833 31834 if ( !this.moved ) { 31835 this.scroller._execEvent('scrollStart'); 31836 } 31837 31838 this.moved = true; 31839 31840 deltaX = point.pageX - this.lastPointX; 31841 this.lastPointX = point.pageX; 31842 31843 deltaY = point.pageY - this.lastPointY; 31844 this.lastPointY = point.pageY; 31845 31846 newX = this.x + deltaX; 31847 newY = this.y + deltaY; 31848 31849 this._pos(newX, newY); 31850 31851// INSERT POINT: indicator._move 31852 31853 e.preventDefault(); 31854 e.stopPropagation(); 31855 }, 31856 31857 _end: function (e) { 31858 if ( !this.initiated ) { 31859 return; 31860 } 31861 31862 this.initiated = false; 31863 31864 e.preventDefault(); 31865 e.stopPropagation(); 31866 31867 utils.removeEvent(window, 'touchmove', this); 31868 utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); 31869 utils.removeEvent(window, 'mousemove', this); 31870 31871 if ( this.scroller.options.snap ) { 31872 var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y); 31873 31874 var time = this.options.snapSpeed || Math.max( 31875 Math.max( 31876 Math.min(Math.abs(this.scroller.x - snap.x), 1000), 31877 Math.min(Math.abs(this.scroller.y - snap.y), 1000) 31878 ), 300); 31879 31880 if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) { 31881 this.scroller.directionX = 0; 31882 this.scroller.directionY = 0; 31883 this.scroller.currentPage = snap; 31884 this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing); 31885 } 31886 } 31887 31888 if ( this.moved ) { 31889 this.scroller._execEvent('scrollEnd'); 31890 } 31891 }, 31892 31893 transitionTime: function (time) { 31894 time = time || 0; 31895 var durationProp = utils.style.transitionDuration; 31896 if(!durationProp) { 31897 return; 31898 } 31899 31900 this.indicatorStyle[durationProp] = time + 'ms'; 31901 31902 if ( !time && utils.isBadAndroid ) { 31903 this.indicatorStyle[durationProp] = '0.0001ms'; 31904 // remove 0.0001ms 31905 var self = this; 31906 rAF(function() { 31907 if(self.indicatorStyle[durationProp] === '0.0001ms') { 31908 self.indicatorStyle[durationProp] = '0s'; 31909 } 31910 }); 31911 } 31912 }, 31913 31914 transitionTimingFunction: function (easing) { 31915 this.indicatorStyle[utils.style.transitionTimingFunction] = easing; 31916 }, 31917 31918 refresh: function () { 31919 this.transitionTime(); 31920 31921 if ( this.options.listenX && !this.options.listenY ) { 31922 this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; 31923 } else if ( this.options.listenY && !this.options.listenX ) { 31924 this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; 31925 } else { 31926 this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; 31927 } 31928 31929 if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) { 31930 utils.addClass(this.wrapper, 'iScrollBothScrollbars'); 31931 utils.removeClass(this.wrapper, 'iScrollLoneScrollbar'); 31932 31933 if ( this.options.defaultScrollbars && this.options.customStyle ) { 31934 if ( this.options.listenX ) { 31935 this.wrapper.style.right = '8px'; 31936 } else { 31937 this.wrapper.style.bottom = '8px'; 31938 } 31939 } 31940 } else { 31941 utils.removeClass(this.wrapper, 'iScrollBothScrollbars'); 31942 utils.addClass(this.wrapper, 'iScrollLoneScrollbar'); 31943 31944 if ( this.options.defaultScrollbars && this.options.customStyle ) { 31945 if ( this.options.listenX ) { 31946 this.wrapper.style.right = '2px'; 31947 } else { 31948 this.wrapper.style.bottom = '2px'; 31949 } 31950 } 31951 } 31952 31953 var r = this.wrapper.offsetHeight; // force refresh 31954 31955 if ( this.options.listenX ) {
31956 this.wrapperWidth = this.wrapper.clientWidth; 31957 if ( this.options.resize ) { 31958 this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); 31959 this.indicatorStyle.width = this.indicatorWidth + 'px'; 31960 } else { 31961 this.indicatorWidth = this.indicator.clientWidth; 31962 } 31963 31964 this.maxPosX = this.wrapperWidth - this.indicatorWidth; 31965 31966 if ( this.options.shrink == 'clip' ) { 31967 this.minBoundaryX = -this.indicatorWidth + 8; 31968 this.maxBoundaryX = this.wrapperWidth - 8; 31969 } else { 31970 this.minBoundaryX = 0; 31971 this.maxBoundaryX = this.maxPosX; 31972 } 31973 31974 this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); 31975 } 31976 31977 if ( this.options.listenY ) { 31978 this.wrapperHeight = this.wrapper.clientHeight; 31979 if ( this.options.resize ) { 31980 this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); 31981 this.indicatorStyle.height = this.indicatorHeight + 'px'; 31982 } else { 31983 this.indicatorHeight = this.indicator.clientHeight; 31984 } 31985 31986 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 31987 31988 if ( this.options.shrink == 'clip' ) { 31989 this.minBoundaryY = -this.indicatorHeight + 8; 31990 this.maxBoundaryY = this.wrapperHeight - 8; 31991 } else { 31992 this.minBoundaryY = 0; 31993 this.maxBoundaryY = this.maxPosY; 31994 } 31995 31996 this.maxPosY = this.wrapperHeight - this.indicatorHeight; 31997 this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); 31998 } 31999 32000 this.updatePosition(); 32001 }, 32002 32003 updatePosition: function () { 32004 var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, 32005 y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; 32006 32007 if ( !this.options.ignoreBoundaries ) { 32008 if ( x < this.minBoundaryX ) { 32009 if ( this.options.shrink == 'scale' ) { 32010 this.width = Math.max(this.indicatorWidth + x, 8); 32011 this.indicatorStyle.width = this.width + 'px'; 32012 } 32013 x = this.minBoundaryX; 32014 } else if ( x > this.maxBoundaryX ) { 32015 if ( this.options.shrink == 'scale' ) { 32016 this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); 32017 this.indicatorStyle.width = this.width + 'px'; 32018 x = this.maxPosX + this.indicatorWidth - this.width; 32019 } else { 32020 x = this.maxBoundaryX; 32021 } 32022 } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) { 32023 this.width = this.indicatorWidth; 32024 this.indicatorStyle.width = this.width + 'px'; 32025 } 32026 32027 if ( y < this.minBoundaryY ) { 32028 if ( this.options.shrink == 'scale' ) { 32029 this.height = Math.max(this.indicatorHeight + y * 3, 8); 32030 this.indicatorStyle.height = this.height + 'px'; 32031 } 32032 y = this.minBoundaryY; 32033 } else if ( y > this.maxBoundaryY ) { 32034 if ( this.options.shrink == 'scale' ) { 32035 this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); 32036 this.indicatorStyle.height = this.height + 'px'; 32037 y = this.maxPosY + this.indicatorHeight - this.height; 32038 } else { 32039 y = this.maxBoundaryY; 32040 } 32041 } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) { 32042 this.height = this.indicatorHeight; 32043 this.indicatorStyle.height = this.height + 'px'; 32044 } 32045 } 32046 32047 this.x = x; 32048 this.y = y; 32049 32050 if ( this.scroller.options.useTransform ) { 32051 this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ; 32052 } else { 32053 this.indicatorStyle.left = x + 'px'; 32054 this.indicatorStyle.top = y + 'px'; 32055 } 32056 }, 32057 32058 _pos: function (x, y) { 32059 if ( x < 0 ) { 32060 x = 0; 32061 } else if ( x > this.maxPosX ) { 32062 x = this.maxPosX; 32063 } 32064 32065 if ( y < 0 ) { 32066 y = 0; 32067 } else if ( y > this.maxPosY ) { 32068 y = this.maxPosY;
32069 } 32070 32071 x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x; 32072 y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y; 32073 32074 this.scroller.scrollTo(x, y); 32075 }, 32076 32077 fade: function (val, hold) { 32078 if ( hold && !this.visible ) { 32079 return; 32080 } 32081 32082 clearTimeout(this.fadeTimeout); 32083 this.fadeTimeout = null; 32084 32085 var time = val ? 250 : 500, 32086 delay = val ? 0 : 300; 32087 32088 val = val ? '1' : '0'; 32089 32090 this.wrapperStyle[utils.style.transitionDuration] = time + 'ms'; 32091 32092 this.fadeTimeout = setTimeout((function (val) { 32093 this.wrapperStyle.opacity = val; 32094 this.visible = +val; 32095 }).bind(this, val), delay); 32096 } 32097}; 32098 32099IScroll.utils = utils; 32100 32101if ( typeof module != 'undefined' && module.exports ) { 32102 module.exports = IScroll; 32103} else if ( typeof define == 'function' && define.amd ) { 32104 define( function () { return IScroll; } ); 32105} else { 32106 window.IScroll = IScroll; 32107} 32108 32109})(window, document, Math); 32110/*! 32111 * fullPage 2.9.4 32112 * https://github.com/alvarotrigo/fullPage.js 32113 * @license MIT licensed 32114 * 32115 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo 32116 */ 32117(function(global, factory) { 32118 'use strict'; 32119 if (typeof define === 'function' && define.amd) { 32120 define(['jquery'], function($) { 32121 return factory($, global, global.document, global.Math); 32122 }); 32123 } else if (typeof exports === "object" && exports) { 32124 module.exports = factory(require('jquery'), global, global.document, global.Math); 32125 } else { 32126 factory(jQuery, global, global.document, global.Math); 32127 } 32128})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) { 32129 'use strict'; 32130 32131 // keeping central set of classnames and selectors 32132 var WRAPPER = 'fullpage-wrapper'; 32133 var WRAPPER_SEL = '.' + WRAPPER; 32134 32135 // slimscroll 32136 var SCROLLABLE = 'fp-scrollable'; 32137 var SCROLLABLE_SEL = '.' + SCROLLABLE; 32138 32139 // util 32140 var RESPONSIVE = 'fp-responsive'; 32141 var NO_TRANSITION = 'fp-notransition'; 32142 var DESTROYED = 'fp-destroyed'; 32143 var ENABLED = 'fp-enabled'; 32144 var VIEWING_PREFIX = 'fp-viewing'; 32145 var ACTIVE = 'active'; 32146 var ACTIVE_SEL = '.' + ACTIVE; 32147 var COMPLETELY = 'fp-completely'; 32148 var COMPLETELY_SEL = '.' + COMPLETELY; 32149 32150 // section 32151 var SECTION_DEFAULT_SEL = '.section'; 32152 var SECTION = 'fp-section'; 32153 var SECTION_SEL = '.' + SECTION; 32154 var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; 32155 var SECTION_FIRST_SEL = SECTION_SEL + ':first'; 32156 var SECTION_LAST_SEL = SECTION_SEL + ':last'; 32157 var TABLE_CELL = 'fp-tableCell'; 32158 var TABLE_CELL_SEL = '.' + TABLE_CELL; 32159 var AUTO_HEIGHT = 'fp-auto-height'; 32160 var AUTO_HEIGHT_SEL = '.fp-auto-height'; 32161 var NORMAL_SCROLL = 'fp-normal-scroll'; 32162 var NORMAL_SCROLL_SEL = '.fp-normal-scroll'; 32163 32164 // section nav 32165 var SECTION_NAV = 'fp-nav'; 32166 var SECTION_NAV_SEL = '#' + SECTION_NAV; 32167 var SECTION_NAV_TOOLTIP = 'fp-tooltip'; 32168 var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP; 32169 var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; 32170 32171 // slide 32172 var SLIDE_DEFAULT_SEL = '.slide'; 32173 var SLIDE = 'fp-slide'; 32174 var SLIDE_SEL = '.' + SLIDE; 32175 var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; 32176 var SLIDES_WRAPPER = 'fp-slides'; 32177 var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; 32178 var SLIDES_CONTAINER = 'fp-slidesContainer'; 32179 var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; 32180 var TABLE = 'fp-table'; 32181 32182 // slide nav 32183 var SLIDES_NAV = 'fp-slidesNav'; 32184 var SLIDES_NAV_SEL = '.' + SLIDES_NAV; 32185 var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; 32186 var SLIDES_ARROW = 'fp-controlArrow'; 32187 var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; 32188 var SLIDES_PREV = 'fp-prev'; 32189 var SLIDES_PREV_SEL = '.' + SLIDES_PREV; 32190 var SLIDES_ARROW_PREV = SLIDES_ARROW + ' ' + SLIDES_PREV; 32191 var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; 32192 var SLIDES_NEXT = 'fp-next';
32193 var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; 32194 var SLIDES_ARROW_NEXT = SLIDES_ARROW + ' ' + SLIDES_NEXT; 32195 var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; 32196 32197 var $window = $(window); 32198 var $document = $(document); 32199 32200 // Default options for iScroll.js used when using scrollOverflow 32201 var iscrollOptions = { 32202 scrollbars: true, 32203 mouseWheel: true, 32204 hideScrollbars: false, 32205 fadeScrollbars: false, 32206 disableMouse: true, 32207 interactiveScrollbars: true, 32208 bounce: false, 32209 }; 32210 32211 $.fn.fullpage = function(options) { 32212 //only once my friend! 32213 if($('html').hasClass(ENABLED)){ displayWarnings(); return; } 32214 32215 // common jQuery objects 32216 var $htmlBody = $('html, body'); 32217 var $body = $('body'); 32218 32219 var FP = $.fn.fullpage; 32220 32221 // Creating some defaults, extending them with any options that were provided 32222 options = $.extend({ 32223 //navigation 32224 menu: false, 32225 anchors:[], 32226 lockAnchors: false, 32227 navigation: false, 32228 navigationPosition: 'right', 32229 navigationTooltips: [], 32230 showActiveTooltip: false, 32231 slidesNavigation: false, 32232 slidesNavPosition: 'bottom', 32233 scrollBar: false, 32234 hybrid: false, 32235 32236 //scrolling 32237 css3: true, 32238 scrollingSpeed: 700, 32239 autoScrolling: true, 32240 fitToSection: true, 32241 fitToSectionDelay: 1000, 32242 easing: 'easeInOutCubic', 32243 easingcss3: 'ease', 32244 loopBottom: false, 32245 loopTop: false, 32246 loopHorizontal: true, 32247 continuousVertical: false, 32248 continuousHorizontal: false, 32249 scrollHorizontally: false, 32250 interlockedSlides: false, 32251 dragAndMove: false, 32252 offsetSections: false, 32253 resetSliders: false, 32254 fadingEffect: false, 32255 normalScrollElements: null, 32256 scrollOverflow: false, 32257 scrollOverflowReset: false, 32258 scrollOverflowHandler: iscrollHandler, 32259 scrollOverflowOptions: null, 32260 touchSensitivity: 5, 32261 normalScrollElementTouchThreshold: 5, 32262 bigSectionsDestination: null, 32263 32264 //Accessibility 32265 keyboardScrolling: true, 32266 animateAnchor: true, 32267 recordHistory: true, 32268 32269 //design 32270 controlArrows: true, 32271 controlArrowColor: '#fff', 32272 verticalCentered: true, 32273 sectionsColor : [], 32274 paddingTop: 0, 32275 paddingBottom: 0, 32276 fixedElements: null, 32277 responsive: 0, //backwards compabitility with responsiveWiddth 32278 responsiveWidth: 0, 32279 responsiveHeight: 0, 32280 responsiveSlides: false, 32281 parallax: false, 32282 parallaxOptions: { 32283 type: 'reveal', 32284 percentage: 62, 32285 property: 'translate' 32286 }, 32287 32288 //Custom selectors 32289 sectionSelector: SECTION_DEFAULT_SEL, 32290 slideSelector: SLIDE_DEFAULT_SEL, 32291 32292 //events 32293 afterLoad: null, 32294 onLeave: null, 32295 afterRender: null, 32296 afterResize: null, 32297 afterReBuild: null, 32298 afterSlideLoad: null, 32299 onSlideLeave: null, 32300 afterResponsive: null, 32301 32302 lazyLoading: true 32303 }, options); 32304 32305 //flag to avoid very fast sliding for landscape sliders 32306 var slideMoving = false; 32307 32308 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 32309 var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints)); 32310 var container = $(this); 32311 var windowsHeight = $window.height(); 32312 var isResizing = false; 32313 var isWindowFocused = true; 32314 var lastScrolledDestiny; 32315 var lastScrolledSlide; 32316 var canScroll = true; 32317 var scrollings = []; 32318 var controlPressed; 32319 var startingSection; 32320 var isScrollAllowed = {}; 32321 isScrollAllowed.m = { 'up':true, 'down':true, 'left':true, 'right':true }; 32322 isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m); 32323 var MSPointer = getMSPointer(); 32324 var events = { 32325 touchmove: 'ontouchmove' in window ? 'touchmove' : MSPointer.move, 32326 touchstart: 'ontouchstart' in window ? 'touchstart' : MSPointer.down 32327 }; 32328 32329 //cheks for passive event support 32330 //added by Uncode from new fullPage updates 32331 var g_supportsPassive = false;
32332 try { 32333 var opts = Object.defineProperty({}, 'passive', { 32334 get: function() { 32335 g_supportsPassive = true; 32336 } 32337 }); 32338 window.addEventListener("testPassive", null, opts); 32339 window.removeEventListener("testPassive", null, opts); 32340 } catch (e) {} 32341 32342 //timeouts 32343 var resizeId; 32344 var afterSectionLoadsId; 32345 var afterSlideLoadsId; 32346 var scrollId; 32347 var scrollId2; 32348 var keydownId; 32349 var originals = $.extend(true, {}, options); //deep copy 32350 32351 //Uncode addition 32352 var $masthead = $('#masthead'); 32353 var hideMenu = !$('body').hasClass('vmenu') && $('body').hasClass('uncode-fp-menu-hide') ? true : false; 32354 var menuHeight = $masthead.hasClass('menu-transparent') || hideMenu ? 0 : UNCODE.menuHeight; 32355 var bodyBorder = UNCODE.bodyBorder; 32356 var adminBarHeight = UNCODE.adminBarHeight; 32357 32358 displayWarnings(); 32359 32360 //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783 32361 iscrollOptions.click = isTouch; // see #2035 32362 32363 //extending iScroll options with the user custom ones 32364 iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions); 32365 32366 //easeInOutCubic animation included in the plugin 32367 $.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;}}); 32368 32369 /** 32370 * Sets the autoScroll option. 32371 * It changes the scroll bar visibility and the history of the site as a result. 32372 */ 32373 function setAutoScrolling(value, type){ 32374 //removing the transformation 32375 if(!value){ 32376 silentScroll(0); 32377 } 32378 32379 setVariableState('autoScrolling', value, type); 32380 32381 var element = $(SECTION_ACTIVE_SEL); 32382 32383 if(options.autoScrolling && !options.scrollBar){ 32384 $htmlBody.css({ 32385 'overflow' : 'hidden !important', 32386 'height' : '100%' 32387 }); 32388 32389 //Uncode addition 32390 //setRecordHistory(originals.recordHistory, 'internal'); 32391 32392 //for IE touch devices 32393 container.css({ 32394 '-ms-touch-action': 'none', 32395 'touch-action': 'none' 32396 }); 32397 32398 if(element.length){ 32399 //moving the container up 32400 silentScroll(element.position().top); 32401 } 32402 32403 }else{ 32404 $htmlBody.css({ 32405 'overflow' : 'visible !important', 32406 'height' : 'initial' 32407 }); 32408 32409 //Uncode addition 32410 //setRecordHistory(false, 'internal'); 32411 32412 //for IE touch devices 32413 container.css({ 32414 '-ms-touch-action': '', 32415 'touch-action': '' 32416 }); 32417 32418 //scrolling the page to the section with no animation 32419 if (element.length) { 32420 $htmlBody.scrollTop(element.position().top); 32421 } 32422 } 32423 } 32424 32425 /** 32426 * Defines wheter to record the history for each hash change in the URL. 32427 */ 32428 function setRecordHistory(value, type){ 32429 setVariableState('recordHistory', value, type); 32430 } 32431 32432 /** 32433 * Defines the scrolling speed 32434 */ 32435 function setScrollingSpeed(value, type){ 32436 setVariableState('scrollingSpeed', value, type); 32437 } 32438 32439 /** 32440 * Sets fitToSection 32441 */ 32442 function setFitToSection(value, type){ 32443 setVariableState('fitToSection', value, type); 32444 } 32445 32446 /** 32447 * Sets lockAnchors 32448 */ 32449 function setLockAnchors(value){ 32450 options.lockAnchors = value; 32451 } 32452 32453 /** 32454 * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. 32455 */ 32456 function setMouseWheelScrolling(value){ 32457 if(value){ 32458 addMouseWheelHandler(); 32459 addMiddleWheelHandler(); 32460 }else{ 32461 removeMouseWheelHandler(); 32462 removeMiddleWheelHandler(); 32463 } 32464 } 32465 32466 /** 32467 * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures. 32468 * Optionally a second parameter can be used to specify the direction for which the action will be applied. 32469 * 32470 * @param directions string containing the direction or directions separated by comma. 32471 */ 32472 function setAllowScrolling(value, directions){ 32473 if(typeof directions !== 'undefined'){ 32474 directions = directions.replace(/ /g,'').split(','); 32475 32476 $.each(directions, function (index, direction){ 32477 setIsScrollAllowed(value, direction, 'm'); 32478 }); 32479 } 32480 else if(value){ 32481 setMouseWheelScrolling(true); 32482 addTouchHandler(); 32483 }else{ 32484 setMouseWheelScrolling(false); 32485 removeTouchHandler(); 32486 } 32487 } 32488 32489 /** 32490 * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys 32491 */ 32492 function setKeyboardScrolling(value, directions){ 32493 if(typeof directions !== 'undefined'){ 32494 directions = directions.replace(/ /g,'').split(','); 32495 32496 $.each(directions, function (index, direction){ 32497 setIsScrollAllowed(value, direction, 'k'); 32498 }); 32499 }else{ 32500 options.keyboardScrolling = value; 32501 } 32502 } 32503 32504 /** 32505 * Moves the page up one section. 32506 */ 32507 function moveSectionUp(){ 32508 var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL); 32509 32510 //looping to the bottom if there's no more sections above 32511 if (!prev.length && (options.loopTop || options.continuousVertical)) {
32512 prev = $(SECTION_SEL).last(); 32513 } 32514 32515 if (prev.length) { 32516 scrollPage(prev, null, true); 32517 } 32518 } 32519 32520 /** 32521 * Moves the page down one section. 32522 */ 32523 function moveSectionDown(){ 32524 var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL); 32525 32526 //looping to the top if there's no more sections below 32527 if(!next.length && 32528 (options.loopBottom || options.continuousVertical)){ 32529 next = $(SECTION_SEL).first(); 32530 } 32531 32532 if(next.length){ 32533 scrollPage(next, null, false); 32534 } 32535 } 32536 32537 /** 32538 * Moves the page to the given section and slide with no animation. 32539 * Anchors or index positions can be used as params. 32540 */ 32541 function silentMoveTo(sectionAnchor, slideAnchor){ 32542 setScrollingSpeed (0, 'internal'); 32543 moveTo(sectionAnchor, slideAnchor); 32544 setScrollingSpeed (originals.scrollingSpeed, 'internal'); 32545 } 32546 32547 /** 32548 * Moves the page to the given section and slide. 32549 * Anchors or index positions can be used as params. 32550 */ 32551 function moveTo(sectionAnchor, slideAnchor){ 32552 var destiny = getSectionByAnchor(sectionAnchor); 32553 32554 if (typeof slideAnchor !== 'undefined'){ 32555 scrollPageAndSlide(sectionAnchor, slideAnchor); 32556 }else if(destiny.length > 0){ 32557 scrollPage(destiny); 32558 } 32559 } 32560 32561 /** 32562 * Slides right the slider of the active section. 32563 * Optional `section` param. 32564 */ 32565 function moveSlideRight(section){ 32566 moveSlide('right', section); 32567 } 32568 32569 /** 32570 * Slides left the slider of the active section. 32571 * Optional `section` param. 32572 */ 32573 function moveSlideLeft(section){ 32574 moveSlide('left', section); 32575 } 32576 32577 /** 32578 * When resizing is finished, we adjust the slides sizes and positions 32579 */ 32580 function reBuild(resizing){ 32581 if(container.hasClass(DESTROYED)){ return; } //nothing to do if the plugin was destroyed 32582 32583 isResizing = true; 32584 32585 windowsHeight = $window.height(); //updating global var 32586 32587 $(SECTION_SEL).each(function(){ 32588 var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL); 32589 var slides = $(this).find(SLIDE_SEL); 32590 32591 //adjusting the height of the table-cell for IE and Firefox 32592 if(options.verticalCentered){ 32593 $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px'); 32594 } 32595 32596 $(this).css('height', windowsHeight + 'px'); 32597 32598 //resizing the scrolling divs 32599 if(options.scrollOverflow){ 32600 if(slides.length){ 32601 slides.each(function(){ 32602 createScrollBar($(this)); 32603 }); 32604 }else{ 32605 createScrollBar($(this)); 32606 } 32607 } 32608 32609 //adjusting the position fo the FULL WIDTH slides... 32610 if (slides.length > 1) { 32611 landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL)); 32612 } 32613 }); 32614 32615 var activeSection = $(SECTION_ACTIVE_SEL); 32616 var sectionIndex = activeSection.index(SECTION_SEL); 32617 32618 //isn't it the first section? 32619 if(sectionIndex){ 32620 //adjusting the position for the current section 32621 silentMoveTo(sectionIndex + 1); 32622 } 32623 32624 isResizing = false; 32625 // Uncode change 32626 // $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container); 32627 $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container, getTableHeight()); 32628 $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container); 32629 } 32630 32631 /** 32632 * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` 32633 * are smaller than the set limit values. 32634 */ 32635 function setResponsive(active){ 32636 var isResponsive = $body.hasClass(RESPONSIVE); 32637 32638 if(active){ 32639 if(!isResponsive){ 32640 setAutoScrolling(false, 'internal'); 32641 setFitToSection(false, 'internal'); 32642 $(SECTION_NAV_SEL).hide(); 32643 $body.addClass(RESPONSIVE); 32644 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 32645 } 32646 } 32647 else if(isResponsive){ 32648 setAutoScrolling(originals.autoScrolling, 'internal'); 32649 setFitToSection(originals.autoScrolling, 'internal'); 32650 $(SECTION_NAV_SEL).show(); 32651 $body.removeClass(RESPONSIVE); 32652 $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active); 32653 } 32654 } 32655 32656 if($(this).length){ 32657 //public functions 32658 FP.setAutoScrolling = setAutoScrolling; 32659 FP.setRecordHistory = setRecordHistory; 32660 FP.setScrollingSpeed = setScrollingSpeed; 32661 FP.setFitToSection = setFitToSection; 32662 FP.setLockAnchors = setLockAnchors; 32663 FP.setMouseWheelScrolling = setMouseWheelScrolling; 32664 FP.setAllowScrolling = setAllowScrolling; 32665 FP.setKeyboardScrolling = setKeyboardScrolling; 32666 FP.moveSectionUp = moveSectionUp; 32667 FP.moveSectionDown = moveSectionDown; 32668 FP.silentMoveTo = silentMoveTo; 32669 FP.moveTo = moveTo; 32670 FP.moveSlideRight = moveSlideRight; 32671 FP.moveSlideLeft = moveSlideLeft; 32672 FP.fitToSection = fitToSection; 32673 FP.reBuild = reBuild; 32674 FP.setResponsive = setResponsive; 32675 FP.destroy = destroy; 32676 32677 init(); 32678 32679 bindEvents(); 32680 } 32681
32682 function init(){ 32683 //if css3 is not supported, it will use jQuery animations 32684 if(options.css3){ 32685 options.css3 = support3d(); 32686 } 32687 32688 options.scrollBar = options.scrollBar || options.hybrid; 32689 32690 setOptionsFromDOM(); 32691 prepareDom(); 32692 setAllowScrolling(true); 32693 setAutoScrolling(options.autoScrolling, 'internal'); 32694 responsive(); 32695 32696 //setting the class for the body element 32697 setBodyClass(); 32698 32699 //Uncode addition 32700 // if(document.readyState === 'complete'){ 32701 // scrollToAnchor(); 32702 // } 32703 // $window.on('load', scrollToAnchor); 32704 } 32705 32706 function bindEvents(){ 32707 $window 32708 //when scrolling... 32709 //.on('scroll', scrollHandler) 32710 32711 //detecting any change on the URL to scroll to the given anchor link 32712 //(a way to detect back history button as we play with the hashes on the URL) 32713 .on('hashchange', hashChangeHandler) 32714 32715 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 32716 .blur(blurHandler) 32717 32718 //when resizing the site, we adjust the heights of the sections, slimScroll... 32719 .resize(resizeHandler); 32720 32721 $document 32722 //Sliding with arrow keys, both, vertical and horizontal 32723 .keydown(keydownHandler) 32724 32725 //to prevent scrolling while zooming 32726 .keyup(keyUpHandler) 32727 32728 //Scrolls to the section when clicking the navigation bullet 32729 .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler) 32730 32731 //Scrolls the slider to the given slide destination for the given section 32732 .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler) 32733 32734 .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler); 32735 32736 //Scrolling horizontally when clicking on the slider controls. 32737 $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler); 32738 32739 /** 32740 * Applying normalScroll elements. 32741 * Ignoring the scrolls over the specified selectors. 32742 */ 32743 if(options.normalScrollElements){ 32744 $document.on('mouseenter', options.normalScrollElements, function () { 32745 setMouseWheelScrolling(false); 32746 }); 32747 32748 $document.on('mouseleave', options.normalScrollElements, function(){ 32749 setMouseWheelScrolling(true); 32750 }); 32751 } 32752 } 32753 32754 /** 32755 * Setting options from DOM elements if they are not provided. 32756 */ 32757 function setOptionsFromDOM(){ 32758 var sections = container.find(options.sectionSelector); 32759 32760 //no anchors option? Checking for them in the DOM attributes 32761 if(!options.anchors.length){ 32762 options.anchors = sections.filter('[data-anchor]').map(function(){ 32763 return $(this).data('anchor').toString(); 32764 }).get(); 32765 } 32766 32767 //no tooltips option? Checking for them in the DOM attributes 32768 if(!options.navigationTooltips.length){ 32769 options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){ 32770 return $(this).data('tooltip').toString(); 32771 }).get(); 32772 } 32773 } 32774 32775 /** 32776 * Works over the DOM structure to set it up for the current fullpage options. 32777 */ 32778 function prepareDom(){ 32779 container.css({ 32780 'height': '100%', 32781 'position': 'relative' 32782 }); 32783 32784 //adding a class to recognize the container internally in the code 32785 container.addClass(WRAPPER); 32786 $('html').addClass(ENABLED); 32787 32788 windowsHeight = $window.height(); 32789 32790 container.removeClass(DESTROYED); //in case it was destroyed before initializing it again 32791 32792 addInternalSelectors(); 32793 32794 //styling the sections / slides / menu 32795 $(SECTION_SEL).each(function(index){ 32796 var section = $(this); 32797 var slides = section.find(SLIDE_SEL); 32798 var numSlides = slides.length; 32799 32800 styleSection(section, index); 32801 styleMenu(section, index); 32802 32803 // if there's any slide 32804 if (numSlides > 0) { 32805 styleSlides(section, slides, numSlides); 32806 }else{ 32807 if(options.verticalCentered){ 32808 addTableClass(section); 32809 } 32810 } 32811 }); 32812 32813 //fixed elements need to be moved out of the plugin container due to problems with CSS3. 32814 if(options.fixedElements && options.css3){ 32815 $(options.fixedElements).appendTo($body); 32816 } 32817 32818 //vertical centered of the navigation + active bullet 32819 if(options.navigation){ 32820 addVerticalNavigation(); 32821 } 32822 32823 enableYoutubeAPI(); 32824 32825 if(options.scrollOverflow){ 32826 if(document.readyState === 'complete'){ 32827 createScrollBarHandler(); 32828 } 32829 //after DOM and images are loaded 32830 $window.on('load', createScrollBarHandler); 32831 }else{ 32832 afterRenderActions(); 32833 } 32834 } 32835 32836 /** 32837 * Styles the horizontal slides for a section. 32838 */ 32839 function styleSlides(section, slides, numSlides){ 32840 var sliderWidth = numSlides * 100; 32841 var slideWidth = 100 / numSlides; 32842 32843 slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />'); 32844 slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />'); 32845 32846 section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%'); 32847 32848 if(numSlides > 1){ 32849 if(options.controlArrows){ 32850 createSlideArrows(section); 32851 } 32852 32853 if(options.slidesNavigation){ 32854 addSlidesNavigation(section, numSlides); 32855 } 32856 } 32857 32858 slides.each(function(index) { 32859 $(this).css('width', slideWidth + '%'); 32860 32861 if(options.verticalCentered){ 32862 addTableClass($(this)); 32863 } 32864 }); 32865 32866 var startingSlide = section.find(SLIDE_ACTIVE_SEL); 32867 32868 //if the slide won't be an starting point, the default will be the first one 32869 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
32869ide by default. 32870 if( startingSlide.length && ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){ 32871 silentLandscapeScroll(startingSlide, 'internal'); 32872 }else{ 32873 slides.eq(0).addClass(ACTIVE); 32874 } 32875 } 32876 32877 /** 32878 * Styling vertical sections 32879 */ 32880 function styleSection(section, index){ 32881 //if no active section is defined, the 1st one will be the default one 32882 if(!index && $(SECTION_ACTIVE_SEL).length === 0) { 32883 section.addClass(ACTIVE); 32884 } 32885 startingSection = $(SECTION_ACTIVE_SEL); 32886 32887 section.css('height', windowsHeight + 'px'); 32888 32889 if(options.paddingTop){ 32890 section.css('padding-top', options.paddingTop); 32891 } 32892 32893 if(options.paddingBottom){ 32894 section.css('padding-bottom', options.paddingBottom); 32895 } 32896 32897 if (typeof options.sectionsColor[index] !== 'undefined') { 32898 section.css('background-color', options.sectionsColor[index]); 32899 } 32900 32901 if (typeof options.anchors[index] !== 'undefined') { 32902 section.attr('data-anchor', options.anchors[index]); 32903 } 32904 } 32905 32906 /** 32907 * Sets the data-anchor attributes to the menu elements and activates the current one. 32908 */ 32909 function styleMenu(section, index){ 32910 if (typeof options.anchors[index] !== 'undefined') { 32911 //activating the menu / nav element on load 32912 if(section.hasClass(ACTIVE)){ 32913 activateMenuAndNav(options.anchors[index], index); 32914 } 32915 } 32916 32917 //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) 32918 if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){ 32919 $(options.menu).appendTo($body); 32920 } 32921 } 32922 32923 /** 32924 * Adds internal classes to be able to provide customizable selectors 32925 * keeping the link with the style sheet. 32926 */ 32927 function addInternalSelectors(){ 32928 container.find(options.sectionSelector).addClass(SECTION); 32929 container.find(options.slideSelector).addClass(SLIDE); 32930 } 32931 32932 /** 32933 * Creates the control arrows for the given section 32934 */ 32935 function createSlideArrows(section){ 32936 section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>'); 32937 32938 if(options.controlArrowColor!='#fff'){ 32939 section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor); 32940 section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent'); 32941 } 32942 32943 if(!options.loopHorizontal){ 32944 section.find(SLIDES_ARROW_PREV_SEL).hide(); 32945 } 32946 } 32947 32948 /** 32949 * Creates a vertical navigation bar. 32950 */ 32951 function addVerticalNavigation(){ 32952 $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>'); 32953 var nav = $(SECTION_NAV_SEL); 32954 32955 nav.addClass(function() { 32956 return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition; 32957 }); 32958 32959 for (var i = 0; i < $(SECTION_SEL).length; i++) { 32960 var link = ''; 32961 if (options.anchors.length) { 32962 link = options.anchors[i]; 32963 } 32964 32965 var li = '<li><a href="#' + link + '"><span></span></a>'; 32966 32967 // Only add tooltip if needed (defined by user) 32968 var tooltip = options.navigationTooltips[i]; 32969 32970 if (typeof tooltip !== 'undefined' && tooltip !== '') { 32971 li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>'; 32972 } 32973 32974 li += '</li>'; 32975 32976 nav.find('ul').append(li); 32977 } 32978 32979 //centering it vertically 32980 $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px'); 32981 32982 //activating the current active section 32983 $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE); 32984 } 32985 32986 /** 32987 * Creates the slim scroll scrollbar for the sections and slides inside them. 32988 */ 32989 function createScrollBarHandler(){ 32990 $(SECTION_SEL).each(function(){ 32991 var slides = $(this).find(SLIDE_SEL); 32992 32993 if(slides.length){ 32994 slides.each(function(){ 32995 createScrollBar($(this)); 32996 }); 32997 }else{ 32998 createScrollBar($(this)); 32999 } 33000 33001 }); 33002 afterRenderActions(); 33003 } 33004 33005 /*
33006 * Enables the Youtube videos API so we can control their flow if necessary. 33007 */ 33008 function enableYoutubeAPI(){ 33009 container.find('iframe[src*="youtube.com/embed/"]').each(function(){ 33010 addURLParam($(this), 'enablejsapi=1'); 33011 }); 33012 } 33013 33014 /** 33015 * Adds a new parameter and its value to the `src` of a given element 33016 */ 33017 function addURLParam(element, newParam){ 33018 var originalSrc = element.attr('src'); 33019 element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam); 33020 } 33021 33022 /* 33023 * Returns the prefix sign to use for a new parameter in an existen URL. 33024 * 33025 * @return {String} ? | & 33026 */ 33027 function getUrlParamSign(url){ 33028 return ( !/\?/.test( url ) ) ? '?' : '&'; 33029 } 33030 33031 /** 33032 * Actions and callbacks to fire afterRender 33033 */ 33034 function afterRenderActions(){ 33035 var section = $(SECTION_ACTIVE_SEL); 33036 33037 section.addClass(COMPLETELY); 33038 33039 if(options.scrollOverflowHandler.afterRender){ 33040 options.scrollOverflowHandler.afterRender(section); 33041 } 33042 lazyLoad(section); 33043 playMedia(section); 33044 options.scrollOverflowHandler.afterLoad(); 33045 33046 if(isDestinyTheStartingSection()){ 33047 $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1)); 33048 } 33049 33050 // Uncode change 33051 // $.isFunction( options.afterRender ) && options.afterRender.call(container); 33052 $.isFunction( options.afterRender ) && options.afterRender.call(container, getTableHeight()); 33053 } 33054 33055 /** 33056 * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization) 33057 */ 33058 function isDestinyTheStartingSection(){ 33059 var anchors = window.location.hash.replace('#', '').split('/'); 33060 var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0])); 33061 33062 return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index(); 33063 } 33064 33065 33066 var isScrolling = false; 33067 var lastScroll = 0; 33068 33069 //when scrolling... 33070 function scrollHandler(){ 33071 var currentSection; 33072 33073 if(!options.autoScrolling || options.scrollBar){ 33074 var currentScroll = $window.scrollTop(); 33075 var scrollDirection = getScrollDirection(currentScroll); 33076 var visibleSectionIndex = 0; 33077 var screen_mid = currentScroll + ($window.height() / 2.0); 33078 var isAtBottom = $body.height() - $window.height() === currentScroll; 33079 var sections = document.querySelectorAll(SECTION_SEL); 33080 33081 //when using `auto-height` for a small last section it won't be centered in the viewport 33082 if(isAtBottom){ 33083 visibleSectionIndex = sections.length - 1; 33084 } 33085 //is at top? when using `auto-height` for a small first section it won't be centered in the viewport 33086 else if(!currentScroll){ 33087 visibleSectionIndex = 0; 33088 } 33089 33090 //taking the section which is showing more content in the viewport 33091 else{ 33092 for (var i = 0; i < sections.length; ++i) { 33093 var section = sections[i]; 33094 33095 // Pick the the last section which passes the middle line of the screen. 33096 if (section.offsetTop <= screen_mid) 33097 { 33098 visibleSectionIndex = i; 33099 } 33100 } 33101 } 33102 33103 if(isCompletelyInViewPort(scrollDirection)){ 33104 if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){ 33105 $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 33106 } 33107 } 33108 33109 //geting the last one, the current one on the screen 33110 currentSection = $(sections).eq(visibleSectionIndex); 33111 33112 //setting the visible section as active when manually scrolling 33113 //executing only once the first time we reach the section 33114 if(!currentSection.hasClass(ACTIVE)){ 33115 isScrolling = true; 33116 var leavingSection = $(SECTION_ACTIVE_SEL); 33117 var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1; 33118 var yMovement = getYmovement(currentSection); 33119 var anchorLink = currentSection.data('anchor'); 33120 var sectionIndex = currentSection.index(SECTION_SEL) + 1; 33121 var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL); 33122 var slideIndex; 33123 var slideAnchorLink; 33124 33125 if(activeSlide.length){ 33126 slideAnchorLink = activeSlide.data('anchor'); 33127 slideIndex = activeSlide.index(); 33128 } 33129 33130 if(canScroll){ 33131 currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE); 33132 33133 $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement); 33134 $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex); 33135 33136 stopMedia(leavingSection); 33137 lazyLoad(currentSection); 33138 playMedia(currentSection); 33139 33140 activateMenuAndNav(anchorLink, sectionIndex - 1); 33141 33142 if(options.anchors.length){ 33143 //needed to enter in hashChange event when using the menu with anchor links 33144 lastScrolledDestiny = anchorLink; 33145 } 33146 setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex); 33147 } 33148 33149 //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet 33150 clearTimeout(scrollId); 33151 scrollId = setTimeout(function(){ 33152 isScrolling = false;
33153 }, 100); 33154 } 33155 33156 if(options.fitToSection){ 33157 //for the auto adjust of the viewport to fit a whole section 33158 clearTimeout(scrollId2); 33159 33160 scrollId2 = setTimeout(function(){ 33161 //checking it again in case it changed during the delay 33162 if(options.fitToSection){ 33163 fitToSection(); 33164 } 33165 }, options.fitToSectionDelay); 33166 } 33167 } 33168 } 33169 33170 /** 33171 * Fits the site to the nearest active section 33172 */ 33173 function fitToSection(){ 33174 //checking fitToSection again in case it was set to false before the timeout delay 33175 if(canScroll){ 33176 //allows to scroll to an active section and 33177 //if the section is already active, we prevent firing callbacks 33178 isResizing = true; 33179 33180 scrollPage($(SECTION_ACTIVE_SEL)); 33181 isResizing = false; 33182 } 33183 } 33184 33185 /** 33186 * Determines whether the active section has seen in its whole or not. 33187 */ 33188 function isCompletelyInViewPort(movement){ 33189 var top = $(SECTION_ACTIVE_SEL).position().top; 33190 var bottom = top + $window.height(); 33191 33192 if(movement == 'up'){ 33193 return bottom >= ($window.scrollTop() + $window.height()); 33194 } 33195 return top <= $window.scrollTop(); 33196 } 33197 33198 /** 33199 * Gets the directon of the the scrolling fired by the scroll event. 33200 */ 33201 function getScrollDirection(currentScroll){ 33202 var direction = currentScroll > lastScroll ? 'down' : 'up'; 33203 33204 lastScroll = currentScroll; 33205 33206 //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination 33207 previousDestTop = currentScroll; 33208 33209 return direction; 33210 } 33211 33212 /** 33213 * Determines the way of scrolling up or down: 33214 * by 'automatically' scrolling a section or by using the default and normal scrolling. 33215 */ 33216 function scrolling(type, scrollable){ 33217 if (!isScrollAllowed.m[type]){ 33218 return; 33219 } 33220 var check = (type === 'down') ? 'bottom' : 'top'; 33221 var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp; 33222 33223 if(scrollable.length > 0 ){ 33224 //is the scrollbar at the start/end of the scroll? 33225 if(options.scrollOverflowHandler.isScrolled(check, scrollable)){ 33226 scrollSection(); 33227 }else{ 33228 return true; 33229 } 33230 }else{ 33231 // moved up/down 33232 scrollSection(); 33233 } 33234 } 33235 33236 /* 33237 * Preventing bouncing in iOS #2285 33238 */ 33239 function preventBouncing(event){ 33240 var e = event.originalEvent; 33241 if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e) && isScrollAllowed.m.up){ 33242 //preventing the easing on iOS devices 33243 event.preventDefault(); 33244 } 33245 } 33246 33247 var touchStartY = 0; 33248 var touchStartX = 0; 33249 var touchEndY = 0; 33250 var touchEndX = 0; 33251 33252 /* Detecting touch events 33253 33254 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 33255 * This way, the touchstart and the touch moves shows an small difference between them which is the 33256 * used one to determine the direction. 33257 */ 33258 function touchMoveHandler(event){ 33259 var e = event.originalEvent; 33260 var activeSection = $(e.target).closest(SECTION_SEL); 33261 33262 // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain 33263 if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) { 33264 33265 if(options.autoScrolling){ 33266 //preventing the easing on iOS devices 33267 event.preventDefault(); 33268 } 33269 33270 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 33271 var touchEvents = getEventsPage(e); 33272 33273 touchEndY = touchEvents.y; 33274 touchEndX = touchEvents.x; 33275 33276 //if movement in the X axys is greater than in the Y and the currect section has slides... 33277 if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) { 33278 33279 //is the movement greater than the minimum resistance to scroll? 33280 if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) { 33281 if (touchStartX > touchEndX) { 33282 if(isScrollAllowed.m.right){ 33283 moveSlideRight(activeSection); //next 33284 } 33285 } else { 33286 if(isScrollAllowed.m.left){ 33287 moveSlideLeft(activeSection); //prev 33288 } 33289 } 33290 } 33291 } 33292 33293 //vertical scrolling (only when autoScrolling is enabled) 33294 else if(options.autoScrolling && canScroll){ 33295 33296 //is the movement greater than the minimum resistance to scroll? 33297 if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) { 33298 if (touchStartY > touchEndY) { 33299 scrolling('down', scrollable); 33300 } else if (touchEndY > touchStartY) { 33301 scrolling('up', scrollable); 33302 } 33303 } 33304 } 33305 } 33306 } 33307 33308 /** 33309 * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements 33310 * Currently works well for iOS - Android might need some testing 33311 * @param {Element} el target element / jquery selector (in subsequent nodes) 33312 * @param {int} hop current hop compared to options.normalScrollElementTouchThreshold 33313 * @return {boolean} true if there is a match to options.normalScrollElements 33314 */ 33315 function checkParentForNormalScrollElement (el, hop) { 33316 hop = hop || 0; 33317 var parent = $(el).parent(); 33318 33319 if (hop < options.normalScrollElementTouchThreshold && 33320 parent.is(options.normalScrollElements) ) { 33321 return true; 33322 } else if (hop == options.normalScrollElementTouchThreshold) { 33323 return false;
33324 } else { 33325 return checkParentForNormalScrollElement(parent, ++hop); 33326 } 33327 } 33328 33329 /** 33330 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 33331 * this way we make sure that is really a touch event what IE is detecting. 33332 */ 33333 function isReallyTouch(e){ 33334 //if is not IE || IE is detecting `touch` or `pen` 33335 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 33336 } 33337 33338 /** 33339 * Handler for the touch start event. 33340 */ 33341 function touchStartHandler(event){ 33342 var e = event.originalEvent; 33343 33344 //stopping the auto scroll to adjust to a section 33345 if(options.fitToSection){ 33346 $htmlBody.stop(); 33347 } 33348 33349 if(isReallyTouch(e)){ 33350 var touchEvents = getEventsPage(e); 33351 touchStartY = touchEvents.y; 33352 touchStartX = touchEvents.x; 33353 } 33354 } 33355 33356 /** 33357 * Gets the average of the last `number` elements of the given array. 33358 */ 33359 function getAverage(elements, number){ 33360 var sum = 0; 33361 33362 //taking `number` elements from the end to make the average, if there are not enought, 1 33363 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 33364 33365 for(var i = 0; i < lastElements.length; i++){ 33366 sum = sum + lastElements[i]; 33367 } 33368 33369 return Math.ceil(sum/number); 33370 } 33371 33372 /** 33373 * Detecting mousewheel scrolling 33374 * 33375 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 33376 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 33377 */ 33378 var prevTime = new Date().getTime(); 33379 33380 function MouseWheelHandler(e) { 33381 var curTime = new Date().getTime(); 33382 var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL); 33383 33384 //autoscrolling and not zooming? 33385 if(options.autoScrolling && !controlPressed && !isNormalScroll){ 33386 // cross-browser wheel delta 33387 e = e || window.event; 33388 var value = e.wheelDelta || -e.deltaY || -e.detail; 33389 var delta = Math.max(-1, Math.min(1, value)); 33390 33391 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 33392 var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection); 33393 33394 //Limiting the array to 150 (lets not waste memory!) 33395 if(scrollings.length > 149){ 33396 scrollings.shift(); 33397 } 33398 33399 //keeping record of the previous scrollings 33400 scrollings.push(Math.abs(value)); 33401 33402 //preventing to scroll the site on mouse wheel when scrollbar is present 33403 if(options.scrollBar){ 33404 e.preventDefault ? e.preventDefault() : e.returnValue = false; 33405 } 33406 33407 var activeSection = $(SECTION_ACTIVE_SEL); 33408 var scrollable = options.scrollOverflowHandler.scrollable(activeSection); 33409 33410 //time difference between the last scroll and the current one 33411 var timeDiff = curTime-prevTime; 33412 prevTime = curTime; 33413 33414 //haven't they scrolled in a while? 33415 //(enough to be consider a different scrolling action to scroll another section) 33416 if(timeDiff > 200){ 33417 //emptying the array, we dont care about old scrollings for our averages 33418 scrollings = []; 33419 } 33420 33421 if(canScroll){ 33422 var averageEnd = getAverage(scrollings, 10); 33423 var averageMiddle = getAverage(scrollings, 70); 33424 var isAccelerating = averageEnd >= averageMiddle; 33425 33426 //to avoid double swipes... 33427 if(isAccelerating && isScrollingVertically){ 33428 //scrolling down? 33429 if (delta < 0) { 33430 scrolling('down', scrollable); 33431 33432 //scrolling up? 33433 }else { 33434 scrolling('up', scrollable); 33435 } 33436 } 33437 } 33438 33439 return false;
33440 } 33441 33442 if(options.fitToSection){ 33443 //stopping the auto scroll to adjust to a section 33444 $htmlBody.stop(); 33445 } 33446 } 33447 33448 /** 33449 * Slides a slider to the given direction. 33450 * Optional `section` param. 33451 */ 33452 function moveSlide(direction, section){ 33453 var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section; 33454 var slides = activeSection.find(SLIDES_WRAPPER_SEL); 33455 var numSlides = slides.find(SLIDE_SEL).length; 33456 33457 // more than one slide needed and nothing should be sliding 33458 if (!slides.length || slideMoving || numSlides < 2) { 33459 return; 33460 } 33461 33462 var currentSlide = slides.find(SLIDE_ACTIVE_SEL); 33463 var destiny = null; 33464 33465 if(direction === 'left'){ 33466 destiny = currentSlide.prev(SLIDE_SEL); 33467 }else{ 33468 destiny = currentSlide.next(SLIDE_SEL); 33469 } 33470 33471 //isn't there a next slide in the secuence? 33472 if(!destiny.length){ 33473 //respect loopHorizontal settin 33474 if (!options.loopHorizontal) return; 33475 33476 if(direction === 'left'){ 33477 destiny = currentSlide.siblings(':last'); 33478 }else{ 33479 destiny = currentSlide.siblings(':first'); 33480 } 33481 } 33482 33483 slideMoving = true; 33484 33485 landscapeScroll(slides, destiny, direction); 33486 } 33487 33488 /** 33489 * Maintains the active slides in the viewport 33490 * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) 33491 */ 33492 function keepSlidesPosition(){ 33493 $(SLIDE_ACTIVE_SEL).each(function(){ 33494 silentLandscapeScroll($(this), 'internal'); 33495 }); 33496 } 33497 33498 var previousDestTop = 0; 33499 /** 33500 * Returns the destination Y position based on the scrolling direction and 33501 * the height of the section. 33502 */ 33503 function getDestinationPosition(element){ 33504 var elemPosition = element.position(); 33505 33506 //top of the desination will be at the top of the viewport 33507 var position = elemPosition.top; 33508 var isScrollingDown = elemPosition.top > previousDestTop; 33509 var sectionBottom = position - windowsHeight + element.outerHeight(); 33510 var bigSectionsDestination = options.bigSectionsDestination; 33511 33512 //Uncode addition 33513 var containerH = container.outerHeight(); 33514 var containerPosition = container.offset(); 33515 33516 //########### Commented by Uncode - START ########### 33517 //is the destination element bigger than the viewport? 33518 // if(element.outerHeight() > windowsHeight){ 33519 // //scrolling up? 33520 // if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){ 33521 // position = sectionBottom; 33522 // } 33523 // } 33524 33525 // //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section 33526 // else if(isScrollingDown || (isResizing && element.is(':last-child')) ){ 33527 // //The bottom of the destination will be at the bottom of the viewport 33528 // position = sectionBottom; 33529 // } 33530 //########### Commented by Uncode - END ########### 33531 33532 //Uncode addition 33533 if ( !$masthead.hasClass('menu-transparent') && $('body').hasClass('uncode-fp-menu-shrink') && !element.is(':first-child') ) 33534 position += 18; 33535 if ( ( containerH + menuHeight + bodyBorder + adminBarHeight - windowsHeight ) < position || ( isResizing && element.is(':last-child') ) ) { 33536 position = sectionBottom + menuHeight + bodyBorder*2 + adminBarHeight; 33537 } 33538 33539 /* 33540 Keeping record of the last scrolled position to determine the scrolling direction. 33541 No conventional methods can be used as the scroll bar might not be present 33542 AND the section might not be active if it is auto-height and didnt reach the middle 33543 of the viewport. 33544 */ 33545 previousDestTop = position; 33546 return position; 33547 } 33548 33549 /** 33550 * Scrolls the site to the given element and scrolls to the slide if a callback is given. 33551 */ 33552 function scrollPage(element, callback, isMovementUp){ 33553 if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function 33554 33555 var dtop = getDestinationPosition(element); 33556 var slideAnchorLink; 33557 var slideIndex; 33558 33559 //local variables 33560 var v = { 33561 element: element, 33562 callback: callback, 33563 isMovementUp: isMovementUp, 33564 dtop: dtop, 33565 yMovement: getYmovement(element), 33566 anchorLink: element.data('anchor'), 33567 sectionIndex: element.index(SECTION_SEL), 33568 activeSlide: element.find(SLIDE_ACTIVE_SEL), 33569 activeSection: $(SECTION_ACTIVE_SEL), 33570 leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1, 33571 33572 //caching the value of isResizing at the momment the function is called 33573 //because it will be checked later inside a setTimeout and the value might change 33574 localIsResizing: isResizing 33575 }; 33576 33577 //quiting when destination scroll is the same as the current one 33578 if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; } 33579 33580 if(v.activeSlide.length){ 33581 slideAnchorLink = v.activeSlide.data('anchor'); 33582 slideIndex = v.activeSlide.index(); 33583 } 33584 33585 // If continuousVertical && we need to wrap around 33586 if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" && 33587 ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or 33588 (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down 33589 33590 v = createInfiniteSections(v); 33591 } 33592 33593 //callback (onLeave) if the site is not just resizing and readjusting the slides 33594 if($.isFunction(options.onLeave) && !v.localIsResizing){ 33595 if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){ 33596 return; 33597 } 33598 } 33599 33600 //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one) 33601 if(!v.localIsResizing){ 33602 stopMedia(v.activeSection); 33603 } 33604 33605 options.scrollOverflowHandler.beforeLeave(); 33606 element.addClass(ACTIVE).siblings().removeClass(ACTIVE); 33607 lazyLoad(element); 33608 options.scrollOverflowHandler.onLeave(); 33609 33610 33611 //preventing from activating the MouseWheelHandler event 33612 //more than once if the page is scrolling 33613 canScroll = false;
33614 33615 setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex); 33616 33617 performMovement(v); 33618 33619 //flag to avoid callingn `scrollPage()` twice in case of using anchor links 33620 lastScrolledDestiny = v.anchorLink; 33621 33622 //avoid firing it twice (as it does also on scroll) 33623 activateMenuAndNav(v.anchorLink, v.sectionIndex); 33624 } 33625 33626 /** 33627 * Performs the vertical movement (by CSS3 or by jQuery) 33628 */ 33629 function performMovement(v){ 33630 // using CSS3 translate functionality 33631 if (options.css3 && options.autoScrolling && !options.scrollBar) { 33632 33633 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 33634 // that's why we round it to 0. 33635 var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)'; 33636 transformContainer(translate3d, true); 33637 33638 //even when the scrollingSpeed is 0 there's a little delay, which might cause the 33639 //scrollingSpeed to change in case of using silentMoveTo(); 33640 if(options.scrollingSpeed){ 33641 clearTimeout(afterSectionLoadsId); 33642 afterSectionLoadsId = setTimeout(function () { 33643 afterSectionLoads(v); 33644 }, options.scrollingSpeed); 33645 }else{ 33646 afterSectionLoads(v); 33647 } 33648 } 33649 33650 // using jQuery animate 33651 else{ 33652 var scrollSettings = getScrollSettings(v); 33653 33654 $(scrollSettings.element).animate( 33655 scrollSettings.options, 33656 options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating `html, body` 33657 if(options.scrollBar){ 33658 33659 /* Hack! 33660 The timeout prevents setting the most dominant section in the viewport as "active" when the user 33661 scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar. 33662 33663 When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished. 33664 */ 33665 setTimeout(function(){ 33666 afterSectionLoads(v); 33667 },30); 33668 }else{ 33669 afterSectionLoads(v); 33670 } 33671 }); 33672 } 33673 } 33674 33675 /** 33676 * Gets the scrolling settings depending on the plugin autoScrolling option 33677 */ 33678 function getScrollSettings(v){ 33679 var scroll = {}; 33680 33681 if(options.autoScrolling && !options.scrollBar){ 33682 scroll.options = { 'top': -v.dtop}; 33683 scroll.element = WRAPPER_SEL; 33684 }else{ 33685 scroll.options = { 'scrollTop': v.dtop}; 33686 scroll.element = 'html, body'; 33687 } 33688 33689 return scroll; 33690 } 33691 33692 /** 33693 * Adds sections before or after the current one to create the infinite effect. 33694 */ 33695 function createInfiniteSections(v){ 33696 // Scrolling down 33697 if (!v.isMovementUp) { 33698 // Move all previous sections to after the active section 33699 $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse()); 33700 } 33701 else { // Scrolling up 33702 // Move all next sections to before the active section 33703 $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL)); 33704 } 33705 33706 // Maintain the displayed position (now that we changed the element order) 33707 silentScroll($(SECTION_ACTIVE_SEL).position().top); 33708 33709 // Maintain the active slides visible in the viewport 33710 keepSlidesPosition(); 33711 33712 // save for later the elements that still need to be reordered 33713 v.wrapAroundElements = v.activeSection; 33714 33715 // Recalculate animation variables 33716 v.dtop = v.element.position().top; 33717 v.yMovement = getYmovement(v.element); 33718 33719 return v; 33720 } 33721 33722 /** 33723 * Fix section order after continuousVertical changes have been animated 33724 */ 33725 function continuousVerticalFixSectionOrder (v) {
33726 // If continuousVertical is in effect (and autoScrolling would also be in effect then), 33727 // finish moving the elements around so the direct navigation will function more simply 33728 if (!v.wrapAroundElements || !v.wrapAroundElements.length) { 33729 return; 33730 } 33731 33732 if (v.isMovementUp) { 33733 $(SECTION_FIRST_SEL).before(v.wrapAroundElements); 33734 } 33735 else { 33736 $(SECTION_LAST_SEL).after(v.wrapAroundElements); 33737 } 33738 33739 silentScroll($(SECTION_ACTIVE_SEL).position().top); 33740 33741 // Maintain the active slides visible in the viewport 33742 keepSlidesPosition(); 33743 } 33744 33745 33746 /** 33747 * Actions to do once the section is loaded. 33748 */ 33749 function afterSectionLoads (v){ 33750 continuousVerticalFixSectionOrder(v); 33751 33752 //callback (afterLoad) if the site is not just resizing and readjusting the slides 33753 $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1)); 33754 options.scrollOverflowHandler.afterLoad(); 33755 33756 if(!v.localIsResizing){ 33757 playMedia(v.element); 33758 } 33759 33760 v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY); 33761 33762 canScroll = true; 33763 33764 $.isFunction(v.callback) && v.callback.call(this); 33765 } 33766 33767 /** 33768 * Sets the value for the given attribute from the `data-` attribute with the same suffix 33769 * ie: data-srcset ==> srcset | data-src ==> src 33770 */ 33771 function setSrc(element, attribute){ 33772 element 33773 .attr(attribute, element.data(attribute)) 33774 .removeAttr('data-' + attribute); 33775 } 33776 33777 /** 33778 * Lazy loads image, video and audio elements. 33779 */ 33780 function lazyLoad(destiny){ 33781 if (!options.lazyLoading){ 33782 return; 33783 } 33784 33785 var panel = getSlideOrSection(destiny); 33786 var element; 33787 33788 panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 33789 element = $(this); 33790 33791 $.each(['src', 'srcset'], function(index, type){ 33792 var attribute = element.attr('data-' + type); 33793 if(typeof attribute !== 'undefined' && attribute){ 33794 setSrc(element, type); 33795 } 33796 }); 33797 33798 if(element.is('source')){ 33799 element.closest('video').get(0).load(); 33800 } 33801 }); 33802 } 33803 33804 /** 33805 * Plays video and audio elements. 33806 */ 33807 function playMedia(destiny){ 33808 var panel = getSlideOrSection(destiny); 33809 33810 //playing HTML5 media elements 33811 panel.find('video, audio').each(function(){ 33812 var element = $(this).get(0); 33813 33814 if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) { 33815 element.play(); 33816 } 33817 }); 33818 33819 //youtube videos 33820 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 33821 var element = $(this).get(0); 33822 33823 if ( element.hasAttribute('data-autoplay') ){ 33824 playYoutube(element); 33825 } 33826 33827 //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load. 33828 element.onload = function() { 33829 if ( element.hasAttribute('data-autoplay') ){ 33830 playYoutube(element); 33831 } 33832 }; 33833 }); 33834 } 33835 33836 /** 33837 * Plays a youtube video 33838 */ 33839 function playYoutube(element){ 33840 element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); 33841 } 33842 33843 /** 33844 * Stops video and audio elements. 33845 */ 33846 function stopMedia(destiny){ 33847 var panel = getSlideOrSection(destiny); 33848 33849 //stopping HTML5 media elements 33850 panel.find('video, audio').each(function(){ 33851 var element = $(this).get(0); 33852 33853 if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) { 33854 element.pause(); 33855 } 33856 }); 33857 33858 //youtube videos 33859 panel.find('iframe[src*="youtube.com/embed/"]').each(function(){ 33860 var element = $(this).get(0); 33861 33862 if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){ 33863 $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*'); 33864 } 33865 }); 33866 } 33867 33868 /** 33869 * Gets the active slide (or section) for the given section 33870 */ 33871 function getSlideOrSection(destiny){ 33872 var slide = destiny.find(SLIDE_ACTIVE_SEL); 33873 if( slide.length ) { 33874 destiny = $(slide); 33875 } 33876 33877 return destiny; 33878 } 33879 33880 /**
33881 * Scrolls to the anchor in the URL when loading the site 33882 */ 33883 function scrollToAnchor(){ 33884 //getting the anchor link in the URL and deleting the `#` 33885 var value = window.location.hash.replace('#', '').split('/'); 33886 var sectionAnchor = decodeURIComponent(value[0]); 33887 var slideAnchor = decodeURIComponent(value[1]); 33888 33889 if(sectionAnchor){ //if theres any # 33890 if(options.animateAnchor){ 33891 scrollPageAndSlide(sectionAnchor, slideAnchor); 33892 }else{ 33893 silentMoveTo(sectionAnchor, slideAnchor); 33894 } 33895 } 33896 } 33897 33898 /** 33899 * Detecting any change on the URL to scroll to the given anchor link 33900 * (a way to detect back history button as we play with the hashes on the URL) 33901 */ 33902 function hashChangeHandler(){ 33903 if(!isScrolling && !options.lockAnchors){ 33904 var value = window.location.hash.replace('#', '').split('/'); 33905 var sectionAnchor = decodeURIComponent(value[0]); 33906 var slideAnchor = decodeURIComponent(value[1]); 33907 33908 //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) 33909 var isFirstSlideMove = (typeof lastScrolledDestiny === 'undefined'); 33910 var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving); 33911 33912 33913 if(sectionAnchor.length){ 33914 /*in order to call scrollpage() only once for each destination at a time 33915 It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` 33916 event is fired on every scroll too.*/ 33917 if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor )) { 33918 scrollPageAndSlide(sectionAnchor, slideAnchor); 33919 } 33920 } 33921 } 33922 } 33923 33924 //Sliding with arrow keys, both, vertical and horizontal 33925 function keydownHandler(e) { 33926 33927 clearTimeout(keydownId); 33928 33929 var activeElement = $(':focus'); 33930 33931 if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') && 33932 activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' && 33933 options.keyboardScrolling && options.autoScrolling){ 33934 var keyCode = e.which; 33935 33936 //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 33937 var keyControls = [40, 38, 32, 33, 34]; 33938 if($.inArray(keyCode, keyControls) > -1){ 33939 e.preventDefault(); 33940 } 33941 33942 controlPressed = e.ctrlKey; 33943 33944 keydownId = setTimeout(function(){ 33945 onkeydown(e); 33946 },150); 33947 } 33948 } 33949 33950 function tooltipTextHandler(){ 33951 $(this).prev().trigger('click'); 33952 } 33953 33954 //to prevent scrolling while zooming 33955 function keyUpHandler(e){ 33956 if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox 33957 controlPressed = e.ctrlKey; 33958 } 33959 } 33960 33961 //binding the mousemove when the mouse's middle button is released 33962 function mouseDownHandler(e){ 33963 //middle button 33964 if (e.which == 2){ 33965 oldPageY = e.pageY; 33966 container.on('mousemove', mouseMoveHandler); 33967 } 33968 } 33969 33970 //unbinding the mousemove when the mouse's middle button is released 33971 function mouseUpHandler(e){ 33972 //middle button 33973 if (e.which == 2){ 33974 container.off('mousemove'); 33975 } 33976 } 33977 33978 //Scrolling horizontally when clicking on the slider controls. 33979 function slideArrowHandler(){ 33980 var section = $(this).closest(SECTION_SEL); 33981 33982 if ($(this).hasClass(SLIDES_PREV)) { 33983 if(isScrollAllowed.m.left){ 33984 moveSlideLeft(section); 33985 } 33986 } else { 33987 if(isScrollAllowed.m.right){ 33988 moveSlideRight(section); 33989 } 33990 } 33991 } 33992 33993 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 33994 function blurHandler(){ 33995 isWindowFocused = false;
33996 controlPressed = false; 33997 } 33998 33999 //Scrolls to the section when clicking the navigation bullet 34000 function sectionBulletHandler(e){ 34001 e.preventDefault(); 34002 var index = $(this).parent().index(); 34003 scrollPage($(SECTION_SEL).eq(index)); 34004 } 34005 34006 //Scrolls the slider to the given slide destination for the given section 34007 function slideBulletHandler(e){ 34008 e.preventDefault(); 34009 var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL); 34010 var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index()); 34011 34012 landscapeScroll(slides, destiny); 34013 } 34014 34015 /** 34016 * Keydown event 34017 */ 34018 function onkeydown(e){ 34019 var shiftPressed = e.shiftKey; 34020 34021 //do nothing if we can not scroll or we are not using horizotnal key arrows. 34022 if(!canScroll && [37,39].indexOf(e.which) < 0){ 34023 return; 34024 } 34025 34026 switch (e.which) { 34027 //up 34028 case 38: 34029 case 33: 34030 if(isScrollAllowed.k.up){ 34031 moveSectionUp(); 34032 } 34033 break; 34034 34035 //down 34036 case 32: //spacebar 34037 if(shiftPressed && isScrollAllowed.k.up){ 34038 moveSectionUp(); 34039 break; 34040 } 34041 /* falls through */ 34042 case 40: 34043 case 34: 34044 if(isScrollAllowed.k.down){ 34045 moveSectionDown(); 34046 } 34047 break; 34048 34049 //Home 34050 case 36: 34051 if(isScrollAllowed.k.up){ 34052 moveTo(1); 34053 } 34054 break; 34055 34056 //End 34057 case 35: 34058 if(isScrollAllowed.k.down){ 34059 moveTo( $(SECTION_SEL).length ); 34060 } 34061 break; 34062 34063 //left 34064 case 37: 34065 if(isScrollAllowed.k.left){ 34066 moveSlideLeft(); 34067 } 34068 break; 34069 34070 //right 34071 case 39: 34072 if(isScrollAllowed.k.right){ 34073 moveSlideRight(); 34074 } 34075 break; 34076 34077 default: 34078 return; // exit this handler for other keys 34079 } 34080 } 34081 34082 /** 34083 * Detecting the direction of the mouse movement. 34084 * Used only for the middle button of the mouse. 34085 */ 34086 var oldPageY = 0; 34087 function mouseMoveHandler(e){ 34088 if(canScroll){ 34089 // moving up 34090 if (e.pageY < oldPageY && isScrollAllowed.m.up){ 34091 moveSectionUp(); 34092 } 34093 34094 // moving down 34095 else if(e.pageY > oldPageY && isScrollAllowed.m.down){ 34096 moveSectionDown(); 34097 } 34098 } 34099 oldPageY = e.pageY; 34100 } 34101 34102 /** 34103 * Scrolls horizontal sliders. 34104 */ 34105 function landscapeScroll(slides, destiny, direction){ 34106 var section = slides.closest(SECTION_SEL); 34107 var v = { 34108 slides: slides, 34109 destiny: destiny, 34110 direction: direction, 34111 destinyPos: destiny.position(), 34112 slideIndex: destiny.index(), 34113 section: section, 34114 sectionIndex: section.index(SECTION_SEL), 34115 anchorLink: section.data('anchor'), 34116 slidesNav: section.find(SLIDES_NAV_SEL), 34117 slideAnchor: getAnchor(destiny), 34118 prevSlide: section.find(SLIDE_ACTIVE_SEL), 34119 prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(), 34120 34121 //caching the value of isResizing at the momment the function is called 34122 //because it will be checked later inside a setTimeout and the value might change 34123 localIsResizing: isResizing 34124 }; 34125 v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex); 34126 v.direction = v.direction ? v.direction : v.xMovement; 34127 34128 //important!! Only do it when not resizing 34129 if(!v.localIsResizing){ 34130 //preventing from scrolling to the next/prev section when using scrollHorizontally 34131 canScroll = false;
34132 } 34133 34134 if(options.onSlideLeave){ 34135 34136 //if the site is not just resizing and readjusting the slides 34137 if(!v.localIsResizing && v.xMovement!=='none'){ 34138 if($.isFunction( options.onSlideLeave )){ 34139 if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){ 34140 slideMoving = false; 34141 return; 34142 } 34143 } 34144 } 34145 } 34146 34147 destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE); 34148 34149 if(!v.localIsResizing){ 34150 stopMedia(v.prevSlide); 34151 lazyLoad(destiny); 34152 } 34153 34154 if(!options.loopHorizontal && options.controlArrows){ 34155 //hidding it for the fist slide, showing for the rest 34156 section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0); 34157 34158 //hidding it for the last slide, showing for the rest 34159 section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child')); 34160 } 34161 34162 //only changing the URL if the slides are in the current section (not for resize re-adjusting) 34163 if(section.hasClass(ACTIVE) && !v.localIsResizing){ 34164 setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex); 34165 } 34166 34167 performHorizontalMove(slides, v, true); 34168 } 34169 34170 34171 function afterSlideLoads(v){ 34172 activeSlidesNavigation(v.slidesNav, v.slideIndex); 34173 34174 //if the site is not just resizing and readjusting the slides 34175 if(!v.localIsResizing){ 34176 $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex); 34177 34178 //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally 34179 //and to prevent double scroll right after a windows resize 34180 canScroll = true; 34181 34182 playMedia(v.destiny); 34183 } 34184 34185 //letting them slide again 34186 slideMoving = false; 34187 } 34188 34189 /** 34190 * Performs the horizontal movement. (CSS3 or jQuery) 34191 * 34192 * @param fireCallback {Bool} - determines whether or not to fire the callback 34193 */ 34194 function performHorizontalMove(slides, v, fireCallback){ 34195 var destinyPos = v.destinyPos; 34196 34197 if(options.css3){ 34198 var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; 34199 34200 addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d), v); 34201 34202 afterSlideLoadsId = setTimeout(function(){ 34203 fireCallback && afterSlideLoads(v); 34204 }, options.scrollingSpeed, options.easing); 34205 }else{ 34206 slides.animate({ 34207 scrollLeft : Math.round(destinyPos.left) 34208 }, options.scrollingSpeed, options.easing, function() { 34209 34210 fireCallback && afterSlideLoads(v); 34211 }); 34212 } 34213 } 34214 34215 /** 34216 * Sets the state for the horizontal bullet navigations. 34217 */ 34218 function activeSlidesNavigation(slidesNav, slideIndex){ 34219 slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE); 34220 slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE); 34221 } 34222 34223 var previousHeight = windowsHeight; 34224 34225 //when resizing the site, we adjust the heights of the sections, slimScroll... 34226 function resizeHandler(){ 34227 //checking if it needs to get responsive 34228 responsive(); 34229 34230 // rebuild immediately on touch devices 34231 if (isTouchDevice) { 34232 var activeElement = $(document.activeElement); 34233 34234 //if the keyboard is NOT visible 34235 if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) { 34236 var currentHeight = $window.height(); 34237 34238 //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) 34239 if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){ 34240 reBuild(true); 34241 previousHeight = currentHeight; 34242 } 34243 } 34244 }else{ 34245 //in order to call the functions only when the resize is finished 34246 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 34247 clearTimeout(resizeId); 34248 34249 resizeId = setTimeout(function(){ 34250 reBuild(true); 34251 }, 350); 34252 } 34253 } 34254 34255 /** 34256 * Checks if the site needs to get responsive and disables autoScrolling if so. 34257 * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. 34258 */ 34259 function responsive(){ 34260 var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity 34261 var heightLimit = options.responsiveHeight; 34262 34263 //only calculating what we need. Remember its called on the resize event. 34264 var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit; 34265 var isBreakingPointHeight = heightLimit && $window.height() < heightLimit; 34266 34267 if(widthLimit && heightLimit){ 34268 setResponsive(isBreakingPointWidth || isBreakingPointHeight); 34269 } 34270 else if(widthLimit){ 34271 setResponsive(isBreakingPointWidth); 34272 } 34273 else if(heightLimit){ 34274 setResponsive(isBreakingPointHeight); 34275 } 34276 } 34277 34278 /** 34279 * Adds transition animations for the given element 34280 */ 34281 function addAnimation(container, element){ 34282 var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3; 34283 34284 container.removeClass(NO_TRANSITION); 34285 return container.css({
34286 '-webkit-transition': transition, 34287 'transition': transition 34288 }); 34289 } 34290 34291 /** 34292 * Remove transition animations for the given element 34293 */ 34294 function removeAnimation(element){ 34295 return element.addClass(NO_TRANSITION); 34296 } 34297 34298 /** 34299 * Activating the vertical navigation bullets according to the given slide name. 34300 */ 34301 function activateNavDots(name, sectionIndex){ 34302 if(options.navigation){ 34303 $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE); 34304 if(name){ 34305 $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE); 34306 }else{ 34307 $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE); 34308 } 34309 } 34310 } 34311 34312 /** 34313 * Activating the website main menu elements according to the given slide name. 34314 */ 34315 function activateMenuElement(name){ 34316 if(options.menu){ 34317 $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE); 34318 $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE); 34319 } 34320 } 34321 34322 /** 34323 * Sets to active the current menu and vertical nav items. 34324 */ 34325 function activateMenuAndNav(anchor, index){ 34326 activateMenuElement(anchor); 34327 activateNavDots(anchor, index); 34328 } 34329 34330 /** 34331 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 34332 * from the current section. 34333 */ 34334 function getYmovement(destiny){ 34335 var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL); 34336 var toIndex = destiny.index(SECTION_SEL); 34337 if( fromIndex == toIndex){ 34338 return 'none'; 34339 } 34340 if(fromIndex > toIndex){ 34341 return 'up'; 34342 } 34343 return 'down'; 34344 } 34345 34346 /** 34347 * Retuns `right` or `left` depending on the scrolling movement to reach its destination 34348 * from the current slide. 34349 */ 34350 function getXmovement(fromIndex, toIndex){ 34351 if( fromIndex == toIndex){ 34352 return 'none'; 34353 } 34354 if(fromIndex > toIndex){ 34355 return 'left'; 34356 } 34357 return 'right'; 34358 } 34359 34360 /** 34361 * Checks if the element needs scrollbar and if the user wants to apply it. 34362 * If so it creates it. 34363 * 34364 * @param {Object} element jQuery object of the section or slide 34365 */ 34366 function createScrollBar(element){ 34367 //User doesn't want scrollbar here? Sayonara baby! 34368 if(element.hasClass('fp-noscroll')) return; 34369 34370 //needed to make `scrollHeight` work under Opera 12 34371 element.css('overflow', 'hidden'); 34372 34373 var scrollOverflowHandler = options.scrollOverflowHandler; 34374 var wrap = scrollOverflowHandler.wrapContent(); 34375 //in case element is a slide 34376 var section = element.closest(SECTION_SEL); 34377 var scrollable = scrollOverflowHandler.scrollable(element); 34378 var contentHeight; 34379 34380 //if there was scroll, the contentHeight will be the one in the scrollable section 34381 if(scrollable.length){ 34382 contentHeight = scrollOverflowHandler.scrollHeight(element); 34383 }else{ 34384 contentHeight = element.get(0).scrollHeight; 34385 if(options.verticalCentered){ 34386 contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight; 34387 } 34388 } 34389 34390 var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top')); 34391 34392 //needs scroll? 34393 if ( contentHeight > scrollHeight) { 34394 //did we already have an scrollbar ? Updating it 34395 if(scrollable.length){ 34396 scrollOverflowHandler.update(element, scrollHeight); 34397 } 34398 //creating the scrolling 34399 else{ 34400 if(options.verticalCentered){ 34401 element.find(TABLE_CELL_SEL).wrapInner(wrap); 34402 }else{ 34403 element.wrapInner(wrap); 34404 } 34405 scrollOverflowHandler.create(element, scrollHeight); 34406 } 34407 } 34408 //removing the scrolling when it is not necessary anymore 34409 else{ 34410 scrollOverflowHandler.remove(element); 34411 } 34412 34413 //undo 34414 element.css('overflow', ''); 34415 } 34416 34417 function addTableClass(element){ 34418 //In case we are styling for the 2nd time as in with reponsiveSlides 34419 if(!element.hasClass(TABLE)){ 34420 element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />'); 34421 } 34422 } 34423 34424 function getTableHeight(element){ 34425 var sectionHeight = windowsHeight; 34426 34427 if(options.paddingTop || options.paddingBottom){ 34428 var section = element; 34429 if(!section.hasClass(SECTION)){ 34430 section = element.closest(SECTION_SEL); 34431 } 34432 34433 var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom')); 34434 sectionHeight = (windowsHeight - paddings); 34435 } 34436 34437 return sectionHeight; 34438 } 34439 34440 /** 34441 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 34442 */ 34443 function transformContainer(translate3d, animated){ 34444 if(animated){ 34445 addAnimation(container); 34446 }else{ 34447 removeAnimation(container); 34448 } 34449 34450 container.css(getTransforms(translate3d)); 34451 34452 //syncronously removing the class after the animation has been applied. 34453 setTimeout(function(){ 34454 container.removeClass(NO_TRANSITION); 34455 },10); 34456 } 34457 34458 /** 34459 * Gets a section by its anchor / index 34460 */ 34461 function getSectionByAnchor(sectionAnchor){ 34462 if(!sectionAnchor) return []; 34463 34464 var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]'); 34465 if(!section.length){ 34466 section = $(SECTION_SEL).eq( sectionAnchor -1); 34467 } 34468 34469 return section; 34470 } 34471 34472 /** 34473 * Gets a slide inside a given section by its anchor / index 34474 */ 34475 function getSlideByAnchor(slideAnchor, section){ 34476 var slides = section.find(SLIDES_WRAPPER_SEL); 34477 var slide = slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]'); 34478
34479 if(!slide.length){ 34480 slide = slides.find(SLIDE_SEL).eq(slideAnchor); 34481 } 34482 34483 return slide; 34484 } 34485 34486 /** 34487 * Scrolls to the given section and slide anchors 34488 */ 34489 function scrollPageAndSlide(destiny, slide){ 34490 var section = getSectionByAnchor(destiny); 34491 34492 //do nothing if there's no section with the given anchor name 34493 if(!section.length) return; 34494 34495 //default slide 34496 if (typeof slide === 'undefined') { 34497 slide = 0; 34498 } 34499 34500 //we need to scroll to the section and then to the slide 34501 if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){ 34502 scrollPage(section, function(){ 34503 scrollSlider(section, slide); 34504 }); 34505 } 34506 //if we were already in the section 34507 else{ 34508 scrollSlider(section, slide); 34509 } 34510 } 34511 34512 /** 34513 * Scrolls the slider to the given slide destination for the given section 34514 */ 34515 function scrollSlider(section, slideAnchor){ 34516 if(typeof slideAnchor !== 'undefined'){ 34517 var slides = section.find(SLIDES_WRAPPER_SEL); 34518 var destiny = getSlideByAnchor(slideAnchor, section); 34519 34520 if(destiny.length){ 34521 landscapeScroll(slides, destiny); 34522 } 34523 } 34524 } 34525 34526 /** 34527 * Creates a landscape navigation bar with dots for horizontal sliders. 34528 */ 34529 function addSlidesNavigation(section, numSlides){ 34530 section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>'); 34531 var nav = section.find(SLIDES_NAV_SEL); 34532 34533 //top or bottom 34534 nav.addClass(options.slidesNavPosition); 34535 34536 for(var i=0; i< numSlides; i++){ 34537 nav.find('ul').append('<li><a href="#"><span></span></a></li>'); 34538 } 34539 34540 //centering it 34541 nav.css('margin-left', '-' + (nav.width()/2) + 'px'); 34542 34543 nav.find('li').first().find('a').addClass(ACTIVE); 34544 } 34545 34546 34547 /** 34548 * Sets the state of the website depending on the active section/slide. 34549 * It changes the URL hash when needed and updates the body class. 34550 */ 34551 function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){ 34552 var sectionHash = ''; 34553 34554 if(options.anchors.length && !options.lockAnchors){ 34555 34556 //isn't it the first slide? 34557 if(slideIndex){ 34558 if(typeof anchorLink !== 'undefined'){ 34559 sectionHash = anchorLink; 34560 } 34561 34562 //slide without anchor link? We take the index instead. 34563 if(typeof slideAnchor === 'undefined'){ 34564 slideAnchor = slideIndex; 34565 } 34566 34567 lastScrolledSlide = slideAnchor; 34568 setUrlHash(sectionHash + '/' + slideAnchor); 34569 34570 //first slide won't have slide anchor, just the section one 34571 }else if(typeof slideIndex !== 'undefined'){ 34572 lastScrolledSlide = slideAnchor; 34573 setUrlHash(anchorLink); 34574 } 34575 34576 //section without slides 34577 else{ 34578 setUrlHash(anchorLink); 34579 } 34580 } 34581 34582 setBodyClass(); 34583 } 34584 34585 /** 34586 * Sets the URL hash. 34587 */ 34588 function setUrlHash(url){ 34589 //Uncode addition 34590 if ( typeof SiteParameters.slide_footer != 'undefined' && url == SiteParameters.slide_footer ) 34591 return false; 34592 34593 if(options.recordHistory){ 34594 location.hash = url; 34595 }else{ 34596 //Uncode addition 34597 //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) 34598 // if(isTouchDevice || isTouch){ 34599 // window.history.replaceState(undefined, undefined, '#' + url); 34600 // }else{ 34601 // var baseUrl = window.location.href.split('#')[0]; 34602 // window.location.replace( baseUrl + '#' + url ); 34603 // } 34604 return false;
34605 } 34606 } 34607 34608 /** 34609 * Gets the anchor for the given slide / section. Its index will be used if there's none. 34610 */ 34611 function getAnchor(element){ 34612 var anchor = element.data('anchor'); 34613 var index = element.index(); 34614 34615 //Slide without anchor link? We take the index instead. 34616 if(typeof anchor === 'undefined'){ 34617 anchor = index; 34618 } 34619 34620 return anchor; 34621 } 34622 34623 /** 34624 * Sets a class for the body of the page depending on the active section / slide 34625 */ 34626 function setBodyClass(){ 34627 var section = $(SECTION_ACTIVE_SEL); 34628 var slide = section.find(SLIDE_ACTIVE_SEL); 34629 34630 var sectionAnchor = getAnchor(section); 34631 var slideAnchor = getAnchor(slide); 34632 34633 var text = String(sectionAnchor); 34634 34635 if(slide.length){ 34636 text = text + '-' + slideAnchor; 34637 } 34638 34639 //changing slash for dash to make it a valid CSS style 34640 text = text.replace('/', '-').replace('#',''); 34641 34642 //removing previous anchor classes 34643 var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); 34644 $body[0].className = $body[0].className.replace(classRe, ''); 34645 34646 //adding the current anchor 34647 $body.addClass(VIEWING_PREFIX + '-' + text); 34648 } 34649 34650 /** 34651 * Checks for translate3d support 34652 * @return boolean 34653 * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support 34654 */ 34655 function support3d() { 34656 var el = document.createElement('p'), 34657 has3d, 34658 transforms = { 34659 'webkitTransform':'-webkit-transform', 34660 'OTransform':'-o-transform', 34661 'msTransform':'-ms-transform', 34662 'MozTransform':'-moz-transform', 34663 'transform':'transform' 34664 }; 34665 34666 // Add it to the body to get the computed style. 34667 document.body.insertBefore(el, null); 34668 34669 for (var t in transforms) { 34670 if (el.style[t] !== undefined) { 34671 el.style[t] = 'translate3d(1px,1px,1px)'; 34672 has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); 34673 } 34674 } 34675 34676 document.body.removeChild(el); 34677 34678 return (has3d !== undefined && has3d.length > 0 && has3d !== 'none'); 34679 } 34680 34681 /** 34682 * Removes the auto scrolling action fired by the mouse wheel and trackpad. 34683 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 34684 */ 34685 function removeMouseWheelHandler(){ 34686 if (document.addEventListener) { 34687 document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 34688 document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox 34689 document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox 34690 } else { 34691 document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 34692 } 34693 } 34694 34695 /** 34696 * Adds the auto scrolling action for the mouse wheel and trackpad. 34697 * After this function is called, the mousewheel and trackpad movements will scroll through sections 34698 * https://developer.mozilla.org/en-US/docs/Web/Events/wheel 34699 */ 34700 function addMouseWheelHandler(){ 34701 var prefix = ''; 34702 var _addEventListener; 34703 34704 if (window.addEventListener){ 34705 _addEventListener = "addEventListener"; 34706 }else{ 34707 _addEventListener = "attachEvent"; 34708 prefix = 'on'; 34709 } 34710 34711 // detect available wheel event 34712 var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel" 34713 document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" 34714 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox 34715 var passiveEvent = g_supportsPassive ? {passive: false }
34715: false; 34716 34717 34718 if(support == 'DOMMouseScroll'){ 34719 document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent); 34720 } 34721 34722 //handle MozMousePixelScroll in older Firefox 34723 else{ 34724 document[ _addEventListener ](prefix + support, MouseWheelHandler, passiveEvent); 34725 } 34726 } 34727 34728 /** 34729 * Binding the mousemove when the mouse's middle button is pressed 34730 */ 34731 function addMiddleWheelHandler(){ 34732 container 34733 .on('mousedown', mouseDownHandler) 34734 .on('mouseup', mouseUpHandler); 34735 } 34736 34737 /** 34738 * Unbinding the mousemove when the mouse's middle button is released 34739 */ 34740 function removeMiddleWheelHandler(){ 34741 container 34742 .off('mousedown', mouseDownHandler) 34743 .off('mouseup', mouseUpHandler); 34744 } 34745 34746 /** 34747 * Adds the possibility to auto scroll through sections on touch devices. 34748 */ 34749 function addTouchHandler(){ 34750 if(isTouchDevice || isTouch){ 34751 if(options.autoScrolling){ 34752 $body.off(events.touchmove).on(events.touchmove, preventBouncing); 34753 } 34754 34755 $(WRAPPER_SEL) 34756 .off(events.touchstart).on(events.touchstart, touchStartHandler) 34757 .off(events.touchmove).on(events.touchmove, touchMoveHandler); 34758 } 34759 } 34760 34761 /** 34762 * Removes the auto scrolling for touch devices. 34763 */ 34764 function removeTouchHandler(){ 34765 if(isTouchDevice || isTouch){ 34766 $(WRAPPER_SEL) 34767 .off(events.touchstart) 34768 .off(events.touchmove); 34769 } 34770 } 34771 34772 /* 34773 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11) 34774 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 34775 */ 34776 function getMSPointer(){ 34777 var pointer; 34778 34779 //IE >= 11 & rest of browsers 34780 if(window.PointerEvent){ 34781 pointer = { down: 'pointerdown', move: 'pointermove'}; 34782 } 34783 34784 //IE < 11 34785 else{ 34786 pointer = { down: 'MSPointerDown', move: 'MSPointerMove'}; 34787 } 34788 34789 return pointer; 34790 } 34791 34792 /** 34793 * Gets the pageX and pageY properties depending on the browser. 34794 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 34795 */ 34796 function getEventsPage(e){ 34797 var events = []; 34798 34799 events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY); 34800 events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX); 34801 34802 //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 34803 if(isTouch && isReallyTouch(e) && options.scrollBar){ 34804 events.y = e.touches[0].pageY; 34805 events.x = e.touches[0].pageX; 34806 } 34807 34808 return events; 34809 } 34810 34811 /** 34812 * Slides silently (with no animation) the active slider to the given slide. 34813 * @param noCallback {bool} true or defined -> no callbacks 34814 */ 34815 function silentLandscapeScroll(activeSlide, noCallbacks){ 34816 setScrollingSpeed (0, 'internal'); 34817 34818 if(typeof noCallbacks !== 'undefined'){ 34819 //preventing firing callbacks afterSlideLoad etc. 34820 isResizing = true; 34821 } 34822 34823 landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide); 34824 34825 if(typeof noCallbacks !== 'undefined'){ 34826 isResizing = false; 34827 } 34828 34829 setScrollingSpeed(originals.scrollingSpeed, 'internal'); 34830 } 34831 34832 /** 34833 * Scrolls silently (with no animation) the page to the given Y position. 34834 */ 34835 function silentScroll(top){ 34836 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 34837 // that's why we round it to 0. 34838 var roundedTop = Math.round(top); 34839 34840 if (options.css3 && options.autoScrolling && !options.scrollBar){ 34841 var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)'; 34842 transformContainer(translate3d, false); 34843 } 34844 else if(options.autoScrolling && !options.scrollBar){ 34845 container.css('top', -roundedTop); 34846 } 34847 else{ 34848 $htmlBody.scrollTop(roundedTop); 34849 } 34850 } 34851 34852 /** 34853 * Returns the cross-browser transform string. 34854 */ 34855 function getTransforms(translate3d){ 34856 return {
34857 '-webkit-transform': translate3d, 34858 '-moz-transform': translate3d, 34859 '-ms-transform':translate3d, 34860 'transform': translate3d 34861 }; 34862 } 34863 34864 /** 34865 * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) 34866 * @type m (mouse) or k (keyboard) 34867 */ 34868 function setIsScrollAllowed(value, direction, type){ 34869 switch (direction){ 34870 case 'up': isScrollAllowed[type].up = value; break; 34871 case 'down': isScrollAllowed[type].down = value; break; 34872 case 'left': isScrollAllowed[type].left = value; break; 34873 case 'right': isScrollAllowed[type].right = value; break; 34874 case 'all': 34875 if(type == 'm'){ 34876 setAllowScrolling(value); 34877 }else{ 34878 setKeyboardScrolling(value); 34879 } 34880 } 34881 } 34882 34883 /* 34884 * Destroys fullpage.js plugin events and optinally its html markup and styles 34885 */ 34886 function destroy(all){ 34887 setAutoScrolling(false, 'internal'); 34888 setAllowScrolling(false); 34889 setKeyboardScrolling(false); 34890 container.addClass(DESTROYED); 34891 34892 clearTimeout(afterSlideLoadsId); 34893 clearTimeout(afterSectionLoadsId); 34894 clearTimeout(resizeId); 34895 clearTimeout(scrollId); 34896 clearTimeout(scrollId2); 34897 34898 $window 34899 .off('scroll', scrollHandler) 34900 .off('hashchange', hashChangeHandler) 34901 .off('resize', resizeHandler); 34902 34903 $document 34904 .off('click touchstart', SECTION_NAV_SEL + ' a') 34905 .off('mouseenter', SECTION_NAV_SEL + ' li') 34906 .off('mouseleave', SECTION_NAV_SEL + ' li') 34907 .off('click touchstart', SLIDES_NAV_LINK_SEL) 34908 .off('mouseover', options.normalScrollElements) 34909 .off('mouseout', options.normalScrollElements); 34910 34911 $(SECTION_SEL) 34912 .off('click touchstart', SLIDES_ARROW_SEL); 34913 34914 clearTimeout(afterSlideLoadsId); 34915 clearTimeout(afterSectionLoadsId); 34916 34917 //lets make a mess! 34918 if(all){ 34919 destroyStructure(); 34920 } 34921 } 34922 34923 /* 34924 * Removes inline styles added by fullpage.js 34925 */ 34926 function destroyStructure(){ 34927 //reseting the `top` or `translate` properties to 0 34928 silentScroll(0); 34929 34930 //loading all the lazy load content 34931 container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){ 34932 setSrc($(this), 'src'); 34933 }); 34934 34935 container.find('img[data-srcset]').each(function(){ 34936 setSrc($(this), 'srcset'); 34937 }); 34938 34939 $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL).remove(); 34940 34941 //removing inline styles 34942 $(SECTION_SEL).css( { 34943 'height': '', 34944 'background-color' : '', 34945 'padding': '' 34946 }); 34947 34948 $(SLIDE_SEL).css( { 34949 'width': '' 34950 }); 34951 34952 container.css({ 34953 'height': '', 34954 'position': '', 34955 '-ms-touch-action': '', 34956 'touch-action': '' 34957 }); 34958 34959 $htmlBody.css({ 34960 'overflow': '', 34961 'height': '' 34962 }); 34963 34964 // remove .fp-enabled class 34965 $('html').removeClass(ENABLED); 34966 34967 // remove .fp-responsive class 34968 $body.removeClass(RESPONSIVE); 34969 34970 // remove all of the .fp-viewing- classes 34971 $.each($body.get(0).className.split(/\s+/), function (index, className) { 34972 if (className.indexOf(VIEWING_PREFIX) === 0) { 34973 $body.removeClass(className); 34974 } 34975 }); 34976 34977 //removing added classes 34978 $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){ 34979 options.scrollOverflowHandler.remove($(this)); 34980 $(this).removeClass(TABLE + ' ' + ACTIVE); 34981 }); 34982 34983 removeAnimation(container); 34984 34985 //Unwrapping content 34986 container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){ 34987 //unwrap not being use in case there's no child element inside and its just text 34988 $(this).replaceWith(this.childNodes); 34989 }); 34990 34991 //removing the applied transition from the fullpage wrapper 34992 container.css({
34993 '-webkit-transition': 'none', 34994 'transition': 'none' 34995 }); 34996 34997 //scrolling the page to the top with no animation 34998 $htmlBody.scrollTop(0); 34999 35000 //removing selectors 35001 var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; 35002 $.each(usedSelectors, function(index, value){ 35003 $('.' + value).removeClass(value); 35004 }); 35005 } 35006 35007 /* 35008 * Sets the state for a variable with multiple states (original, and temporal) 35009 * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. 35010 * This function is used to keep track of both states, the original and the temporal one. 35011 * If type is not 'internal', then we assume the user is globally changing the variable. 35012 */ 35013 function setVariableState(variable, value, type){ 35014 options[variable] = value; 35015 if(type !== 'internal'){ 35016 originals[variable] = value; 35017 } 35018 } 35019 35020 /** 35021 * Displays warnings 35022 */ 35023 function displayWarnings(){ 35024 var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax']; 35025 //UNCODE.addition 35026 // if($('html').hasClass(ENABLED)){ 35027 // showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); 35028 // return; 35029 // } 35030 35031 // Disable mutually exclusive settings 35032 //UNCODE.addition 35033 // if (options.continuousVertical && 35034 // (options.loopTop || options.loopBottom)) { 35035 // options.continuousVertical = false;
35036 // showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 35037 // } 35038 35039 // if(options.scrollBar && options.scrollOverflow){ 35040 // showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox'); 35041 // } 35042 35043 // if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){ 35044 // options.continuousVertical = false; 35045 // showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 35046 // } 35047 35048 //using extensions? Wrong file! 35049 $.each(extensions, function(index, extension){ 35050 //is the option set to true? 35051 if(options[extension]){ 35052 showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension); 35053 } 35054 }); 35055 35056 //anchors can not have the same value as any element ID or NAME 35057 $.each(options.anchors, function(index, name){ 35058 35059 //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) 35060 var nameAttr = $document.find('[name]').filter(function() { 35061 return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase(); 35062 }); 35063 35064 var idAttr = $document.find('[id]').filter(function() { 35065 return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase(); 35066 }); 35067 35068 if(idAttr.length || nameAttr.length ){ 35069 showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).'); 35070 idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property'); 35071 nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property'); 35072 } 35073 }); 35074 } 35075 35076 /** 35077 * Shows a message in the console of the given type. 35078 */ 35079 function showError(type, text){ 35080 console && console[type] && console[type]('fullPage: ' + text); 35081 } 35082 35083 }; //end of $.fn.fullpage 35084 35085 if(typeof IScroll !== 'undefined'){ 35086 /* 35087 * Turns iScroll `mousewheel` option off dynamically 35088 * https://github.com/cubiq/iscroll/issues/1036 35089 */ 35090 IScroll.prototype.wheelOn = function () { 35091 this.wrapper.addEventListener('wheel', this); 35092 this.wrapper.addEventListener('mousewheel', this); 35093 this.wrapper.addEventListener('DOMMouseScroll', this); 35094 }; 35095 35096 /* 35097 * Turns iScroll `mousewheel` option on dynamically 35098 * https://github.com/cubiq/iscroll/issues/1036 35099 */ 35100 IScroll.prototype.wheelOff = function () { 35101 this.wrapper.removeEventListener('wheel', this); 35102 this.wrapper.removeEventListener('mousewheel', this); 35103 this.wrapper.removeEventListener('DOMMouseScroll', this); 35104 }; 35105 } 35106 35107 /** 35108 * An object to handle overflow scrolling. 35109 * This uses jquery.slimScroll to accomplish overflow scrolling. 35110 * It is possible to pass in an alternate scrollOverflowHandler 35111 * to the fullpage.js option that implements the same functions 35112 * as this handler. 35113 * 35114 * @type {Object} 35115 */ 35116 var iscrollHandler = { 35117 refreshId: null, 35118 iScrollInstances: [], 35119 35120 // Enables or disables the mouse wheel for the active section or all slides in it 35121 toggleWheel: function(value){ 35122 var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL); 35123 scrollable.each(function(){ 35124 var iScrollInstance = $(this).data('iscrollInstance'); 35125 if(typeof iScrollInstance !== 'undefined' && iScrollInstance){ 35126 if(value){ 35127 iScrollInstance.wheelOn(); 35128 } 35129 else{ 35130 iScrollInstance.wheelOff(); 35131 } 35132 } 35133 }); 35134 }, 35135 35136 /** 35137 * Turns off iScroll for the destination section. 35138 * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
35139 * scroll the destination section/slide before the sections animations ends. 35140 */ 35141 onLeave: function(){ 35142 iscrollHandler.toggleWheel(false); 35143 }, 35144 35145 // Turns off iScroll for the leaving section 35146 beforeLeave: function(){ 35147 iscrollHandler.onLeave() 35148 }, 35149 35150 // Turns on iScroll on section load 35151 afterLoad: function(){ 35152 iscrollHandler.toggleWheel(true); 35153 }, 35154 35155 /** 35156 * Called when overflow scrolling is needed for a section. 35157 * 35158 * @param {Object} element jQuery object containing current section 35159 * @param {Number} scrollHeight Current window height in pixels 35160 */ 35161 create: function(element, scrollHeight) { 35162 var scrollable = element.find(SCROLLABLE_SEL); 35163 35164 scrollable.height(scrollHeight); 35165 scrollable.each(function() { 35166 var $this = $(this); 35167 var iScrollInstance = $this.data('iscrollInstance'); 35168 if (iScrollInstance) { 35169 $.each(iscrollHandler.iScrollInstances, function(){ 35170 $(this).destroy(); 35171 }); 35172 } 35173 35174 iScrollInstance = new IScroll($this.get(0), iscrollOptions); 35175 iscrollHandler.iScrollInstances.push(iScrollInstance); 35176 35177 //off by default until the section gets active 35178 iScrollInstance.wheelOff(); 35179 35180 $this.data('iscrollInstance', iScrollInstance); 35181 }); 35182 }, 35183 35184 /** 35185 * Return a boolean depending on whether the scrollable element is a 35186 * the end or at the start of the scrolling depending on the given type. 35187 * 35188 * @param {String} type Either 'top' or 'bottom' 35189 * @param {Object} scrollable jQuery object for the scrollable element 35190 * @return {Boolean} 35191 */ 35192 isScrolled: function(type, scrollable) { 35193 var scroller = scrollable.data('iscrollInstance'); 35194 35195 //no scroller? 35196 if (!scroller) { 35197 return true; 35198 } 35199 35200 //Uncode addition 35201 var uncode_body_borders = parseFloat($('.body-borders').attr('data-border')) || 0; 35202 //End Uncode addition 35203 35204 if (type === 'top') { 35205 return scroller.y >= 0 && !scrollable.scrollTop(); 35206 } else if (type === 'bottom') { 35207 //Uncode change 35208 // return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight; 35209 return (0 - scroller.y) + scrollable.scrollTop() + 1 + ( uncode_body_borders * 2 ) + scrollable.innerHeight() >= scrollable[0].scrollHeight; 35210 //End Uncode change 35211 } 35212 }, 35213 35214 /** 35215 * Returns the scrollable element for the given section. 35216 * If there are landscape slides, will only return a scrollable element 35217 * if it is in the active slide. 35218 * 35219 * @param {Object} activeSection jQuery object containing current section 35220 * @return {Boolean} 35221 */ 35222 scrollable: function(activeSection){ 35223 // if there are landscape slides, we check if the scrolling bar is in the current one or not 35224 if (activeSection.find(SLIDES_WRAPPER_SEL).length) { 35225 return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL); 35226 } 35227 return activeSection.find(SCROLLABLE_SEL); 35228 }, 35229 35230 /** 35231 * Returns the scroll height of the wrapped content. 35232 * If this is larger than the window height minus section padding, 35233 * overflow scrolling is needed. 35234 * 35235 * @param {Object} element jQuery object containing current section 35236 * @return {Number} 35237 */ 35238 scrollHeight: function(element) { 35239 return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight; 35240 }, 35241 35242 /** 35243 * Called when overflow scrolling is no longer needed for a section. 35244 * 35245 * @param {Object}
vendor: 5,435 bytes, lines 35245-35396
35245 element jQuery object containing current section 35246 */ 35247 remove: function(element) { 35248 var scrollable = element.find(SCROLLABLE_SEL); 35249 if (scrollable.length) { 35250 var iScrollInstance = scrollable.data('iscrollInstance'); 35251 iScrollInstance.destroy(); 35252 35253 scrollable.data('iscrollInstance', null); 35254 } 35255 element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap(); 35256 }, 35257 35258 /** 35259 * Called when overflow scrolling has already been setup but the 35260 * window height has potentially changed. 35261 * 35262 * @param {Object} element jQuery object containing current section 35263 * @param {Number} scrollHeight Current window height in pixels 35264 */ 35265 update: function(element, scrollHeight) { 35266 //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a 35267 //short period of time. 35268 //it also comes on handy because iScroll requires the use of timeout when using `refresh`. 35269 clearTimeout(iscrollHandler.refreshId); 35270 iscrollHandler.refreshId = setTimeout(function(){ 35271 $.each(iscrollHandler.iScrollInstances, function(){ 35272 $(this).get(0).refresh(); 35273 }); 35274 }, 150); 35275 35276 //updating the wrappers height 35277 element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px'); 35278 }, 35279 35280 /** 35281 * Called to get any additional elements needed to wrap the section 35282 * content in order to facilitate overflow scrolling. 35283 * 35284 * @return {String|Object} Can be a string containing HTML, 35285 * a DOM element, or jQuery object. 35286 */ 35287 wrapContent: function() { 35288 return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>'; 35289 } 35290 }; 35291}); 35292 35293(function (global, factory) { 35294 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 35295 typeof define === 'function' && define.amd ? define(['exports'], factory) : 35296 (global = global || self, factory(global.window = global.window || {})); 35297 }(this, (function (exports) { 'use strict'; 35298 35299 function _defineProperties(target, props) { 35300 for (var i = 0; i < props.length; i++) { 35301 var descriptor = props[i]; 35302 descriptor.enumerable = descriptor.enumerable || false; 35303 descriptor.configurable = true; 35304 if ("value" in descriptor) descriptor.writable = true; 35305 Object.defineProperty(target, descriptor.key, descriptor); 35306 } 35307 } 35308 35309 function _createClass(Constructor, protoProps, staticProps) { 35310 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 35311 if (staticProps) _defineProperties(Constructor, staticProps); 35312 return Constructor; 35313 } 35314 35315 /*! 35316 * Observer 3.12.5 35317 * https://gsap.com 35318 * 35319 * @license Copyright 2008-2024, GreenSock. All rights reserved. 35320 * Subject to the terms at https://gsap.com/standard-license or for 35321 * Club GSAP members, the agreement issued with that membership. 35322 * @author: Jack Doyle, [email protected] 35323 */ 35324 var gsap, 35325 _coreInitted, 35326 _clamp, 35327 _win, 35328 _doc, 35329 _docEl, 35330 _body, 35331 _isTouch, 35332 _pointerType, 35333 ScrollTrigger, 35334 _root, 35335 _normalizer, 35336 _eventTypes, 35337 _context, 35338 _getGSAP = function _getGSAP() { 35339 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 35340 }, 35341 _startup = 1, 35342 _observers = [], 35343 _scrollers = [], 35344 _proxies = [], 35345 _getTime = Date.now, 35346 _bridge = function _bridge(name, value) { 35347 return value; 35348 }, 35349 _integrate = function _integrate() { 35350 var core = ScrollTrigger.core, 35351 data = core.bridge || {}, 35352 scrollers = core._scrollers, 35353 proxies = core._proxies; 35354 scrollers.push.apply(scrollers, _scrollers); 35355 proxies.push.apply(proxies, _proxies); 35356 _scrollers = scrollers; 35357 _proxies = proxies; 35358 35359 _bridge = function _bridge(name, value) { 35360 return data[name](value); 35361 }; 35362 }, 35363 _getProxyProp = function _getProxyProp(element, property) { 35364 return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property]; 35365 }, 35366 _isViewport = function _isViewport(el) { 35367 return !!~_root.indexOf(el); 35368 }, 35369 _addListener = function _addListener(element, type, func, passive, capture) { 35370 return element.addEventListener(type, func, { 35371 passive: passive !== false, 35372 capture: !!capture 35373 }); 35374 }, 35375 _removeListener = function _removeListener(element, type, func, capture) { 35376 return element.removeEventListener(type, func, !!capture); 35377 }, 35378 _scrollLeft = "scrollLeft", 35379 _scrollTop = "scrollTop", 35380 _onScroll = function _onScroll() { 35381 return _normalizer && _normalizer.isPressed || _scrollers.cache++; 35382 }, 35383 _scrollCacheFunc = function _scrollCacheFunc(f, doNotCache) { 35384 var cachingFunc = function cachingFunc(value) { 35385 if (value || value === 0) { 35386 _startup && (_win.history.scrollRestoration = "manual"); 35387 var isNormalizing = _normalizer && _normalizer.isPressed; 35388 value = cachingFunc.v = Math.round(value) || (_normalizer && _normalizer.iOS ? 1 : 0); 35389 f(value); 35390 cachingFunc.cacheID = _scrollers.cache; 35391 isNormalizing && _bridge("ss", value); 35392 } else if (doNotCache || _scrollers.cache !== cachingFunc.cacheID || _bridge("ref")) { 35393 cachingFunc.cacheID = _scrollers.cache; 35394 cachingFunc.v = f(); 35395 } 35396
vendor: 13,754 bytes, lines 35397-35850
35397 return cachingFunc.v + cachingFunc.offset; 35398 }; 35399 35400 cachingFunc.offset = 0; 35401 return f && cachingFunc; 35402 }, 35403 _horizontal = { 35404 s: _scrollLeft, 35405 p: "left", 35406 p2: "Left", 35407 os: "right", 35408 os2: "Right", 35409 d: "width", 35410 d2: "Width", 35411 a: "x", 35412 sc: _scrollCacheFunc(function (value) { 35413 return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0; 35414 }) 35415 }, 35416 _vertical = { 35417 s: _scrollTop, 35418 p: "top", 35419 p2: "Top", 35420 os: "bottom", 35421 os2: "Bottom", 35422 d: "height", 35423 d2: "Height", 35424 a: "y", 35425 op: _horizontal, 35426 sc: _scrollCacheFunc(function (value) { 35427 return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0; 35428 }) 35429 }, 35430 _getTarget = function _getTarget(t, self) { 35431 return (self && self._ctx && self._ctx.selector || gsap.utils.toArray)(t)[0] || (typeof t === "string" && gsap.config().nullTargetWarn !== false ? console.warn("Element not found:", t) : null); 35432 }, 35433 _getScrollFunc = function _getScrollFunc(element, _ref) { 35434 var s = _ref.s, 35435 sc = _ref.sc; 35436 _isViewport(element) && (element = _doc.scrollingElement || _docEl); 35437 35438 var i = _scrollers.indexOf(element), 35439 offset = sc === _vertical.sc ? 1 : 2; 35440 35441 !~i && (i = _scrollers.push(element) - 1); 35442 _scrollers[i + offset] || _addListener(element, "scroll", _onScroll); 35443 var prev = _scrollers[i + offset], 35444 func = prev || (_scrollers[i + offset] = _scrollCacheFunc(_getProxyProp(element, s), true) || (_isViewport(element) ? sc : _scrollCacheFunc(function (value) { 35445 return arguments.length ? element[s] = value : element[s]; 35446 }))); 35447 func.target = element; 35448 prev || (func.smooth = gsap.getProperty(element, "scrollBehavior") === "smooth"); 35449 return func; 35450 }, 35451 _getVelocityProp = function _getVelocityProp(value, minTimeRefresh, useDelta) { 35452 var v1 = value, 35453 v2 = value, 35454 t1 = _getTime(), 35455 t2 = t1, 35456 min = minTimeRefresh || 50, 35457 dropToZeroTime = Math.max(500, min * 3), 35458 update = function update(value, force) { 35459 var t = _getTime(); 35460 35461 if (force || t - t1 > min) { 35462 v2 = v1; 35463 v1 = value; 35464 t2 = t1; 35465 t1 = t; 35466 } else if (useDelta) { 35467 v1 += value; 35468 } else { 35469 v1 = v2 + (value - v2) / (t - t2) * (t1 - t2); 35470 } 35471 }, 35472 reset = function reset() { 35473 v2 = v1 = useDelta ? 0 : v1; 35474 t2 = t1 = 0; 35475 }, 35476 getVelocity = function getVelocity(latestValue) { 35477 var tOld = t2, 35478 vOld = v2, 35479 t = _getTime(); 35480 35481 (latestValue || latestValue === 0) && latestValue !== v1 && update(latestValue); 35482 return t1 === t2 || t - t2 > dropToZeroTime ? 0 : (v1 + (useDelta ? vOld : -vOld)) / ((useDelta ? t : t1) - tOld) * 1000; 35483 }; 35484 35485 return { 35486 update: update, 35487 reset: reset, 35488 getVelocity: getVelocity 35489 }; 35490 }, 35491 _getEvent = function _getEvent(e, preventDefault) { 35492 preventDefault && !e._gsapAllow && e.preventDefault(); 35493 return e.changedTouches ? e.changedTouches[0] : e; 35494 }, 35495 _getAbsoluteMax = function _getAbsoluteMax(a) { 35496 var max = Math.max.apply(Math, a), 35497 min = Math.min.apply(Math, a); 35498 return Math.abs(max) >= Math.abs(min) ? max : min; 35499 }, 35500 _setScrollTrigger = function _setScrollTrigger() { 35501 ScrollTrigger = gsap.core.globals().ScrollTrigger; 35502 ScrollTrigger && ScrollTrigger.core && _integrate(); 35503 }, 35504 _initCore = function _initCore(core) { 35505 gsap = core || _getGSAP(); 35506 35507 if (!_coreInitted && gsap && typeof document !== "undefined" && document.body) { 35508 _win = window; 35509 _doc = document; 35510 _docEl = _doc.documentElement; 35511 _body = _doc.body; 35512 _root = [_win, _doc, _docEl, _body]; 35513 _clamp = gsap.utils.clamp; 35514 35515 _context = gsap.core.context || function () {}; 35516 35517 _pointerType = "onpointerenter" in _body ? "pointer" : "mouse"; 35518 _isTouch = Observer.isTouch = _win.matchMedia && _win.matchMedia("(hover: none), (pointer: coarse)").matches ? 1 : "ontouchstart" in _win || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0 ? 2 : 0; 35519 _eventTypes = Observer.eventTypes = ("ontouchstart" in _docEl ? "touchstart,touchmove,touchcancel,touchend" : !("onpointerdown" in _docEl) ? "mousedown,mousemove,mouseup,mouseup" : "pointerdown,pointermove,pointercancel,pointerup").split(","); 35520 setTimeout(function () { 35521 return _startup = 0; 35522 }, 500); 35523 35524 _setScrollTrigger(); 35525 35526 _coreInitted = 1; 35527 } 35528 35529 return _coreInitted; 35530 }; 35531 35532 _horizontal.op = _vertical; 35533 _scrollers.cache = 0; 35534 var Observer = function () { 35535 function Observer(vars) { 35536 this.init(vars); 35537 } 35538 35539 var _proto = Observer.prototype; 35540 35541 _proto.init = function init(vars) { 35542 _coreInitted || _initCore(gsap) || console.warn("Please gsap.registerPlugin(Observer)"); 35543 ScrollTrigger || _setScrollTrigger(); 35544 var tolerance = vars.tolerance, 35545 dragMinimum = vars.dragMinimum, 35546 type = vars.type, 35547 target = vars.target, 35548 lineHeight = vars.lineHeight, 35549 debounce = vars.debounce, 35550 preventDefault = vars.preventDefault, 35551 onStop = vars.onStop, 35552 onStopDelay = vars.onStopDelay, 35553 ignore = vars.ignore, 35554 wheelSpeed = vars.wheelSpeed, 35555 event = vars.event, 35556 onDragStart = vars.onDragStart, 35557 onDragEnd = vars.onDragEnd, 35558 onDrag = vars.onDrag, 35559 onPress = vars.onPress, 35560 onRelease = vars.onRelease, 35561 onRight = vars.onRight, 35562 onLeft = vars.onLeft, 35563 onUp = vars.onUp, 35564 onDown = vars.onDown, 35565 onChangeX = vars.onChangeX, 35566 onChangeY = vars.onChangeY, 35567 onChange = vars.onChange, 35568 onToggleX = vars.onToggleX, 35569 onToggleY = vars.onToggleY, 35570 onHover = vars.onHover, 35571 onHoverEnd = vars.onHoverEnd, 35572 onMove = vars.onMove, 35573 ignoreCheck = vars.ignoreCheck, 35574 isNormalizer = vars.isNormalizer, 35575 onGestureStart = vars.onGestureStart, 35576 onGestureEnd = vars.onGestureEnd, 35577 onWheel = vars.onWheel, 35578 onEnable = vars.onEnable, 35579 onDisable = vars.onDisable, 35580 onClick = vars.onClick, 35581 scrollSpeed = vars.scrollSpeed, 35582 capture = vars.capture, 35583 allowClicks = vars.allowClicks, 35584 lockAxis = vars.lockAxis, 35585 onLockAxis = vars.onLockAxis; 35586 this.target = target = _getTarget(target) || _docEl; 35587 this.vars = vars; 35588 ignore && (ignore = gsap.utils.toArray(ignore)); 35589 tolerance = tolerance || 1e-9; 35590 dragMinimum = dragMinimum || 0; 35591 wheelSpeed = wheelSpeed || 1; 35592 scrollSpeed = scrollSpeed || 1; 35593 type = type || "wheel,touch,pointer"; 35594 debounce = debounce !== false; 35595 lineHeight || (lineHeight = parseFloat(_win.getComputedStyle(_body).lineHeight) || 22); 35596 35597 var id, 35598 onStopDelayedCall, 35599 dragged, 35600 moved, 35601 wheeled, 35602 locked, 35603 axis, 35604 self = this, 35605 prevDeltaX = 0, 35606 prevDeltaY = 0, 35607 passive = vars.passive || !preventDefault, 35608 scrollFuncX = _getScrollFunc(target, _horizontal), 35609 scrollFuncY = _getScrollFunc(target, _vertical), 35610 scrollX = scrollFuncX(), 35611 scrollY = scrollFuncY(), 35612 limitToTouch = ~type.indexOf("touch") && !~type.indexOf("pointer") && _eventTypes[0] === "pointerdown", 35613 isViewport = _isViewport(target), 35614 ownerDoc = target.ownerDocument || _doc, 35615 deltaX = [0, 0, 0], 35616 deltaY = [0, 0, 0], 35617 onClickTime = 0, 35618 clickCapture = function clickCapture() { 35619 return onClickTime = _getTime(); 35620 }, 35621 _ignoreCheck = function _ignoreCheck(e, isPointerOrTouch) { 35622 return (self.event = e) && ignore && ~ignore.indexOf(e.target) || isPointerOrTouch && limitToTouch && e.pointerType !== "touch" || ignoreCheck && ignoreCheck(e, isPointerOrTouch); 35623 }, 35624 onStopFunc = function onStopFunc() { 35625 self._vx.reset(); 35626 35627 self._vy.reset(); 35628 35629 onStopDelayedCall.pause(); 35630 onStop && onStop(self); 35631 }, 35632 update = function update() { 35633 var dx = self.deltaX = _getAbsoluteMax(deltaX), 35634 dy = self.deltaY = _getAbsoluteMax(deltaY), 35635 changedX = Math.abs(dx) >= tolerance, 35636 changedY = Math.abs(dy) >= tolerance; 35637 35638 onChange && (changedX || changedY) && onChange(self, dx, dy, deltaX, deltaY); 35639 35640 if (changedX) { 35641 onRight && self.deltaX > 0 && onRight(self); 35642 onLeft && self.deltaX < 0 && onLeft(self); 35643 onChangeX && onChangeX(self); 35644 onToggleX && self.deltaX < 0 !== prevDeltaX < 0 && onToggleX(self); 35645 prevDeltaX = self.deltaX; 35646 deltaX[0] = deltaX[1] = deltaX[2] = 0; 35647 } 35648 35649 if (changedY) { 35650 onDown && self.deltaY > 0 && onDown(self); 35651 onUp && self.deltaY < 0 && onUp(self); 35652 onChangeY && onChangeY(self); 35653 onToggleY && self.deltaY < 0 !== prevDeltaY < 0 && onToggleY(self); 35654 prevDeltaY = self.deltaY; 35655 deltaY[0] = deltaY[1] = deltaY[2] = 0; 35656 } 35657 35658 if (moved || dragged) { 35659 onMove && onMove(self); 35660 35661 if (dragged) { 35662 onDrag(self); 35663 dragged = false; 35664 } 35665 35666 moved = false; 35667 } 35668 35669 locked && !(locked = false) && onLockAxis && onLockAxis(self); 35670 35671 if (wheeled) { 35672 onWheel(self); 35673 wheeled = false; 35674 } 35675 35676 id = 0; 35677 }, 35678 onDelta = function onDelta(x, y, index) { 35679 deltaX[index] += x; 35680 deltaY[index] += y; 35681 35682 self._vx.update(x); 35683 35684 self._vy.update(y); 35685 35686 debounce ? id || (id = requestAnimationFrame(update)) : update(); 35687 }, 35688 onTouchOrPointerDelta = function onTouchOrPointerDelta(x, y) { 35689 if (lockAxis && !axis) { 35690 self.axis = axis = Math.abs(x) > Math.abs(y) ? "x" : "y"; 35691 locked = true; 35692 } 35693 35694 if (axis !== "y") { 35695 deltaX[2] += x; 35696 35697 self._vx.update(x, true); 35698 } 35699 35700 if (axis !== "x") { 35701 deltaY[2] += y; 35702 35703 self._vy.update(y, true); 35704 } 35705 35706 debounce ? id || (id = requestAnimationFrame(update)) : update(); 35707 }, 35708 _onDrag = function _onDrag(e) { 35709 if (_ignoreCheck(e, 1)) { 35710 return; 35711 } 35712 35713 e = _getEvent(e, preventDefault); 35714 var x = e.clientX, 35715 y = e.clientY, 35716 dx = x - self.x, 35717 dy = y - self.y, 35718 isDragging = self.isDragging; 35719 self.x = x; 35720 self.y = y; 35721 35722 if (isDragging || Math.abs(self.startX - x) >= dragMinimum || Math.abs(self.startY - y) >= dragMinimum) { 35723 onDrag && (dragged = true); 35724 isDragging || (self.isDragging = true); 35725 onTouchOrPointerDelta(dx, dy); 35726 isDragging || onDragStart && onDragStart(self); 35727 } 35728 }, 35729 _onPress = self.onPress = function (e) { 35730 if (_ignoreCheck(e, 1) || e && e.button) { 35731 return; 35732 } 35733 35734 self.axis = axis = null; 35735 onStopDelayedCall.pause(); 35736 self.isPressed = true; 35737 e = _getEvent(e); 35738 prevDeltaX = prevDeltaY = 0; 35739 self.startX = self.x = e.clientX; 35740 self.startY = self.y = e.clientY; 35741 35742 self._vx.reset(); 35743 35744 self._vy.reset(); 35745 35746 _addListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, passive, true); 35747 35748 self.deltaX = self.deltaY = 0; 35749 onPress && onPress(self); 35750 }, 35751 _onRelease = self.onRelease = function (e) { 35752 if (_ignoreCheck(e, 1)) { 35753 return; 35754 } 35755 35756 _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true); 35757 35758 var isTrackingDrag = !isNaN(self.y - self.startY), 35759 wasDragging = self.isDragging, 35760 isDragNotClick = wasDragging && (Math.abs(self.x - self.startX) > 3 || Math.abs(self.y - self.startY) > 3), 35761 eventData = _getEvent(e); 35762 35763 if (!isDragNotClick && isTrackingDrag) { 35764 self._vx.reset(); 35765 35766 self._vy.reset(); 35767 35768 if (preventDefault && allowClicks) { 35769 gsap.delayedCall(0.08, function () { 35770 if (_getTime() - onClickTime > 300 && !e.defaultPrevented) { 35771 if (e.target.click) { 35772 e.target.click(); 35773 } else if (ownerDoc.createEvent) { 35774 var syntheticEvent = ownerDoc.createEvent("MouseEvents"); 35775 syntheticEvent.initMouseEvent("click", true, true, _win, 1, eventData.screenX, eventData.screenY, eventData.clientX, eventData.clientY, false, false, false, false, 0, null); 35776 e.target.dispatchEvent(syntheticEvent); 35777 } 35778 } 35779 }); 35780 } 35781 } 35782 35783 self.isDragging = self.isGesturing = self.isPressed = false; 35784 onStop && wasDragging && !isNormalizer && onStopDelayedCall.restart(true); 35785 onDragEnd && wasDragging && onDragEnd(self); 35786 onRelease && onRelease(self, isDragNotClick); 35787 }, 35788 _onGestureStart = function _onGestureStart(e) { 35789 return e.touches && e.touches.length > 1 && (self.isGesturing = true) && onGestureStart(e, self.isDragging); 35790 }, 35791 _onGestureEnd = function _onGestureEnd() { 35792 return (self.isGesturing = false) || onGestureEnd(self); 35793 }, 35794 onScroll = function onScroll(e) { 35795 if (_ignoreCheck(e)) { 35796 return; 35797 } 35798 35799 var x = scrollFuncX(), 35800 y = scrollFuncY(); 35801 onDelta((x - scrollX) * scrollSpeed, (y - scrollY) * scrollSpeed, 1); 35802 scrollX = x; 35803 scrollY = y; 35804 onStop && onStopDelayedCall.restart(true); 35805 }, 35806 _onWheel = function _onWheel(e) { 35807 if (_ignoreCheck(e)) { 35808 return; 35809 } 35810 35811 e = _getEvent(e, preventDefault); 35812 onWheel && (wheeled = true); 35813 var multiplier = (e.deltaMode === 1 ? lineHeight : e.deltaMode === 2 ? _win.innerHeight : 1) * wheelSpeed; 35814 onDelta(e.deltaX * multiplier, e.deltaY * multiplier, 0); 35815 onStop && !isNormalizer && onStopDelayedCall.restart(true); 35816 }, 35817 _onMove = function _onMove(e) { 35818 if (_ignoreCheck(e)) { 35819 return; 35820 } 35821 35822 var x = e.clientX, 35823 y = e.clientY, 35824 dx = x - self.x, 35825 dy = y - self.y; 35826 self.x = x; 35827 self.y = y; 35828 moved = true; 35829 onStop && onStopDelayedCall.restart(true); 35830 (dx || dy) && onTouchOrPointerDelta(dx, dy); 35831 }, 35832 _onHover = function _onHover(e) { 35833 self.event = e; 35834 onHover(self); 35835 }, 35836 _onHoverEnd = function _onHoverEnd(e) { 35837 self.event = e; 35838 onHoverEnd(self); 35839 }, 35840 _onClick = function _onClick(e) { 35841 return _ignoreCheck(e) || _getEvent(e, preventDefault) && onClick(self); 35842 }; 35843 35844 onStopDelayedCall = self._dc = gsap.delayedCall(onStopDelay || 0.25, onStopFunc).pause(); 35845 self.deltaX = self.deltaY = 0; 35846 self._vx = _getVelocityProp(0, 50, true); 35847 self._vy = _getVelocityProp(0, 50, true); 35848 self.scrollX = scrollFuncX; 35849 self.scrollY = scrollFuncY; 35850 self.isDragging = self.isGesturing = self.isPressed = false;
vendor: 7,173 bytes, lines 35851-36093
35851 35852 _context(this); 35853 35854 self.enable = function (e) { 35855 if (!self.isEnabled) { 35856 _addListener(isViewport ? ownerDoc : target, "scroll", _onScroll); 35857 35858 type.indexOf("scroll") >= 0 && _addListener(isViewport ? ownerDoc : target, "scroll", onScroll, passive, capture); 35859 type.indexOf("wheel") >= 0 && _addListener(target, "wheel", _onWheel, passive, capture); 35860 35861 if (type.indexOf("touch") >= 0 && _isTouch || type.indexOf("pointer") >= 0) { 35862 _addListener(target, _eventTypes[0], _onPress, passive, capture); 35863 35864 _addListener(ownerDoc, _eventTypes[2], _onRelease); 35865 35866 _addListener(ownerDoc, _eventTypes[3], _onRelease); 35867 35868 allowClicks && _addListener(target, "click", clickCapture, true, true); 35869 onClick && _addListener(target, "click", _onClick); 35870 onGestureStart && _addListener(ownerDoc, "gesturestart", _onGestureStart); 35871 onGestureEnd && _addListener(ownerDoc, "gestureend", _onGestureEnd); 35872 onHover && _addListener(target, _pointerType + "enter", _onHover); 35873 onHoverEnd && _addListener(target, _pointerType + "leave", _onHoverEnd); 35874 onMove && _addListener(target, _pointerType + "move", _onMove); 35875 } 35876 35877 self.isEnabled = true; 35878 e && e.type && _onPress(e); 35879 onEnable && onEnable(self); 35880 } 35881 35882 return self; 35883 }; 35884 35885 self.disable = function () { 35886 if (self.isEnabled) { 35887 _observers.filter(function (o) { 35888 return o !== self && _isViewport(o.target); 35889 }).length || _removeListener(isViewport ? ownerDoc : target, "scroll", _onScroll); 35890 35891 if (self.isPressed) { 35892 self._vx.reset(); 35893 35894 self._vy.reset(); 35895 35896 _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true); 35897 } 35898 35899 _removeListener(isViewport ? ownerDoc : target, "scroll", onScroll, capture); 35900 35901 _removeListener(target, "wheel", _onWheel, capture); 35902 35903 _removeListener(target, _eventTypes[0], _onPress, capture); 35904 35905 _removeListener(ownerDoc, _eventTypes[2], _onRelease); 35906 35907 _removeListener(ownerDoc, _eventTypes[3], _onRelease); 35908 35909 _removeListener(target, "click", clickCapture, true); 35910 35911 _removeListener(target, "click", _onClick); 35912 35913 _removeListener(ownerDoc, "gesturestart", _onGestureStart); 35914 35915 _removeListener(ownerDoc, "gestureend", _onGestureEnd); 35916 35917 _removeListener(target, _pointerType + "enter", _onHover); 35918 35919 _removeListener(target, _pointerType + "leave", _onHoverEnd); 35920 35921 _removeListener(target, _pointerType + "move", _onMove); 35922 35923 self.isEnabled = self.isPressed = self.isDragging = false; 35924 onDisable && onDisable(self); 35925 } 35926 }; 35927 35928 self.kill = self.revert = function () { 35929 self.disable(); 35930 35931 var i = _observers.indexOf(self); 35932 35933 i >= 0 && _observers.splice(i, 1); 35934 _normalizer === self && (_normalizer = 0); 35935 }; 35936 35937 _observers.push(self); 35938 35939 isNormalizer && _isViewport(target) && (_normalizer = self); 35940 self.enable(event); 35941 }; 35942 35943 _createClass(Observer, [{ 35944 key: "velocityX", 35945 get: function get() { 35946 return this._vx.getVelocity(); 35947 } 35948 }, { 35949 key: "velocityY", 35950 get: function get() { 35951 return this._vy.getVelocity(); 35952 } 35953 }]); 35954 35955 return Observer; 35956 }(); 35957 Observer.version = "3.12.5"; 35958 35959 Observer.create = function (vars) { 35960 return new Observer(vars); 35961 }; 35962 35963 Observer.register = _initCore; 35964 35965 Observer.getAll = function () { 35966 return _observers.slice(); 35967 }; 35968 35969 Observer.getById = function (id) { 35970 return _observers.filter(function (o) { 35971 return o.vars.id === id; 35972 })[0]; 35973 }; 35974 35975 _getGSAP() && gsap.registerPlugin(Observer); 35976 35977 /*! 35978 * ScrollTrigger 3.12.5 35979 * https://gsap.com 35980 * 35981 * @license Copyright 2008-2024, GreenSock. All rights reserved. 35982 * Subject to the terms at https://gsap.com/standard-license or for 35983 * Club GSAP members, the agreement issued with that membership. 35984 * @author: Jack Doyle, [email protected] 35985 */ 35986 35987 var gsap$1, 35988 _coreInitted$1, 35989 _win$1, 35990 _doc$1, 35991 _docEl$1, 35992 _body$1, 35993 _root$1, 35994 _resizeDelay, 35995 _toArray, 35996 _clamp$1, 35997 _time2, 35998 _syncInterval, 35999 _refreshing, 36000 _pointerIsDown, 36001 _transformProp, 36002 _i, 36003 _prevWidth, 36004 _prevHeight, 36005 _autoRefresh, 36006 _sort, 36007 _suppressOverwrites, 36008 _ignoreResize, 36009 _normalizer$1, 36010 _ignoreMobileResize, 36011 _baseScreenHeight, 36012 _baseScreenWidth, 36013 _fixIOSBug, 36014 _context$1, 36015 _scrollRestoration, 36016 _div100vh, 36017 _100vh, 36018 _isReverted, 36019 _clampingMax, 36020 _limitCallbacks, 36021 _startup$1 = 1, 36022 _getTime$1 = Date.now, 36023 _time1 = _getTime$1(), 36024 _lastScrollTime = 0, 36025 _enabled = 0, 36026 _parseClamp = function _parseClamp(value, type, self) { 36027 var clamp = _isString(value) && (value.substr(0, 6) === "clamp(" || value.indexOf("max") > -1); 36028 self["_" + type + "Clamp"] = clamp; 36029 return clamp ? value.substr(6, value.length - 7) : value; 36030 }, 36031 _keepClamp = function _keepClamp(value, clamp) { 36032 return clamp && (!_isString(value) || value.substr(0, 6) !== "clamp(") ? "clamp(" + value + ")" : value; 36033 }, 36034 _rafBugFix = function _rafBugFix() { 36035 return _enabled && requestAnimationFrame(_rafBugFix); 36036 }, 36037 _pointerDownHandler = function _pointerDownHandler() { 36038 return _pointerIsDown = 1; 36039 }, 36040 _pointerUpHandler = function _pointerUpHandler() { 36041 return _pointerIsDown = 0; 36042 }, 36043 _passThrough = function _passThrough(v) { 36044 return v; 36045 }, 36046 _round = function _round(value) { 36047 return Math.round(value * 100000) / 100000 || 0; 36048 }, 36049 _windowExists = function _windowExists() { 36050 return typeof window !== "undefined"; 36051 }, 36052 _getGSAP$1 = function _getGSAP() { 36053 return gsap$1 || _windowExists() && (gsap$1 = window.gsap) && gsap$1.registerPlugin && gsap$1; 36054 }, 36055 _isViewport$1 = function _isViewport(e) { 36056 return !!~_root$1.indexOf(e); 36057 }, 36058 _getViewportDimension = function _getViewportDimension(dimensionProperty) { 36059 return (dimensionProperty === "Height" ? _100vh : _win$1["inner" + dimensionProperty]) || _docEl$1["client" + dimensionProperty] || _body$1["client" + dimensionProperty]; 36060 }, 36061 _getBoundsFunc = function _getBoundsFunc(element) { 36062 return _getProxyProp(element, "getBoundingClientRect") || (_isViewport$1(element) ? function () { 36063 _winOffsets.width = _win$1.innerWidth; 36064 _winOffsets.height = _100vh; 36065 return _winOffsets; 36066 } : function () { 36067 return _getBounds(element); 36068 }); 36069 }, 36070 _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref) { 36071 var d = _ref.d, 36072 d2 = _ref.d2, 36073 a = _ref.a; 36074 return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () { 36075 return a()[d]; 36076 } : function () { 36077 return (isViewport ? _getViewportDimension(d2) : scroller["client" + d2]) || 0; 36078 }; 36079 }, 36080 _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) { 36081 return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () { 36082 return _winOffsets; 36083 }; 36084 }, 36085 _maxScroll = function _maxScroll(element, _ref2) { 36086 var s = _ref2.s, 36087 d2 = _ref2.d2, 36088 d = _ref2.d, 36089 a = _ref2.a; 36090 return Math.max(0, (s = "scroll" + d2) && (a = _getProxyProp(element, s)) ? a() - _getBoundsFunc(element)()[d] : _isViewport$1(element) ? (_docEl$1[s] || _body$1[s]) - _getViewportDimension(d2) : element[s] - element["offset" + d2]); 36091 }, 36092 _iterateAutoRefresh = function _iterateAutoRefresh(func, events) { 36093 for (var i = 0; i < _autoRefresh.length; i += 3) {
vendor: 4,900 bytes, lines 36094-36275
36094 (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]); 36095 } 36096 }, 36097 _isString = function _isString(value) { 36098 return typeof value === "string"; 36099 }, 36100 _isFunction = function _isFunction(value) { 36101 return typeof value === "function"; 36102 }, 36103 _isNumber = function _isNumber(value) { 36104 return typeof value === "number"; 36105 }, 36106 _isObject = function _isObject(value) { 36107 return typeof value === "object"; 36108 }, 36109 _endAnimation = function _endAnimation(animation, reversed, pause) { 36110 return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause(); 36111 }, 36112 _callback = function _callback(self, func) { 36113 if (self.enabled) { 36114 var result = self._ctx ? self._ctx.add(function () { 36115 return func(self); 36116 }) : func(self); 36117 result && result.totalTime && (self.callbackAnimation = result); 36118 } 36119 }, 36120 _abs = Math.abs, 36121 _left = "left", 36122 _top = "top", 36123 _right = "right", 36124 _bottom = "bottom", 36125 _width = "width", 36126 _height = "height", 36127 _Right = "Right", 36128 _Left = "Left", 36129 _Top = "Top", 36130 _Bottom = "Bottom", 36131 _padding = "padding", 36132 _margin = "margin", 36133 _Width = "Width", 36134 _Height = "Height", 36135 _px = "px", 36136 _getComputedStyle = function _getComputedStyle(element) { 36137 return _win$1.getComputedStyle(element); 36138 }, 36139 _makePositionable = function _makePositionable(element) { 36140 var position = _getComputedStyle(element).position; 36141 36142 element.style.position = position === "absolute" || position === "fixed" ? position : "relative"; 36143 }, 36144 _setDefaults = function _setDefaults(obj, defaults) { 36145 for (var p in defaults) { 36146 p in obj || (obj[p] = defaults[p]); 36147 } 36148 36149 return obj; 36150 }, 36151 _getBounds = function _getBounds(element, withoutTransforms) { 36152 var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap$1.to(element, { 36153 x: 0, 36154 y: 0, 36155 xPercent: 0, 36156 yPercent: 0, 36157 rotation: 0, 36158 rotationX: 0, 36159 rotationY: 0, 36160 scale: 1, 36161 skewX: 0, 36162 skewY: 0 36163 }).progress(1), 36164 bounds = element.getBoundingClientRect(); 36165 tween && tween.progress(0).kill(); 36166 return bounds; 36167 }, 36168 _getSize = function _getSize(element, _ref3) { 36169 var d2 = _ref3.d2; 36170 return element["offset" + d2] || element["client" + d2] || 0; 36171 }, 36172 _getLabelRatioArray = function _getLabelRatioArray(timeline) { 36173 var a = [], 36174 labels = timeline.labels, 36175 duration = timeline.duration(), 36176 p; 36177 36178 for (p in labels) { 36179 a.push(labels[p] / duration); 36180 } 36181 36182 return a; 36183 }, 36184 _getClosestLabel = function _getClosestLabel(animation) { 36185 return function (value) { 36186 return gsap$1.utils.snap(_getLabelRatioArray(animation), value); 36187 }; 36188 }, 36189 _snapDirectional = function _snapDirectional(snapIncrementOrArray) { 36190 var snap = gsap$1.utils.snap(snapIncrementOrArray), 36191 a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) { 36192 return a - b; 36193 }); 36194 return a ? function (value, direction, threshold) { 36195 if (threshold === void 0) { 36196 threshold = 1e-3; 36197 } 36198 36199 var i; 36200 36201 if (!direction) { 36202 return snap(value); 36203 } 36204 36205 if (direction > 0) { 36206 value -= threshold; 36207 36208 for (i = 0; i < a.length; i++) { 36209 if (a[i] >= value) { 36210 return a[i]; 36211 } 36212 } 36213 36214 return a[i - 1]; 36215 } else { 36216 i = a.length; 36217 value += threshold; 36218 36219 while (i--) { 36220 if (a[i] <= value) { 36221 return a[i]; 36222 } 36223 } 36224 } 36225 36226 return a[0]; 36227 } : function (value, direction, threshold) { 36228 if (threshold === void 0) { 36229 threshold = 1e-3; 36230 } 36231 36232 var snapped = snap(value); 36233 return !direction || Math.abs(snapped - value) < threshold || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray); 36234 }; 36235 }, 36236 _getLabelAtDirection = function _getLabelAtDirection(timeline) { 36237 return function (value, st) { 36238 return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction); 36239 }; 36240 }, 36241 _multiListener = function _multiListener(func, element, types, callback) { 36242 return types.split(",").forEach(function (type) { 36243 return func(element, type, callback); 36244 }); 36245 }, 36246 _addListener$1 = function _addListener(element, type, func, nonPassive, capture) { 36247 return element.addEventListener(type, func, { 36248 passive: !nonPassive, 36249 capture: !!capture 36250 }); 36251 }, 36252 _removeListener$1 = function _removeListener(element, type, func, capture) { 36253 return element.removeEventListener(type, func, !!capture); 36254 }, 36255 _wheelListener = function _wheelListener(func, el, scrollFunc) { 36256 scrollFunc = scrollFunc && scrollFunc.wheelHandler; 36257 36258 if (scrollFunc) { 36259 func(el, "wheel", scrollFunc); 36260 func(el, "touchmove", scrollFunc); 36261 } 36262 }, 36263 _markerDefaults = { 36264 startColor: "green", 36265 endColor: "red", 36266 indent: 0, 36267 fontSize: "16px", 36268 fontWeight: "normal" 36269 }, 36270 _defaults = { 36271 toggleActions: "play", 36272 anticipatePin: 0 36273 }, 36274 _keywords = { 36275 top: 0,
vendor: 14,119 bytes, lines 36276-36716
36276 left: 0, 36277 center: 0.5, 36278 bottom: 1, 36279 right: 1 36280 }, 36281 _offsetToPx = function _offsetToPx(value, size) { 36282 if (_isString(value)) { 36283 var eqIndex = value.indexOf("="), 36284 relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0; 36285 36286 if (~eqIndex) { 36287 value.indexOf("%") > eqIndex && (relative *= size / 100); 36288 value = value.substr(0, eqIndex - 1); 36289 } 36290 36291 value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0); 36292 } 36293 36294 return value; 36295 }, 36296 _createMarker = function _createMarker(type, name, container, direction, _ref4, offset, matchWidthEl, containerAnimation) { 36297 var startColor = _ref4.startColor, 36298 endColor = _ref4.endColor, 36299 fontSize = _ref4.fontSize, 36300 indent = _ref4.indent, 36301 fontWeight = _ref4.fontWeight; 36302 36303 var e = _doc$1.createElement("div"), 36304 useFixedPosition = _isViewport$1(container) || _getProxyProp(container, "pinType") === "fixed", 36305 isScroller = type.indexOf("scroller") !== -1, 36306 parent = useFixedPosition ? _body$1 : container, 36307 isStart = type.indexOf("start") !== -1, 36308 color = isStart ? startColor : endColor, 36309 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;"; 36310 36311 css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;"); 36312 (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;"); 36313 matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;"); 36314 e._isStart = isStart; 36315 e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : "")); 36316 e.style.cssText = css; 36317 e.innerText = name || name === 0 ? type + "-" + name : type; 36318 parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e); 36319 e._offset = e["offset" + direction.op.d2]; 36320 36321 _positionMarker(e, 0, direction, isStart); 36322 36323 return e; 36324 }, 36325 _positionMarker = function _positionMarker(marker, start, direction, flipped) { 36326 var vars = { 36327 display: "block" 36328 }, 36329 side = direction[flipped ? "os2" : "p2"], 36330 oppositeSide = direction[flipped ? "p2" : "os2"]; 36331 marker._isFlipped = flipped; 36332 vars[direction.a + "Percent"] = flipped ? -100 : 0; 36333 vars[direction.a] = flipped ? "1px" : 0; 36334 vars["border" + side + _Width] = 1; 36335 vars["border" + oppositeSide + _Width] = 0; 36336 vars[direction.p] = start + "px"; 36337 gsap$1.set(marker, vars); 36338 }, 36339 _triggers = [], 36340 _ids = {}, 36341 _rafID, 36342 _sync = function _sync() { 36343 return _getTime$1() - _lastScrollTime > 34 && (_rafID || (_rafID = requestAnimationFrame(_updateAll))); 36344 }, 36345 _onScroll$1 = function _onScroll() { 36346 if (!_normalizer$1 || !_normalizer$1.isPressed || _normalizer$1.startX > _body$1.clientWidth) { 36347 _scrollers.cache++; 36348 36349 if (_normalizer$1) { 36350 _rafID || (_rafID = requestAnimationFrame(_updateAll)); 36351 } else { 36352 _updateAll(); 36353 } 36354 36355 _lastScrollTime || _dispatch("scrollStart"); 36356 _lastScrollTime = _getTime$1(); 36357 } 36358 }, 36359 _setBaseDimensions = function _setBaseDimensions() { 36360 _baseScreenWidth = _win$1.innerWidth; 36361 _baseScreenHeight = _win$1.innerHeight; 36362 }, 36363 _onResize = function _onResize() { 36364 _scrollers.cache++; 36365 !_refreshing && !_ignoreResize && !_doc$1.fullscreenElement && !_doc$1.webkitFullscreenElement && (!_ignoreMobileResize || _baseScreenWidth !== _win$1.innerWidth || Math.abs(_win$1.innerHeight - _baseScreenHeight) > _win$1.innerHeight * 0.25) && _resizeDelay.restart(true); 36366 }, 36367 _listeners = {}, 36368 _emptyArray = [], 36369 _softRefresh = function _softRefresh() { 36370 return _removeListener$1(ScrollTrigger$1, "scrollEnd", _softRefresh) || _refreshAll(true); 36371 }, 36372 _dispatch = function _dispatch(type) { 36373 return _listeners[type] && _listeners[type].map(function (f) { 36374 return f(); 36375 }) || _emptyArray; 36376 }, 36377 _savedStyles = [], 36378 _revertRecorded = function _revertRecorded(media) { 36379 for (var i = 0; i < _savedStyles.length; i += 5) { 36380 if (!media || _savedStyles[i + 4] && _savedStyles[i + 4].query === media) { 36381 _savedStyles[i].style.cssText = _savedStyles[i + 1]; 36382 _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || ""); 36383 _savedStyles[i + 3].uncache = 1; 36384 } 36385 } 36386 }, 36387 _revertAll = function _revertAll(kill, media) { 36388 var trigger; 36389 36390 for (_i = 0; _i < _triggers.length; _i++) { 36391 trigger = _triggers[_i]; 36392 36393 if (trigger && (!media || trigger._ctx === media)) { 36394 if (kill) { 36395 trigger.kill(1); 36396 } else { 36397 trigger.revert(true, true); 36398 } 36399 } 36400 } 36401 36402 _isReverted = true; 36403 media && _revertRecorded(media); 36404 media || _dispatch("revert"); 36405 }, 36406 _clearScrollMemory = function _clearScrollMemory(scrollRestoration, force) { 36407 _scrollers.cache++; 36408 (force || !_refreshingAll) && _scrollers.forEach(function (obj) { 36409 return _isFunction(obj) && obj.cacheID++ && (obj.rec = 0); 36410 }); 36411 _isString(scrollRestoration) && (_win$1.history.scrollRestoration = _scrollRestoration = scrollRestoration); 36412 }, 36413 _refreshingAll, 36414 _refreshID = 0, 36415 _queueRefreshID, 36416 _queueRefreshAll = function _queueRefreshAll() { 36417 if (_queueRefreshID !== _refreshID) { 36418 var id = _queueRefreshID = _refreshID; 36419 requestAnimationFrame(function () { 36420 return id === _refreshID && _refreshAll(true); 36421 }); 36422 } 36423 }, 36424 _refresh100vh = function _refresh100vh() { 36425 _body$1.appendChild(_div100vh); 36426 36427 _100vh = !_normalizer$1 && _div100vh.offsetHeight || _win$1.innerHeight; 36428 36429 _body$1.removeChild(_div100vh); 36430 }, 36431 _hideAllMarkers = function _hideAllMarkers(hide) { 36432 return _toArray(".gsap-marker-start, .gsap-marker-end, .gsap-marker-scroller-start, .gsap-marker-scroller-end").forEach(function (el) { 36433 return el.style.display = hide ? "none" : "block"; 36434 }); 36435 }, 36436 _refreshAll = function _refreshAll(force, skipRevert) { 36437 if (_lastScrollTime && !force && !_isReverted) { 36438 _addListener$1(ScrollTrigger$1, "scrollEnd", _softRefresh); 36439 36440 return; 36441 } 36442 36443 _refresh100vh(); 36444 36445 _refreshingAll = ScrollTrigger$1.isRefreshing = true; 36446 36447 _scrollers.forEach(function (obj) { 36448 return _isFunction(obj) && ++obj.cacheID && (obj.rec = obj()); 36449 }); 36450 36451 var refreshInits = _dispatch("refreshInit"); 36452 36453 _sort && ScrollTrigger$1.sort(); 36454 skipRevert || _revertAll(); 36455 36456 _scrollers.forEach(function (obj) { 36457 if (_isFunction(obj)) { 36458 obj.smooth && (obj.target.style.scrollBehavior = "auto"); 36459 obj(0); 36460 } 36461 }); 36462 36463 _triggers.slice(0).forEach(function (t) { 36464 return t.refresh(); 36465 }); 36466 36467 _isReverted = false; 36468 36469 _triggers.forEach(function (t) { 36470 if (t._subPinOffset && t.pin) { 36471 var prop = t.vars.horizontal ? "offsetWidth" : "offsetHeight", 36472 original = t.pin[prop]; 36473 t.revert(true, 1); 36474 t.adjustPinSpacing(t.pin[prop] - original); 36475 t.refresh(); 36476 } 36477 }); 36478 36479 _clampingMax = 1; 36480 36481 _hideAllMarkers(true); 36482 36483 _triggers.forEach(function (t) { 36484 var max = _maxScroll(t.scroller, t._dir), 36485 endClamp = t.vars.end === "max" || t._endClamp && t.end > max, 36486 startClamp = t._startClamp && t.start >= max; 36487 36488 (endClamp || startClamp) && t.setPositions(startClamp ? max - 1 : t.start, endClamp ? Math.max(startClamp ? max : t.start + 1, max) : t.end, true); 36489 }); 36490 36491 _hideAllMarkers(false); 36492 36493 _clampingMax = 0; 36494 refreshInits.forEach(function (result) { 36495 return result && result.render && result.render(-1); 36496 }); 36497 36498 _scrollers.forEach(function (obj) { 36499 if (_isFunction(obj)) { 36500 obj.smooth && requestAnimationFrame(function () { 36501 return obj.target.style.scrollBehavior = "smooth"; 36502 }); 36503 obj.rec && obj(obj.rec); 36504 } 36505 }); 36506 36507 _clearScrollMemory(_scrollRestoration, 1); 36508 36509 _resizeDelay.pause(); 36510 36511 _refreshID++; 36512 _refreshingAll = 2; 36513 36514 _updateAll(2); 36515 36516 _triggers.forEach(function (t) { 36517 return _isFunction(t.vars.onRefresh) && t.vars.onRefresh(t); 36518 }); 36519 36520 _refreshingAll = ScrollTrigger$1.isRefreshing = false; 36521 36522 _dispatch("refresh"); 36523 }, 36524 _lastScroll = 0, 36525 _direction = 1, 36526 _primary, 36527 _updateAll = function _updateAll(force) { 36528 if (force === 2 || !_refreshingAll && !_isReverted) { 36529 ScrollTrigger$1.isUpdating = true; 36530 _primary && _primary.update(0); 36531 36532 var l = _triggers.length, 36533 time = _getTime$1(), 36534 recordVelocity = time - _time1 >= 50, 36535 scroll = l && _triggers[0].scroll(); 36536 36537 _direction = _lastScroll > scroll ? -1 : 1; 36538 _refreshingAll || (_lastScroll = scroll); 36539 36540 if (recordVelocity) { 36541 if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) { 36542 _lastScrollTime = 0; 36543 36544 _dispatch("scrollEnd"); 36545 } 36546 36547 _time2 = _time1; 36548 _time1 = time; 36549 } 36550 36551 if (_direction < 0) { 36552 _i = l; 36553 36554 while (_i-- > 0) { 36555 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 36556 } 36557 36558 _direction = 1; 36559 } else { 36560 for (_i = 0; _i < l; _i++) { 36561 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 36562 } 36563 } 36564 36565 ScrollTrigger$1.isUpdating = false; 36566 } 36567 36568 _rafID = 0; 36569 }, 36570 _propNamesToCopy = [_left, _top, _bottom, _right, _margin + _Bottom, _margin + _Right, _margin + _Top, _margin + _Left, "display", "flexShrink", "float", "zIndex", "gridColumnStart", "gridColumnEnd", "gridRowStart", "gridRowEnd", "gridArea", "justifySelf", "alignSelf", "placeSelf", "order"], 36571 _stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]), 36572 _swapPinOut = function _swapPinOut(pin, spacer, state) { 36573 _setState(state); 36574 36575 var cache = pin._gsap; 36576 36577 if (cache.spacerIsNative) { 36578 _setState(cache.spacerState); 36579 } else if (pin._gsap.swappedIn) { 36580 var parent = spacer.parentNode; 36581 36582 if (parent) { 36583 parent.insertBefore(pin, spacer); 36584 parent.removeChild(spacer); 36585 } 36586 } 36587 36588 pin._gsap.swappedIn = false; 36589 }, 36590 _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) { 36591 if (!pin._gsap.swappedIn) { 36592 var i = _propNamesToCopy.length, 36593 spacerStyle = spacer.style, 36594 pinStyle = pin.style, 36595 p; 36596 36597 while (i--) { 36598 p = _propNamesToCopy[i]; 36599 spacerStyle[p] = cs[p]; 36600 } 36601 36602 spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative"; 36603 cs.display === "inline" && (spacerStyle.display = "inline-block"); 36604 pinStyle[_bottom] = pinStyle[_right] = "auto"; 36605 spacerStyle.flexBasis = cs.flexBasis || "auto"; 36606 spacerStyle.overflow = "visible"; 36607 spacerStyle.boxSizing = "border-box"; 36608 spacerStyle[_width] = _getSize(pin, _horizontal) + _px; 36609 spacerStyle[_height] = _getSize(pin, _vertical) + _px; 36610 spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0"; 36611 36612 _setState(spacerState); 36613 36614 pinStyle[_width] = pinStyle["max" + _Width] = cs[_width]; 36615 pinStyle[_height] = pinStyle["max" + _Height] = cs[_height]; 36616 pinStyle[_padding] = cs[_padding]; 36617 36618 if (pin.parentNode !== spacer) { 36619 pin.parentNode.insertBefore(spacer, pin); 36620 spacer.appendChild(pin); 36621 } 36622 36623 pin._gsap.swappedIn = true; 36624 } 36625 }, 36626 _capsExp = /([A-Z])/g, 36627 _setState = function _setState(state) { 36628 if (state) { 36629 var style = state.t.style, 36630 l = state.length, 36631 i = 0, 36632 p, 36633 value; 36634 (state.t._gsap || gsap$1.core.getCache(state.t)).uncache = 1; 36635 36636 for (; i < l; i += 2) { 36637 value = state[i + 1]; 36638 p = state[i]; 36639 36640 if (value) { 36641 style[p] = value; 36642 } else if (style[p]) { 36643 style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 36644 } 36645 } 36646 } 36647 }, 36648 _getState = function _getState(element) { 36649 var l = _stateProps.length, 36650 style = element.style, 36651 state = [], 36652 i = 0; 36653 36654 for (; i < l; i++) { 36655 state.push(_stateProps[i], style[_stateProps[i]]); 36656 } 36657 36658 state.t = element; 36659 return state; 36660 }, 36661 _copyState = function _copyState(state, override, omitOffsets) { 36662 var result = [], 36663 l = state.length, 36664 i = omitOffsets ? 8 : 0, 36665 p; 36666 36667 for (; i < l; i += 2) { 36668 p = state[i]; 36669 result.push(p, p in override ? override[p] : state[i + 1]); 36670 } 36671 36672 result.t = state.t; 36673 return result; 36674 }, 36675 _winOffsets = { 36676 left: 0, 36677 top: 0 36678 }, 36679 _parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation, clampZeroProp) { 36680 _isFunction(value) && (value = value(self)); 36681 36682 if (_isString(value) && value.substr(0, 3) === "max") { 36683 value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0); 36684 } 36685 36686 var time = containerAnimation ? containerAnimation.time() : 0, 36687 p1, 36688 p2, 36689 element; 36690 containerAnimation && containerAnimation.seek(0); 36691 isNaN(value) || (value = +value); 36692 36693 if (!_isNumber(value)) { 36694 _isFunction(trigger) && (trigger = trigger(self)); 36695 var offsets = (value || "0").split(" "), 36696 bounds, 36697 localOffset, 36698 globalOffset, 36699 display; 36700 element = _getTarget(trigger, self) || _body$1; 36701 bounds = _getBounds(element) || {}; 36702 36703 if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") { 36704 display = element.style.display; 36705 element.style.display = "block"; 36706 bounds = _getBounds(element); 36707 display ? element.style.display = display : element.style.removeProperty("display"); 36708 } 36709 36710 localOffset = _offsetToPx(offsets[0], bounds[direction.d]); 36711 globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize); 36712 value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset; 36713 markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20); 36714 scrollerSize -= scrollerSize - globalOffset; 36715 } else { 36716 containerAnimation && (value = gsap$1.utils.mapRange(containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, 0, scrollerMa
vendor: 4,541 bytes, lines 36716-36872
36716x, value)); 36717 markerScroller && _positionMarker(markerScroller, scrollerSize, direction, true); 36718 } 36719 36720 if (clampZeroProp) { 36721 self[clampZeroProp] = value || -0.001; 36722 value < 0 && (value = 0); 36723 } 36724 36725 if (marker) { 36726 var position = value + scrollerSize, 36727 isStart = marker._isStart; 36728 p1 = "scroll" + direction.d2; 36729 36730 _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body$1[p1], _docEl$1[p1]) : marker.parentNode[p1]) <= position + 1); 36731 36732 if (useFixedPosition) { 36733 scrollerBounds = _getBounds(markerScroller); 36734 useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px); 36735 } 36736 } 36737 36738 if (containerAnimation && element) { 36739 p1 = _getBounds(element); 36740 containerAnimation.seek(scrollerMax); 36741 p2 = _getBounds(element); 36742 containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p]; 36743 value = value / containerAnimation._caScrollDist * scrollerMax; 36744 } 36745 36746 containerAnimation && containerAnimation.seek(time); 36747 return containerAnimation ? value : Math.round(value); 36748 }, 36749 _prefixExp = /(webkit|moz|length|cssText|inset)/i, 36750 _reparent = function _reparent(element, parent, top, left) { 36751 if (element.parentNode !== parent) { 36752 var style = element.style, 36753 p, 36754 cs; 36755 36756 if (parent === _body$1) { 36757 element._stOrig = style.cssText; 36758 cs = _getComputedStyle(element); 36759 36760 for (p in cs) { 36761 if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") { 36762 style[p] = cs[p]; 36763 } 36764 } 36765 36766 style.top = top; 36767 style.left = left; 36768 } else { 36769 style.cssText = element._stOrig; 36770 } 36771 36772 gsap$1.core.getCache(element).uncache = 1; 36773 parent.appendChild(element); 36774 } 36775 }, 36776 _interruptionTracker = function _interruptionTracker(getValueFunc, initialValue, onInterrupt) { 36777 var last1 = initialValue, 36778 last2 = last1; 36779 return function (value) { 36780 var current = Math.round(getValueFunc()); 36781 36782 if (current !== last1 && current !== last2 && Math.abs(current - last1) > 3 && Math.abs(current - last2) > 3) { 36783 value = current; 36784 onInterrupt && onInterrupt(); 36785 } 36786 36787 last2 = last1; 36788 last1 = value; 36789 return value; 36790 }; 36791 }, 36792 _shiftMarker = function _shiftMarker(marker, direction, value) { 36793 var vars = {}; 36794 vars[direction.p] = "+=" + value; 36795 gsap$1.set(marker, vars); 36796 }, 36797 _getTweenCreator = function _getTweenCreator(scroller, direction) { 36798 var getScroll = _getScrollFunc(scroller, direction), 36799 prop = "_scroll" + direction.p2, 36800 getTween = function getTween(scrollTo, vars, initialValue, change1, change2) { 36801 var tween = getTween.tween, 36802 onComplete = vars.onComplete, 36803 modifiers = {}; 36804 initialValue = initialValue || getScroll(); 36805 36806 var checkForInterruption = _interruptionTracker(getScroll, initialValue, function () { 36807 tween.kill(); 36808 getTween.tween = 0; 36809 }); 36810 36811 change2 = change1 && change2 || 0; 36812 change1 = change1 || scrollTo - initialValue; 36813 tween && tween.kill(); 36814 vars[prop] = scrollTo; 36815 vars.inherit = false; 36816 vars.modifiers = modifiers; 36817 36818 modifiers[prop] = function () { 36819 return checkForInterruption(initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio); 36820 }; 36821 36822 vars.onUpdate = function () { 36823 _scrollers.cache++; 36824 getTween.tween && _updateAll(); 36825 }; 36826 36827 vars.onComplete = function () { 36828 getTween.tween = 0; 36829 onComplete && onComplete.call(tween); 36830 }; 36831 36832 tween = getTween.tween = gsap$1.to(scroller, vars); 36833 return tween; 36834 }; 36835 36836 scroller[prop] = getScroll; 36837 36838 getScroll.wheelHandler = function () { 36839 return getTween.tween && getTween.tween.kill() && (getTween.tween = 0); 36840 }; 36841 36842 _addListener$1(scroller, "wheel", getScroll.wheelHandler); 36843 36844 ScrollTrigger$1.isTouch && _addListener$1(scroller, "touchmove", getScroll.wheelHandler); 36845 return getTween; 36846 }; 36847 36848 var ScrollTrigger$1 = function () { 36849 function ScrollTrigger(vars, animation) { 36850 _coreInitted$1 || ScrollTrigger.register(gsap$1) || console.warn("Please gsap.registerPlugin(ScrollTrigger)"); 36851 36852 _context$1(this); 36853 36854 this.init(vars, animation); 36855 } 36856 36857 var _proto = ScrollTrigger.prototype; 36858 36859 _proto.init = function init(vars, animation) { 36860 this.progress = this.start = 0; 36861 this.vars && this.kill(true, true); 36862 36863 if (!_enabled) { 36864 this.update = this.refresh = this.kill = _passThrough; 36865 return; 36866 } 36867 36868 vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? { 36869 trigger: vars 36870 } : vars, _defaults); 36871 36872 var _vars = vars,
vendor: 4,184 bytes, lines 36873-37013
36873 onUpdate = _vars.onUpdate, 36874 toggleClass = _vars.toggleClass, 36875 id = _vars.id, 36876 onToggle = _vars.onToggle, 36877 onRefresh = _vars.onRefresh, 36878 scrub = _vars.scrub, 36879 trigger = _vars.trigger, 36880 pin = _vars.pin, 36881 pinSpacing = _vars.pinSpacing, 36882 invalidateOnRefresh = _vars.invalidateOnRefresh, 36883 anticipatePin = _vars.anticipatePin, 36884 onScrubComplete = _vars.onScrubComplete, 36885 onSnapComplete = _vars.onSnapComplete, 36886 once = _vars.once, 36887 snap = _vars.snap, 36888 pinReparent = _vars.pinReparent, 36889 pinSpacer = _vars.pinSpacer, 36890 containerAnimation = _vars.containerAnimation, 36891 fastScrollEnd = _vars.fastScrollEnd, 36892 preventOverlaps = _vars.preventOverlaps, 36893 direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _horizontal : _vertical, 36894 isToggle = !scrub && scrub !== 0, 36895 scroller = _getTarget(vars.scroller || _win$1), 36896 scrollerCache = gsap$1.core.getCache(scroller), 36897 isViewport = _isViewport$1(scroller), 36898 useFixedPosition = ("pinType" in vars ? vars.pinType : _getProxyProp(scroller, "pinType") || isViewport && "fixed") === "fixed", 36899 callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack], 36900 toggleActions = isToggle && vars.toggleActions.split(" "), 36901 markers = "markers" in vars ? vars.markers : _defaults.markers, 36902 borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0, 36903 self = this, 36904 onRefreshInit = vars.onRefreshInit && function () { 36905 return vars.onRefreshInit(self); 36906 }, 36907 getScrollerSize = _getSizeFunc(scroller, isViewport, direction), 36908 getScrollerOffsets = _getOffsetsFunc(scroller, isViewport), 36909 lastSnap = 0, 36910 lastRefresh = 0, 36911 prevProgress = 0, 36912 scrollFunc = _getScrollFunc(scroller, direction), 36913 tweenTo, 36914 pinCache, 36915 snapFunc, 36916 scroll1, 36917 scroll2, 36918 start, 36919 end, 36920 markerStart, 36921 markerEnd, 36922 markerStartTrigger, 36923 markerEndTrigger, 36924 markerVars, 36925 executingOnRefresh, 36926 change, 36927 pinOriginalState, 36928 pinActiveState, 36929 pinState, 36930 spacer, 36931 offset, 36932 pinGetter, 36933 pinSetter, 36934 pinStart, 36935 pinChange, 36936 spacingStart, 36937 spacerState, 36938 markerStartSetter, 36939 pinMoves, 36940 markerEndSetter, 36941 cs, 36942 snap1, 36943 snap2, 36944 scrubTween, 36945 scrubSmooth, 36946 snapDurClamp, 36947 snapDelayedCall, 36948 prevScroll, 36949 prevAnimProgress, 36950 caMarkerSetter, 36951 customRevertReturn; 36952 36953 self._startClamp = self._endClamp = false; 36954 self._dir = direction; 36955 anticipatePin *= 45; 36956 self.scroller = scroller; 36957 self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc; 36958 scroll1 = scrollFunc(); 36959 self.vars = vars; 36960 animation = animation || vars.animation; 36961 36962 if ("refreshPriority" in vars) { 36963 _sort = 1; 36964 vars.refreshPriority === -9999 && (_primary = self); 36965 } 36966 36967 scrollerCache.tweenScroll = scrollerCache.tweenScroll || { 36968 top: _getTweenCreator(scroller, _vertical), 36969 left: _getTweenCreator(scroller, _horizontal) 36970 }; 36971 self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p]; 36972 36973 self.scrubDuration = function (value) { 36974 scrubSmooth = _isNumber(value) && value; 36975 36976 if (!scrubSmooth) { 36977 scrubTween && scrubTween.progress(1).kill(); 36978 scrubTween = 0; 36979 } else { 36980 scrubTween ? scrubTween.duration(value) : scrubTween = gsap$1.to(animation, { 36981 ease: "expo", 36982 totalProgress: "+=0", 36983 inherit: false, 36984 duration: scrubSmooth, 36985 paused: true, 36986 onComplete: function onComplete() { 36987 return onScrubComplete && onScrubComplete(self); 36988 } 36989 }); 36990 } 36991 }; 36992 36993 if (animation) { 36994 animation.vars.lazy = false; 36995 animation._initted && !self.isReverted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.duration() && animation.render(0, true, true); 36996 self.animation = animation.pause(); 36997 animation.scrollTrigger = self; 36998 self.scrubDuration(scrub); 36999 snap1 = 0; 37000 id || (id = animation.vars.id); 37001 } 37002 37003 if (snap) { 37004 if (!_isObject(snap) || snap.push) { 37005 snap = { 37006 snapTo: snap 37007 }; 37008 } 37009 37010 "scrollBehavior" in _body$1.style && gsap$1.set(isViewport ? [_body$1, _docEl$1] : scroller, { 37011 scrollBehavior: "auto" 37012 }); 37013
vendor: 4,259 bytes, lines 37014-37109
37014 _scrollers.forEach(function (o) { 37015 return _isFunction(o) && o.target === (isViewport ? _doc$1.scrollingElement || _docEl$1 : scroller) && (o.smooth = false); 37016 }); 37017 37018 snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) { 37019 return _snapDirectional(snap.snapTo)(value, _getTime$1() - lastRefresh < 500 ? 0 : st.direction); 37020 } : gsap$1.utils.snap(snap.snapTo); 37021 snapDurClamp = snap.duration || { 37022 min: 0.1, 37023 max: 2 37024 }; 37025 snapDurClamp = _isObject(snapDurClamp) ? _clamp$1(snapDurClamp.min, snapDurClamp.max) : _clamp$1(snapDurClamp, snapDurClamp); 37026 snapDelayedCall = gsap$1.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () { 37027 var scroll = scrollFunc(), 37028 refreshedRecently = _getTime$1() - lastRefresh < 500, 37029 tween = tweenTo.tween; 37030 37031 if ((refreshedRecently || Math.abs(self.getVelocity()) < 10) && !tween && !_pointerIsDown && lastSnap !== scroll) { 37032 var progress = (scroll - start) / change, 37033 totalProgress = animation && !isToggle ? animation.totalProgress() : progress, 37034 velocity = refreshedRecently ? 0 : (totalProgress - snap2) / (_getTime$1() - _time2) * 1000 || 0, 37035 change1 = gsap$1.utils.clamp(-progress, 1 - progress, _abs(velocity / 2) * velocity / 0.185), 37036 naturalEnd = progress + (snap.inertia === false ? 0 : change1), 37037 endValue, 37038 endScroll, 37039 _snap = snap, 37040 onStart = _snap.onStart, 37041 _onInterrupt = _snap.onInterrupt, 37042 _onComplete = _snap.onComplete; 37043 endValue = snapFunc(naturalEnd, self); 37044 _isNumber(endValue) || (endValue = naturalEnd); 37045 endScroll = Math.round(start + endValue * change); 37046 37047 if (scroll <= end && scroll >= start && endScroll !== scroll) { 37048 if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) { 37049 return; 37050 } 37051 37052 if (snap.inertia === false) { 37053 change1 = endValue - progress; 37054 } 37055 37056 tweenTo(endScroll, { 37057 duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)), 37058 ease: snap.ease || "power3", 37059 data: _abs(endScroll - scroll), 37060 onInterrupt: function onInterrupt() { 37061 return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self); 37062 }, 37063 onComplete: function onComplete() { 37064 self.update(); 37065 lastSnap = scrollFunc(); 37066 37067 if (animation) { 37068 scrubTween ? scrubTween.resetTo("totalProgress", endValue, animation._tTime / animation._tDur) : animation.progress(endValue); 37069 } 37070 37071 snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress; 37072 onSnapComplete && onSnapComplete(self); 37073 _onComplete && _onComplete(self); 37074 } 37075 }, scroll, change1 * change, endScroll - scroll - change1 * change); 37076 onStart && onStart(self, tweenTo.tween); 37077 } 37078 } else if (self.isActive && lastSnap !== scroll) { 37079 snapDelayedCall.restart(true); 37080 } 37081 }).pause(); 37082 } 37083 37084 id && (_ids[id] = self); 37085 trigger = self.trigger = _getTarget(trigger || pin !== true && pin); 37086 customRevertReturn = trigger && trigger._gsap && trigger._gsap.stRevert; 37087 customRevertReturn && (customRevertReturn = customRevertReturn(self)); 37088 pin = pin === true ? trigger : _getTarget(pin); 37089 _isString(toggleClass) && (toggleClass = { 37090 targets: trigger, 37091 className: toggleClass 37092 }); 37093 37094 if (pin) { 37095 pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && pin.parentNode && pin.parentNode.style && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding); 37096 self.pin = pin; 37097 pinCache = gsap$1.core.getCache(pin); 37098 37099 if (!pinCache.spacer) { 37100 if (pinSpacer) { 37101 pinSpacer = _getTarget(pinSpacer); 37102 pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement); 37103 pinCache.spacerIsNative = !!pinSpacer; 37104 pinSpacer && (pinCache.spacerState = _getState(pinSpacer)); 37105 } 37106 37107 pinCache.spacer = spacer = pinSpacer || _doc$1.createElement("div"); 37108 spacer.classList.add("pin-spacer"); 37109 id && spacer.classList.add("pin-spacer-" + id);
vendor: 4,987 bytes, lines 37110-37264
37110 pinCache.pinState = pinOriginalState = _getState(pin); 37111 } else { 37112 pinOriginalState = pinCache.pinState; 37113 } 37114 37115 vars.force3D !== false && gsap$1.set(pin, { 37116 force3D: true 37117 }); 37118 self.spacer = spacer = pinCache.spacer; 37119 cs = _getComputedStyle(pin); 37120 spacingStart = cs[pinSpacing + direction.os2]; 37121 pinGetter = gsap$1.getProperty(pin); 37122 pinSetter = gsap$1.quickSetter(pin, direction.a, _px); 37123 37124 _swapPinIn(pin, spacer, cs); 37125 37126 pinState = _getState(pin); 37127 } 37128 37129 if (markers) { 37130 markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults; 37131 markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0); 37132 markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger); 37133 offset = markerStartTrigger["offset" + direction.op.d2]; 37134 37135 var content = _getTarget(_getProxyProp(scroller, "content") || scroller); 37136 37137 markerStart = this.markerStart = _createMarker("start", id, content, direction, markerVars, offset, 0, containerAnimation); 37138 markerEnd = this.markerEnd = _createMarker("end", id, content, direction, markerVars, offset, 0, containerAnimation); 37139 containerAnimation && (caMarkerSetter = gsap$1.quickSetter([markerStart, markerEnd], direction.a, _px)); 37140 37141 if (!useFixedPosition && !(_proxies.length && _getProxyProp(scroller, "fixedMarkers") === true)) { 37142 _makePositionable(isViewport ? _body$1 : scroller); 37143 37144 gsap$1.set([markerStartTrigger, markerEndTrigger], { 37145 force3D: true 37146 }); 37147 markerStartSetter = gsap$1.quickSetter(markerStartTrigger, direction.a, _px); 37148 markerEndSetter = gsap$1.quickSetter(markerEndTrigger, direction.a, _px); 37149 } 37150 } 37151 37152 if (containerAnimation) { 37153 var oldOnUpdate = containerAnimation.vars.onUpdate, 37154 oldParams = containerAnimation.vars.onUpdateParams; 37155 containerAnimation.eventCallback("onUpdate", function () { 37156 self.update(0, 0, 1); 37157 oldOnUpdate && oldOnUpdate.apply(containerAnimation, oldParams || []); 37158 }); 37159 } 37160 37161 self.previous = function () { 37162 return _triggers[_triggers.indexOf(self) - 1]; 37163 }; 37164 37165 self.next = function () { 37166 return _triggers[_triggers.indexOf(self) + 1]; 37167 }; 37168 37169 self.revert = function (revert, temp) { 37170 if (!temp) { 37171 return self.kill(true); 37172 } 37173 37174 var r = revert !== false || !self.enabled, 37175 prevRefreshing = _refreshing; 37176 37177 if (r !== self.isReverted) { 37178 if (r) { 37179 prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0); 37180 prevProgress = self.progress; 37181 prevAnimProgress = animation && animation.progress(); 37182 } 37183 37184 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 37185 return m.style.display = r ? "none" : "block"; 37186 }); 37187 37188 if (r) { 37189 _refreshing = self; 37190 self.update(r); 37191 } 37192 37193 if (pin && (!pinReparent || !self.isActive)) { 37194 if (r) { 37195 _swapPinOut(pin, spacer, pinOriginalState); 37196 } else { 37197 _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState); 37198 } 37199 } 37200 37201 r || self.update(r); 37202 _refreshing = prevRefreshing; 37203 self.isReverted = r; 37204 } 37205 }; 37206 37207 self.refresh = function (soft, force, position, pinOffset) { 37208 if ((_refreshing || !self.enabled) && !force) { 37209 return; 37210 } 37211 37212 if (pin && soft && _lastScrollTime) { 37213 _addListener$1(ScrollTrigger, "scrollEnd", _softRefresh); 37214 37215 return; 37216 } 37217 37218 !_refreshingAll && onRefreshInit && onRefreshInit(self); 37219 _refreshing = self; 37220 37221 if (tweenTo.tween && !position) { 37222 tweenTo.tween.kill(); 37223 tweenTo.tween = 0; 37224 } 37225 37226 scrubTween && scrubTween.pause(); 37227 invalidateOnRefresh && animation && animation.revert({ 37228 kill: false 37229 }).invalidate(); 37230 self.isReverted || self.revert(true, true); 37231 self._subPinOffset = false; 37232 37233 var size = getScrollerSize(), 37234 scrollerBounds = getScrollerOffsets(), 37235 max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction), 37236 isFirstRefresh = change <= 0.01, 37237 offset = 0, 37238 otherPinOffset = pinOffset || 0, 37239 parsedEnd = _isObject(position) ? position.end : vars.end, 37240 parsedEndTrigger = vars.endTrigger || trigger, 37241 parsedStart = _isObject(position) ? position.start : vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"), 37242 pinnedContainer = self.pinnedContainer = vars.pinnedContainer && _getTarget(vars.pinnedContainer, self), 37243 triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0, 37244 i = triggerIndex, 37245 cs, 37246 bounds, 37247 scroll, 37248 isVertical, 37249 override, 37250 curTrigger, 37251 curPin, 37252 oppositeScroll, 37253 initted, 37254 revertedPins, 37255 forcedOverflow, 37256 markerStartOffset, 37257 markerEndOffset; 37258 37259 if (markers && _isObject(position)) { 37260 markerStartOffset = gsap$1.getProperty(markerStartTrigger, direction.p); 37261 markerEndOffset = gsap$1.getProperty(markerEndTrigger, direction.p); 37262 } 37263 37264 while (i--) {
vendor: 4,360 bytes, lines 37265-37376
37265 curTrigger = _triggers[i]; 37266 curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = self); 37267 curPin = curTrigger.pin; 37268 37269 if (curPin && (curPin === trigger || curPin === pin || curPin === pinnedContainer) && !curTrigger.isReverted) { 37270 revertedPins || (revertedPins = []); 37271 revertedPins.unshift(curTrigger); 37272 curTrigger.revert(true, true); 37273 } 37274 37275 if (curTrigger !== _triggers[i]) { 37276 triggerIndex--; 37277 i--; 37278 } 37279 } 37280 37281 _isFunction(parsedStart) && (parsedStart = parsedStart(self)); 37282 parsedStart = _parseClamp(parsedStart, "start", self); 37283 start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation, self._startClamp && "_startClamp") || (pin ? -0.001 : 0); 37284 _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self)); 37285 37286 if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) { 37287 if (~parsedEnd.indexOf(" ")) { 37288 parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd; 37289 } else { 37290 offset = _offsetToPx(parsedEnd.substr(2), size); 37291 parsedEnd = _isString(parsedStart) ? parsedStart : (containerAnimation ? gsap$1.utils.mapRange(0, containerAnimation.duration(), containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, start) : start) + offset; 37292 parsedEndTrigger = trigger; 37293 } 37294 } 37295 37296 parsedEnd = _parseClamp(parsedEnd, "end", self); 37297 end = Math.max(start, _parsePosition(parsedEnd || (parsedEndTrigger ? "100% 0" : max), parsedEndTrigger, size, direction, scrollFunc() + offset, markerEnd, markerEndTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation, self._endClamp && "_endClamp")) || -0.001; 37298 offset = 0; 37299 i = triggerIndex; 37300 37301 while (i--) { 37302 curTrigger = _triggers[i]; 37303 curPin = curTrigger.pin; 37304 37305 if (curPin && curTrigger.start - curTrigger._pinPush <= start && !containerAnimation && curTrigger.end > 0) { 37306 cs = curTrigger.end - (self._startClamp ? Math.max(0, curTrigger.start) : curTrigger.start); 37307 37308 if ((curPin === trigger && curTrigger.start - curTrigger._pinPush < start || curPin === pinnedContainer) && isNaN(parsedStart)) { 37309 offset += cs * (1 - curTrigger.progress); 37310 } 37311 37312 curPin === pin && (otherPinOffset += cs); 37313 } 37314 } 37315 37316 start += offset; 37317 end += offset; 37318 self._startClamp && (self._startClamp += offset); 37319 37320 if (self._endClamp && !_refreshingAll) { 37321 self._endClamp = end || -0.001; 37322 end = Math.min(end, _maxScroll(scroller, direction)); 37323 } 37324 37325 change = end - start || (start -= 0.01) && 0.001; 37326 37327 if (isFirstRefresh) { 37328 prevProgress = gsap$1.utils.clamp(0, 1, gsap$1.utils.normalize(start, end, prevScroll)); 37329 } 37330 37331 self._pinPush = otherPinOffset; 37332 37333 if (markerStart && offset) { 37334 cs = {}; 37335 cs[direction.a] = "+=" + offset; 37336 pinnedContainer && (cs[direction.p] = "-=" + scrollFunc()); 37337 gsap$1.set([markerStart, markerEnd], cs); 37338 } 37339 37340 if (pin && !(_clampingMax && self.end >= _maxScroll(scroller, direction))) { 37341 cs = _getComputedStyle(pin); 37342 isVertical = direction === _vertical; 37343 scroll = scrollFunc(); 37344 pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset; 37345 37346 if (!max && end > 1) { 37347 forcedOverflow = (isViewport ? _doc$1.scrollingElement || _docEl$1 : scroller).style; 37348 forcedOverflow = { 37349 style: forcedOverflow, 37350 value: forcedOverflow["overflow" + direction.a.toUpperCase()] 37351 }; 37352 37353 if (isViewport && _getComputedStyle(_body$1)["overflow" + direction.a.toUpperCase()] !== "scroll") { 37354 forcedOverflow.style["overflow" + direction.a.toUpperCase()] = "scroll"; 37355 } 37356 } 37357 37358 _swapPinIn(pin, spacer, cs); 37359 37360 pinState = _getState(pin); 37361 bounds = _getBounds(pin, true); 37362 oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)(); 37363 37364 if (pinSpacing) { 37365 spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px]; 37366 spacerState.t = spacer; 37367 i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0; 37368 37369 if (i) { 37370 spacerState.push(direction.d, i + _px); 37371 spacer.style.flexBasis !== "auto" && (spacer.style.flexBasis = i + _px); 37372 } 37373 37374 _setState(spacerState); 37375 37376 if (pinnedContainer) {
vendor: 9,034 bytes, lines 37377-37619
37377 _triggers.forEach(function (t) { 37378 if (t.pin === pinnedContainer && t.vars.pinSpacing !== false) { 37379 t._subPinOffset = true; 37380 } 37381 }); 37382 } 37383 37384 useFixedPosition && scrollFunc(prevScroll); 37385 } else { 37386 i = _getSize(pin, direction); 37387 i && spacer.style.flexBasis !== "auto" && (spacer.style.flexBasis = i + _px); 37388 } 37389 37390 if (useFixedPosition) { 37391 override = { 37392 top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px, 37393 left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px, 37394 boxSizing: "border-box", 37395 position: "fixed" 37396 }; 37397 override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px; 37398 override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px; 37399 override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0"; 37400 override[_padding] = cs[_padding]; 37401 override[_padding + _Top] = cs[_padding + _Top]; 37402 override[_padding + _Right] = cs[_padding + _Right]; 37403 override[_padding + _Bottom] = cs[_padding + _Bottom]; 37404 override[_padding + _Left] = cs[_padding + _Left]; 37405 pinActiveState = _copyState(pinOriginalState, override, pinReparent); 37406 _refreshingAll && scrollFunc(0); 37407 } 37408 37409 if (animation) { 37410 initted = animation._initted; 37411 37412 _suppressOverwrites(1); 37413 37414 animation.render(animation.duration(), true, true); 37415 pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset; 37416 pinMoves = Math.abs(change - pinChange) > 1; 37417 useFixedPosition && pinMoves && pinActiveState.splice(pinActiveState.length - 2, 2); 37418 animation.render(0, true, true); 37419 initted || animation.invalidate(true); 37420 animation.parent || animation.totalTime(animation.totalTime()); 37421 37422 _suppressOverwrites(0); 37423 } else { 37424 pinChange = change; 37425 } 37426 37427 forcedOverflow && (forcedOverflow.value ? forcedOverflow.style["overflow" + direction.a.toUpperCase()] = forcedOverflow.value : forcedOverflow.style.removeProperty("overflow-" + direction.a)); 37428 } else if (trigger && scrollFunc() && !containerAnimation) { 37429 bounds = trigger.parentNode; 37430 37431 while (bounds && bounds !== _body$1) { 37432 if (bounds._pinOffset) { 37433 start -= bounds._pinOffset; 37434 end -= bounds._pinOffset; 37435 } 37436 37437 bounds = bounds.parentNode; 37438 } 37439 } 37440 37441 revertedPins && revertedPins.forEach(function (t) { 37442 return t.revert(false, true); 37443 }); 37444 self.start = start; 37445 self.end = end; 37446 scroll1 = scroll2 = _refreshingAll ? prevScroll : scrollFunc(); 37447 37448 if (!containerAnimation && !_refreshingAll) { 37449 scroll1 < prevScroll && scrollFunc(prevScroll); 37450 self.scroll.rec = 0; 37451 } 37452 37453 self.revert(false, true); 37454 lastRefresh = _getTime$1(); 37455 37456 if (snapDelayedCall) { 37457 lastSnap = -1; 37458 snapDelayedCall.restart(true); 37459 } 37460 37461 _refreshing = 0; 37462 animation && isToggle && (animation._initted || prevAnimProgress) && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress || 0, true).render(animation.time(), true, true); 37463 37464 if (isFirstRefresh || prevProgress !== self.progress || containerAnimation || invalidateOnRefresh) { 37465 animation && !isToggle && animation.totalProgress(containerAnimation && start < -0.001 && !prevProgress ? gsap$1.utils.normalize(start, end, 0) : prevProgress, true); 37466 self.progress = isFirstRefresh || (scroll1 - start) / change === prevProgress ? 0 : prevProgress; 37467 } 37468 37469 pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange)); 37470 scrubTween && scrubTween.invalidate(); 37471 37472 if (!isNaN(markerStartOffset)) { 37473 markerStartOffset -= gsap$1.getProperty(markerStartTrigger, direction.p); 37474 markerEndOffset -= gsap$1.getProperty(markerEndTrigger, direction.p); 37475 37476 _shiftMarker(markerStartTrigger, direction, markerStartOffset); 37477 37478 _shiftMarker(markerStart, direction, markerStartOffset - (pinOffset || 0)); 37479 37480 _shiftMarker(markerEndTrigger, direction, markerEndOffset); 37481 37482 _shiftMarker(markerEnd, direction, markerEndOffset - (pinOffset || 0)); 37483 } 37484 37485 isFirstRefresh && !_refreshingAll && self.update(); 37486 37487 if (onRefresh && !_refreshingAll && !executingOnRefresh) { 37488 executingOnRefresh = true; 37489 onRefresh(self); 37490 executingOnRefresh = false; 37491 } 37492 }; 37493 37494 self.getVelocity = function () { 37495 return (scrollFunc() - scroll2) / (_getTime$1() - _time2) * 1000 || 0; 37496 }; 37497 37498 self.endAnimation = function () { 37499 _endAnimation(self.callbackAnimation); 37500 37501 if (animation) { 37502 scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1); 37503 } 37504 }; 37505 37506 self.labelToScroll = function (label) { 37507 return animation && animation.labels && (start || self.refresh() || start) + animation.labels[label] / animation.duration() * change || 0; 37508 }; 37509 37510 self.getTrailing = function (name) { 37511 var i = _triggers.indexOf(self), 37512 a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1); 37513 37514 return (_isString(name) ? a.filter(function (t) { 37515 return t.vars.preventOverlaps === name; 37516 }) : a).filter(function (t) { 37517 return self.direction > 0 ? t.end <= start : t.start >= end; 37518 }); 37519 }; 37520 37521 self.update = function (reset, recordVelocity, forceFake) { 37522 if (containerAnimation && !forceFake && !reset) { 37523 return; 37524 } 37525 37526 var scroll = _refreshingAll === true ? prevScroll : self.scroll(), 37527 p = reset ? 0 : (scroll - start) / change, 37528 clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0, 37529 prevProgress = self.progress, 37530 isActive, 37531 wasActive, 37532 toggleState, 37533 action, 37534 stateChanged, 37535 toggled, 37536 isAtMax, 37537 isTakingAction; 37538 37539 if (recordVelocity) { 37540 scroll2 = scroll1; 37541 scroll1 = containerAnimation ? scrollFunc() : scroll; 37542 37543 if (snap) { 37544 snap2 = snap1; 37545 snap1 = animation && !isToggle ? animation.totalProgress() : clipped; 37546 } 37547 } 37548 37549 if (anticipatePin && pin && !_refreshing && !_startup$1 && _lastScrollTime) { 37550 if (!clipped && start < scroll + (scroll - scroll2) / (_getTime$1() - _time2) * anticipatePin) { 37551 clipped = 0.0001; 37552 } else if (clipped === 1 && end > scroll + (scroll - scroll2) / (_getTime$1() - _time2) * anticipatePin) { 37553 clipped = 0.9999; 37554 } 37555 } 37556 37557 if (clipped !== prevProgress && self.enabled) { 37558 isActive = self.isActive = !!clipped && clipped < 1; 37559 wasActive = !!prevProgress && prevProgress < 1; 37560 toggled = isActive !== wasActive; 37561 stateChanged = toggled || !!clipped !== !!prevProgress; 37562 self.direction = clipped > prevProgress ? 1 : -1; 37563 self.progress = clipped; 37564 37565 if (stateChanged && !_refreshing) { 37566 toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3; 37567 37568 if (isToggle) { 37569 action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState]; 37570 isTakingAction = animation && (action === "complete" || action === "reset" || action in animation); 37571 } 37572 } 37573 37574 preventOverlaps && (toggled || isTakingAction) && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) { 37575 return t.endAnimation(); 37576 })); 37577 37578 if (!isToggle) { 37579 if (scrubTween && !_refreshing && !_startup$1) { 37580 scrubTween._dp._time - scrubTween._start !== scrubTween._time && scrubTween.render(scrubTween._dp._time - scrubTween._start); 37581 37582 if (scrubTween.resetTo) { 37583 scrubTween.resetTo("totalProgress", clipped, animation._tTime / animation._tDur); 37584 } else { 37585 scrubTween.vars.totalProgress = clipped; 37586 scrubTween.invalidate().restart(); 37587 } 37588 } else if (animation) { 37589 animation.totalProgress(clipped, !!(_refreshing && (lastRefresh || reset))); 37590 } 37591 } 37592 37593 if (pin) { 37594 reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart); 37595 37596 if (!useFixedPosition) { 37597 pinSetter(_round(pinStart + pinChange * clipped)); 37598 } else if (stateChanged) { 37599 isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction); 37600 37601 if (pinReparent) { 37602 if (!reset && (isActive || isAtMax)) { 37603 var bounds = _getBounds(pin, true), 37604 _offset = scroll - start; 37605 37606 _reparent(pin, _body$1, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px); 37607 } else { 37608 _reparent(pin, spacer); 37609 } 37610 } 37611 37612 _setState(isActive || isAtMax ? pinActiveState : pinState); 37613 37614 pinMoves && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0)); 37615 } 37616 } 37617 37618 snap && !tweenTo.tween && !_refreshing && !_startup$1 && snapDelayedCall.restart(true); 37619 toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEac
vendor: 4,284 bytes, lines 37619-37760
37619h(function (el) { 37620 return el.classList[isActive || once ? "add" : "remove"](toggleClass.className); 37621 }); 37622 onUpdate && !isToggle && !reset && onUpdate(self); 37623 37624 if (stateChanged && !_refreshing) { 37625 if (isToggle) { 37626 if (isTakingAction) { 37627 if (action === "complete") { 37628 animation.pause().totalProgress(1); 37629 } else if (action === "reset") { 37630 animation.restart(true).pause(); 37631 } else if (action === "restart") { 37632 animation.restart(true); 37633 } else { 37634 animation[action](); 37635 } 37636 } 37637 37638 onUpdate && onUpdate(self); 37639 } 37640 37641 if (toggled || !_limitCallbacks) { 37642 onToggle && toggled && _callback(self, onToggle); 37643 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 37644 once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); 37645 37646 if (!toggled) { 37647 toggleState = clipped === 1 ? 1 : 3; 37648 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 37649 } 37650 } 37651 37652 if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) { 37653 _endAnimation(self.callbackAnimation); 37654 37655 scrubTween ? scrubTween.progress(1) : _endAnimation(animation, action === "reverse" ? 1 : !clipped, 1); 37656 } 37657 } else if (isToggle && onUpdate && !_refreshing) { 37658 onUpdate(self); 37659 } 37660 } 37661 37662 if (markerEndSetter) { 37663 var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll; 37664 markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0)); 37665 markerEndSetter(n); 37666 } 37667 37668 caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0)); 37669 }; 37670 37671 self.enable = function (reset, refresh) { 37672 if (!self.enabled) { 37673 self.enabled = true; 37674 37675 _addListener$1(scroller, "resize", _onResize); 37676 37677 isViewport || _addListener$1(scroller, "scroll", _onScroll$1); 37678 onRefreshInit && _addListener$1(ScrollTrigger, "refreshInit", onRefreshInit); 37679 37680 if (reset !== false) { 37681 self.progress = prevProgress = 0; 37682 scroll1 = scroll2 = lastSnap = scrollFunc(); 37683 } 37684 37685 refresh !== false && self.refresh(); 37686 } 37687 }; 37688 37689 self.getTween = function (snap) { 37690 return snap && tweenTo ? tweenTo.tween : scrubTween; 37691 }; 37692 37693 self.setPositions = function (newStart, newEnd, keepClamp, pinOffset) { 37694 if (containerAnimation) { 37695 var st = containerAnimation.scrollTrigger, 37696 duration = containerAnimation.duration(), 37697 _change = st.end - st.start; 37698 37699 newStart = st.start + _change * newStart / duration; 37700 newEnd = st.start + _change * newEnd / duration; 37701 } 37702 37703 self.refresh(false, false, { 37704 start: _keepClamp(newStart, keepClamp && !!self._startClamp), 37705 end: _keepClamp(newEnd, keepClamp && !!self._endClamp) 37706 }, pinOffset); 37707 self.update(); 37708 }; 37709 37710 self.adjustPinSpacing = function (amount) { 37711 if (spacerState && amount) { 37712 var i = spacerState.indexOf(direction.d) + 1; 37713 spacerState[i] = parseFloat(spacerState[i]) + amount + _px; 37714 spacerState[1] = parseFloat(spacerState[1]) + amount + _px; 37715 37716 _setState(spacerState); 37717 } 37718 }; 37719 37720 self.disable = function (reset, allowAnimation) { 37721 if (self.enabled) { 37722 reset !== false && self.revert(true, true); 37723 self.enabled = self.isActive = false; 37724 allowAnimation || scrubTween && scrubTween.pause(); 37725 prevScroll = 0; 37726 pinCache && (pinCache.uncache = 1); 37727 onRefreshInit && _removeListener$1(ScrollTrigger, "refreshInit", onRefreshInit); 37728 37729 if (snapDelayedCall) { 37730 snapDelayedCall.pause(); 37731 tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0); 37732 } 37733 37734 if (!isViewport) { 37735 var i = _triggers.length; 37736 37737 while (i--) { 37738 if (_triggers[i].scroller === scroller && _triggers[i] !== self) { 37739 return; 37740 } 37741 } 37742 37743 _removeListener$1(scroller, "resize", _onResize); 37744 37745 isViewport || _removeListener$1(scroller, "scroll", _onScroll$1); 37746 } 37747 } 37748 }; 37749 37750 self.kill = function (revert, allowAnimation) { 37751 self.disable(revert, allowAnimation); 37752 scrubTween && !allowAnimation && scrubTween.kill(); 37753 id && delete _ids[id]; 37754 37755 var i = _triggers.indexOf(self); 37756 37757 i >= 0 && _triggers.splice(i, 1); 37758 i === _i && _direction > 0 && _i--; 37759 i = 0; 37760
vendor: 15,520 bytes, lines 37761-38267
37761 _triggers.forEach(function (t) { 37762 return t.scroller === self.scroller && (i = 1); 37763 }); 37764 37765 i || _refreshingAll || (self.scroll.rec = 0); 37766 37767 if (animation) { 37768 animation.scrollTrigger = null; 37769 revert && animation.revert({ 37770 kill: false 37771 }); 37772 allowAnimation || animation.kill(); 37773 } 37774 37775 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 37776 return m.parentNode && m.parentNode.removeChild(m); 37777 }); 37778 _primary === self && (_primary = 0); 37779 37780 if (pin) { 37781 pinCache && (pinCache.uncache = 1); 37782 i = 0; 37783 37784 _triggers.forEach(function (t) { 37785 return t.pin === pin && i++; 37786 }); 37787 37788 i || (pinCache.spacer = 0); 37789 } 37790 37791 vars.onKill && vars.onKill(self); 37792 }; 37793 37794 _triggers.push(self); 37795 37796 self.enable(false, false); 37797 customRevertReturn && customRevertReturn(self); 37798 37799 if (animation && animation.add && !change) { 37800 var updateFunc = self.update; 37801 37802 self.update = function () { 37803 self.update = updateFunc; 37804 start || end || self.refresh(); 37805 }; 37806 37807 gsap$1.delayedCall(0.01, self.update); 37808 change = 0.01; 37809 start = end = 0; 37810 } else { 37811 self.refresh(); 37812 } 37813 37814 pin && _queueRefreshAll(); 37815 }; 37816 37817 ScrollTrigger.register = function register(core) { 37818 if (!_coreInitted$1) { 37819 gsap$1 = core || _getGSAP$1(); 37820 _windowExists() && window.document && ScrollTrigger.enable(); 37821 _coreInitted$1 = _enabled; 37822 } 37823 37824 return _coreInitted$1; 37825 }; 37826 37827 ScrollTrigger.defaults = function defaults(config) { 37828 if (config) { 37829 for (var p in config) { 37830 _defaults[p] = config[p]; 37831 } 37832 } 37833 37834 return _defaults; 37835 }; 37836 37837 ScrollTrigger.disable = function disable(reset, kill) { 37838 _enabled = 0; 37839 37840 _triggers.forEach(function (trigger) { 37841 return trigger[kill ? "kill" : "disable"](reset); 37842 }); 37843 37844 _removeListener$1(_win$1, "wheel", _onScroll$1); 37845 37846 _removeListener$1(_doc$1, "scroll", _onScroll$1); 37847 37848 clearInterval(_syncInterval); 37849 37850 _removeListener$1(_doc$1, "touchcancel", _passThrough); 37851 37852 _removeListener$1(_body$1, "touchstart", _passThrough); 37853 37854 _multiListener(_removeListener$1, _doc$1, "pointerdown,touchstart,mousedown", _pointerDownHandler); 37855 37856 _multiListener(_removeListener$1, _doc$1, "pointerup,touchend,mouseup", _pointerUpHandler); 37857 37858 _resizeDelay.kill(); 37859 37860 _iterateAutoRefresh(_removeListener$1); 37861 37862 for (var i = 0; i < _scrollers.length; i += 3) { 37863 _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 1]); 37864 37865 _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 2]); 37866 } 37867 }; 37868 37869 ScrollTrigger.enable = function enable() { 37870 _win$1 = window; 37871 _doc$1 = document; 37872 _docEl$1 = _doc$1.documentElement; 37873 _body$1 = _doc$1.body; 37874 37875 if (gsap$1) { 37876 _toArray = gsap$1.utils.toArray; 37877 _clamp$1 = gsap$1.utils.clamp; 37878 _context$1 = gsap$1.core.context || _passThrough; 37879 _suppressOverwrites = gsap$1.core.suppressOverwrites || _passThrough; 37880 _scrollRestoration = _win$1.history.scrollRestoration || "auto"; 37881 _lastScroll = _win$1.pageYOffset; 37882 gsap$1.core.globals("ScrollTrigger", ScrollTrigger); 37883 37884 if (_body$1) { 37885 _enabled = 1; 37886 _div100vh = document.createElement("div"); 37887 _div100vh.style.height = "100vh"; 37888 _div100vh.style.position = "absolute"; 37889 37890 _refresh100vh(); 37891 37892 _rafBugFix(); 37893 37894 Observer.register(gsap$1); 37895 ScrollTrigger.isTouch = Observer.isTouch; 37896 _fixIOSBug = Observer.isTouch && /(iPad|iPhone|iPod|Mac)/g.test(navigator.userAgent); 37897 _ignoreMobileResize = Observer.isTouch === 1; 37898 37899 _addListener$1(_win$1, "wheel", _onScroll$1); 37900 37901 _root$1 = [_win$1, _doc$1, _docEl$1, _body$1]; 37902 37903 if (gsap$1.matchMedia) { 37904 ScrollTrigger.matchMedia = function (vars) { 37905 var mm = gsap$1.matchMedia(), 37906 p; 37907 37908 for (p in vars) { 37909 mm.add(p, vars[p]); 37910 } 37911 37912 return mm; 37913 }; 37914 37915 gsap$1.addEventListener("matchMediaInit", function () { 37916 return _revertAll(); 37917 }); 37918 gsap$1.addEventListener("matchMediaRevert", function () { 37919 return _revertRecorded(); 37920 }); 37921 gsap$1.addEventListener("matchMedia", function () { 37922 _refreshAll(0, 1); 37923 37924 _dispatch("matchMedia"); 37925 }); 37926 gsap$1.matchMedia("(orientation: portrait)", function () { 37927 _setBaseDimensions(); 37928 37929 return _setBaseDimensions; 37930 }); 37931 } else { 37932 console.warn("Requires GSAP 3.11.0 or later"); 37933 } 37934 37935 _setBaseDimensions(); 37936 37937 _addListener$1(_doc$1, "scroll", _onScroll$1); 37938 37939 var bodyStyle = _body$1.style, 37940 border = bodyStyle.borderTopStyle, 37941 AnimationProto = gsap$1.core.Animation.prototype, 37942 bounds, 37943 i; 37944 AnimationProto.revert || Object.defineProperty(AnimationProto, "revert", { 37945 value: function value() { 37946 return this.time(-0.01, true); 37947 } 37948 }); 37949 bodyStyle.borderTopStyle = "solid"; 37950 bounds = _getBounds(_body$1); 37951 _vertical.m = Math.round(bounds.top + _vertical.sc()) || 0; 37952 _horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0; 37953 border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style"); 37954 _syncInterval = setInterval(_sync, 250); 37955 gsap$1.delayedCall(0.5, function () { 37956 return _startup$1 = 0; 37957 }); 37958 37959 _addListener$1(_doc$1, "touchcancel", _passThrough); 37960 37961 _addListener$1(_body$1, "touchstart", _passThrough); 37962 37963 _multiListener(_addListener$1, _doc$1, "pointerdown,touchstart,mousedown", _pointerDownHandler); 37964 37965 _multiListener(_addListener$1, _doc$1, "pointerup,touchend,mouseup", _pointerUpHandler); 37966 37967 _transformProp = gsap$1.utils.checkPrefix("transform"); 37968 37969 _stateProps.push(_transformProp); 37970 37971 _coreInitted$1 = _getTime$1(); 37972 _resizeDelay = gsap$1.delayedCall(0.2, _refreshAll).pause(); 37973 _autoRefresh = [_doc$1, "visibilitychange", function () { 37974 var w = _win$1.innerWidth, 37975 h = _win$1.innerHeight; 37976 37977 if (_doc$1.hidden) { 37978 _prevWidth = w; 37979 _prevHeight = h; 37980 } else if (_prevWidth !== w || _prevHeight !== h) { 37981 _onResize(); 37982 } 37983 }, _doc$1, "DOMContentLoaded", _refreshAll, _win$1, "load", _refreshAll, _win$1, "resize", _onResize]; 37984 37985 _iterateAutoRefresh(_addListener$1); 37986 37987 _triggers.forEach(function (trigger) { 37988 return trigger.enable(0, 1); 37989 }); 37990 37991 for (i = 0; i < _scrollers.length; i += 3) { 37992 _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 1]); 37993 37994 _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 2]); 37995 } 37996 } 37997 } 37998 }; 37999 38000 ScrollTrigger.config = function config(vars) { 38001 "limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks); 38002 var ms = vars.syncInterval; 38003 ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms); 38004 "ignoreMobileResize" in vars && (_ignoreMobileResize = ScrollTrigger.isTouch === 1 && vars.ignoreMobileResize); 38005 38006 if ("autoRefreshEvents" in vars) { 38007 _iterateAutoRefresh(_removeListener$1) || _iterateAutoRefresh(_addListener$1, vars.autoRefreshEvents || "none"); 38008 _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1; 38009 } 38010 }; 38011 38012 ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) { 38013 var t = _getTarget(target), 38014 i = _scrollers.indexOf(t), 38015 isViewport = _isViewport$1(t); 38016 38017 if (~i) { 38018 _scrollers.splice(i, isViewport ? 6 : 2); 38019 } 38020 38021 if (vars) { 38022 isViewport ? _proxies.unshift(_win$1, vars, _body$1, vars, _docEl$1, vars) : _proxies.unshift(t, vars); 38023 } 38024 }; 38025 38026 ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) { 38027 _triggers.forEach(function (t) { 38028 return t._ctx && t._ctx.query === query && t._ctx.kill(true, true); 38029 }); 38030 }; 38031 38032 ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) { 38033 var bounds = (_isString(element) ? _getTarget(element) : element).getBoundingClientRect(), 38034 offset = bounds[horizontal ? _width : _height] * ratio || 0; 38035 return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win$1.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win$1.innerHeight; 38036 }; 38037 38038 ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) { 38039 _isString(element) && (element = _getTarget(element)); 38040 var bounds = element.getBoundingClientRect(), 38041 size = bounds[horizontal ? _width : _height], 38042 offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0; 38043 return horizontal ? (bounds.left + offset) / _win$1.innerWidth : (bounds.top + offset) / _win$1.innerHeight; 38044 }; 38045 38046 ScrollTrigger.killAll = function killAll(allowListeners) { 38047 _triggers.slice(0).forEach(function (t) { 38048 return t.vars.id !== "ScrollSmoother" && t.kill(); 38049 }); 38050 38051 if (allowListeners !== true) { 38052 var listeners = _listeners.killAll || []; 38053 _listeners = {}; 38054 listeners.forEach(function (f) { 38055 return f(); 38056 }); 38057 } 38058 }; 38059 38060 return ScrollTrigger; 38061 }(); 38062 ScrollTrigger$1.version = "3.12.5"; 38063 38064 ScrollTrigger$1.saveStyles = function (targets) { 38065 return targets ? _toArray(targets).forEach(function (target) { 38066 if (target && target.style) { 38067 var i = _savedStyles.indexOf(target); 38068 38069 i >= 0 && _savedStyles.splice(i, 5); 38070 38071 _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap$1.core.getCache(target), _context$1()); 38072 } 38073 }) : _savedStyles; 38074 }; 38075 38076 ScrollTrigger$1.revert = function (soft, media) { 38077 return _revertAll(!soft, media); 38078 }; 38079 38080 ScrollTrigger$1.create = function (vars, animation) { 38081 return new ScrollTrigger$1(vars, animation); 38082 }; 38083 38084 ScrollTrigger$1.refresh = function (safe) { 38085 return safe ? _onResize() : (_coreInitted$1 || ScrollTrigger$1.register()) && _refreshAll(true); 38086 }; 38087 38088 ScrollTrigger$1.update = function (force) { 38089 return ++_scrollers.cache && _updateAll(force === true ? 2 : 0); 38090 }; 38091 38092 ScrollTrigger$1.clearScrollMemory = _clearScrollMemory; 38093 38094 ScrollTrigger$1.maxScroll = function (element, horizontal) { 38095 return _maxScroll(element, horizontal ? _horizontal : _vertical); 38096 }; 38097 38098 ScrollTrigger$1.getScrollFunc = function (element, horizontal) { 38099 return _getScrollFunc(_getTarget(element), horizontal ? _horizontal : _vertical); 38100 }; 38101 38102 ScrollTrigger$1.getById = function (id) { 38103 return _ids[id]; 38104 }; 38105 38106 ScrollTrigger$1.getAll = function () { 38107 return _triggers.filter(function (t) { 38108 return t.vars.id !== "ScrollSmoother"; 38109 }); 38110 }; 38111 38112 ScrollTrigger$1.isScrolling = function () { 38113 return !!_lastScrollTime; 38114 }; 38115 38116 ScrollTrigger$1.snapDirectional = _snapDirectional; 38117 38118 ScrollTrigger$1.addEventListener = function (type, callback) { 38119 var a = _listeners[type] || (_listeners[type] = []); 38120 ~a.indexOf(callback) || a.push(callback); 38121 }; 38122 38123 ScrollTrigger$1.removeEventListener = function (type, callback) { 38124 var a = _listeners[type], 38125 i = a && a.indexOf(callback); 38126 i >= 0 && a.splice(i, 1); 38127 }; 38128 38129 ScrollTrigger$1.batch = function (targets, vars) { 38130 var result = [], 38131 varsCopy = {}, 38132 interval = vars.interval || 0.016, 38133 batchMax = vars.batchMax || 1e9, 38134 proxyCallback = function proxyCallback(type, callback) { 38135 var elements = [], 38136 triggers = [], 38137 delay = gsap$1.delayedCall(interval, function () { 38138 callback(elements, triggers); 38139 elements = []; 38140 triggers = []; 38141 }).pause(); 38142 return function (self) { 38143 elements.length || delay.restart(true); 38144 elements.push(self.trigger); 38145 triggers.push(self); 38146 batchMax <= elements.length && delay.progress(1); 38147 }; 38148 }, 38149 p; 38150 38151 for (p in vars) { 38152 varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p]; 38153 } 38154 38155 if (_isFunction(batchMax)) { 38156 batchMax = batchMax(); 38157 38158 _addListener$1(ScrollTrigger$1, "refresh", function () { 38159 return batchMax = vars.batchMax(); 38160 }); 38161 } 38162 38163 _toArray(targets).forEach(function (target) { 38164 var config = {}; 38165 38166 for (p in varsCopy) { 38167 config[p] = varsCopy[p]; 38168 } 38169 38170 config.trigger = target; 38171 result.push(ScrollTrigger$1.create(config)); 38172 }); 38173 38174 return result; 38175 }; 38176 38177 var _clampScrollAndGetDurationMultiplier = function _clampScrollAndGetDurationMultiplier(scrollFunc, current, end, max) { 38178 current > max ? scrollFunc(max) : current < 0 && scrollFunc(0); 38179 return end > max ? (max - current) / (end - current) : end < 0 ? current / (current - end) : 1; 38180 }, 38181 _allowNativePanning = function _allowNativePanning(target, direction) { 38182 if (direction === true) { 38183 target.style.removeProperty("touch-action"); 38184 } else { 38185 target.style.touchAction = direction === true ? "auto" : direction ? "pan-" + direction + (Observer.isTouch ? " pinch-zoom" : "") : "none"; 38186 } 38187 38188 target === _docEl$1 && _allowNativePanning(_body$1, direction); 38189 }, 38190 _overflow = { 38191 auto: 1, 38192 scroll: 1 38193 }, 38194 _nestedScroll = function _nestedScroll(_ref5) { 38195 var event = _ref5.event, 38196 target = _ref5.target, 38197 axis = _ref5.axis; 38198 38199 var node = (event.changedTouches ? event.changedTouches[0] : event).target, 38200 cache = node._gsap || gsap$1.core.getCache(node), 38201 time = _getTime$1(), 38202 cs; 38203 38204 if (!cache._isScrollT || time - cache._isScrollT > 2000) { 38205 while (node && node !== _body$1 && (node.scrollHeight <= node.clientHeight && node.scrollWidth <= node.clientWidth || !(_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]))) { 38206 node = node.parentNode; 38207 } 38208 38209 cache._isScroll = node && node !== target && !_isViewport$1(node) && (_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]); 38210 cache._isScrollT = time; 38211 } 38212 38213 if (cache._isScroll || axis === "x") { 38214 event.stopPropagation(); 38215 event._gsapAllow = true; 38216 } 38217 }, 38218 _inputObserver = function _inputObserver(target, type, inputs, nested) { 38219 return Observer.create({ 38220 target: target, 38221 capture: true, 38222 debounce: false, 38223 lockAxis: true, 38224 type: type, 38225 onWheel: nested = nested && _nestedScroll, 38226 onPress: nested, 38227 onDrag: nested, 38228 onScroll: nested, 38229 onEnable: function onEnable() { 38230 return inputs && _addListener$1(_doc$1, Observer.eventTypes[0], _captureInputs, false, true); 38231 }, 38232 onDisable: function onDisable() { 38233 return _removeListener$1(_doc$1, Observer.eventTypes[0], _captureInputs, true); 38234 } 38235 }); 38236 }, 38237 _inputExp = /(input|label|select|textarea)/i, 38238 _inputIsFocused, 38239 _captureInputs = function _captureInputs(e) { 38240 var isInput = _inputExp.test(e.target.tagName); 38241 38242 if (isInput || _inputIsFocused) { 38243 e._gsapAllow = true; 38244 _inputIsFocused = isInput; 38245 } 38246 }, 38247 _getScrollNormalizer = function _getScrollNormalizer(vars) { 38248 _isObject(vars) || (vars = {}); 38249 vars.preventDefault = vars.isNormalizer = vars.allowClicks = true; 38250 vars.type || (vars.type = "wheel,touch"); 38251 vars.debounce = !!vars.debounce; 38252 vars.id = vars.id || "normalizer"; 38253 38254 var _vars2 = vars, 38255 normalizeScrollX = _vars2.normalizeScrollX, 38256 momentum = _vars2.momentum, 38257 allowNestedScroll = _vars2.allowNestedScroll, 38258 onRelease = _vars2.onRelease, 38259 self, 38260 maxY, 38261 target = _getTarget(vars.target) || _docEl$1, 38262 smoother = gsap$1.core.globals().ScrollSmoother, 38263 smootherInstance = smoother && smoother.get(), 38264 content = _fixIOSBug && (vars.content && _getTarget(vars.content) || smootherInstance && vars.content !== false && !smootherInstance.smooth() && smootherInstance.content()), 38265 scrollFuncY = _getScrollFunc(target, _vertical), 38266 scrollFuncX = _getScrollFunc(target, _horizontal), 38267 scale = 1,
vendor: 4,132 bytes, lines 38268-38389
38268 initialScale = (Observer.isTouch && _win$1.visualViewport ? _win$1.visualViewport.scale * _win$1.visualViewport.width : _win$1.outerWidth) / _win$1.innerWidth, 38269 wheelRefresh = 0, 38270 resolveMomentumDuration = _isFunction(momentum) ? function () { 38271 return momentum(self); 38272 } : function () { 38273 return momentum || 2.8; 38274 }, 38275 lastRefreshID, 38276 skipTouchMove, 38277 inputObserver = _inputObserver(target, vars.type, true, allowNestedScroll), 38278 resumeTouchMove = function resumeTouchMove() { 38279 return skipTouchMove = false; 38280 }, 38281 scrollClampX = _passThrough, 38282 scrollClampY = _passThrough, 38283 updateClamps = function updateClamps() { 38284 maxY = _maxScroll(target, _vertical); 38285 scrollClampY = _clamp$1(_fixIOSBug ? 1 : 0, maxY); 38286 normalizeScrollX && (scrollClampX = _clamp$1(0, _maxScroll(target, _horizontal))); 38287 lastRefreshID = _refreshID; 38288 }, 38289 removeContentOffset = function removeContentOffset() { 38290 content._gsap.y = _round(parseFloat(content._gsap.y) + scrollFuncY.offset) + "px"; 38291 content.style.transform = "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, " + parseFloat(content._gsap.y) + ", 0, 1)"; 38292 scrollFuncY.offset = scrollFuncY.cacheID = 0; 38293 }, 38294 ignoreDrag = function ignoreDrag() { 38295 if (skipTouchMove) { 38296 requestAnimationFrame(resumeTouchMove); 38297 38298 var offset = _round(self.deltaY / 2), 38299 scroll = scrollClampY(scrollFuncY.v - offset); 38300 38301 if (content && scroll !== scrollFuncY.v + scrollFuncY.offset) { 38302 scrollFuncY.offset = scroll - scrollFuncY.v; 38303 38304 var y = _round((parseFloat(content && content._gsap.y) || 0) - scrollFuncY.offset); 38305 38306 content.style.transform = "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, " + y + ", 0, 1)"; 38307 content._gsap.y = y + "px"; 38308 scrollFuncY.cacheID = _scrollers.cache; 38309 38310 _updateAll(); 38311 } 38312 38313 return true; 38314 } 38315 38316 scrollFuncY.offset && removeContentOffset(); 38317 skipTouchMove = true; 38318 }, 38319 tween, 38320 startScrollX, 38321 startScrollY, 38322 onStopDelayedCall, 38323 onResize = function onResize() { 38324 updateClamps(); 38325 38326 if (tween.isActive() && tween.vars.scrollY > maxY) { 38327 scrollFuncY() > maxY ? tween.progress(1) && scrollFuncY(maxY) : tween.resetTo("scrollY", maxY); 38328 } 38329 }; 38330 38331 content && gsap$1.set(content, { 38332 y: "+=0" 38333 }); 38334 38335 vars.ignoreCheck = function (e) { 38336 return _fixIOSBug && e.type === "touchmove" && ignoreDrag() || scale > 1.05 && e.type !== "touchstart" || self.isGesturing || e.touches && e.touches.length > 1; 38337 }; 38338 38339 vars.onPress = function () { 38340 skipTouchMove = false; 38341 var prevScale = scale; 38342 scale = _round((_win$1.visualViewport && _win$1.visualViewport.scale || 1) / initialScale); 38343 tween.pause(); 38344 prevScale !== scale && _allowNativePanning(target, scale > 1.01 ? true : normalizeScrollX ? false : "x"); 38345 startScrollX = scrollFuncX(); 38346 startScrollY = scrollFuncY(); 38347 updateClamps(); 38348 lastRefreshID = _refreshID; 38349 }; 38350 38351 vars.onRelease = vars.onGestureStart = function (self, wasDragging) { 38352 scrollFuncY.offset && removeContentOffset(); 38353 38354 if (!wasDragging) { 38355 onStopDelayedCall.restart(true); 38356 } else { 38357 _scrollers.cache++; 38358 var dur = resolveMomentumDuration(), 38359 currentScroll, 38360 endScroll; 38361 38362 if (normalizeScrollX) { 38363 currentScroll = scrollFuncX(); 38364 endScroll = currentScroll + dur * 0.05 * -self.velocityX / 0.227; 38365 dur *= _clampScrollAndGetDurationMultiplier(scrollFuncX, currentScroll, endScroll, _maxScroll(target, _horizontal)); 38366 tween.vars.scrollX = scrollClampX(endScroll); 38367 } 38368 38369 currentScroll = scrollFuncY(); 38370 endScroll = currentScroll + dur * 0.05 * -self.velocityY / 0.227; 38371 dur *= _clampScrollAndGetDurationMultiplier(scrollFuncY, currentScroll, endScroll, _maxScroll(target, _vertical)); 38372 tween.vars.scrollY = scrollClampY(endScroll); 38373 tween.invalidate().duration(dur).play(0.01); 38374 38375 if (_fixIOSBug && tween.vars.scrollY >= maxY || currentScroll >= maxY - 1) { 38376 gsap$1.to({}, { 38377 onUpdate: onResize, 38378 duration: dur 38379 }); 38380 } 38381 } 38382 38383 onRelease && onRelease(self); 38384 }; 38385 38386 vars.onWheel = function () { 38387 tween._ts && tween.pause(); 38388 38389 if (_getTime$1() - wheelRefresh > 1000) {
vendor: 28,617 bytes, lines 38390-39444
38390 lastRefreshID = 0; 38391 wheelRefresh = _getTime$1(); 38392 } 38393 }; 38394 38395 vars.onChange = function (self, dx, dy, xArray, yArray) { 38396 _refreshID !== lastRefreshID && updateClamps(); 38397 dx && normalizeScrollX && scrollFuncX(scrollClampX(xArray[2] === dx ? startScrollX + (self.startX - self.x) : scrollFuncX() + dx - xArray[1])); 38398 38399 if (dy) { 38400 scrollFuncY.offset && removeContentOffset(); 38401 var isTouch = yArray[2] === dy, 38402 y = isTouch ? startScrollY + self.startY - self.y : scrollFuncY() + dy - yArray[1], 38403 yClamped = scrollClampY(y); 38404 isTouch && y !== yClamped && (startScrollY += yClamped - y); 38405 scrollFuncY(yClamped); 38406 } 38407 38408 (dy || dx) && _updateAll(); 38409 }; 38410 38411 vars.onEnable = function () { 38412 _allowNativePanning(target, normalizeScrollX ? false : "x"); 38413 38414 ScrollTrigger$1.addEventListener("refresh", onResize); 38415 38416 _addListener$1(_win$1, "resize", onResize); 38417 38418 if (scrollFuncY.smooth) { 38419 scrollFuncY.target.style.scrollBehavior = "auto"; 38420 scrollFuncY.smooth = scrollFuncX.smooth = false; 38421 } 38422 38423 inputObserver.enable(); 38424 }; 38425 38426 vars.onDisable = function () { 38427 _allowNativePanning(target, true); 38428 38429 _removeListener$1(_win$1, "resize", onResize); 38430 38431 ScrollTrigger$1.removeEventListener("refresh", onResize); 38432 inputObserver.kill(); 38433 }; 38434 38435 vars.lockAxis = vars.lockAxis !== false; 38436 self = new Observer(vars); 38437 self.iOS = _fixIOSBug; 38438 _fixIOSBug && !scrollFuncY() && scrollFuncY(1); 38439 _fixIOSBug && gsap$1.ticker.add(_passThrough); 38440 onStopDelayedCall = self._dc; 38441 tween = gsap$1.to(self, { 38442 ease: "power4", 38443 paused: true, 38444 inherit: false, 38445 scrollX: normalizeScrollX ? "+=0.1" : "+=0", 38446 scrollY: "+=0.1", 38447 modifiers: { 38448 scrollY: _interruptionTracker(scrollFuncY, scrollFuncY(), function () { 38449 return tween.pause(); 38450 }) 38451 }, 38452 onUpdate: _updateAll, 38453 onComplete: onStopDelayedCall.vars.onComplete 38454 }); 38455 return self; 38456 }; 38457 38458 ScrollTrigger$1.sort = function (func) { 38459 return _triggers.sort(func || function (a, b) { 38460 return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6); 38461 }); 38462 }; 38463 38464 ScrollTrigger$1.observe = function (vars) { 38465 return new Observer(vars); 38466 }; 38467 38468 ScrollTrigger$1.normalizeScroll = function (vars) { 38469 if (typeof vars === "undefined") { 38470 return _normalizer$1; 38471 } 38472 38473 if (vars === true && _normalizer$1) { 38474 return _normalizer$1.enable(); 38475 } 38476 38477 if (vars === false) { 38478 _normalizer$1 && _normalizer$1.kill(); 38479 _normalizer$1 = vars; 38480 return; 38481 } 38482 38483 var normalizer = vars instanceof Observer ? vars : _getScrollNormalizer(vars); 38484 _normalizer$1 && _normalizer$1.target === normalizer.target && _normalizer$1.kill(); 38485 _isViewport$1(normalizer.target) && (_normalizer$1 = normalizer); 38486 return normalizer; 38487 }; 38488 38489 ScrollTrigger$1.core = { 38490 _getVelocityProp: _getVelocityProp, 38491 _inputObserver: _inputObserver, 38492 _scrollers: _scrollers, 38493 _proxies: _proxies, 38494 bridge: { 38495 ss: function ss() { 38496 _lastScrollTime || _dispatch("scrollStart"); 38497 _lastScrollTime = _getTime$1(); 38498 }, 38499 ref: function ref() { 38500 return _refreshing; 38501 } 38502 } 38503 }; 38504 _getGSAP$1() && gsap$1.registerPlugin(ScrollTrigger$1); 38505 38506 exports.ScrollTrigger = ScrollTrigger$1; 38507 exports.default = ScrollTrigger$1; 38508 38509 if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;} 38510 38511 }))); 38512 38513/*! 38514 * CustomEase 3.12.7 38515 * https://gsap.com 38516 * 38517 * @license Copyright 2025, GreenSock. All rights reserved. 38518 * Subject to the terms at https://gsap.com/standard-license or for Club GSAP members, the agreement issued with that membership. 38519 * @author: Jack Doyle, [email protected] 38520 */ 38521 38522 (function (global, factory) { 38523 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 38524 typeof define === 'function' && define.amd ? define(['exports'], factory) : 38525 (global = global || self, factory(global.window = global.window || {})); 38526}(this, (function (exports) { 'use strict'; 38527 38528 var _svgPathExp = /[achlmqstvz]|(-?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig, 38529 _scientific = /[\+\-]?\d*\.?\d+e[\+\-]?\d+/ig, 38530 _DEG2RAD = Math.PI / 180, 38531 _sin = Math.sin, 38532 _cos = Math.cos, 38533 _abs = Math.abs, 38534 _sqrt = Math.sqrt, 38535 _isNumber = function _isNumber(value) { 38536 return typeof value === "number"; 38537 }, 38538 _roundingNum = 1e5, 38539 _round = function _round(value) { 38540 return Math.round(value * _roundingNum) / _roundingNum || 0; 38541 }; 38542 function transformRawPath(rawPath, a, b, c, d, tx, ty) { 38543 var j = rawPath.length, 38544 segment, 38545 l, 38546 i, 38547 x, 38548 y; 38549 38550 while (--j > -1) { 38551 segment = rawPath[j]; 38552 l = segment.length; 38553 38554 for (i = 0; i < l; i += 2) { 38555 x = segment[i]; 38556 y = segment[i + 1]; 38557 segment[i] = x * a + y * c + tx; 38558 segment[i + 1] = x * b + y * d + ty; 38559 } 38560 } 38561 38562 rawPath._dirty = 1; 38563 return rawPath; 38564 } 38565 38566 function arcToSegment(lastX, lastY, rx, ry, angle, largeArcFlag, sweepFlag, x, y) { 38567 if (lastX === x && lastY === y) { 38568 return; 38569 } 38570 38571 rx = _abs(rx); 38572 ry = _abs(ry); 38573 38574 var angleRad = angle % 360 * _DEG2RAD, 38575 cosAngle = _cos(angleRad), 38576 sinAngle = _sin(angleRad), 38577 PI = Math.PI, 38578 TWOPI = PI * 2, 38579 dx2 = (lastX - x) / 2, 38580 dy2 = (lastY - y) / 2, 38581 x1 = cosAngle * dx2 + sinAngle * dy2, 38582 y1 = -sinAngle * dx2 + cosAngle * dy2, 38583 x1_sq = x1 * x1, 38584 y1_sq = y1 * y1, 38585 radiiCheck = x1_sq / (rx * rx) + y1_sq / (ry * ry); 38586 38587 if (radiiCheck > 1) { 38588 rx = _sqrt(radiiCheck) * rx; 38589 ry = _sqrt(radiiCheck) * ry; 38590 } 38591 38592 var rx_sq = rx * rx, 38593 ry_sq = ry * ry, 38594 sq = (rx_sq * ry_sq - rx_sq * y1_sq - ry_sq * x1_sq) / (rx_sq * y1_sq + ry_sq * x1_sq); 38595 38596 if (sq < 0) { 38597 sq = 0; 38598 } 38599 38600 var coef = (largeArcFlag === sweepFlag ? -1 : 1) * _sqrt(sq), 38601 cx1 = coef * (rx * y1 / ry), 38602 cy1 = coef * -(ry * x1 / rx), 38603 sx2 = (lastX + x) / 2, 38604 sy2 = (lastY + y) / 2, 38605 cx = sx2 + (cosAngle * cx1 - sinAngle * cy1), 38606 cy = sy2 + (sinAngle * cx1 + cosAngle * cy1), 38607 ux = (x1 - cx1) / rx, 38608 uy = (y1 - cy1) / ry, 38609 vx = (-x1 - cx1) / rx, 38610 vy = (-y1 - cy1) / ry, 38611 temp = ux * ux + uy * uy, 38612 angleStart = (uy < 0 ? -1 : 1) * Math.acos(ux / _sqrt(temp)), 38613 angleExtent = (ux * vy - uy * vx < 0 ? -1 : 1) * Math.acos((ux * vx + uy * vy) / _sqrt(temp * (vx * vx + vy * vy))); 38614 38615 isNaN(angleExtent) && (angleExtent = PI); 38616 38617 if (!sweepFlag && angleExtent > 0) { 38618 angleExtent -= TWOPI; 38619 } else if (sweepFlag && angleExtent < 0) { 38620 angleExtent += TWOPI; 38621 } 38622 38623 angleStart %= TWOPI; 38624 angleExtent %= TWOPI; 38625 38626 var segments = Math.ceil(_abs(angleExtent) / (TWOPI / 4)), 38627 rawPath = [], 38628 angleIncrement = angleExtent / segments, 38629 controlLength = 4 / 3 * _sin(angleIncrement / 2) / (1 + _cos(angleIncrement / 2)), 38630 ma = cosAngle * rx, 38631 mb = sinAngle * rx, 38632 mc = sinAngle * -ry, 38633 md = cosAngle * ry, 38634 i; 38635 38636 for (i = 0; i < segments; i++) { 38637 angle = angleStart + i * angleIncrement; 38638 x1 = _cos(angle); 38639 y1 = _sin(angle); 38640 ux = _cos(angle += angleIncrement); 38641 uy = _sin(angle); 38642 rawPath.push(x1 - controlLength * y1, y1 + controlLength * x1, ux + controlLength * uy, uy - controlLength * ux, ux, uy); 38643 } 38644 38645 for (i = 0; i < rawPath.length; i += 2) { 38646 x1 = rawPath[i]; 38647 y1 = rawPath[i + 1]; 38648 rawPath[i] = x1 * ma + y1 * mc + cx; 38649 rawPath[i + 1] = x1 * mb + y1 * md + cy; 38650 } 38651 38652 rawPath[i - 2] = x; 38653 rawPath[i - 1] = y; 38654 return rawPath; 38655 } 38656 38657 function stringToRawPath(d) { 38658 var a = (d + "").replace(_scientific, function (m) { 38659 var n = +m; 38660 return n < 0.0001 && n > -0.0001 ? 0 : n; 38661 }).match(_svgPathExp) || [], 38662 path = [], 38663 relativeX = 0, 38664 relativeY = 0, 38665 twoThirds = 2 / 3, 38666 elements = a.length, 38667 points = 0, 38668 errorMessage = "ERROR: malformed path: " + d, 38669 i, 38670 j, 38671 x, 38672 y, 38673 command, 38674 isRelative, 38675 segment, 38676 startX, 38677 startY, 38678 difX, 38679 difY, 38680 beziers, 38681 prevCommand, 38682 flag1, 38683 flag2, 38684 line = function line(sx, sy, ex, ey) { 38685 difX = (ex - sx) / 3; 38686 difY = (ey - sy) / 3; 38687 segment.push(sx + difX, sy + difY, ex - difX, ey - difY, ex, ey); 38688 }; 38689 38690 if (!d || !isNaN(a[0]) || isNaN(a[1])) { 38691 console.log(errorMessage); 38692 return path; 38693 } 38694 38695 for (i = 0; i < elements; i++) { 38696 prevCommand = command; 38697 38698 if (isNaN(a[i])) { 38699 command = a[i].toUpperCase(); 38700 isRelative = command !== a[i]; 38701 } else { 38702 i--; 38703 } 38704 38705 x = +a[i + 1]; 38706 y = +a[i + 2]; 38707 38708 if (isRelative) { 38709 x += relativeX; 38710 y += relativeY; 38711 } 38712 38713 if (!i) { 38714 startX = x; 38715 startY = y; 38716 } 38717 38718 if (command === "M") { 38719 if (segment) { 38720 if (segment.length < 8) { 38721 path.length -= 1; 38722 } else { 38723 points += segment.length; 38724 } 38725 } 38726 38727 relativeX = startX = x; 38728 relativeY = startY = y; 38729 segment = [x, y]; 38730 path.push(segment); 38731 i += 2; 38732 command = "L"; 38733 } else if (command === "C") { 38734 if (!segment) { 38735 segment = [0, 0]; 38736 } 38737 38738 if (!isRelative) { 38739 relativeX = relativeY = 0; 38740 } 38741 38742 segment.push(x, y, relativeX + a[i + 3] * 1, relativeY + a[i + 4] * 1, relativeX += a[i + 5] * 1, relativeY += a[i + 6] * 1); 38743 i += 6; 38744 } else if (command === "S") { 38745 difX = relativeX; 38746 difY = relativeY; 38747 38748 if (prevCommand === "C" || prevCommand === "S") { 38749 difX += relativeX - segment[segment.length - 4]; 38750 difY += relativeY - segment[segment.length - 3]; 38751 } 38752 38753 if (!isRelative) { 38754 relativeX = relativeY = 0; 38755 } 38756 38757 segment.push(difX, difY, x, y, relativeX += a[i + 3] * 1, relativeY += a[i + 4] * 1); 38758 i += 4; 38759 } else if (command === "Q") { 38760 difX = relativeX + (x - relativeX) * twoThirds; 38761 difY = relativeY + (y - relativeY) * twoThirds; 38762 38763 if (!isRelative) { 38764 relativeX = relativeY = 0; 38765 } 38766 38767 relativeX += a[i + 3] * 1; 38768 relativeY += a[i + 4] * 1; 38769 segment.push(difX, difY, relativeX + (x - relativeX) * twoThirds, relativeY + (y - relativeY) * twoThirds, relativeX, relativeY); 38770 i += 4; 38771 } else if (command === "T") { 38772 difX = relativeX - segment[segment.length - 4]; 38773 difY = relativeY - segment[segment.length - 3]; 38774 segment.push(relativeX + difX, relativeY + difY, x + (relativeX + difX * 1.5 - x) * twoThirds, y + (relativeY + difY * 1.5 - y) * twoThirds, relativeX = x, relativeY = y); 38775 i += 2; 38776 } else if (command === "H") { 38777 line(relativeX, relativeY, relativeX = x, relativeY); 38778 i += 1; 38779 } else if (command === "V") { 38780 line(relativeX, relativeY, relativeX, relativeY = x + (isRelative ? relativeY - relativeX : 0)); 38781 i += 1; 38782 } else if (command === "L" || command === "Z") { 38783 if (command === "Z") { 38784 x = startX; 38785 y = startY; 38786 segment.closed = true; 38787 } 38788 38789 if (command === "L" || _abs(relativeX - x) > 0.5 || _abs(relativeY - y) > 0.5) { 38790 line(relativeX, relativeY, x, y); 38791 38792 if (command === "L") { 38793 i += 2; 38794 } 38795 } 38796 38797 relativeX = x; 38798 relativeY = y; 38799 } else if (command === "A") { 38800 flag1 = a[i + 4]; 38801 flag2 = a[i + 5]; 38802 difX = a[i + 6]; 38803 difY = a[i + 7]; 38804 j = 7; 38805 38806 if (flag1.length > 1) { 38807 if (flag1.length < 3) { 38808 difY = difX; 38809 difX = flag2; 38810 j--; 38811 } else { 38812 difY = flag2; 38813 difX = flag1.substr(2); 38814 j -= 2; 38815 } 38816 38817 flag2 = flag1.charAt(1); 38818 flag1 = flag1.charAt(0); 38819 } 38820 38821 beziers = arcToSegment(relativeX, relativeY, +a[i + 1], +a[i + 2], +a[i + 3], +flag1, +flag2, (isRelative ? relativeX : 0) + difX * 1, (isRelative ? relativeY : 0) + difY * 1); 38822 i += j; 38823 38824 if (beziers) { 38825 for (j = 0; j < beziers.length; j++) { 38826 segment.push(beziers[j]); 38827 } 38828 } 38829 38830 relativeX = segment[segment.length - 2]; 38831 relativeY = segment[segment.length - 1]; 38832 } else { 38833 console.log(errorMessage); 38834 } 38835 } 38836 38837 i = segment.length; 38838 38839 if (i < 6) { 38840 path.pop(); 38841 i = 0; 38842 } else if (segment[0] === segment[i - 2] && segment[1] === segment[i - 1]) { 38843 segment.closed = true; 38844 } 38845 38846 path.totalPoints = points + i; 38847 return path; 38848 } 38849 function rawPathToString(rawPath) { 38850 if (_isNumber(rawPath[0])) { 38851 rawPath = [rawPath]; 38852 } 38853 38854 var result = "", 38855 l = rawPath.length, 38856 sl, 38857 s, 38858 i, 38859 segment; 38860 38861 for (s = 0; s < l; s++) { 38862 segment = rawPath[s]; 38863 result += "M" + _round(segment[0]) + "," + _round(segment[1]) + " C"; 38864 sl = segment.length; 38865 38866 for (i = 2; i < sl; i++) { 38867 result += _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i]) + " "; 38868 } 38869 38870 if (segment.closed) { 38871 result += "z"; 38872 } 38873 } 38874 38875 return result; 38876 } 38877 38878 /*! 38879 * CustomEase 3.12.7 38880 * https://gsap.com 38881 * 38882 * @license Copyright 2008-2025, GreenSock. All rights reserved. 38883 * Subject to the terms at https://gsap.com/standard-license or for 38884 * Club GSAP members, the agreement issued with that membership. 38885 * @author: Jack Doyle, [email protected] 38886 */ 38887 38888 var gsap, 38889 _coreInitted, 38890 _getGSAP = function _getGSAP() { 38891 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 38892 }, 38893 _initCore = function _initCore() { 38894 gsap = _getGSAP(); 38895 38896 if (gsap) { 38897 gsap.registerEase("_CE", CustomEase.create); 38898 _coreInitted = 1; 38899 } else { 38900 console.warn("Please gsap.registerPlugin(CustomEase)"); 38901 } 38902 }, 38903 _bigNum = 1e20, 38904 _round$1 = function _round(value) { 38905 return ~~(value * 1000 + (value < 0 ? -.5 : .5)) / 1000; 38906 }, 38907 _numExp = /[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/gi, 38908 _needsParsingExp = /[cLlsSaAhHvVtTqQ]/g, 38909 _findMinimum = function _findMinimum(values) { 38910 var l = values.length, 38911 min = _bigNum, 38912 i; 38913 38914 for (i = 1; i < l; i += 6) { 38915 +values[i] < min && (min = +values[i]); 38916 } 38917 38918 return min; 38919 }, 38920 _normalize = function _normalize(values, height, originY) { 38921 if (!originY && originY !== 0) { 38922 originY = Math.max(+values[values.length - 1], +values[1]); 38923 } 38924 38925 var tx = +values[0] * -1, 38926 ty = -originY, 38927 l = values.length, 38928 sx = 1 / (+values[l - 2] + tx), 38929 sy = -height || (Math.abs(+values[l - 1] - +values[1]) < 0.01 * (+values[l - 2] - +values[0]) ? _findMinimum(values) + ty : +values[l - 1] + ty), 38930 i; 38931 38932 if (sy) { 38933 sy = 1 / sy; 38934 } else { 38935 sy = -sx; 38936 } 38937 38938 for (i = 0; i < l; i += 2) { 38939 values[i] = (+values[i] + tx) * sx; 38940 values[i + 1] = (+values[i + 1] + ty) * sy; 38941 } 38942 }, 38943 _bezierToPoints = function _bezierToPoints(x1, y1, x2, y2, x3, y3, x4, y4, threshold, points, index) { 38944 var x12 = (x1 + x2) / 2, 38945 y12 = (y1 + y2) / 2, 38946 x23 = (x2 + x3) / 2, 38947 y23 = (y2 + y3) / 2, 38948 x34 = (x3 + x4) / 2, 38949 y34 = (y3 + y4) / 2, 38950 x123 = (x12 + x23) / 2, 38951 y123 = (y12 + y23) / 2, 38952 x234 = (x23 + x34) / 2, 38953 y234 = (y23 + y34) / 2, 38954 x1234 = (x123 + x234) / 2, 38955 y1234 = (y123 + y234) / 2, 38956 dx = x4 - x1, 38957 dy = y4 - y1, 38958 d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx), 38959 d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx), 38960 length; 38961 38962 if (!points) { 38963 points = [{ 38964 x: x1, 38965 y: y1 38966 }, { 38967 x: x4, 38968 y: y4 38969 }]; 38970 index = 1; 38971 } 38972 38973 points.splice(index || points.length - 1, 0, { 38974 x: x1234, 38975 y: y1234 38976 }); 38977 38978 if ((d2 + d3) * (d2 + d3) > threshold * (dx * dx + dy * dy)) { 38979 length = points.length; 38980 38981 _bezierToPoints(x1, y1, x12, y12, x123, y123, x1234, y1234, threshold, points, index); 38982 38983 _bezierToPoints(x1234, y1234, x234, y234, x34, y34, x4, y4, threshold, points, index + 1 + (points.length - length)); 38984 } 38985 38986 return points; 38987 }; 38988 38989 var CustomEase = function () { 38990 function CustomEase(id, data, config) { 38991 _coreInitted || _initCore(); 38992 this.id = id; 38993 this.setData(data, config); 38994 } 38995 38996 var _proto = CustomEase.prototype; 38997 38998 _proto.setData = function setData(data, config) { 38999 config = config || {}; 39000 data = data || "0,0,1,1"; 39001 var values = data.match(_numExp), 39002 closest = 1, 39003 points = [], 39004 lookup = [], 39005 precision = config.precision || 1, 39006 fast = precision <= 1, 39007 l, 39008 a1, 39009 a2, 39010 i, 39011 inc, 39012 j, 39013 point, 39014 prevPoint, 39015 p; 39016 this.data = data; 39017 39018 if (_needsParsingExp.test(data) || ~data.indexOf("M") && data.indexOf("C") < 0) { 39019 values = stringToRawPath(data)[0]; 39020 } 39021 39022 l = values.length; 39023 39024 if (l === 4) { 39025 values.unshift(0, 0); 39026 values.push(1, 1); 39027 l = 8; 39028 } else if ((l - 2) % 6) { 39029 throw "Invalid CustomEase"; 39030 } 39031 39032 if (+values[0] !== 0 || +values[l - 2] !== 1) { 39033 _normalize(values, config.height, config.originY); 39034 } 39035 39036 this.segment = values; 39037 39038 for (i = 2; i < l; i += 6) { 39039 a1 = { 39040 x: +values[i - 2], 39041 y: +values[i - 1] 39042 }; 39043 a2 = { 39044 x: +values[i + 4], 39045 y: +values[i + 5] 39046 }; 39047 points.push(a1, a2); 39048 39049 _bezierToPoints(a1.x, a1.y, +values[i], +values[i + 1], +values[i + 2], +values[i + 3], a2.x, a2.y, 1 / (precision * 200000), points, points.length - 1); 39050 } 39051 39052 l = points.length; 39053 39054 for (i = 0; i < l; i++) { 39055 point = points[i]; 39056 prevPoint = points[i - 1] || point; 39057 39058 if ((point.x > prevPoint.x || prevPoint.y !== point.y && prevPoint.x === point.x || point === prevPoint) && point.x <= 1) { 39059 prevPoint.cx = point.x - prevPoint.x; 39060 prevPoint.cy = point.y - prevPoint.y; 39061 prevPoint.n = point; 39062 prevPoint.nx = point.x; 39063 39064 if (fast && i > 1 && Math.abs(prevPoint.cy / prevPoint.cx - points[i - 2].cy / points[i - 2].cx) > 2) { 39065 fast = 0; 39066 } 39067 39068 if (prevPoint.cx < closest) { 39069 if (!prevPoint.cx) { 39070 prevPoint.cx = 0.001; 39071 39072 if (i === l - 1) { 39073 prevPoint.x -= 0.001; 39074 closest = Math.min(closest, 0.001); 39075 fast = 0; 39076 } 39077 } else { 39078 closest = prevPoint.cx; 39079 } 39080 } 39081 } else { 39082 points.splice(i--, 1); 39083 l--; 39084 } 39085 } 39086 39087 l = 1 / closest + 1 | 0; 39088 inc = 1 / l; 39089 j = 0; 39090 point = points[0]; 39091 39092 if (fast) { 39093 for (i = 0; i < l; i++) { 39094 p = i * inc; 39095 39096 if (point.nx < p) { 39097 point = points[++j]; 39098 } 39099 39100 a1 = point.y + (p - point.x) / point.cx * point.cy; 39101 lookup[i] = { 39102 x: p, 39103 cx: inc, 39104 y: a1, 39105 cy: 0, 39106 nx: 9 39107 }; 39108 39109 if (i) { 39110 lookup[i - 1].cy = a1 - lookup[i - 1].y; 39111 } 39112 } 39113 39114 j = points[points.length - 1]; 39115 lookup[l - 1].cy = j.y - a1; 39116 lookup[l - 1].cx = j.x - lookup[lookup.length - 1].x; 39117 } else { 39118 for (i = 0; i < l; i++) { 39119 if (point.nx < i * inc) { 39120 point = points[++j]; 39121 } 39122 39123 lookup[i] = point; 39124 } 39125 39126 if (j < points.length - 1) { 39127 lookup[i - 1] = points[points.length - 2]; 39128 } 39129 } 39130 39131 this.ease = function (p) { 39132 var point = lookup[p * l | 0] || lookup[l - 1]; 39133 39134 if (point.nx < p) { 39135 point = point.n; 39136 } 39137 39138 return point.y + (p - point.x) / point.cx * point.cy; 39139 }; 39140 39141 this.ease.custom = this; 39142 this.id && gsap && gsap.registerEase(this.id, this.ease); 39143 return this; 39144 }; 39145 39146 _proto.getSVGData = function getSVGData(config) { 39147 return CustomEase.getSVGData(this, config); 39148 }; 39149 39150 CustomEase.create = function create(id, data, config) { 39151 return new CustomEase(id, data, config).ease; 39152 }; 39153 39154 CustomEase.register = function register(core) { 39155 gsap = core; 39156 39157 _initCore(); 39158 }; 39159 39160 CustomEase.get = function get(id) { 39161 return gsap.parseEase(id); 39162 }; 39163 39164 CustomEase.getSVGData = function getSVGData(ease, config) { 39165 config = config || {}; 39166 var width = config.width || 100, 39167 height = config.height || 100, 39168 x = config.x || 0, 39169 y = (config.y || 0) + height, 39170 e = gsap.utils.toArray(config.path)[0], 39171 a, 39172 slope, 39173 i, 39174 inc, 39175 tx, 39176 ty, 39177 precision, 39178 threshold, 39179 prevX, 39180 prevY; 39181 39182 if (config.invert) { 39183 height = -height; 39184 y = 0; 39185 } 39186 39187 if (typeof ease === "string") { 39188 ease = gsap.parseEase(ease); 39189 } 39190 39191 if (ease.custom) { 39192 ease = ease.custom; 39193 } 39194 39195 if (ease instanceof CustomEase) { 39196 a = rawPathToString(transformRawPath([ease.segment], width, 0, 0, -height, x, y)); 39197 } else { 39198 a = [x, y]; 39199 precision = Math.max(5, (config.precision || 1) * 200); 39200 inc = 1 / precision; 39201 precision += 2; 39202 threshold = 5 / precision; 39203 prevX = _round$1(x + inc * width); 39204 prevY = _round$1(y + ease(inc) * -height); 39205 slope = (prevY - y) / (prevX - x); 39206 39207 for (i = 2; i < precision; i++) { 39208 tx = _round$1(x + i * inc * width); 39209 ty = _round$1(y + ease(i * inc) * -height); 39210 39211 if (Math.abs((ty - prevY) / (tx - prevX) - slope) > threshold || i === precision - 1) { 39212 a.push(prevX, prevY); 39213 slope = (ty - prevY) / (tx - prevX); 39214 } 39215 39216 prevX = tx; 39217 prevY = ty; 39218 } 39219 39220 a = "M" + a.join(","); 39221 } 39222 39223 e && e.setAttribute("d", a); 39224 return a; 39225 }; 39226 39227 return CustomEase; 39228 }(); 39229 CustomEase.version = "3.12.7"; 39230 CustomEase.headless = true; 39231 _getGSAP() && gsap.registerPlugin(CustomEase); 39232 39233 exports.CustomEase = CustomEase; 39234 exports.default = CustomEase; 39235 39236 Object.defineProperty(exports, '__esModule', { value: true }); 39237 39238}))); 39239(function (global, factory) { 39240 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 39241 typeof define === 'function' && define.amd ? define(['exports'], factory) : 39242 (global = global || self, factory(global.window = global.window || {})); 39243}(this, (function (exports) { 'use strict'; 39244 39245 function _inheritsLoose(subClass, superClass) { 39246 subClass.prototype = Object.create(superClass.prototype); 39247 subClass.prototype.constructor = subClass; 39248 subClass.__proto__ = superClass; 39249 } 39250 39251 function _assertThisInitialized(self) { 39252 if (self === void 0) { 39253 throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 39254 } 39255 39256 return self; 39257 } 39258 39259 var _doc, 39260 _win, 39261 _docElement, 39262 _body, 39263 _divContainer, 39264 _svgContainer, 39265 _identityMatrix, 39266 _gEl, 39267 _transformProp = "transform", 39268 _transformOriginProp = _transformProp + "Origin", 39269 _hasOffsetBug, 39270 _setDoc = function _setDoc(element) { 39271 var doc = element.ownerDocument || element; 39272 39273 if (!(_transformProp in element.style) && "msTransform" in element.style) { 39274 _transformProp = "msTransform"; 39275 _transformOriginProp = _transformProp + "Origin"; 39276 } 39277 39278 while (doc.parentNode && (doc = doc.parentNode)) {} 39279 39280 _win = window; 39281 _identityMatrix = new Matrix2D(); 39282 39283 if (doc) { 39284 _doc = doc; 39285 _docElement = doc.documentElement; 39286 _body = doc.body; 39287 _gEl = _doc.createElementNS("http://www.w3.org/2000/svg", "g"); 39288 _gEl.style.transform = "none"; 39289 var d1 = doc.createElement("div"), 39290 d2 = doc.createElement("div"), 39291 root = doc && (doc.body || doc.firstElementChild); 39292 39293 if (root && root.appendChild) { 39294 root.appendChild(d1); 39295 d1.appendChild(d2); 39296 d1.setAttribute("style", "position:static;transform:translate3d(0,0,1px)"); 39297 _hasOffsetBug = d2.offsetParent !== d1; 39298 root.removeChild(d1); 39299 } 39300 } 39301 39302 return doc; 39303 }, 39304 _forceNonZeroScale = function _forceNonZeroScale(e) { 39305 var a, cache; 39306 39307 while (e && e !== _body) { 39308 cache = e._gsap; 39309 cache && cache.uncache && cache.get(e, "x"); 39310 39311 if (cache && !cache.scaleX && !cache.scaleY && cache.renderTransform) { 39312 cache.scaleX = cache.scaleY = 1e-4; 39313 cache.renderTransform(1, cache); 39314 a ? a.push(cache) : a = [cache]; 39315 } 39316 39317 e = e.parentNode; 39318 } 39319 39320 return a; 39321 }, 39322 _svgTemps = [], 39323 _divTemps = [], 39324 _getDocScrollTop = function _getDocScrollTop() { 39325 return _win.pageYOffset || _doc.scrollTop || _docElement.scrollTop || _body.scrollTop || 0; 39326 }, 39327 _getDocScrollLeft = function _getDocScrollLeft() { 39328 return _win.pageXOffset || _doc.scrollLeft || _docElement.scrollLeft || _body.scrollLeft || 0; 39329 }, 39330 _svgOwner = function _svgOwner(element) { 39331 return element.ownerSVGElement || ((element.tagName + "").toLowerCase() === "svg" ? element : null); 39332 }, 39333 _isFixed = function _isFixed(element) { 39334 if (_win.getComputedStyle(element).position === "fixed") { 39335 return true; 39336 } 39337 39338 element = element.parentNode; 39339 39340 if (element && element.nodeType === 1) { 39341 return _isFixed(element); 39342 } 39343 }, 39344 _createSibling = function _createSibling(element, i) { 39345 if (element.parentNode && (_doc || _setDoc(element))) { 39346 var svg = _svgOwner(element), 39347 ns = svg ? svg.getAttribute("xmlns") || "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml", 39348 type = svg ? i ? "rect" : "g" : "div", 39349 x = i !== 2 ? 0 : 100, 39350 y = i === 3 ? 100 : 0, 39351 css = "position:absolute;display:block;pointer-events:none;margin:0;padding:0;", 39352 e = _doc.createElementNS ? _doc.createElementNS(ns.replace(/^https/, "http"), type) : _doc.createElement(type); 39353 39354 if (i) { 39355 if (!svg) { 39356 if (!_divContainer) { 39357 _divContainer = _createSibling(element); 39358 _divContainer.style.cssText = css; 39359 } 39360 39361 e.style.cssText = css + "width:0.1px;height:0.1px;top:" + y + "px;left:" + x + "px"; 39362 39363 _divContainer.appendChild(e); 39364 } else { 39365 _svgContainer || (_svgContainer = _createSibling(element)); 39366 e.setAttribute("width", 0.01); 39367 e.setAttribute("height", 0.01); 39368 e.setAttribute("transform", "translate(" + x + "," + y + ")"); 39369 39370 _svgContainer.appendChild(e); 39371 } 39372 } 39373 39374 return e; 39375 } 39376 39377 throw "Need document and parent."; 39378 }, 39379 _consolidate = function _consolidate(m) { 39380 var c = new Matrix2D(), 39381 i = 0; 39382 39383 for (; i < m.numberOfItems; i++) { 39384 c.multiply(m.getItem(i).matrix); 39385 } 39386 39387 return c; 39388 }, 39389 _getCTM = function _getCTM(svg) { 39390 var m = svg.getCTM(), 39391 transform; 39392 39393 if (!m) { 39394 transform = svg.style[_transformProp]; 39395 svg.style[_transformProp] = "none"; 39396 svg.appendChild(_gEl); 39397 m = _gEl.getCTM(); 39398 svg.removeChild(_gEl); 39399 transform ? svg.style[_transformProp] = transform : svg.style.removeProperty(_transformProp.replace(/([A-Z])/g, "-$1").toLowerCase()); 39400 } 39401 39402 return m || _identityMatrix.clone(); 39403 }, 39404 _placeSiblings = function _placeSiblings(element, adjustGOffset) { 39405 var svg = _svgOwner(element), 39406 isRootSVG = element === svg, 39407 siblings = svg ? _svgTemps : _divTemps, 39408 parent = element.parentNode, 39409 container, 39410 m, 39411 b, 39412 x, 39413 y, 39414 cs; 39415 39416 if (element === _win) { 39417 return element; 39418 } 39419 39420 siblings.length || siblings.push(_createSibling(element, 1), _createSibling(element, 2), _createSibling(element, 3)); 39421 container = svg ? _svgContainer : _divContainer; 39422 39423 if (svg) { 39424 if (isRootSVG) { 39425 b = _getCTM(element); 39426 x = -b.e / b.a; 39427 y = -b.f / b.d; 39428 m = _identityMatrix; 39429 } else if (element.getBBox) { 39430 b = element.getBBox(); 39431 m = element.transform ? element.transform.baseVal : {}; 39432 m = !m.numberOfItems ? _identityMatrix : m.numberOfItems > 1 ? _consolidate(m) : m.getItem(0).matrix; 39433 x = m.a * b.x + m.c * b.y; 39434 y = m.b * b.x + m.d * b.y; 39435 } else { 39436 m = new Matrix2D(); 39437 x = y = 0; 39438 } 39439 39440 if (adjustGOffset && element.tagName.toLowerCase() === "g") { 39441 x = y = 0; 39442 } 39443 39444 (isRootSVG ? svg : parent).appendChild(container);
vendor: 1,139 bytes, lines 39445-39480
39445 container.setAttribute("transform", "matrix(" + m.a + "," + m.b + "," + m.c + "," + m.d + "," + (m.e + x) + "," + (m.f + y) + ")"); 39446 } else { 39447 x = y = 0; 39448 39449 if (_hasOffsetBug) { 39450 m = element.offsetParent; 39451 b = element; 39452 39453 while (b && (b = b.parentNode) && b !== m && b.parentNode) { 39454 if ((_win.getComputedStyle(b)[_transformProp] + "").length > 4) { 39455 x = b.offsetLeft; 39456 y = b.offsetTop; 39457 b = 0; 39458 } 39459 } 39460 } 39461 39462 cs = _win.getComputedStyle(element); 39463 39464 if (cs.position !== "absolute" && cs.position !== "fixed") { 39465 m = element.offsetParent; 39466 39467 while (parent && parent !== m) { 39468 x += parent.scrollLeft || 0; 39469 y += parent.scrollTop || 0; 39470 parent = parent.parentNode; 39471 } 39472 } 39473 39474 b = container.style; 39475 b.top = element.offsetTop - y + "px"; 39476 b.left = element.offsetLeft - x + "px"; 39477 b[_transformProp] = cs[_transformProp]; 39478 b[_transformOriginProp] = cs[_transformOriginProp]; 39479 b.position = cs.position === "fixed" ? "fixed" : "absolute"; 39480 element.parentNode
vendor: 37,456 bytes, lines 39480-40735
39480.appendChild(container); 39481 } 39482 39483 return container; 39484 }, 39485 _setMatrix = function _setMatrix(m, a, b, c, d, e, f) { 39486 m.a = a; 39487 m.b = b; 39488 m.c = c; 39489 m.d = d; 39490 m.e = e; 39491 m.f = f; 39492 return m; 39493 }; 39494 39495 var Matrix2D = function () { 39496 function Matrix2D(a, b, c, d, e, f) { 39497 if (a === void 0) { 39498 a = 1; 39499 } 39500 39501 if (b === void 0) { 39502 b = 0; 39503 } 39504 39505 if (c === void 0) { 39506 c = 0; 39507 } 39508 39509 if (d === void 0) { 39510 d = 1; 39511 } 39512 39513 if (e === void 0) { 39514 e = 0; 39515 } 39516 39517 if (f === void 0) { 39518 f = 0; 39519 } 39520 39521 _setMatrix(this, a, b, c, d, e, f); 39522 } 39523 39524 var _proto = Matrix2D.prototype; 39525 39526 _proto.inverse = function inverse() { 39527 var a = this.a, 39528 b = this.b, 39529 c = this.c, 39530 d = this.d, 39531 e = this.e, 39532 f = this.f, 39533 determinant = a * d - b * c || 1e-10; 39534 return _setMatrix(this, d / determinant, -b / determinant, -c / determinant, a / determinant, (c * f - d * e) / determinant, -(a * f - b * e) / determinant); 39535 }; 39536 39537 _proto.multiply = function multiply(matrix) { 39538 var a = this.a, 39539 b = this.b, 39540 c = this.c, 39541 d = this.d, 39542 e = this.e, 39543 f = this.f, 39544 a2 = matrix.a, 39545 b2 = matrix.c, 39546 c2 = matrix.b, 39547 d2 = matrix.d, 39548 e2 = matrix.e, 39549 f2 = matrix.f; 39550 return _setMatrix(this, a2 * a + c2 * c, a2 * b + c2 * d, b2 * a + d2 * c, b2 * b + d2 * d, e + e2 * a + f2 * c, f + e2 * b + f2 * d); 39551 }; 39552 39553 _proto.clone = function clone() { 39554 return new Matrix2D(this.a, this.b, this.c, this.d, this.e, this.f); 39555 }; 39556 39557 _proto.equals = function equals(matrix) { 39558 var a = this.a, 39559 b = this.b, 39560 c = this.c, 39561 d = this.d, 39562 e = this.e, 39563 f = this.f; 39564 return a === matrix.a && b === matrix.b && c === matrix.c && d === matrix.d && e === matrix.e && f === matrix.f; 39565 }; 39566 39567 _proto.apply = function apply(point, decoratee) { 39568 if (decoratee === void 0) { 39569 decoratee = {}; 39570 } 39571 39572 var x = point.x, 39573 y = point.y, 39574 a = this.a, 39575 b = this.b, 39576 c = this.c, 39577 d = this.d, 39578 e = this.e, 39579 f = this.f; 39580 decoratee.x = x * a + y * c + e || 0; 39581 decoratee.y = x * b + y * d + f || 0; 39582 return decoratee; 39583 }; 39584 39585 return Matrix2D; 39586 }(); 39587 function getGlobalMatrix(element, inverse, adjustGOffset, includeScrollInFixed) { 39588 if (!element || !element.parentNode || (_doc || _setDoc(element)).documentElement === element) { 39589 return new Matrix2D(); 39590 } 39591 39592 var zeroScales = _forceNonZeroScale(element), 39593 svg = _svgOwner(element), 39594 temps = svg ? _svgTemps : _divTemps, 39595 container = _placeSiblings(element, adjustGOffset), 39596 b1 = temps[0].getBoundingClientRect(), 39597 b2 = temps[1].getBoundingClientRect(), 39598 b3 = temps[2].getBoundingClientRect(), 39599 parent = container.parentNode, 39600 isFixed = !includeScrollInFixed && _isFixed(element), 39601 m = new Matrix2D((b2.left - b1.left) / 100, (b2.top - b1.top) / 100, (b3.left - b1.left) / 100, (b3.top - b1.top) / 100, b1.left + (isFixed ? 0 : _getDocScrollLeft()), b1.top + (isFixed ? 0 : _getDocScrollTop())); 39602 39603 parent.removeChild(container); 39604 39605 if (zeroScales) { 39606 b1 = zeroScales.length; 39607 39608 while (b1--) { 39609 b2 = zeroScales[b1]; 39610 b2.scaleX = b2.scaleY = 0; 39611 b2.renderTransform(1, b2); 39612 } 39613 } 39614 39615 return inverse ? m.inverse() : m; 39616 } 39617 39618 var gsap, 39619 _win$1, 39620 _doc$1, 39621 _docElement$1, 39622 _body$1, 39623 _tempDiv, 39624 _placeholderDiv, 39625 _coreInitted, 39626 _checkPrefix, 39627 _toArray, 39628 _supportsPassive, 39629 _isTouchDevice, 39630 _touchEventLookup, 39631 _isMultiTouching, 39632 _isAndroid, 39633 InertiaPlugin, 39634 _defaultCursor, 39635 _supportsPointer, 39636 _context, 39637 _getStyleSaver, 39638 _dragCount = 0, 39639 _windowExists = function _windowExists() { 39640 return typeof window !== "undefined"; 39641 }, 39642 _getGSAP = function _getGSAP() { 39643 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 39644 }, 39645 _isFunction = function _isFunction(value) { 39646 return typeof value === "function"; 39647 }, 39648 _isObject = function _isObject(value) { 39649 return typeof value === "object"; 39650 }, 39651 _isUndefined = function _isUndefined(value) { 39652 return typeof value === "undefined"; 39653 }, 39654 _emptyFunc = function _emptyFunc() { 39655 return false; 39656 }, 39657 _transformProp$1 = "transform", 39658 _transformOriginProp$1 = "transformOrigin", 39659 _round = function _round(value) { 39660 return Math.round(value * 10000) / 10000; 39661 }, 39662 _isArray = Array.isArray, 39663 _createElement = function _createElement(type, ns) { 39664 var e = _doc$1.createElementNS ? _doc$1.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc$1.createElement(type); 39665 return e.style ? e : _doc$1.createElement(type); 39666 }, 39667 _RAD2DEG = 180 / Math.PI, 39668 _bigNum = 1e20, 39669 _identityMatrix$1 = new Matrix2D(), 39670 _getTime = Date.now || function () { 39671 return new Date().getTime(); 39672 }, 39673 _renderQueue = [], 39674 _lookup = {}, 39675 _lookupCount = 0, 39676 _clickableTagExp = /^(?:a|input|textarea|button|select)$/i, 39677 _lastDragTime = 0, 39678 _temp1 = {}, 39679 _windowProxy = {}, 39680 _copy = function _copy(obj, factor) { 39681 var copy = {}, 39682 p; 39683 39684 for (p in obj) { 39685 copy[p] = factor ? obj[p] * factor : obj[p]; 39686 } 39687 39688 return copy; 39689 }, 39690 _extend = function _extend(obj, defaults) { 39691 for (var p in defaults) { 39692 if (!(p in obj)) { 39693 obj[p] = defaults[p]; 39694 } 39695 } 39696 39697 return obj; 39698 }, 39699 _setTouchActionForAllDescendants = function _setTouchActionForAllDescendants(elements, value) { 39700 var i = elements.length, 39701 children; 39702 39703 while (i--) { 39704 value ? elements[i].style.touchAction = value : elements[i].style.removeProperty("touch-action"); 39705 children = elements[i].children; 39706 children && children.length && _setTouchActionForAllDescendants(children, value); 39707 } 39708 }, 39709 _renderQueueTick = function _renderQueueTick() { 39710 return _renderQueue.forEach(function (func) { 39711 return func(); 39712 }); 39713 }, 39714 _addToRenderQueue = function _addToRenderQueue(func) { 39715 _renderQueue.push(func); 39716 39717 if (_renderQueue.length === 1) { 39718 gsap.ticker.add(_renderQueueTick); 39719 } 39720 }, 39721 _renderQueueTimeout = function _renderQueueTimeout() { 39722 return !_renderQueue.length && gsap.ticker.remove(_renderQueueTick); 39723 }, 39724 _removeFromRenderQueue = function _removeFromRenderQueue(func) { 39725 var i = _renderQueue.length; 39726 39727 while (i--) { 39728 if (_renderQueue[i] === func) { 39729 _renderQueue.splice(i, 1); 39730 } 39731 } 39732 39733 gsap.to(_renderQueueTimeout, { 39734 overwrite: true, 39735 delay: 15, 39736 duration: 0, 39737 onComplete: _renderQueueTimeout, 39738 data: "_draggable" 39739 }); 39740 }, 39741 _setDefaults = function _setDefaults(obj, defaults) { 39742 for (var p in defaults) { 39743 if (!(p in obj)) { 39744 obj[p] = defaults[p]; 39745 } 39746 } 39747 39748 return obj; 39749 }, 39750 _addListener = function _addListener(element, type, func, capture) { 39751 if (element.addEventListener) { 39752 var touchType = _touchEventLookup[type]; 39753 capture = capture || (_supportsPassive ? { 39754 passive: false 39755 } : null); 39756 element.addEventListener(touchType || type, func, capture); 39757 touchType && type !== touchType && element.addEventListener(type, func, capture); 39758 } 39759 }, 39760 _removeListener = function _removeListener(element, type, func, capture) { 39761 if (element.removeEventListener) { 39762 var touchType = _touchEventLookup[type]; 39763 element.removeEventListener(touchType || type, func, capture); 39764 touchType && type !== touchType && element.removeEventListener(type, func, capture); 39765 } 39766 }, 39767 _preventDefault = function _preventDefault(event) { 39768 event.preventDefault && event.preventDefault(); 39769 event.preventManipulation && event.preventManipulation(); 39770 }, 39771 _hasTouchID = function _hasTouchID(list, ID) { 39772 var i = list.length; 39773 39774 while (i--) { 39775 if (list[i].identifier === ID) { 39776 return true; 39777 } 39778 } 39779 }, 39780 _onMultiTouchDocumentEnd = function _onMultiTouchDocumentEnd(event) { 39781 _isMultiTouching = event.touches && _dragCount < event.touches.length; 39782 39783 _removeListener(event.target, "touchend", _onMultiTouchDocumentEnd); 39784 }, 39785 _onMultiTouchDocument = function _onMultiTouchDocument(event) { 39786 _isMultiTouching = event.touches && _dragCount < event.touches.length; 39787 39788 _addListener(event.target, "touchend", _onMultiTouchDocumentEnd); 39789 }, 39790 _getDocScrollTop$1 = function _getDocScrollTop(doc) { 39791 return _win$1.pageYOffset || doc.scrollTop || doc.documentElement.scrollTop || doc.body.scrollTop || 0; 39792 }, 39793 _getDocScrollLeft$1 = function _getDocScrollLeft(doc) { 39794 return _win$1.pageXOffset || doc.scrollLeft || doc.documentElement.scrollLeft || doc.body.scrollLeft || 0; 39795 }, 39796 _addScrollListener = function _addScrollListener(e, callback) { 39797 _addListener(e, "scroll", callback); 39798 39799 if (!_isRoot(e.parentNode)) { 39800 _addScrollListener(e.parentNode, callback); 39801 } 39802 }, 39803 _removeScrollListener = function _removeScrollListener(e, callback) { 39804 _removeListener(e, "scroll", callback); 39805 39806 if (!_isRoot(e.parentNode)) { 39807 _removeScrollListener(e.parentNode, callback); 39808 } 39809 }, 39810 _isRoot = function _isRoot(e) { 39811 return !!(!e || e === _docElement$1 || e.nodeType === 9 || e === _doc$1.body || e === _win$1 || !e.nodeType || !e.parentNode); 39812 }, 39813 _getMaxScroll = function _getMaxScroll(element, axis) { 39814 var dim = axis === "x" ? "Width" : "Height", 39815 scroll = "scroll" + dim, 39816 client = "client" + dim; 39817 return Math.max(0, _isRoot(element) ? Math.max(_docElement$1[scroll], _body$1[scroll]) - (_win$1["inner" + dim] || _docElement$1[client] || _body$1[client]) : element[scroll] - element[client]); 39818 }, 39819 _recordMaxScrolls = function _recordMaxScrolls(e, skipCurrent) { 39820 var x = _getMaxScroll(e, "x"), 39821 y = _getMaxScroll(e, "y"); 39822 39823 if (_isRoot(e)) { 39824 e = _windowProxy; 39825 } else { 39826 _recordMaxScrolls(e.parentNode, skipCurrent); 39827 } 39828 39829 e._gsMaxScrollX = x; 39830 e._gsMaxScrollY = y; 39831 39832 if (!skipCurrent) { 39833 e._gsScrollX = e.scrollLeft || 0; 39834 e._gsScrollY = e.scrollTop || 0; 39835 } 39836 }, 39837 _setStyle = function _setStyle(element, property, value) { 39838 var style = element.style; 39839 39840 if (!style) { 39841 return; 39842 } 39843 39844 if (_isUndefined(style[property])) { 39845 property = _checkPrefix(property, element) || property; 39846 } 39847 39848 if (value == null) { 39849 style.removeProperty && style.removeProperty(property.replace(/([A-Z])/g, "-$1").toLowerCase()); 39850 } else { 39851 style[property] = value; 39852 } 39853 }, 39854 _getComputedStyle = function _getComputedStyle(element) { 39855 return _win$1.getComputedStyle(element instanceof Element ? element : element.host || (element.parentNode || {}).host || element); 39856 }, 39857 _tempRect = {}, 39858 _parseRect = function _parseRect(e) { 39859 if (e === _win$1) { 39860 _tempRect.left = _tempRect.top = 0; 39861 _tempRect.width = _tempRect.right = _docElement$1.clientWidth || e.innerWidth || _body$1.clientWidth || 0; 39862 _tempRect.height = _tempRect.bottom = (e.innerHeight || 0) - 20 < _docElement$1.clientHeight ? _docElement$1.clientHeight : e.innerHeight || _body$1.clientHeight || 0; 39863 return _tempRect; 39864 } 39865 39866 var doc = e.ownerDocument || _doc$1, 39867 r = !_isUndefined(e.pageX) ? { 39868 left: e.pageX - _getDocScrollLeft$1(doc), 39869 top: e.pageY - _getDocScrollTop$1(doc), 39870 right: e.pageX - _getDocScrollLeft$1(doc) + 1, 39871 bottom: e.pageY - _getDocScrollTop$1(doc) + 1 39872 } : !e.nodeType && !_isUndefined(e.left) && !_isUndefined(e.top) ? e : _toArray(e)[0].getBoundingClientRect(); 39873 39874 if (_isUndefined(r.right) && !_isUndefined(r.width)) { 39875 r.right = r.left + r.width; 39876 r.bottom = r.top + r.height; 39877 } else if (_isUndefined(r.width)) { 39878 r = { 39879 width: r.right - r.left, 39880 height: r.bottom - r.top, 39881 right: r.right, 39882 left: r.left, 39883 bottom: r.bottom, 39884 top: r.top 39885 }; 39886 } 39887 39888 return r; 39889 }, 39890 _dispatchEvent = function _dispatchEvent(target, type, callbackName) { 39891 var vars = target.vars, 39892 callback = vars[callbackName], 39893 listeners = target._listeners[type], 39894 result; 39895 39896 if (_isFunction(callback)) { 39897 result = callback.apply(vars.callbackScope || target, vars[callbackName + "Params"] || [target.pointerEvent]); 39898 } 39899 39900 if (listeners && target.dispatchEvent(type) === false) { 39901 result = false; 39902 } 39903 39904 return result; 39905 }, 39906 _getBounds = function _getBounds(target, context) { 39907 var e = _toArray(target)[0], 39908 top, 39909 left, 39910 offset; 39911 39912 if (!e.nodeType && e !== _win$1) { 39913 if (!_isUndefined(target.left)) { 39914 offset = { 39915 x: 0, 39916 y: 0 39917 }; 39918 return { 39919 left: target.left - offset.x, 39920 top: target.top - offset.y, 39921 width: target.width, 39922 height: target.height 39923 }; 39924 } 39925 39926 left = target.min || target.minX || target.minRotation || 0; 39927 top = target.min || target.minY || 0; 39928 return { 39929 left: left, 39930 top: top, 39931 width: (target.max || target.maxX || target.maxRotation || 0) - left, 39932 height: (target.max || target.maxY || 0) - top 39933 }; 39934 } 39935 39936 return _getElementBounds(e, context); 39937 }, 39938 _point1 = {}, 39939 _getElementBounds = function _getElementBounds(element, context) { 39940 context = _toArray(context)[0]; 39941 var isSVG = element.getBBox && element.ownerSVGElement, 39942 doc = element.ownerDocument || _doc$1, 39943 left, 39944 right, 39945 top, 39946 bottom, 39947 matrix, 39948 p1, 39949 p2, 39950 p3, 39951 p4, 39952 bbox, 39953 width, 39954 height, 39955 cs; 39956 39957 if (element === _win$1) { 39958 top = _getDocScrollTop$1(doc); 39959 left = _getDocScrollLeft$1(doc); 39960 right = left + (doc.documentElement.clientWidth || element.innerWidth || doc.body.clientWidth || 0); 39961 bottom = top + ((element.innerHeight || 0) - 20 < doc.documentElement.clientHeight ? doc.documentElement.clientHeight : element.innerHeight || doc.body.clientHeight || 0); 39962 } else if (context === _win$1 || _isUndefined(context)) { 39963 return element.getBoundingClientRect(); 39964 } else { 39965 left = top = 0; 39966 39967 if (isSVG) { 39968 bbox = element.getBBox(); 39969 width = bbox.width; 39970 height = bbox.height; 39971 } else { 39972 if (element.viewBox && (bbox = element.viewBox.baseVal)) { 39973 left = bbox.x || 0; 39974 top = bbox.y || 0; 39975 width = bbox.width; 39976 height = bbox.height; 39977 } 39978 39979 if (!width) { 39980 cs = _getComputedStyle(element); 39981 bbox = cs.boxSizing === "border-box"; 39982 width = (parseFloat(cs.width) || element.clientWidth || 0) + (bbox ? 0 : parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth)); 39983 height = (parseFloat(cs.height) || element.clientHeight || 0) + (bbox ? 0 : parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth)); 39984 } 39985 } 39986 39987 right = width; 39988 bottom = height; 39989 } 39990 39991 if (element === context) { 39992 return { 39993 left: left, 39994 top: top, 39995 width: right - left, 39996 height: bottom - top 39997 }; 39998 } 39999 40000 matrix = getGlobalMatrix(context, true).multiply(getGlobalMatrix(element)); 40001 p1 = matrix.apply({ 40002 x: left, 40003 y: top 40004 }); 40005 p2 = matrix.apply({ 40006 x: right, 40007 y: top 40008 }); 40009 p3 = matrix.apply({ 40010 x: right, 40011 y: bottom 40012 }); 40013 p4 = matrix.apply({ 40014 x: left, 40015 y: bottom 40016 }); 40017 left = Math.min(p1.x, p2.x, p3.x, p4.x); 40018 top = Math.min(p1.y, p2.y, p3.y, p4.y); 40019 return { 40020 left: left, 40021 top: top, 40022 width: Math.max(p1.x, p2.x, p3.x, p4.x) - left, 40023 height: Math.max(p1.y, p2.y, p3.y, p4.y) - top 40024 }; 40025 }, 40026 _parseInertia = function _parseInertia(draggable, snap, max, min, factor, forceZeroVelocity) { 40027 var vars = {}, 40028 a, 40029 i, 40030 l; 40031 40032 if (snap) { 40033 if (factor !== 1 && snap instanceof Array) { 40034 vars.end = a = []; 40035 l = snap.length; 40036 40037 if (_isObject(snap[0])) { 40038 for (i = 0; i < l; i++) { 40039 a[i] = _copy(snap[i], factor); 40040 } 40041 } else { 40042 for (i = 0; i < l; i++) { 40043 a[i] = snap[i] * factor; 40044 } 40045 } 40046 40047 max += 1.1; 40048 min -= 1.1; 40049 } else if (_isFunction(snap)) { 40050 vars.end = function (value) { 40051 var result = snap.call(draggable, value), 40052 copy, 40053 p; 40054 40055 if (factor !== 1) { 40056 if (_isObject(result)) { 40057 copy = {}; 40058 40059 for (p in result) { 40060 copy[p] = result[p] * factor; 40061 } 40062 40063 result = copy; 40064 } else { 40065 result *= factor; 40066 } 40067 } 40068 40069 return result; 40070 }; 40071 } else { 40072 vars.end = snap; 40073 } 40074 } 40075 40076 if (max || max === 0) { 40077 vars.max = max; 40078 } 40079 40080 if (min || min === 0) { 40081 vars.min = min; 40082 } 40083 40084 if (forceZeroVelocity) { 40085 vars.velocity = 0; 40086 } 40087 40088 return vars; 40089 }, 40090 _isClickable = function _isClickable(element) { 40091 var data; 40092 return !element || !element.getAttribute || element === _body$1 ? false : (data = element.getAttribute("data-clickable")) === "true" || data !== "false" && (_clickableTagExp.test(element.nodeName + "") || element.getAttribute("contentEditable") === "true") ? true : _isClickable(element.parentNode); 40093 }, 40094 _setSelectable = function _setSelectable(elements, selectable) { 40095 var i = elements.length, 40096 e; 40097 40098 while (i--) { 40099 e = elements[i]; 40100 e.ondragstart = e.onselectstart = selectable ? null : _emptyFunc; 40101 gsap.set(e, { 40102 lazy: true, 40103 userSelect: selectable ? "text" : "none" 40104 }); 40105 } 40106 }, 40107 _isFixed$1 = function _isFixed(element) { 40108 if (_getComputedStyle(element).position === "fixed") { 40109 return true; 40110 } 40111 40112 element = element.parentNode; 40113 40114 if (element && element.nodeType === 1) { 40115 return _isFixed(element); 40116 } 40117 }, 40118 _supports3D, 40119 _addPaddingBR, 40120 ScrollProxy = function ScrollProxy(element, vars) { 40121 element = gsap.utils.toArray(element)[0]; 40122 vars = vars || {}; 40123 var content = document.createElement("div"), 40124 style = content.style, 40125 node = element.firstChild, 40126 offsetTop = 0, 40127 offsetLeft = 0, 40128 prevTop = element.scrollTop, 40129 prevLeft = element.scrollLeft, 40130 scrollWidth = element.scrollWidth, 40131 scrollHeight = element.scrollHeight, 40132 extraPadRight = 0, 40133 maxLeft = 0, 40134 maxTop = 0, 40135 elementWidth, 40136 elementHeight, 40137 contentHeight, 40138 nextNode, 40139 transformStart, 40140 transformEnd; 40141 40142 if (_supports3D && vars.force3D !== false) { 40143 transformStart = "translate3d("; 40144 transformEnd = "px,0px)"; 40145 } else if (_transformProp$1) { 40146 transformStart = "translate("; 40147 transformEnd = "px)"; 40148 } 40149 40150 this.scrollTop = function (value, force) { 40151 if (!arguments.length) { 40152 return -this.top(); 40153 } 40154 40155 this.top(-value, force); 40156 }; 40157 40158 this.scrollLeft = function (value, force) { 40159 if (!arguments.length) { 40160 return -this.left(); 40161 } 40162 40163 this.left(-value, force); 40164 }; 40165 40166 this.left = function (value, force) { 40167 if (!arguments.length) { 40168 return -(element.scrollLeft + offsetLeft); 40169 } 40170 40171 var dif = element.scrollLeft - prevLeft, 40172 oldOffset = offsetLeft; 40173 40174 if ((dif > 2 || dif < -2) && !force) { 40175 prevLeft = element.scrollLeft; 40176 gsap.killTweensOf(this, { 40177 left: 1, 40178 scrollLeft: 1 40179 }); 40180 this.left(-prevLeft); 40181 40182 if (vars.onKill) { 40183 vars.onKill(); 40184 } 40185 40186 return; 40187 } 40188 40189 value = -value; 40190 40191 if (value < 0) { 40192 offsetLeft = value - 0.5 | 0; 40193 value = 0; 40194 } else if (value > maxLeft) { 40195 offsetLeft = value - maxLeft | 0; 40196 value = maxLeft; 40197 } else { 40198 offsetLeft = 0; 40199 } 40200 40201 if (offsetLeft || oldOffset) { 40202 if (!this._skip) { 40203 style[_transformProp$1] = transformStart + -offsetLeft + "px," + -offsetTop + transformEnd; 40204 } 40205 40206 if (offsetLeft + extraPadRight >= 0) { 40207 style.paddingRight = offsetLeft + extraPadRight + "px"; 40208 } 40209 } 40210 40211 element.scrollLeft = value | 0; 40212 prevLeft = element.scrollLeft; 40213 }; 40214 40215 this.top = function (value, force) { 40216 if (!arguments.length) { 40217 return -(element.scrollTop + offsetTop); 40218 } 40219 40220 var dif = element.scrollTop - prevTop, 40221 oldOffset = offsetTop; 40222 40223 if ((dif > 2 || dif < -2) && !force) { 40224 prevTop = element.scrollTop; 40225 gsap.killTweensOf(this, { 40226 top: 1, 40227 scrollTop: 1 40228 }); 40229 this.top(-prevTop); 40230 40231 if (vars.onKill) { 40232 vars.onKill(); 40233 } 40234 40235 return; 40236 } 40237 40238 value = -value; 40239 40240 if (value < 0) { 40241 offsetTop = value - 0.5 | 0; 40242 value = 0; 40243 } else if (value > maxTop) { 40244 offsetTop = value - maxTop | 0; 40245 value = maxTop; 40246 } else { 40247 offsetTop = 0; 40248 } 40249 40250 if (offsetTop || oldOffset) { 40251 if (!this._skip) { 40252 style[_transformProp$1] = transformStart + -offsetLeft + "px," + -offsetTop + transformEnd; 40253 } 40254 } 40255 40256 element.scrollTop = value | 0; 40257 prevTop = element.scrollTop; 40258 }; 40259 40260 this.maxScrollTop = function () { 40261 return maxTop; 40262 }; 40263 40264 this.maxScrollLeft = function () { 40265 return maxLeft; 40266 }; 40267 40268 this.disable = function () { 40269 node = content.firstChild; 40270 40271 while (node) { 40272 nextNode = node.nextSibling; 40273 element.appendChild(node); 40274 node = nextNode; 40275 } 40276 40277 if (element === content.parentNode) { 40278 element.removeChild(content); 40279 } 40280 }; 40281 40282 this.enable = function () { 40283 node = element.firstChild; 40284 40285 if (node === content) { 40286 return; 40287 } 40288 40289 while (node) { 40290 nextNode = node.nextSibling; 40291 content.appendChild(node); 40292 node = nextNode; 40293 } 40294 40295 element.appendChild(content); 40296 this.calibrate(); 40297 }; 40298 40299 this.calibrate = function (force) { 40300 var widthMatches = element.clientWidth === elementWidth, 40301 cs, 40302 x, 40303 y; 40304 prevTop = element.scrollTop; 40305 prevLeft = element.scrollLeft; 40306 40307 if (widthMatches && element.clientHeight === elementHeight && content.offsetHeight === contentHeight && scrollWidth === element.scrollWidth && scrollHeight === element.scrollHeight && !force) { 40308 return; 40309 } 40310 40311 if (offsetTop || offsetLeft) { 40312 x = this.left(); 40313 y = this.top(); 40314 this.left(-element.scrollLeft); 40315 this.top(-element.scrollTop); 40316 } 40317 40318 cs = _getComputedStyle(element); 40319 40320 if (!widthMatches || force) { 40321 style.display = "block"; 40322 style.width = "auto"; 40323 style.paddingRight = "0px"; 40324 extraPadRight = Math.max(0, element.scrollWidth - element.clientWidth); 40325 40326 if (extraPadRight) { 40327 extraPadRight += parseFloat(cs.paddingLeft) + (_addPaddingBR ? parseFloat(cs.paddingRight) : 0); 40328 } 40329 } 40330 40331 style.display = "inline-block"; 40332 style.position = "relative"; 40333 style.overflow = "visible"; 40334 style.verticalAlign = "top"; 40335 style.boxSizing = "content-box"; 40336 style.width = "100%"; 40337 style.paddingRight = extraPadRight + "px"; 40338 40339 if (_addPaddingBR) { 40340 style.paddingBottom = cs.paddingBottom; 40341 } 40342 40343 elementWidth = element.clientWidth; 40344 elementHeight = element.clientHeight; 40345 scrollWidth = element.scrollWidth; 40346 scrollHeight = element.scrollHeight; 40347 maxLeft = element.scrollWidth - elementWidth; 40348 maxTop = element.scrollHeight - elementHeight; 40349 contentHeight = content.offsetHeight; 40350 style.display = "block"; 40351 40352 if (x || y) { 40353 this.left(x); 40354 this.top(y); 40355 } 40356 }; 40357 40358 this.content = content; 40359 this.element = element; 40360 this._skip = false; 40361 this.enable(); 40362 }, 40363 _initCore = function _initCore(required) { 40364 if (_windowExists() && document.body) { 40365 var nav = window && window.navigator; 40366 _win$1 = window; 40367 _doc$1 = document; 40368 _docElement$1 = _doc$1.documentElement; 40369 _body$1 = _doc$1.body; 40370 _tempDiv = _createElement("div"); 40371 _supportsPointer = !!window.PointerEvent; 40372 _placeholderDiv = _createElement("div"); 40373 _placeholderDiv.style.cssText = "visibility:hidden;height:1px;top:-1px;pointer-events:none;position:relative;clear:both;cursor:grab"; 40374 _defaultCursor = _placeholderDiv.style.cursor === "grab" ? "grab" : "move"; 40375 _isAndroid = nav && nav.userAgent.toLowerCase().indexOf("android") !== -1; 40376 _isTouchDevice = "ontouchstart" in _docElement$1 && "orientation" in _win$1 || nav && (nav.MaxTouchPoints > 0 || nav.msMaxTouchPoints > 0); 40377 40378 _addPaddingBR = function () { 40379 var div = _createElement("div"), 40380 child = _createElement("div"), 40381 childStyle = child.style, 40382 parent = _body$1, 40383 val; 40384 40385 childStyle.display = "inline-block"; 40386 childStyle.position = "relative"; 40387 div.style.cssText = "width:90px;height:40px;padding:10px;overflow:auto;visibility:hidden"; 40388 div.appendChild(child); 40389 parent.appendChild(div); 40390 val = child.offsetHeight + 18 > div.scrollHeight; 40391 parent.removeChild(div); 40392 return val; 40393 }(); 40394 40395 _touchEventLookup = function (types) { 40396 var standard = types.split(","), 40397 converted = ("onpointerdown" in _tempDiv ? "pointerdown,pointermove,pointerup,pointercancel" : "onmspointerdown" in _tempDiv ? "MSPointerDown,MSPointerMove,MSPointerUp,MSPointerCancel" : types).split(","), 40398 obj = {}, 40399 i = 4; 40400 40401 while (--i > -1) { 40402 obj[standard[i]] = converted[i]; 40403 obj[converted[i]] = standard[i]; 40404 } 40405 40406 try { 40407 _docElement$1.addEventListener("test", null, Object.defineProperty({}, "passive", { 40408 get: function get() { 40409 _supportsPassive = 1; 40410 } 40411 })); 40412 } catch (e) {} 40413 40414 return obj; 40415 }("touchstart,touchmove,touchend,touchcancel"); 40416 40417 _addListener(_doc$1, "touchcancel", _emptyFunc); 40418 40419 _addListener(_win$1, "touchmove", _emptyFunc); 40420 40421 _body$1 && _body$1.addEventListener("touchstart", _emptyFunc); 40422 40423 _addListener(_doc$1, "contextmenu", function () { 40424 for (var p in _lookup) { 40425 if (_lookup[p].isPressed) { 40426 _lookup[p].endDrag(); 40427 } 40428 } 40429 }); 40430 40431 gsap = _coreInitted = _getGSAP(); 40432 } 40433 40434 if (gsap) { 40435 InertiaPlugin = gsap.plugins.inertia; 40436 40437 _context = gsap.core.context || function () {}; 40438 40439 _checkPrefix = gsap.utils.checkPrefix; 40440 _transformProp$1 = _checkPrefix(_transformProp$1); 40441 _transformOriginProp$1 = _checkPrefix(_transformOriginProp$1); 40442 _toArray = gsap.utils.toArray; 40443 _getStyleSaver = gsap.core.getStyleSaver; 40444 _supports3D = !!_checkPrefix("perspective"); 40445 } else if (required) { 40446 console.warn("Please gsap.registerPlugin(Draggable)"); 40447 } 40448 }; 40449 40450 var EventDispatcher = function () { 40451 function EventDispatcher(target) { 40452 this._listeners = {}; 40453 this.target = target || this; 40454 } 40455 40456 var _proto = EventDispatcher.prototype; 40457 40458 _proto.addEventListener = function addEventListener(type, callback) { 40459 var list = this._listeners[type] || (this._listeners[type] = []); 40460 40461 if (!~list.indexOf(callback)) { 40462 list.push(callback); 40463 } 40464 }; 40465 40466 _proto.removeEventListener = function removeEventListener(type, callback) { 40467 var list = this._listeners[type], 40468 i = list && list.indexOf(callback); 40469 i >= 0 && list.splice(i, 1); 40470 }; 40471 40472 _proto.dispatchEvent = function dispatchEvent(type) { 40473 var _this = this; 40474 40475 var result; 40476 (this._listeners[type] || []).forEach(function (callback) { 40477 return callback.call(_this, { 40478 type: type, 40479 target: _this.target 40480 }) === false && (result = false); 40481 }); 40482 return result; 40483 }; 40484 40485 return EventDispatcher; 40486 }(); 40487 40488 var Draggable = function (_EventDispatcher) { 40489 _inheritsLoose(Draggable, _EventDispatcher); 40490 40491 function Draggable(target, vars) { 40492 var _this2; 40493 40494 _this2 = _EventDispatcher.call(this) || this; 40495 _coreInitted || _initCore(1); 40496 target = _toArray(target)[0]; 40497 _this2.styles = _getStyleSaver && _getStyleSaver(target, "transform,left,top"); 40498 40499 if (!InertiaPlugin) { 40500 InertiaPlugin = gsap.plugins.inertia; 40501 } 40502 40503 _this2.vars = vars = _copy(vars || {}); 40504 _this2.target = target; 40505 _this2.x = _this2.y = _this2.rotation = 0; 40506 _this2.dragResistance = parseFloat(vars.dragResistance) || 0; 40507 _this2.edgeResistance = isNaN(vars.edgeResistance) ? 1 : parseFloat(vars.edgeResistance) || 0; 40508 _this2.lockAxis = vars.lockAxis; 40509 _this2.autoScroll = vars.autoScroll || 0; 40510 _this2.lockedAxis = null; 40511 _this2.allowEventDefault = !!vars.allowEventDefault; 40512 gsap.getProperty(target, "x"); 40513 40514 var type = (vars.type || "x,y").toLowerCase(), 40515 xyMode = ~type.indexOf("x") || ~type.indexOf("y"), 40516 rotationMode = type.indexOf("rotation") !== -1, 40517 xProp = rotationMode ? "rotation" : xyMode ? "x" : "left", 40518 yProp = xyMode ? "y" : "top", 40519 allowX = !!(~type.indexOf("x") || ~type.indexOf("left") || type === "scroll"), 40520 allowY = !!(~type.indexOf("y") || ~type.indexOf("top") || type === "scroll"), 40521 minimumMovement = vars.minimumMovement || 2, 40522 self = _assertThisInitialized(_this2), 40523 triggers = _toArray(vars.trigger || vars.handle || target), 40524 killProps = {}, 40525 dragEndTime = 0, 40526 checkAutoScrollBounds = false, 40527 autoScrollMarginTop = vars.autoScrollMarginTop || 40, 40528 autoScrollMarginRight = vars.autoScrollMarginRight || 40, 40529 autoScrollMarginBottom = vars.autoScrollMarginBottom || 40, 40530 autoScrollMarginLeft = vars.autoScrollMarginLeft || 40, 40531 isClickable = vars.clickableTest || _isClickable, 40532 clickTime = 0, 40533 gsCache = target._gsap || gsap.core.getCache(target), 40534 isFixed = _isFixed$1(target), 40535 getPropAsNum = function getPropAsNum(property, unit) { 40536 return parseFloat(gsCache.get(target, property, unit)); 40537 }, 40538 ownerDoc = target.ownerDocument || _doc$1, 40539 enabled, 40540 scrollProxy, 40541 startPointerX, 40542 startPointerY, 40543 startElementX, 40544 startElementY, 40545 hasBounds, 40546 hasDragCallback, 40547 hasMoveCallback, 40548 maxX, 40549 minX, 40550 maxY, 40551 minY, 40552 touch, 40553 touchID, 40554 rotationOrigin, 40555 dirty, 40556 old, 40557 snapX, 40558 snapY, 40559 snapXY, 40560 isClicking, 40561 touchEventTarget, 40562 matrix, 40563 interrupted, 40564 allowNativeTouchScrolling, 40565 touchDragAxis, 40566 isDispatching, 40567 clickDispatch, 40568 trustedClickDispatch, 40569 isPreventingDefault, 40570 innerMatrix, 40571 dragged, 40572 onContextMenu = function onContextMenu(e) { 40573 _preventDefault(e); 40574 40575 e.stopImmediatePropagation && e.stopImmediatePropagation(); 40576 return false; 40577 }, 40578 render = function render(suppressEvents) { 40579 if (self.autoScroll && self.isDragging && (checkAutoScrollBounds || dirty)) { 40580 var e = target, 40581 autoScrollFactor = self.autoScroll * 15, 40582 parent, 40583 isRoot, 40584 rect, 40585 pointerX, 40586 pointerY, 40587 changeX, 40588 changeY, 40589 gap; 40590 checkAutoScrollBounds = false; 40591 _windowProxy.scrollTop = _win$1.pageYOffset != null ? _win$1.pageYOffset : ownerDoc.documentElement.scrollTop != null ? ownerDoc.documentElement.scrollTop : ownerDoc.body.scrollTop; 40592 _windowProxy.scrollLeft = _win$1.pageXOffset != null ? _win$1.pageXOffset : ownerDoc.documentElement.scrollLeft != null ? ownerDoc.documentElement.scrollLeft : ownerDoc.body.scrollLeft; 40593 pointerX = self.pointerX - _windowProxy.scrollLeft; 40594 pointerY = self.pointerY - _windowProxy.scrollTop; 40595 40596 while (e && !isRoot) { 40597 isRoot = _isRoot(e.parentNode); 40598 parent = isRoot ? _windowProxy : e.parentNode; 40599 rect = isRoot ? { 40600 bottom: Math.max(_docElement$1.clientHeight, _win$1.innerHeight || 0), 40601 right: Math.max(_docElement$1.clientWidth, _win$1.innerWidth || 0), 40602 left: 0, 40603 top: 0 40604 } : parent.getBoundingClientRect(); 40605 changeX = changeY = 0; 40606 40607 if (allowY) { 40608 gap = parent._gsMaxScrollY - parent.scrollTop; 40609 40610 if (gap < 0) { 40611 changeY = gap; 40612 } else if (pointerY > rect.bottom - autoScrollMarginBottom && gap) { 40613 checkAutoScrollBounds = true; 40614 changeY = Math.min(gap, autoScrollFactor * (1 - Math.max(0, rect.bottom - pointerY) / autoScrollMarginBottom) | 0); 40615 } else if (pointerY < rect.top + autoScrollMarginTop && parent.scrollTop) { 40616 checkAutoScrollBounds = true; 40617 changeY = -Math.min(parent.scrollTop, autoScrollFactor * (1 - Math.max(0, pointerY - rect.top) / autoScrollMarginTop) | 0); 40618 } 40619 40620 if (changeY) { 40621 parent.scrollTop += changeY; 40622 } 40623 } 40624 40625 if (allowX) { 40626 gap = parent._gsMaxScrollX - parent.scrollLeft; 40627 40628 if (gap < 0) { 40629 changeX = gap; 40630 } else if (pointerX > rect.right - autoScrollMarginRight && gap) { 40631 checkAutoScrollBounds = true; 40632 changeX = Math.min(gap, autoScrollFactor * (1 - Math.max(0, rect.right - pointerX) / autoScrollMarginRight) | 0); 40633 } else if (pointerX < rect.left + autoScrollMarginLeft && parent.scrollLeft) { 40634 checkAutoScrollBounds = true; 40635 changeX = -Math.min(parent.scrollLeft, autoScrollFactor * (1 - Math.max(0, pointerX - rect.left) / autoScrollMarginLeft) | 0); 40636 } 40637 40638 if (changeX) { 40639 parent.scrollLeft += changeX; 40640 } 40641 } 40642 40643 if (isRoot && (changeX || changeY)) { 40644 _win$1.scrollTo(parent.scrollLeft, parent.scrollTop); 40645 40646 setPointerPosition(self.pointerX + changeX, self.pointerY + changeY); 40647 } 40648 40649 e = parent; 40650 } 40651 } 40652 40653 if (dirty) { 40654 var x = self.x, 40655 y = self.y; 40656 40657 if (rotationMode) { 40658 self.deltaX = x - parseFloat(gsCache.rotation); 40659 self.rotation = x; 40660 gsCache.rotation = x + "deg"; 40661 gsCache.renderTransform(1, gsCache); 40662 } else { 40663 if (scrollProxy) { 40664 if (allowY) { 40665 self.deltaY = y - scrollProxy.top(); 40666 scrollProxy.top(y); 40667 } 40668 40669 if (allowX) { 40670 self.deltaX = x - scrollProxy.left(); 40671 scrollProxy.left(x); 40672 } 40673 } else if (xyMode) { 40674 if (allowY) { 40675 self.deltaY = y - parseFloat(gsCache.y); 40676 gsCache.y = y + "px"; 40677 } 40678 40679 if (allowX) { 40680 self.deltaX = x - parseFloat(gsCache.x); 40681 gsCache.x = x + "px"; 40682 } 40683 40684 gsCache.renderTransform(1, gsCache); 40685 } else { 40686 if (allowY) { 40687 self.deltaY = y - parseFloat(target.style.top || 0); 40688 target.style.top = y + "px"; 40689 } 40690 40691 if (allowX) { 40692 self.deltaX = x - parseFloat(target.style.left || 0); 40693 target.style.left = x + "px"; 40694 } 40695 } 40696 } 40697 40698 if (hasDragCallback && !suppressEvents && !isDispatching) { 40699 isDispatching = true; 40700 40701 if (_dispatchEvent(self, "drag", "onDrag") === false) { 40702 if (allowX) { 40703 self.x -= self.deltaX; 40704 } 40705 40706 if (allowY) { 40707 self.y -= self.deltaY; 40708 } 40709 40710 render(true); 40711 } 40712 40713 isDispatching = false; 40714 } 40715 } 40716 40717 dirty = false; 40718 }, 40719 syncXY = function syncXY(skipOnUpdate, skipSnap) { 40720 var x = self.x, 40721 y = self.y, 40722 snappedValue, 40723 cs; 40724 40725 if (!target._gsap) { 40726 gsCache = gsap.core.getCache(target); 40727 } 40728 40729 gsCache.uncache && gsap.getProperty(target, "x"); 40730 40731 if (xyMode) { 40732 self.x = parseFloat(gsCache.x); 40733 self.y = parseFloat(gsCache.y); 40734 } else if (rotationMode) { 40735 self.x = self.rotation =
40735parseFloat(gsCache.rotation
vendor: 18,327 bytes, lines 40735-41285
40735); 40736 } else if (scrollProxy) { 40737 self.y = scrollProxy.top(); 40738 self.x = scrollProxy.left(); 40739 } else { 40740 self.y = parseFloat(target.style.top || (cs = _getComputedStyle(target)) && cs.top) || 0; 40741 self.x = parseFloat(target.style.left || (cs || {}).left) || 0; 40742 } 40743 40744 if ((snapX || snapY || snapXY) && !skipSnap && (self.isDragging || self.isThrowing)) { 40745 if (snapXY) { 40746 _temp1.x = self.x; 40747 _temp1.y = self.y; 40748 snappedValue = snapXY(_temp1); 40749 40750 if (snappedValue.x !== self.x) { 40751 self.x = snappedValue.x; 40752 dirty = true; 40753 } 40754 40755 if (snappedValue.y !== self.y) { 40756 self.y = snappedValue.y; 40757 dirty = true; 40758 } 40759 } 40760 40761 if (snapX) { 40762 snappedValue = snapX(self.x); 40763 40764 if (snappedValue !== self.x) { 40765 self.x = snappedValue; 40766 40767 if (rotationMode) { 40768 self.rotation = snappedValue; 40769 } 40770 40771 dirty = true; 40772 } 40773 } 40774 40775 if (snapY) { 40776 snappedValue = snapY(self.y); 40777 40778 if (snappedValue !== self.y) { 40779 self.y = snappedValue; 40780 } 40781 40782 dirty = true; 40783 } 40784 } 40785 40786 dirty && render(true); 40787 40788 if (!skipOnUpdate) { 40789 self.deltaX = self.x - x; 40790 self.deltaY = self.y - y; 40791 40792 _dispatchEvent(self, "throwupdate", "onThrowUpdate"); 40793 } 40794 }, 40795 buildSnapFunc = function buildSnapFunc(snap, min, max, factor) { 40796 if (min == null) { 40797 min = -_bigNum; 40798 } 40799 40800 if (max == null) { 40801 max = _bigNum; 40802 } 40803 40804 if (_isFunction(snap)) { 40805 return function (n) { 40806 var edgeTolerance = !self.isPressed ? 1 : 1 - self.edgeResistance; 40807 return snap.call(self, (n > max ? max + (n - max) * edgeTolerance : n < min ? min + (n - min) * edgeTolerance : n) * factor) * factor; 40808 }; 40809 } 40810 40811 if (_isArray(snap)) { 40812 return function (n) { 40813 var i = snap.length, 40814 closest = 0, 40815 absDif = _bigNum, 40816 val, 40817 dif; 40818 40819 while (--i > -1) { 40820 val = snap[i]; 40821 dif = val - n; 40822 40823 if (dif < 0) { 40824 dif = -dif; 40825 } 40826 40827 if (dif < absDif && val >= min && val <= max) { 40828 closest = i; 40829 absDif = dif; 40830 } 40831 } 40832 40833 return snap[closest]; 40834 }; 40835 } 40836 40837 return isNaN(snap) ? function (n) { 40838 return n; 40839 } : function () { 40840 return snap * factor; 40841 }; 40842 }, 40843 buildPointSnapFunc = function buildPointSnapFunc(snap, minX, maxX, minY, maxY, radius, factor) { 40844 radius = radius && radius < _bigNum ? radius * radius : _bigNum; 40845 40846 if (_isFunction(snap)) { 40847 return function (point) { 40848 var edgeTolerance = !self.isPressed ? 1 : 1 - self.edgeResistance, 40849 x = point.x, 40850 y = point.y, 40851 result, 40852 dx, 40853 dy; 40854 point.x = x = x > maxX ? maxX + (x - maxX) * edgeTolerance : x < minX ? minX + (x - minX) * edgeTolerance : x; 40855 point.y = y = y > maxY ? maxY + (y - maxY) * edgeTolerance : y < minY ? minY + (y - minY) * edgeTolerance : y; 40856 result = snap.call(self, point); 40857 40858 if (result !== point) { 40859 point.x = result.x; 40860 point.y = result.y; 40861 } 40862 40863 if (factor !== 1) { 40864 point.x *= factor; 40865 point.y *= factor; 40866 } 40867 40868 if (radius < _bigNum) { 40869 dx = point.x - x; 40870 dy = point.y - y; 40871 40872 if (dx * dx + dy * dy > radius) { 40873 point.x = x; 40874 point.y = y; 40875 } 40876 } 40877 40878 return point; 40879 }; 40880 } 40881 40882 if (_isArray(snap)) { 40883 return function (p) { 40884 var i = snap.length, 40885 closest = 0, 40886 minDist = _bigNum, 40887 x, 40888 y, 40889 point, 40890 dist; 40891 40892 while (--i > -1) { 40893 point = snap[i]; 40894 x = point.x - p.x; 40895 y = point.y - p.y; 40896 dist = x * x + y * y; 40897 40898 if (dist < minDist) { 40899 closest = i; 40900 minDist = dist; 40901 } 40902 } 40903 40904 return minDist <= radius ? snap[closest] : p; 40905 }; 40906 } 40907 40908 return function (n) { 40909 return n; 40910 }; 40911 }, 40912 calculateBounds = function calculateBounds() { 40913 var bounds, targetBounds, snap, snapIsRaw; 40914 hasBounds = false; 40915 40916 if (scrollProxy) { 40917 scrollProxy.calibrate(); 40918 self.minX = minX = -scrollProxy.maxScrollLeft(); 40919 self.minY = minY = -scrollProxy.maxScrollTop(); 40920 self.maxX = maxX = self.maxY = maxY = 0; 40921 hasBounds = true; 40922 } else if (!!vars.bounds) { 40923 bounds = _getBounds(vars.bounds, target.parentNode); 40924 40925 if (rotationMode) { 40926 self.minX = minX = bounds.left; 40927 self.maxX = maxX = bounds.left + bounds.width; 40928 self.minY = minY = self.maxY = maxY = 0; 40929 } else if (!_isUndefined(vars.bounds.maxX) || !_isUndefined(vars.bounds.maxY)) { 40930 bounds = vars.bounds; 40931 self.minX = minX = bounds.minX; 40932 self.minY = minY = bounds.minY; 40933 self.maxX = maxX = bounds.maxX; 40934 self.maxY = maxY = bounds.maxY; 40935 } else { 40936 targetBounds = _getBounds(target, target.parentNode); 40937 self.minX = minX = Math.round(getPropAsNum(xProp, "px") + bounds.left - targetBounds.left); 40938 self.minY = minY = Math.round(getPropAsNum(yProp, "px") + bounds.top - targetBounds.top); 40939 self.maxX = maxX = Math.round(minX + (bounds.width - targetBounds.width)); 40940 self.maxY = maxY = Math.round(minY + (bounds.height - targetBounds.height)); 40941 } 40942 40943 if (minX > maxX) { 40944 self.minX = maxX; 40945 self.maxX = maxX = minX; 40946 minX = self.minX; 40947 } 40948 40949 if (minY > maxY) { 40950 self.minY = maxY; 40951 self.maxY = maxY = minY; 40952 minY = self.minY; 40953 } 40954 40955 if (rotationMode) { 40956 self.minRotation = minX; 40957 self.maxRotation = maxX; 40958 } 40959 40960 hasBounds = true; 40961 } 40962 40963 if (vars.liveSnap) { 40964 snap = vars.liveSnap === true ? vars.snap || {} : vars.liveSnap; 40965 snapIsRaw = _isArray(snap) || _isFunction(snap); 40966 40967 if (rotationMode) { 40968 snapX = buildSnapFunc(snapIsRaw ? snap : snap.rotation, minX, maxX, 1); 40969 snapY = null; 40970 } else { 40971 if (snap.points) { 40972 snapXY = buildPointSnapFunc(snapIsRaw ? snap : snap.points, minX, maxX, minY, maxY, snap.radius, scrollProxy ? -1 : 1); 40973 } else { 40974 if (allowX) { 40975 snapX = buildSnapFunc(snapIsRaw ? snap : snap.x || snap.left || snap.scrollLeft, minX, maxX, scrollProxy ? -1 : 1); 40976 } 40977 40978 if (allowY) { 40979 snapY = buildSnapFunc(snapIsRaw ? snap : snap.y || snap.top || snap.scrollTop, minY, maxY, scrollProxy ? -1 : 1); 40980 } 40981 } 40982 } 40983 } 40984 }, 40985 onThrowComplete = function onThrowComplete() { 40986 self.isThrowing = false; 40987 40988 _dispatchEvent(self, "throwcomplete", "onThrowComplete"); 40989 }, 40990 onThrowInterrupt = function onThrowInterrupt() { 40991 self.isThrowing = false; 40992 }, 40993 animate = function animate(inertia, forceZeroVelocity) { 40994 var snap, snapIsRaw, tween, overshootTolerance; 40995 40996 if (inertia && InertiaPlugin) { 40997 if (inertia === true) { 40998 snap = vars.snap || vars.liveSnap || {}; 40999 snapIsRaw = _isArray(snap) || _isFunction(snap); 41000 inertia = { 41001 resistance: (vars.throwResistance || vars.resistance || 1000) / (rotationMode ? 10 : 1) 41002 }; 41003 41004 if (rotationMode) { 41005 inertia.rotation = _parseInertia(self, snapIsRaw ? snap : snap.rotation, maxX, minX, 1, forceZeroVelocity); 41006 } else { 41007 if (allowX) { 41008 inertia[xProp] = _parseInertia(self, snapIsRaw ? snap : snap.points || snap.x || snap.left, maxX, minX, scrollProxy ? -1 : 1, forceZeroVelocity || self.lockedAxis === "x"); 41009 } 41010 41011 if (allowY) { 41012 inertia[yProp] = _parseInertia(self, snapIsRaw ? snap : snap.points || snap.y || snap.top, maxY, minY, scrollProxy ? -1 : 1, forceZeroVelocity || self.lockedAxis === "y"); 41013 } 41014 41015 if (snap.points || _isArray(snap) && _isObject(snap[0])) { 41016 inertia.linkedProps = xProp + "," + yProp; 41017 inertia.radius = snap.radius; 41018 } 41019 } 41020 } 41021 41022 self.isThrowing = true; 41023 overshootTolerance = !isNaN(vars.overshootTolerance) ? vars.overshootTolerance : vars.edgeResistance === 1 ? 0 : 1 - self.edgeResistance + 0.2; 41024 41025 if (!inertia.duration) { 41026 inertia.duration = { 41027 max: Math.max(vars.minDuration || 0, "maxDuration" in vars ? vars.maxDuration : 2), 41028 min: !isNaN(vars.minDuration) ? vars.minDuration : overshootTolerance === 0 || _isObject(inertia) && inertia.resistance > 1000 ? 0 : 0.5, 41029 overshoot: overshootTolerance 41030 }; 41031 } 41032 41033 self.tween = tween = gsap.to(scrollProxy || target, { 41034 inertia: inertia, 41035 data: "_draggable", 41036 inherit: false, 41037 onComplete: onThrowComplete, 41038 onInterrupt: onThrowInterrupt, 41039 onUpdate: vars.fastMode ? _dispatchEvent : syncXY, 41040 onUpdateParams: vars.fastMode ? [self, "onthrowupdate", "onThrowUpdate"] : snap && snap.radius ? [false, true] : [] 41041 }); 41042 41043 if (!vars.fastMode) { 41044 if (scrollProxy) { 41045 scrollProxy._skip = true; 41046 } 41047 41048 tween.render(1e9, true, true); 41049 syncXY(true, true); 41050 self.endX = self.x; 41051 self.endY = self.y; 41052 41053 if (rotationMode) { 41054 self.endRotation = self.x; 41055 } 41056 41057 tween.play(0); 41058 syncXY(true, true); 41059 41060 if (scrollProxy) { 41061 scrollProxy._skip = false; 41062 } 41063 } 41064 } else if (hasBounds) { 41065 self.applyBounds(); 41066 } 41067 }, 41068 updateMatrix = function updateMatrix(shiftStart) { 41069 var start = matrix, 41070 p; 41071 matrix = getGlobalMatrix(target.parentNode, true); 41072 41073 if (shiftStart && self.isPressed && !matrix.equals(start || new Matrix2D())) { 41074 p = start.inverse().apply({ 41075 x: startPointerX, 41076 y: startPointerY 41077 }); 41078 matrix.apply(p, p); 41079 startPointerX = p.x; 41080 startPointerY = p.y; 41081 } 41082 41083 if (matrix.equals(_identityMatrix$1)) { 41084 matrix = null; 41085 } 41086 }, 41087 recordStartPositions = function recordStartPositions() { 41088 var edgeTolerance = 1 - self.edgeResistance, 41089 offsetX = isFixed ? _getDocScrollLeft$1(ownerDoc) : 0, 41090 offsetY = isFixed ? _getDocScrollTop$1(ownerDoc) : 0, 41091 parsedOrigin, 41092 x, 41093 y; 41094 41095 if (xyMode) { 41096 gsCache.x = getPropAsNum(xProp, "px") + "px"; 41097 gsCache.y = getPropAsNum(yProp, "px") + "px"; 41098 gsCache.renderTransform(); 41099 } 41100 41101 updateMatrix(false); 41102 _point1.x = self.pointerX - offsetX; 41103 _point1.y = self.pointerY - offsetY; 41104 matrix && matrix.apply(_point1, _point1); 41105 startPointerX = _point1.x; 41106 startPointerY = _point1.y; 41107 41108 if (dirty) { 41109 setPointerPosition(self.pointerX, self.pointerY); 41110 render(true); 41111 } 41112 41113 innerMatrix = getGlobalMatrix(target); 41114 41115 if (scrollProxy) { 41116 calculateBounds(); 41117 startElementY = scrollProxy.top(); 41118 startElementX = scrollProxy.left(); 41119 } else { 41120 if (isTweening()) { 41121 syncXY(true, true); 41122 calculateBounds(); 41123 } else { 41124 self.applyBounds(); 41125 } 41126 41127 if (rotationMode) { 41128 parsedOrigin = target.ownerSVGElement ? [gsCache.xOrigin - target.getBBox().x, gsCache.yOrigin - target.getBBox().y] : (_getComputedStyle(target)[_transformOriginProp$1] || "0 0").split(" "); 41129 rotationOrigin = self.rotationOrigin = getGlobalMatrix(target).apply({ 41130 x: parseFloat(parsedOrigin[0]) || 0, 41131 y: parseFloat(parsedOrigin[1]) || 0 41132 }); 41133 syncXY(true, true); 41134 x = self.pointerX - rotationOrigin.x - offsetX; 41135 y = rotationOrigin.y - self.pointerY + offsetY; 41136 startElementX = self.x; 41137 startElementY = self.y = Math.atan2(y, x) * _RAD2DEG; 41138 } else { 41139 startElementY = getPropAsNum(yProp, "px"); 41140 startElementX = getPropAsNum(xProp, "px"); 41141 } 41142 } 41143 41144 if (hasBounds && edgeTolerance) { 41145 if (startElementX > maxX) { 41146 startElementX = maxX + (startElementX - maxX) / edgeTolerance; 41147 } else if (startElementX < minX) { 41148 startElementX = minX - (minX - startElementX) / edgeTolerance; 41149 } 41150 41151 if (!rotationMode) { 41152 if (startElementY > maxY) { 41153 startElementY = maxY + (startElementY - maxY) / edgeTolerance; 41154 } else if (startElementY < minY) { 41155 startElementY = minY - (minY - startElementY) / edgeTolerance; 41156 } 41157 } 41158 } 41159 41160 self.startX = startElementX = _round(startElementX); 41161 self.startY = startElementY = _round(startElementY); 41162 }, 41163 isTweening = function isTweening() { 41164 return self.tween && self.tween.isActive(); 41165 }, 41166 removePlaceholder = function removePlaceholder() { 41167 if (_placeholderDiv.parentNode && !isTweening() && !self.isDragging) { 41168 _placeholderDiv.parentNode.removeChild(_placeholderDiv); 41169 } 41170 }, 41171 onPress = function onPress(e, force) { 41172 var i; 41173 41174 if (!enabled || self.isPressed || !e || (e.type === "mousedown" || e.type === "pointerdown") && !force && _getTime() - clickTime < 30 && _touchEventLookup[self.pointerEvent.type]) { 41175 isPreventingDefault && e && enabled && _preventDefault(e); 41176 return; 41177 } 41178 41179 interrupted = isTweening(); 41180 dragged = false; 41181 self.pointerEvent = e; 41182 41183 if (_touchEventLookup[e.type]) { 41184 touchEventTarget = ~e.type.indexOf("touch") ? e.currentTarget || e.target : ownerDoc; 41185 41186 _addListener(touchEventTarget, "touchend", onRelease); 41187 41188 _addListener(touchEventTarget, "touchmove", onMove); 41189 41190 _addListener(touchEventTarget, "touchcancel", onRelease); 41191 41192 _addListener(ownerDoc, "touchstart", _onMultiTouchDocument); 41193 } else { 41194 touchEventTarget = null; 41195 41196 _addListener(ownerDoc, "mousemove", onMove); 41197 } 41198 41199 touchDragAxis = null; 41200 41201 if (!_supportsPointer || !touchEventTarget) { 41202 _addListener(ownerDoc, "mouseup", onRelease); 41203 41204 e && e.target && _addListener(e.target, "mouseup", onRelease); 41205 } 41206 41207 isClicking = isClickable.call(self, e.target) && vars.dragClickables === false && !force; 41208 41209 if (isClicking) { 41210 _addListener(e.target, "change", onRelease); 41211 41212 _dispatchEvent(self, "pressInit", "onPressInit"); 41213 41214 _dispatchEvent(self, "press", "onPress"); 41215 41216 _setSelectable(triggers, true); 41217 41218 isPreventingDefault = false; 41219 return; 41220 } 41221 41222 allowNativeTouchScrolling = !touchEventTarget || allowX === allowY || self.vars.allowNativeTouchScrolling === false || self.vars.allowContextMenu && e && (e.ctrlKey || e.which > 2) ? false : allowX ? "y" : "x"; 41223 isPreventingDefault = !allowNativeTouchScrolling && !self.allowEventDefault; 41224 41225 if (isPreventingDefault) { 41226 _preventDefault(e); 41227 41228 _addListener(_win$1, "touchforcechange", _preventDefault); 41229 } 41230 41231 if (e.changedTouches) { 41232 e = touch = e.changedTouches[0]; 41233 touchID = e.identifier; 41234 } else if (e.pointerId) { 41235 touchID = e.pointerId; 41236 } else { 41237 touch = touchID = null; 41238 } 41239 41240 _dragCount++; 41241 41242 _addToRenderQueue(render); 41243 41244 startPointerY = self.pointerY = e.pageY; 41245 startPointerX = self.pointerX = e.pageX; 41246 41247 _dispatchEvent(self, "pressInit", "onPressInit"); 41248 41249 if (allowNativeTouchScrolling || self.autoScroll) { 41250 _recordMaxScrolls(target.parentNode); 41251 } 41252 41253 if (target.parentNode && self.autoScroll && !scrollProxy && !rotationMode && target.parentNode._gsMaxScrollX && !_placeholderDiv.parentNode && !target.getBBox) { 41254 _placeholderDiv.style.width = target.parentNode.scrollWidth + "px"; 41255 target.parentNode.appendChild(_placeholderDiv); 41256 } 41257 41258 recordStartPositions(); 41259 self.tween && self.tween.kill(); 41260 self.isThrowing = false; 41261 gsap.killTweensOf(scrollProxy || target, killProps, true); 41262 scrollProxy && gsap.killTweensOf(target, { 41263 scrollTo: 1 41264 }, true); 41265 self.tween = self.lockedAxis = null; 41266 41267 if (vars.zIndexBoost || !rotationMode && !scrollProxy && vars.zIndexBoost !== false) { 41268 target.style.zIndex = Draggable.zIndex++; 41269 } 41270 41271 self.isPressed = true; 41272 hasDragCallback = !!(vars.onDrag || self._listeners.drag); 41273 hasMoveCallback = !!(vars.onMove || self._listeners.move); 41274 41275 if (vars.cursor !== false || vars.activeCursor) { 41276 i = triggers.length; 41277 41278 while (--i > -1) { 41279 gsap.set(triggers[i], { 41280 cursor: vars.activeCursor || vars.cursor || (_defaultCursor === "grab" ? "grabbing" : _defaultCursor) 41281 }); 41282 } 41283 } 41284 41285 _dispatchEvent(self, "press", "onPress");
vendor: 2,447 bytes, lines 41286-41353
41286 }, 41287 onMove = function onMove(e) { 41288 var originalEvent = e, 41289 touches, 41290 pointerX, 41291 pointerY, 41292 i, 41293 dx, 41294 dy; 41295 41296 if (!enabled || _isMultiTouching || !self.isPressed || !e) { 41297 isPreventingDefault && e && enabled && _preventDefault(e); 41298 return; 41299 } 41300 41301 self.pointerEvent = e; 41302 touches = e.changedTouches; 41303 41304 if (touches) { 41305 e = touches[0]; 41306 41307 if (e !== touch && e.identifier !== touchID) { 41308 i = touches.length; 41309 41310 while (--i > -1 && (e = touches[i]).identifier !== touchID && e.target !== target) {} 41311 41312 if (i < 0) { 41313 return; 41314 } 41315 } 41316 } else if (e.pointerId && touchID && e.pointerId !== touchID) { 41317 return; 41318 } 41319 41320 if (touchEventTarget && allowNativeTouchScrolling && !touchDragAxis) { 41321 _point1.x = e.pageX - (isFixed ? _getDocScrollLeft$1(ownerDoc) : 0); 41322 _point1.y = e.pageY - (isFixed ? _getDocScrollTop$1(ownerDoc) : 0); 41323 matrix && matrix.apply(_point1, _point1); 41324 pointerX = _point1.x; 41325 pointerY = _point1.y; 41326 dx = Math.abs(pointerX - startPointerX); 41327 dy = Math.abs(pointerY - startPointerY); 41328 41329 if (dx !== dy && (dx > minimumMovement || dy > minimumMovement) || _isAndroid && allowNativeTouchScrolling === touchDragAxis) { 41330 touchDragAxis = dx > dy && allowX ? "x" : "y"; 41331 41332 if (allowNativeTouchScrolling && touchDragAxis !== allowNativeTouchScrolling) { 41333 _addListener(_win$1, "touchforcechange", _preventDefault); 41334 } 41335 41336 if (self.vars.lockAxisOnTouchScroll !== false && allowX && allowY) { 41337 self.lockedAxis = touchDragAxis === "x" ? "y" : "x"; 41338 _isFunction(self.vars.onLockAxis) && self.vars.onLockAxis.call(self, originalEvent); 41339 } 41340 41341 if (_isAndroid && allowNativeTouchScrolling === touchDragAxis) { 41342 onRelease(originalEvent); 41343 return; 41344 } 41345 } 41346 } 41347 41348 if (!self.allowEventDefault && (!allowNativeTouchScrolling || touchDragAxis && allowNativeTouchScrolling !== touchDragAxis) && originalEvent.cancelable !== false) { 41349 _preventDefault(originalEvent); 41350 41351 isPreventingDefault = true; 41352 } else if (isPreventingDefault) { 41353 isPreventingDefault = false;
vendor: 3,917 bytes, lines 41354-41482
41354 } 41355 41356 if (self.autoScroll) { 41357 checkAutoScrollBounds = true; 41358 } 41359 41360 setPointerPosition(e.pageX, e.pageY, hasMoveCallback); 41361 }, 41362 setPointerPosition = function setPointerPosition(pointerX, pointerY, invokeOnMove) { 41363 var dragTolerance = 1 - self.dragResistance, 41364 edgeTolerance = 1 - self.edgeResistance, 41365 prevPointerX = self.pointerX, 41366 prevPointerY = self.pointerY, 41367 prevStartElementY = startElementY, 41368 prevX = self.x, 41369 prevY = self.y, 41370 prevEndX = self.endX, 41371 prevEndY = self.endY, 41372 prevEndRotation = self.endRotation, 41373 prevDirty = dirty, 41374 xChange, 41375 yChange, 41376 x, 41377 y, 41378 dif, 41379 temp; 41380 self.pointerX = pointerX; 41381 self.pointerY = pointerY; 41382 41383 if (isFixed) { 41384 pointerX -= _getDocScrollLeft$1(ownerDoc); 41385 pointerY -= _getDocScrollTop$1(ownerDoc); 41386 } 41387 41388 if (rotationMode) { 41389 y = Math.atan2(rotationOrigin.y - pointerY, pointerX - rotationOrigin.x) * _RAD2DEG; 41390 dif = self.y - y; 41391 41392 if (dif > 180) { 41393 startElementY -= 360; 41394 self.y = y; 41395 } else if (dif < -180) { 41396 startElementY += 360; 41397 self.y = y; 41398 } 41399 41400 if (self.x !== startElementX || Math.abs(startElementY - y) > minimumMovement) { 41401 self.y = y; 41402 x = startElementX + (startElementY - y) * dragTolerance; 41403 } else { 41404 x = startElementX; 41405 } 41406 } else { 41407 if (matrix) { 41408 temp = pointerX * matrix.a + pointerY * matrix.c + matrix.e; 41409 pointerY = pointerX * matrix.b + pointerY * matrix.d + matrix.f; 41410 pointerX = temp; 41411 } 41412 41413 yChange = pointerY - startPointerY; 41414 xChange = pointerX - startPointerX; 41415 41416 if (yChange < minimumMovement && yChange > -minimumMovement) { 41417 yChange = 0; 41418 } 41419 41420 if (xChange < minimumMovement && xChange > -minimumMovement) { 41421 xChange = 0; 41422 } 41423 41424 if ((self.lockAxis || self.lockedAxis) && (xChange || yChange)) { 41425 temp = self.lockedAxis; 41426 41427 if (!temp) { 41428 self.lockedAxis = temp = allowX && Math.abs(xChange) > Math.abs(yChange) ? "y" : allowY ? "x" : null; 41429 41430 if (temp && _isFunction(self.vars.onLockAxis)) { 41431 self.vars.onLockAxis.call(self, self.pointerEvent); 41432 } 41433 } 41434 41435 if (temp === "y") { 41436 yChange = 0; 41437 } else if (temp === "x") { 41438 xChange = 0; 41439 } 41440 } 41441 41442 x = _round(startElementX + xChange * dragTolerance); 41443 y = _round(startElementY + yChange * dragTolerance); 41444 } 41445 41446 if ((snapX || snapY || snapXY) && (self.x !== x || self.y !== y && !rotationMode)) { 41447 if (snapXY) { 41448 _temp1.x = x; 41449 _temp1.y = y; 41450 temp = snapXY(_temp1); 41451 x = _round(temp.x); 41452 y = _round(temp.y); 41453 } 41454 41455 if (snapX) { 41456 x = _round(snapX(x)); 41457 } 41458 41459 if (snapY) { 41460 y = _round(snapY(y)); 41461 } 41462 } 41463 41464 if (hasBounds) { 41465 if (x > maxX) { 41466 x = maxX + Math.round((x - maxX) * edgeTolerance); 41467 } else if (x < minX) { 41468 x = minX + Math.round((x - minX) * edgeTolerance); 41469 } 41470 41471 if (!rotationMode) { 41472 if (y > maxY) { 41473 y = Math.round(maxY + (y - maxY) * edgeTolerance); 41474 } else if (y < minY) { 41475 y = Math.round(minY + (y - minY) * edgeTolerance); 41476 } 41477 } 41478 } 41479 41480 if (self.x !== x || self.y !== y && !rotationMode) { 41481 if (rotationMode) { 41482 self.endRotation = self.x = self.endX = x
vendor: 13,666 bytes, lines 41482-41889
41482; 41483 dirty = true; 41484 } else { 41485 if (allowY) { 41486 self.y = self.endY = y; 41487 dirty = true; 41488 } 41489 41490 if (allowX) { 41491 self.x = self.endX = x; 41492 dirty = true; 41493 } 41494 } 41495 41496 if (!invokeOnMove || _dispatchEvent(self, "move", "onMove") !== false) { 41497 if (!self.isDragging && self.isPressed) { 41498 self.isDragging = dragged = true; 41499 41500 _dispatchEvent(self, "dragstart", "onDragStart"); 41501 } 41502 } else { 41503 self.pointerX = prevPointerX; 41504 self.pointerY = prevPointerY; 41505 startElementY = prevStartElementY; 41506 self.x = prevX; 41507 self.y = prevY; 41508 self.endX = prevEndX; 41509 self.endY = prevEndY; 41510 self.endRotation = prevEndRotation; 41511 dirty = prevDirty; 41512 } 41513 } 41514 }, 41515 onRelease = function onRelease(e, force) { 41516 if (!enabled || !self.isPressed || e && touchID != null && !force && (e.pointerId && e.pointerId !== touchID && e.target !== target || e.changedTouches && !_hasTouchID(e.changedTouches, touchID))) { 41517 isPreventingDefault && e && enabled && _preventDefault(e); 41518 return; 41519 } 41520 41521 self.isPressed = false; 41522 var originalEvent = e, 41523 wasDragging = self.isDragging, 41524 isContextMenuRelease = self.vars.allowContextMenu && e && (e.ctrlKey || e.which > 2), 41525 placeholderDelayedCall = gsap.delayedCall(0.001, removePlaceholder), 41526 touches, 41527 i, 41528 syntheticEvent, 41529 eventTarget, 41530 syntheticClick; 41531 41532 if (touchEventTarget) { 41533 _removeListener(touchEventTarget, "touchend", onRelease); 41534 41535 _removeListener(touchEventTarget, "touchmove", onMove); 41536 41537 _removeListener(touchEventTarget, "touchcancel", onRelease); 41538 41539 _removeListener(ownerDoc, "touchstart", _onMultiTouchDocument); 41540 } else { 41541 _removeListener(ownerDoc, "mousemove", onMove); 41542 } 41543 41544 _removeListener(_win$1, "touchforcechange", _preventDefault); 41545 41546 if (!_supportsPointer || !touchEventTarget) { 41547 _removeListener(ownerDoc, "mouseup", onRelease); 41548 41549 e && e.target && _removeListener(e.target, "mouseup", onRelease); 41550 } 41551 41552 dirty = false; 41553 41554 if (wasDragging) { 41555 dragEndTime = _lastDragTime = _getTime(); 41556 self.isDragging = false; 41557 } 41558 41559 _removeFromRenderQueue(render); 41560 41561 if (isClicking && !isContextMenuRelease) { 41562 if (e) { 41563 _removeListener(e.target, "change", onRelease); 41564 41565 self.pointerEvent = originalEvent; 41566 } 41567 41568 _setSelectable(triggers, false); 41569 41570 _dispatchEvent(self, "release", "onRelease"); 41571 41572 _dispatchEvent(self, "click", "onClick"); 41573 41574 isClicking = false; 41575 return; 41576 } 41577 41578 i = triggers.length; 41579 41580 while (--i > -1) { 41581 _setStyle(triggers[i], "cursor", vars.cursor || (vars.cursor !== false ? _defaultCursor : null)); 41582 } 41583 41584 _dragCount--; 41585 41586 if (e) { 41587 touches = e.changedTouches; 41588 41589 if (touches) { 41590 e = touches[0]; 41591 41592 if (e !== touch && e.identifier !== touchID) { 41593 i = touches.length; 41594 41595 while (--i > -1 && (e = touches[i]).identifier !== touchID && e.target !== target) {} 41596 41597 if (i < 0 && !force) { 41598 return; 41599 } 41600 } 41601 } 41602 41603 self.pointerEvent = originalEvent; 41604 self.pointerX = e.pageX; 41605 self.pointerY = e.pageY; 41606 } 41607 41608 if (isContextMenuRelease && originalEvent) { 41609 _preventDefault(originalEvent); 41610 41611 isPreventingDefault = true; 41612 41613 _dispatchEvent(self, "release", "onRelease"); 41614 } else if (originalEvent && !wasDragging) { 41615 isPreventingDefault = false; 41616 41617 if (interrupted && (vars.snap || vars.bounds)) { 41618 animate(vars.inertia || vars.throwProps); 41619 } 41620 41621 _dispatchEvent(self, "release", "onRelease"); 41622 41623 if ((!_isAndroid || originalEvent.type !== "touchmove") && originalEvent.type.indexOf("cancel") === -1) { 41624 _dispatchEvent(self, "click", "onClick"); 41625 41626 if (_getTime() - clickTime < 300) { 41627 _dispatchEvent(self, "doubleclick", "onDoubleClick"); 41628 } 41629 41630 eventTarget = originalEvent.target || target; 41631 clickTime = _getTime(); 41632 41633 syntheticClick = function syntheticClick() { 41634 if (clickTime !== clickDispatch && self.enabled() && !self.isPressed && !originalEvent.defaultPrevented) { 41635 if (eventTarget.click) { 41636 eventTarget.click(); 41637 } else if (ownerDoc.createEvent) { 41638 syntheticEvent = ownerDoc.createEvent("MouseEvents"); 41639 syntheticEvent.initMouseEvent("click", true, true, _win$1, 1, self.pointerEvent.screenX, self.pointerEvent.screenY, self.pointerX, self.pointerY, false, false, false, false, 0, null); 41640 eventTarget.dispatchEvent(syntheticEvent); 41641 } 41642 } 41643 }; 41644 41645 if (!_isAndroid && !originalEvent.defaultPrevented) { 41646 gsap.delayedCall(0.05, syntheticClick); 41647 } 41648 } 41649 } else { 41650 animate(vars.inertia || vars.throwProps); 41651 41652 if (!self.allowEventDefault && originalEvent && (vars.dragClickables !== false || !isClickable.call(self, originalEvent.target)) && wasDragging && (!allowNativeTouchScrolling || touchDragAxis && allowNativeTouchScrolling === touchDragAxis) && originalEvent.cancelable !== false) { 41653 isPreventingDefault = true; 41654 41655 _preventDefault(originalEvent); 41656 } else { 41657 isPreventingDefault = false; 41658 } 41659 41660 _dispatchEvent(self, "release", "onRelease"); 41661 } 41662 41663 isTweening() && placeholderDelayedCall.duration(self.tween.duration()); 41664 wasDragging && _dispatchEvent(self, "dragend", "onDragEnd"); 41665 return true; 41666 }, 41667 updateScroll = function updateScroll(e) { 41668 if (e && self.isDragging && !scrollProxy) { 41669 var parent = e.target || target.parentNode, 41670 deltaX = parent.scrollLeft - parent._gsScrollX, 41671 deltaY = parent.scrollTop - parent._gsScrollY; 41672 41673 if (deltaX || deltaY) { 41674 if (matrix) { 41675 startPointerX -= deltaX * matrix.a + deltaY * matrix.c; 41676 startPointerY -= deltaY * matrix.d + deltaX * matrix.b; 41677 } else { 41678 startPointerX -= deltaX; 41679 startPointerY -= deltaY; 41680 } 41681 41682 parent._gsScrollX += deltaX; 41683 parent._gsScrollY += deltaY; 41684 setPointerPosition(self.pointerX, self.pointerY); 41685 } 41686 } 41687 }, 41688 onClick = function onClick(e) { 41689 var time = _getTime(), 41690 recentlyClicked = time - clickTime < 100, 41691 recentlyDragged = time - dragEndTime < 50, 41692 alreadyDispatched = recentlyClicked && clickDispatch === clickTime, 41693 defaultPrevented = self.pointerEvent && self.pointerEvent.defaultPrevented, 41694 alreadyDispatchedTrusted = recentlyClicked && trustedClickDispatch === clickTime, 41695 trusted = e.isTrusted || e.isTrusted == null && recentlyClicked && alreadyDispatched; 41696 41697 if ((alreadyDispatched || recentlyDragged && self.vars.suppressClickOnDrag !== false) && e.stopImmediatePropagation) { 41698 e.stopImmediatePropagation(); 41699 } 41700 41701 if (recentlyClicked && !(self.pointerEvent && self.pointerEvent.defaultPrevented) && (!alreadyDispatched || trusted && !alreadyDispatchedTrusted)) { 41702 if (trusted && alreadyDispatched) { 41703 trustedClickDispatch = clickTime; 41704 } 41705 41706 clickDispatch = clickTime; 41707 return; 41708 } 41709 41710 if (self.isPressed || recentlyDragged || recentlyClicked) { 41711 if (!trusted || !e.detail || !recentlyClicked || defaultPrevented) { 41712 _preventDefault(e); 41713 } 41714 } 41715 41716 if (!recentlyClicked && !recentlyDragged && !dragged) { 41717 e && e.target && (self.pointerEvent = e); 41718 41719 _dispatchEvent(self, "click", "onClick"); 41720 } 41721 }, 41722 localizePoint = function localizePoint(p) { 41723 return matrix ? { 41724 x: p.x * matrix.a + p.y * matrix.c + matrix.e, 41725 y: p.x * matrix.b + p.y * matrix.d + matrix.f 41726 } : { 41727 x: p.x, 41728 y: p.y 41729 }; 41730 }; 41731 41732 old = Draggable.get(target); 41733 old && old.kill(); 41734 41735 _this2.startDrag = function (event, align) { 41736 var r1, r2, p1, p2; 41737 onPress(event || self.pointerEvent, true); 41738 41739 if (align && !self.hitTest(event || self.pointerEvent)) { 41740 r1 = _parseRect(event || self.pointerEvent); 41741 r2 = _parseRect(target); 41742 p1 = localizePoint({ 41743 x: r1.left + r1.width / 2, 41744 y: r1.top + r1.height / 2 41745 }); 41746 p2 = localizePoint({ 41747 x: r2.left + r2.width / 2, 41748 y: r2.top + r2.height / 2 41749 }); 41750 startPointerX -= p1.x - p2.x; 41751 startPointerY -= p1.y - p2.y; 41752 } 41753 41754 if (!self.isDragging) { 41755 self.isDragging = dragged = true; 41756 41757 _dispatchEvent(self, "dragstart", "onDragStart"); 41758 } 41759 }; 41760 41761 _this2.drag = onMove; 41762 41763 _this2.endDrag = function (e) { 41764 return onRelease(e || self.pointerEvent, true); 41765 }; 41766 41767 _this2.timeSinceDrag = function () { 41768 return self.isDragging ? 0 : (_getTime() - dragEndTime) / 1000; 41769 }; 41770 41771 _this2.timeSinceClick = function () { 41772 return (_getTime() - clickTime) / 1000; 41773 }; 41774 41775 _this2.hitTest = function (target, threshold) { 41776 return Draggable.hitTest(self.target, target, threshold); 41777 }; 41778 41779 _this2.getDirection = function (from, diagonalThreshold) { 41780 var mode = from === "velocity" && InertiaPlugin ? from : _isObject(from) && !rotationMode ? "element" : "start", 41781 xChange, 41782 yChange, 41783 ratio, 41784 direction, 41785 r1, 41786 r2; 41787 41788 if (mode === "element") { 41789 r1 = _parseRect(self.target); 41790 r2 = _parseRect(from); 41791 } 41792 41793 xChange = mode === "start" ? self.x - startElementX : mode === "velocity" ? InertiaPlugin.getVelocity(target, xProp) : r1.left + r1.width / 2 - (r2.left + r2.width / 2); 41794 41795 if (rotationMode) { 41796 return xChange < 0 ? "counter-clockwise" : "clockwise"; 41797 } else { 41798 diagonalThreshold = diagonalThreshold || 2; 41799 yChange = mode === "start" ? self.y - startElementY : mode === "velocity" ? InertiaPlugin.getVelocity(target, yProp) : r1.top + r1.height / 2 - (r2.top + r2.height / 2); 41800 ratio = Math.abs(xChange / yChange); 41801 direction = ratio < 1 / diagonalThreshold ? "" : xChange < 0 ? "left" : "right"; 41802 41803 if (ratio < diagonalThreshold) { 41804 if (direction !== "") { 41805 direction += "-"; 41806 } 41807 41808 direction += yChange < 0 ? "up" : "down"; 41809 } 41810 } 41811 41812 return direction; 41813 }; 41814 41815 _this2.applyBounds = function (newBounds, sticky) { 41816 var x, y, forceZeroVelocity, e, parent, isRoot; 41817 41818 if (newBounds && vars.bounds !== newBounds) { 41819 vars.bounds = newBounds; 41820 return self.update(true, sticky); 41821 } 41822 41823 syncXY(true); 41824 calculateBounds(); 41825 41826 if (hasBounds && !isTweening()) { 41827 x = self.x; 41828 y = self.y; 41829 41830 if (x > maxX) { 41831 x = maxX; 41832 } else if (x < minX) { 41833 x = minX; 41834 } 41835 41836 if (y > maxY) { 41837 y = maxY; 41838 } else if (y < minY) { 41839 y = minY; 41840 } 41841 41842 if (self.x !== x || self.y !== y) { 41843 forceZeroVelocity = true; 41844 self.x = self.endX = x; 41845 41846 if (rotationMode) { 41847 self.endRotation = x; 41848 } else { 41849 self.y = self.endY = y; 41850 } 41851 41852 dirty = true; 41853 render(true); 41854 41855 if (self.autoScroll && !self.isDragging) { 41856 _recordMaxScrolls(target.parentNode); 41857 41858 e = target; 41859 _windowProxy.scrollTop = _win$1.pageYOffset != null ? _win$1.pageYOffset : ownerDoc.documentElement.scrollTop != null ? ownerDoc.documentElement.scrollTop : ownerDoc.body.scrollTop; 41860 _windowProxy.scrollLeft = _win$1.pageXOffset != null ? _win$1.pageXOffset : ownerDoc.documentElement.scrollLeft != null ? ownerDoc.documentElement.scrollLeft : ownerDoc.body.scrollLeft; 41861 41862 while (e && !isRoot) { 41863 isRoot = _isRoot(e.parentNode); 41864 parent = isRoot ? _windowProxy : e.parentNode; 41865 41866 if (allowY && parent.scrollTop > parent._gsMaxScrollY) { 41867 parent.scrollTop = parent._gsMaxScrollY; 41868 } 41869 41870 if (allowX && parent.scrollLeft > parent._gsMaxScrollX) { 41871 parent.scrollLeft = parent._gsMaxScrollX; 41872 } 41873 41874 e = parent; 41875 } 41876 } 41877 } 41878 41879 if (self.isThrowing && (forceZeroVelocity || self.endX > maxX || self.endX < minX || self.endY > maxY || self.endY < minY)) { 41880 animate(vars.inertia || vars.throwProps, forceZeroVelocity); 41881 } 41882 } 41883 41884 return self; 41885 }; 41886 41887 _this2.update = function (applyBounds, sticky, ignoreExternalChanges) { 41888 if (sticky && self.isPressed) { 41889
vendor: 3,070 bytes, lines 41889-41990
41889var m = getGlobalMatrix(target), 41890 p = innerMatrix.apply({ 41891 x: self.x - startElementX, 41892 y: self.y - startElementY 41893 }), 41894 m2 = getGlobalMatrix(target.parentNode, true); 41895 m2.apply({ 41896 x: m.e - p.x, 41897 y: m.f - p.y 41898 }, p); 41899 self.x -= p.x - m2.e; 41900 self.y -= p.y - m2.f; 41901 render(true); 41902 recordStartPositions(); 41903 } 41904 41905 var x = self.x, 41906 y = self.y; 41907 updateMatrix(!sticky); 41908 41909 if (applyBounds) { 41910 self.applyBounds(); 41911 } else { 41912 dirty && ignoreExternalChanges && render(true); 41913 syncXY(true); 41914 } 41915 41916 if (sticky) { 41917 setPointerPosition(self.pointerX, self.pointerY); 41918 dirty && render(true); 41919 } 41920 41921 if (self.isPressed && !sticky && (allowX && Math.abs(x - self.x) > 0.01 || allowY && Math.abs(y - self.y) > 0.01 && !rotationMode)) { 41922 recordStartPositions(); 41923 } 41924 41925 if (self.autoScroll) { 41926 _recordMaxScrolls(target.parentNode, self.isDragging); 41927 41928 checkAutoScrollBounds = self.isDragging; 41929 render(true); 41930 41931 _removeScrollListener(target, updateScroll); 41932 41933 _addScrollListener(target, updateScroll); 41934 } 41935 41936 return self; 41937 }; 41938 41939 _this2.enable = function (type) { 41940 var setVars = { 41941 lazy: true 41942 }, 41943 id, 41944 i, 41945 trigger; 41946 41947 if (vars.cursor !== false) { 41948 setVars.cursor = vars.cursor || _defaultCursor; 41949 } 41950 41951 if (gsap.utils.checkPrefix("touchCallout")) { 41952 setVars.touchCallout = "none"; 41953 } 41954 41955 if (type !== "soft") { 41956 _setTouchActionForAllDescendants(triggers, allowX === allowY ? "none" : vars.allowNativeTouchScrolling && target.scrollHeight === target.clientHeight === (target.scrollWidth === target.clientHeight) || vars.allowEventDefault ? "manipulation" : allowX ? "pan-y" : "pan-x"); 41957 41958 i = triggers.length; 41959 41960 while (--i > -1) { 41961 trigger = triggers[i]; 41962 _supportsPointer || _addListener(trigger, "mousedown", onPress); 41963 41964 _addListener(trigger, "touchstart", onPress); 41965 41966 _addListener(trigger, "click", onClick, true); 41967 41968 gsap.set(trigger, setVars); 41969 41970 if (trigger.getBBox && trigger.ownerSVGElement && allowX !== allowY) { 41971 gsap.set(trigger.ownerSVGElement, { 41972 touchAction: vars.allowNativeTouchScrolling || vars.allowEventDefault ? "manipulation" : allowX ? "pan-y" : "pan-x" 41973 }); 41974 } 41975 41976 vars.allowContextMenu || _addListener(trigger, "contextmenu", onContextMenu); 41977 } 41978 41979 _setSelectable(triggers, false); 41980 } 41981 41982 _addScrollListener(target, updateScroll); 41983 41984 enabled = true; 41985 41986 if (InertiaPlugin && type !== "soft") { 41987 InertiaPlugin.track(scrollProxy || target, xyMode ? "x,y" : rotationMode ? "rotation" : "top,left"); 41988 } 41989 41990 target._gsDragID = id =
vendor: 5,466 bytes, lines 41990-42196
41990 "d" + _lookupCount++; 41991 _lookup[id] = self; 41992 41993 if (scrollProxy) { 41994 scrollProxy.enable(); 41995 scrollProxy.element._gsDragID = id; 41996 } 41997 41998 (vars.bounds || rotationMode) && recordStartPositions(); 41999 vars.bounds && self.applyBounds(); 42000 return self; 42001 }; 42002 42003 _this2.disable = function (type) { 42004 var dragging = self.isDragging, 42005 i = triggers.length, 42006 trigger; 42007 42008 while (--i > -1) { 42009 _setStyle(triggers[i], "cursor", null); 42010 } 42011 42012 if (type !== "soft") { 42013 _setTouchActionForAllDescendants(triggers, null); 42014 42015 i = triggers.length; 42016 42017 while (--i > -1) { 42018 trigger = triggers[i]; 42019 42020 _setStyle(trigger, "touchCallout", null); 42021 42022 _removeListener(trigger, "mousedown", onPress); 42023 42024 _removeListener(trigger, "touchstart", onPress); 42025 42026 _removeListener(trigger, "click", onClick, true); 42027 42028 _removeListener(trigger, "contextmenu", onContextMenu); 42029 } 42030 42031 _setSelectable(triggers, true); 42032 42033 if (touchEventTarget) { 42034 _removeListener(touchEventTarget, "touchcancel", onRelease); 42035 42036 _removeListener(touchEventTarget, "touchend", onRelease); 42037 42038 _removeListener(touchEventTarget, "touchmove", onMove); 42039 } 42040 42041 _removeListener(ownerDoc, "mouseup", onRelease); 42042 42043 _removeListener(ownerDoc, "mousemove", onMove); 42044 } 42045 42046 _removeScrollListener(target, updateScroll); 42047 42048 enabled = false; 42049 42050 if (InertiaPlugin && type !== "soft") { 42051 InertiaPlugin.untrack(scrollProxy || target, xyMode ? "x,y" : rotationMode ? "rotation" : "top,left"); 42052 self.tween && self.tween.kill(); 42053 } 42054 42055 scrollProxy && scrollProxy.disable(); 42056 42057 _removeFromRenderQueue(render); 42058 42059 self.isDragging = self.isPressed = isClicking = false; 42060 dragging && _dispatchEvent(self, "dragend", "onDragEnd"); 42061 return self; 42062 }; 42063 42064 _this2.enabled = function (value, type) { 42065 return arguments.length ? value ? self.enable(type) : self.disable(type) : enabled; 42066 }; 42067 42068 _this2.kill = function () { 42069 self.isThrowing = false; 42070 self.tween && self.tween.kill(); 42071 self.disable(); 42072 gsap.set(triggers, { 42073 clearProps: "userSelect" 42074 }); 42075 delete _lookup[target._gsDragID]; 42076 return self; 42077 }; 42078 42079 _this2.revert = function () { 42080 this.kill(); 42081 this.styles && this.styles.revert(); 42082 }; 42083 42084 if (~type.indexOf("scroll")) { 42085 scrollProxy = _this2.scrollProxy = new ScrollProxy(target, _extend({ 42086 onKill: function onKill() { 42087 self.isPressed && onRelease(null); 42088 } 42089 }, vars)); 42090 target.style.overflowY = allowY && !_isTouchDevice ? "auto" : "hidden"; 42091 target.style.overflowX = allowX && !_isTouchDevice ? "auto" : "hidden"; 42092 target = scrollProxy.content; 42093 } 42094 42095 if (rotationMode) { 42096 killProps.rotation = 1; 42097 } else { 42098 if (allowX) { 42099 killProps[xProp] = 1; 42100 } 42101 42102 if (allowY) { 42103 killProps[yProp] = 1; 42104 } 42105 } 42106 42107 gsCache.force3D = "force3D" in vars ? vars.force3D : true; 42108 42109 _context(_assertThisInitialized(_this2)); 42110 42111 _this2.enable(); 42112 42113 return _this2; 42114 } 42115 42116 Draggable.register = function register(core) { 42117 gsap = core; 42118 42119 _initCore(); 42120 }; 42121 42122 Draggable.create = function create(targets, vars) { 42123 _coreInitted || _initCore(true); 42124 return _toArray(targets).map(function (target) { 42125 return new Draggable(target, vars); 42126 }); 42127 }; 42128 42129 Draggable.get = function get(target) { 42130 return _lookup[(_toArray(target)[0] || {})._gsDragID]; 42131 }; 42132 42133 Draggable.timeSinceDrag = function timeSinceDrag() { 42134 return (_getTime() - _lastDragTime) / 1000; 42135 }; 42136 42137 Draggable.hitTest = function hitTest(obj1, obj2, threshold) { 42138 if (obj1 === obj2) { 42139 return false; 42140 } 42141 42142 var r1 = _parseRect(obj1), 42143 r2 = _parseRect(obj2), 42144 top = r1.top, 42145 left = r1.left, 42146 right = r1.right, 42147 bottom = r1.bottom, 42148 width = r1.width, 42149 height = r1.height, 42150 isOutside = r2.left > right || r2.right < left || r2.top > bottom || r2.bottom < top, 42151 overlap, 42152 area, 42153 isRatio; 42154 42155 if (isOutside || !threshold) { 42156 return !isOutside; 42157 } 42158 42159 isRatio = (threshold + "").indexOf("%") !== -1; 42160 threshold = parseFloat(threshold) || 0; 42161 overlap = { 42162 left: Math.max(left, r2.left), 42163 top: Math.max(top, r2.top) 42164 }; 42165 overlap.width = Math.min(right, r2.right) - overlap.left; 42166 overlap.height = Math.min(bottom, r2.bottom) - overlap.top; 42167 42168 if (overlap.width < 0 || overlap.height < 0) { 42169 return false; 42170 } 42171 42172 if (isRatio) { 42173 threshold *= 0.01; 42174 area = overlap.width * overlap.height; 42175 return area >= width * height * threshold || area >= r2.width * r2.height * threshold; 42176 } 42177 42178 return overlap.width > threshold && overlap.height > threshold; 42179 }; 42180 42181 return Draggable; 42182 }(EventDispatcher); 42183 42184 _setDefaults(Draggable.prototype, { 42185 pointerX: 0, 42186 pointerY: 0, 42187 startX: 0, 42188 startY: 0, 42189 deltaX: 0, 42190 deltaY: 0, 42191 isDragging: false, 42192 isPressed: false 42193 }); 42194 42195 Draggable.zIndex = 1000; 42196 Draggable.version = "3.1
421962.5"; 42197 _getGSAP() && gsap.registerPlugin(Draggable); 42198 42199 exports.Draggable = Draggable; 42200 exports.default = Draggable; 42201 42202 if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;} 42203 42204}))); 42205/* ======================================================================== 42206 * Bootstrap: collapse.js v3.1.1 42207 * http://getbootstrap.com/javascript/#collapse 42208 * ======================================================================== 42209 * Copyright 2011-2014 Twitter, Inc. 42210 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 42211 * ======================================================================== */ 42212 42213 42214+function ($) { 42215 'use strict'; 42216 42217 // COLLAPSE PUBLIC CLASS DEFINITION 42218 // ================================ 42219 42220 var Collapse = function (element, options) { 42221 this.$element = $(element) 42222 this.options = $.extend({}, Collapse.DEFAULTS, options) 42223 this.transitioning = null 42224 42225 if (this.options.parent) this.$parent = $(this.options.parent) 42226 if (this.options.toggle) this.toggle() 42227 } 42228 42229 Collapse.DEFAULTS = { 42230 toggle: true 42231 } 42232 42233 Collapse.prototype.dimension = function () { 42234 var hasWidth = this.$element.hasClass('width') 42235 return hasWidth ? 'width' : 'height' 42236 } 42237 42238 Collapse.prototype.show = function () { 42239 if (this.transitioning || this.$element.hasClass('in')) return 42240 42241 var startEvent = $.Event('show.bs.collapse') 42242 this.$element.trigger(startEvent) 42243 if (startEvent.isDefaultPrevented()) return 42244 42245 var actives = this.$parent && this.$parent.find('> .panel > .in') 42246 42247 if (actives && actives.length) { 42248 var hasData = actives.data('bs.collapse') 42249 if (hasData && hasData.transitioning) return 42250 //START UNCODE EDIT 42251 var parentNoToggle = this.$parent.data('no-toggle') 42252 if (!parentNoToggle) { 42253 actives.collapse('hide') 42254 } 42255 //END UNCODE EDIT 42256 hasData || actives.data('bs.collapse', null) 42257 } 42258 42259 var dimension = this.dimension() 42260 42261 this.$element 42262 .removeClass('collapse') 42263 .addClass('collapsing')[dimension](0) 42264 42265 this.transitioning = 1 42266 42267 var complete = function (e) { 42268 if (e && e.target != this.$element[0]) return 42269 this.$element 42270 .removeClass('collapsing') 42271 .addClass('collapse in')[dimension]('auto') 42272 this.transitioning = 0 42273 this.$element.trigger('shown.bs.collapse') 42274 } 42275 42276 if (!$.support.transition) return complete.call(this) 42277 42278 var scrollSize = $.camelCase(['scroll', dimension].join('-')) 42279 42280 this.$element 42281 .one($.support.transition.end, $.proxy(complete, this)) 42282 .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) 42283 } 42284 42285 Collapse.prototype.hide = function () { 42286 if (this.transitioning || !this.$element.hasClass('in')) return 42287 42288 var startEvent = $.Event('hide.bs.collapse') 42289 this.$element.trigger(startEvent) 42290 if (startEvent.isDefaultPrevented()) return 42291 42292 var dimension = this.dimension() 42293 42294 this.$element[dimension](this.$element[dimension]())[0].offsetHeight 42295 42296 this.$element 42297 .addClass('collapsing') 42298 .removeClass('collapse') 42299 .removeClass('in') 42300 42301 this.transitioning = 1 42302 42303 var complete = function (e) { 42304 if (e && e.target != this.$element[0]) return 42305 this.transitioning = 0 42306 this.$element 42307 .trigger('hidden.bs.collapse') 42308 .removeClass('collapsing') 42309 .addClass('collapse') 42310 } 42311 42312 if (!$.support.transition) return complete.call(this) 42313 42314 this.$element 42315 [dimension](0) 42316 .one($.support.transition.end, $.proxy(complete, this)) 42317 .emulateTransitionEnd(350) 42318 } 42319 42320 Collapse.prototype.toggle = function () { 42321 this[this.$element.hasClass('in') ? 'hide' : 'show']() 42322 } 42323 42324 42325 // COLLAPSE PLUGIN DEFINITION 42326 // ========================== 42327 42328 var old = $.fn.collapse 42329 42330 $.fn.collapse = function (option) { 42331 return this.each(function () { 42332 var $this = $(this) 42333 var data = $this.data('bs.collapse') 42334 var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 42335 42336 if (!data && options.toggle && option == 'show') option = !option 42337 if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 42338 if (typeof option == 'string') data[option]() 42339 }) 42340 } 42341 42342 $.fn.collapse.Constructor = Collapse 42343 42344 42345 // COLLAPSE NO CONFLICT 42346 // ==================== 42347 42348 $.fn.collapse.noConflict = function () { 42349 $.fn.collapse = old 42350 return this 42351 } 42352 42353 42354 // COLLAPSE DATA-API 42355 // ================= 42356 42357 $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 42358 var $this = $(this), href 42359 var target = $this.attr('data-target') 42360 || e.preventDefault() 42361 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 42362 //Edited by Uncode to replace ID in panel [START] 42363 var _target = href.replace(/^#/, ""); 42364 if ( $('[data-id="' + _target + '"]').length ) { 42365 var $target = $('[data-id="' + _target + '"]') 42366 } else { 42367 var $target = $(target) 42368 } 42369 //Edited by Uncode to replace ID in panel [END] 42370 var data = $target.data('bs.collapse') 42371 var option = data ? 'toggle' : $this.data() 42372 var parent = $this.attr('data-parent') 42373 var $parent = parent && $(parent) 42374 42375 if (!data || !data.transitioning) { 42376 if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') 42377 $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 42378 } 42379 42380 $target.collapse(option) 42381 }) 42382 42383}(jQuery); 42384 42385/* ======================================================================== 42386 * Bootstrap: tab.js v3.1.1 42387 * http://getbootstrap.com/javascript/#tabs 42388 * ======================================================================== 42389 * Copyright 2011-2014 Twitter, Inc. 42390 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 42391 * ======================================================================== */ 42392 42393 42394+function ($) { 42395 'use strict'; 42396 42397 // TAB CLASS DEFINITION 42398 // ==================== 42399 42400 var Tab = function (element) { 42401 this.element = $(element) 42402 } 42403 42404 Tab.prototype.show = function () { 42405 var $this = this.element 42406 var $ul = $this.closest('ul:not(.dropdown-menu)') 42407 var selector = $this.data('target') 42408 42409 if (!selector) { 42410 selector = $this.attr('href') 42411 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 42412 } 42413 42414 if ($this.parent('li').hasClass('active')) return 42415 42416 var previous = $ul.find('.active:last a')[0] 42417 var e = $.Event('show.bs.tab', { 42418 relatedTarget: previous 42419 }) 42420 42421 $this.trigger(e) 42422 42423 if (e.isDefaultPrevented()) return 42424 42425 //Edited by Uncode to replace ID in panel [START] 42426 var _target = selector.replace(/^#/, ""); 42427 if ( $('[data-id="' + _target + '"]').length ) 42428 var $target = $('[data-id="' + _target + '"]') 42429 else 42430 var $target = $(selector) 42431 //Edited by Uncode to replace ID in panel [END] 42432 42433 this.activate($this.parent('li'), $ul) 42434 this.activate($target, $target.parent(), function () { 42435 $this.trigger({ 42436 type: 'shown.bs.tab', 42437 relatedTarget: previous 42438 }) 42439 }) 42440 } 42441 42442 Tab.prototype.activate = function (element, container, callback) { 42443 var $active = container.find('> .active').add(container.find('> .active > .active')) 42444 var transition = callback 42445 && $.support.transition 42446 && $active.hasClass('fade') 42447 42448 function next() { 42449 $active 42450 .removeClass('active') 42451 .find('> .dropdown-menu > .active') 42452 .removeClass('active') 42453 42454 $active 42455 .find('.tab-excerpt').slideUp(); 42456 42457 element.addClass('active') 42458 $('.tab-excerpt', element).slideDown(); 42459 42460 //if (transition) { 42461 element[0].offsetWidth // reflow for transition 42462 element.add($active).addClass('in') 42463 /*} else { 42464 element.removeClass('fade') 42465 }*/ 42466 42467 if (element.parents('.dropdown-menu').length) { 42468 element.closest('li.dropdown').addClass('active') 42469 } 42470 42471 if ( ! element.is('li') ) { 42472 element.closest('.tab-content').find('> .active').not(element).removeClass('active'); 42473 } 42474 42475 callback && callback() 42476 } 42477 42478 transition ? 42479 $active 42480 .one($.support.transition.end, next) 42481 .emulateTransitionEnd(150) : 42482 next() 42483 42484 $active.removeClass('in') 42485 } 42486 42487 42488 // TAB PLUGIN DEFINITION 42489 // ===================== 42490 42491 var old = $.fn.tab 42492 42493 $.fn.tab = function ( option ) { 42494 return this.each(function () { 42495 var $this = $(this) 42496 var data = $this.data('bs.tab') 42497 42498 if (!data) $this.data('bs.tab', (data = new Tab(this))) 42499 if (typeof option == 'string') data[option]() 42500 }) 42501 } 42502 42503 $.fn.tab.Constructor = Tab 42504 42505 42506 // TAB NO CONFLICT 42507 // =============== 42508 42509 $.fn.tab.noConflict = function () { 42510 $.fn.tab = old 42511 return this 42512 } 42513 42514 42515 // TAB DATA-API 42516 // ============ 42517 42518 $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 42519 e.preventDefault() 42520 $(this).tab('show') 42521 }) 42522 42523}(jQuery); 42524 42525/* ======================================================================== 42526 * Bootstrap: tooltip.js v3.1.1 42527 * http://getbootstrap.com/javascript/#tooltip 42528 * Inspired by the original jQuery.tipsy by Jason Frame 42529 * ======================================================================== 42530 * Copyright 2011-2014 Twitter, Inc. 42531 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 42532 * ======================================================================== */ 42533 42534 42535+function ($) { 42536 'use strict'; 42537 42538 // TOOLTIP PUBLIC CLASS DEFINITION 42539 // =============================== 42540 42541 var Tooltip = function (element, options) { 42542 this.type = 42543 this.options = 42544 this.enabled = 42545 this.timeout = 42546 this.hoverState = 42547 this.$element = null 42548 42549 this.init('tooltip', element, options) 42550 } 42551 42552 Tooltip.DEFAULTS = { 42553 animation: true, 42554 placement: 'top', 42555 selector: false, 42556 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 42557 trigger: 'hover focus', 42558 title: '', 42559 delay: 0, 42560 html: false, 42561 container: false, 42562 viewport: { 42563 selector: 'body', 42564 padding: 0 42565 } 42566 } 42567 42568 Tooltip.prototype.init = function (type, element, options) { 42569 this.enabled = true 42570 this.type = type 42571 this.$element = $(element) 42572 this.options = this.getOptions(options) 42573 this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) 42574 42575 var triggers = this.options.trigger.split(' ') 42576 42577 for (var i = triggers.length; i--;) { 42578 var trigger = triggers[i] 42579 42580 if (trigger == 'click') { 42581 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 42582 } else if (trigger != 'manual') { 42583 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 42584 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 42585 42586 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 42587 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 42588 } 42589 } 42590 42591 this.options.selector ? 42592 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 42593 this.fixTitle() 42594 } 42595 42596 Tooltip.prototype.getDefaults = function () { 42597 return Tooltip.DEFAULTS 42598 } 42599 42600 Tooltip.prototype.getOptions = function (options) { 42601 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 42602 42603 if (options.delay && typeof options.delay == 'number') { 42604 options.delay = { 42605 show: options.delay, 42606 hide: options.delay 42607 } 42608 } 42609 42610 return options 42611 } 42612 42613 Tooltip.prototype.getDelegateOptions = function () { 42614 var options = {} 42615 var defaults = this.getDefaults() 42616 42617 this._options && $.each(this._options, function (key, value) { 42618 if (defaults[key] != value) options[key] = value 42619 }) 42620 42621 return options 42622 } 42623 42624 Tooltip.prototype.enter = function (obj) { 42625 var self = obj instanceof this.constructor ? 42626 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 42627 42628 clearTimeout(self.timeout) 42629 42630 self.hoverState = 'in' 42631 42632 if (!self.options.delay || !self.options.delay.show) return self.show() 42633 42634 self.timeout = setTimeout(function () { 42635 if (self.hoverState == 'in') self.show() 42636 }, self.options.delay.show) 42637 } 42638 42639 Tooltip.prototype.leave = function (obj) { 42640 var self = obj instanceof this.constructor ? 42641 obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) 42642 42643 clearTimeout(self.timeout) 42644 42645 self.hoverState = 'out' 42646 42647 if (!self.options.delay || !self.options.delay.hide) return self.hide() 42648 42649 self.timeout = setTimeout(function () { 42650 if (self.hoverState == 'out') self.hide() 42651 }, self.options.delay.hide) 42652 } 42653 42654 Tooltip.prototype.show = function () { 42655 var e = $.Event('show.bs.' + this.type) 42656 42657 if (this.hasContent() && this.enabled) { 42658 this.$element.trigger(e) 42659 42660 if (e.isDefaultPrevented()) return 42661 var that = this; 42662 42663 var $tip = this.tip() 42664 42665 this.setContent() 42666 42667 if (this.options.animation) $tip.addClass('fade') 42668 42669 var placement = typeof this.options.placement == 'function' ? 42670 this.options.placement.call(this, $tip[0], this.$element[0]) : 42671 this.options.placement 42672 42673 var autoToken = /\s?auto?\s?/i 42674 var autoPlace = autoToken.test(placement) 42675 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 42676 42677 $tip 42678 .detach() 42679 .css({ top: 0, left: 0, display: 'block' }) 42680 .addClass(placement) 42681 42682 this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) 42683 42684 var pos = this.getPosition() 42685 var actualWidth = $tip[0].offsetWidth 42686 var actualHeight = $tip[0].offsetHeight 42687 42688 if (autoPlace) { 42689 var orgPlacement = placement 42690 var $parent = this.$element.parent() 42691 var parentDim = this.getPosition($parent) 42692 42693 placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' : 42694 placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' : 42695 placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' : 42696 placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' : 42697 placement 42698 42699 $tip 42700 .removeClass(orgPlacement) 42701 .addClass(placement) 42702 } 42703 42704 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 42705 42706 this.applyPlacement(calculatedOffset, placement) 42707 this.hoverState = null 42708 42709 var complete = function() { 42710 that.$element.trigger('shown.bs.' + that.type) 42711 } 42712 42713 $.support.transition && this.$tip.hasClass('fade') ? 42714 $tip 42715 .one($.support.transition.end, complete) 42716 .emulateTransitionEnd(150) : 42717 complete() 42718 } 42719 } 42720 42721 Tooltip.prototype.applyPlacement = function (offset, placement) { 42722 var $tip = this.tip() 42723 var width = $tip[0].offsetWidth 42724 var height = $tip[0].offsetHeight 42725 42726 // manually read margins because getBoundingClientRect includes difference 42727 var marginTop = parseInt($tip.css('margin-top'), 10) 42728 var marginLeft = parseInt($tip.css('margin-left'), 10) 42729 42730 // we must check for NaN for ie 8/9 42731 if (isNaN(marginTop)) marginTop = 0 42732 if (isNaN(marginLeft)) marginLeft = 0 42733 42734 offset.top = offset.top + marginTop 42735 offset.left = offset.left + marginLeft 42736 42737 // $.fn.offset doesn't round pixel values 42738 // so we use setOffset directly with our own function B-0 42739 $.offset.setOffset($tip[0], $.extend({ 42740 using: function (props) { 42741 $tip.css({ 42742 top: Math.round(props.top), 42743 left: Math.round(props.left) 42744 }) 42745 } 42746 }, offset), 0) 42747 42748 $tip.addClass('in') 42749 42750 // check to see if placing tip in new offset caused the tip to resize itself 42751 var actualWidth = $tip[0].offsetWidth 42752 var actualHeight = $tip[0].offsetHeight 42753 42754 if (placement == 'top' && actualHeight != height) { 42755 offset.top = offset.top + height - actualHeight 42756 } 42757 42758 var delta = this.getViewportAdjustedDelta(placement, offset, actualWid
42758th, actualHeight) 42759 42760 if (delta.left) offset.left += delta.left 42761 else offset.top += delta.top 42762 42763 var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 42764 var arrowPosition = delta.left ? 'left' : 'top' 42765 var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' 42766 42767 $tip.offset(offset) 42768 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) 42769 } 42770 42771 Tooltip.prototype.replaceArrow = function (delta, dimension, position) { 42772 this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '') 42773 } 42774 42775 Tooltip.prototype.setContent = function () { 42776 var $tip = this.tip() 42777 var title = this.getTitle() 42778 42779 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 42780 $tip.removeClass('fade in top bottom left right') 42781 } 42782 42783 Tooltip.prototype.hide = function () { 42784 var that = this 42785 var $tip = this.tip() 42786 var e = $.Event('hide.bs.' + this.type) 42787 42788 function complete() { 42789 if (that.hoverState != 'in') $tip.detach() 42790 that.$element.trigger('hidden.bs.' + that.type) 42791 } 42792 42793 this.$element.trigger(e) 42794 42795 if (e.isDefaultPrevented()) return 42796 42797 $tip.removeClass('in') 42798 42799 $.support.transition && this.$tip.hasClass('fade') ? 42800 $tip 42801 .one($.support.transition.end, complete) 42802 .emulateTransitionEnd(150) : 42803 complete() 42804 42805 this.hoverState = null 42806 42807 return this 42808 } 42809 42810 Tooltip.prototype.fixTitle = function () { 42811 var $e = this.$element 42812 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { 42813 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 42814 } 42815 } 42816 42817 Tooltip.prototype.hasContent = function () { 42818 return this.getTitle() 42819 } 42820 42821 Tooltip.prototype.getPosition = function ($element) { 42822 $element = $element || this.$element 42823 var el = $element[0] 42824 var isBody = el.tagName == 'BODY' 42825 return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, { 42826 scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(), 42827 width: isBody ? $(window).width() : $element.outerWidth(), 42828 height: isBody ? $(window).height() : $element.outerHeight() 42829 }, isBody ? {top: 0, left: 0} : $element.offset()) 42830 } 42831 42832 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 42833 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 42834 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 42835 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 42836 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 42837 42838 } 42839 42840 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 42841 var delta = { top: 0, left: 0 } 42842 if (!this.$viewport) return delta 42843 42844 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 42845 var viewportDimensions = this.getPosition(this.$viewport) 42846 42847 if (/right|left/.test(placement)) { 42848 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 42849 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 42850 if (topEdgeOffset < viewportDimensions.top) { // top overflow 42851 delta.top = viewportDimensions.top - topEdgeOffset 42852 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 42853 delta.top = viewportDimensions.top + viewportDimensions.height - bottom
42853EdgeOffset 42854 } 42855 } else { 42856 var leftEdgeOffset = pos.left - viewportPadding 42857 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 42858 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 42859 delta.left = viewportDimensions.left - leftEdgeOffset 42860 } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow 42861 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 42862 } 42863 } 42864 42865 return delta 42866 } 42867 42868 Tooltip.prototype.getTitle = function () { 42869 var title 42870 var $e = this.$element 42871 var o = this.options 42872 42873 title = $e.attr('data-original-title') 42874 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 42875 42876 return title 42877 } 42878 42879 Tooltip.prototype.tip = function () { 42880 return this.$tip = this.$tip || $(this.options.template) 42881 } 42882 42883 Tooltip.prototype.arrow = function () { 42884 return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow') 42885 } 42886 42887 Tooltip.prototype.validate = function () { 42888 if (!this.$element[0].parentNode) { 42889 this.hide() 42890 this.$element = null 42891 this.options = null 42892 } 42893 } 42894 42895 Tooltip.prototype.enable = function () { 42896 this.enabled = true 42897 } 42898 42899 Tooltip.prototype.disable = function () { 42900 this.enabled = false 42901 } 42902 42903 Tooltip.prototype.toggleEnabled = function () { 42904 this.enabled = !this.enabled 42905 } 42906 42907 Tooltip.prototype.toggle = function (e) { 42908 var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this 42909 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 42910 } 42911 42912 Tooltip.prototype.destroy = function () { 42913 clearTimeout(this.timeout) 42914 this.hide().$element.off('.' + this.type).removeData('bs.' + this.type) 42915 } 42916 42917 42918 // TOOLTIP PLUGIN DEFINITION 42919 // ========================= 42920 42921 var old = $.fn.tooltip 42922 42923 $.fn.tooltip = function (option) { 42924 return this.each(function () { 42925 var $this = $(this) 42926 var data = $this.data('bs.tooltip') 42927 var options = typeof option == 'object' && option 42928 42929 if (!data && option == 'destroy') return 42930 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 42931 if (typeof option == 'string') data[option]() 42932 }) 42933 } 42934 42935 $.fn.tooltip.Constructor = Tooltip 42936 42937 42938 // TOOLTIP NO CONFLICT 42939 // =================== 42940 42941 $.fn.tooltip.noConflict = function () { 42942 $.fn.tooltip = old 42943 return this 42944 } 42945 42946}(jQuery); 42947 42948/* ======================================================================== 42949 * Bootstrap: transition.js v3.1.1 42950 * http://getbootstrap.com/javascript/#transitions 42951 * ======================================================================== 42952 * Copyright 2011-2014 Twitter, Inc. 42953 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 42954 * ======================================================================== */ 42955 42956 42957+function ($) { 42958 'use strict'; 42959 42960 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 42961 // ============================================================ 42962 42963 function transitionEnd() { 42964 var el = document.createElement('bootstrap') 42965 42966 var transEndEventNames = { 42967 WebkitTransition : 'webkitTransitionEnd', 42968 MozTransition : 'transitionend', 42969 OTransition : 'oTransitionEnd otransitionend', 42970 transition : 'transitionend' 42971 } 42972 42973 for (var name in transEndEventNames) { 42974 if (el.style[name] !== undefined) { 42975 return { end: transEndEventNames[name] } 42976 } 42977 } 42978 42979 return false // explicit for ie8 ( ._.) 42980 } 42981 42982 // http://blog.alexmaccaw.com/css-transitions 42983 $.fn.emulateTransitionEnd = function (duration) { 42984 var called = false, $el = this 42985 $(this).one($.support.transition.end, function () { called = true }) 42986 var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 42987 setTimeout(callback, duration) 42988 return this 42989 } 42990 42991 $(function () { 42992 $.support.transition = transitionEnd() 42993 }) 42994 42995}(jQuery); 42996 42997 42998// ------------------------------------------ 42999// Rellax.js 43000// Buttery smooth parallax library 43001// Copyright (c) 2016 Moe Amaya (@moeamaya) 43002// MIT license 43003// 43004// Thanks to Paraxify.js and Jaime Cabllero 43005// for parallax concepts 43006// ------------------------------------------ 43007 43008(function (root, factory) { 43009 if (typeof define === 'function' && define.amd) { 43010 // AMD. Register as an anonymous module. 43011 define([], factory); 43012 } else if (typeof module === 'object' && module.exports) { 43013 // Node. Does not work with strict CommonJS, but 43014 // only CommonJS-like environments that support module.exports, 43015 // like Node. 43016 module.exports = factory(); 43017 } else { 43018 // Browser globals (root is window) 43019 root.Rellax = factory(); 43020 } 43021}(typeof window !== "undefined" ? window : global, function () { 43022 var Rellax = function(el, options){ 43023 "use strict"; 43024 43025 var self = Object.create(Rellax.prototype); 43026 43027 var posY = 0; 43028 var screenY = 0; 43029 var posX = 0; 43030 var screenX = 0; 43031 var blocks = []; 43032 var pause = true; 43033 43034 // check what requestAnimationFrame to use, and if 43035 // it's not supported, use the onscroll event 43036 var loop = window.requestAnimationFrame || 43037 window.webkitRequestAnimationFrame || 43038 window.mozRequestAnimationFrame || 43039 window.msRequestAnimationFrame || 43040 window.oRequestAnimationFrame || 43041 function(callback){ return setTimeout(callback, 1000 / 60); }; 43042 43043 // store the id for later use 43044 var loopId = null; 43045 43046 // Test via a getter in the options object to see if the passive property is accessed 43047 var supportsPassive = false;
vendor: 10,724 bytes, lines 43048-43349
43048 try { 43049 var opts = Object.defineProperty({}, 'passive', { 43050 get: function() { 43051 supportsPassive = true; 43052 } 43053 }); 43054 window.addEventListener("testPassive", null, opts); 43055 window.removeEventListener("testPassive", null, opts); 43056 } catch (e) {} 43057 43058 // check what cancelAnimation method to use 43059 var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout; 43060 43061 // check which transform property to use 43062 var transformProp = window.transformProp || (function(){ 43063 var testEl = document.createElement('div'); 43064 if (testEl.style.transform === null) { 43065 var vendors = ['Webkit', 'Moz', 'ms']; 43066 for (var vendor in vendors) { 43067 if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) { 43068 return vendors[vendor] + 'Transform'; 43069 } 43070 } 43071 } 43072 return 'transform'; 43073 })(); 43074 43075 // Default Settings 43076 self.options = { 43077 speed: -2, 43078 verticalSpeed: null, 43079 horizontalSpeed: null, 43080 breakpoints: [576, 768, 1201], 43081 center: false, 43082 wrapper: null, 43083 relativeToWrapper: false, 43084 round: true, 43085 vertical: true, 43086 horizontal: false, 43087 verticalScrollAxis: "y", 43088 horizontalScrollAxis: "x", 43089 callback: function() {}, 43090 }; 43091 43092 // User defined options (might have more in the future) 43093 if (options){ 43094 Object.keys(options).forEach(function(key){ 43095 self.options[key] = options[key]; 43096 }); 43097 } 43098 43099 function validateCustomBreakpoints () { 43100 if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) { 43101 var isAscending = true; 43102 var isNumerical = true; 43103 var lastVal; 43104 self.options.breakpoints.forEach(function (i) { 43105 if (typeof i !== 'number') isNumerical = false; 43106 if (lastVal !== null) { 43107 if (i < lastVal) isAscending = false; 43108 } 43109 lastVal = i; 43110 }); 43111 if (isAscending && isNumerical) return; 43112 } 43113 // revert defaults if set incorrectly 43114 self.options.breakpoints = [576, 768, 1201]; 43115 console.warn("Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted"); 43116 } 43117 43118 if (options && options.breakpoints) { 43119 validateCustomBreakpoints(); 43120 } 43121 43122 // By default, rellax class 43123 if (!el) { 43124 el = '.rellax'; 43125 } 43126 43127 // check if el is a className or a node 43128 var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el]; 43129 43130 // Now query selector 43131 if (elements.length > 0) { 43132 self.elems = elements; 43133 } 43134 43135 // The elements don't exist 43136 else { 43137 console.warn("Rellax: The elements you're trying to select don't exist."); 43138 return; 43139 } 43140 43141 // Has a wrapper and it exists 43142 if (self.options.wrapper) { 43143 if (!self.options.wrapper.nodeType) { 43144 var wrapper = document.querySelector(self.options.wrapper); 43145 43146 if (wrapper) { 43147 self.options.wrapper = wrapper; 43148 } else { 43149 console.warn("Rellax: The wrapper you're trying to use doesn't exist."); 43150 return; 43151 } 43152 } 43153 } 43154 43155 // set a placeholder for the current breakpoint 43156 var currentBreakpoint; 43157 43158 // helper to determine current breakpoint 43159 var getCurrentBreakpoint = function (w) { 43160 var bp = self.options.breakpoints; 43161 if (w < bp[0]) return 'xs'; 43162 if (w >= bp[0] && w < bp[1]) return 'sm'; 43163 if (w >= bp[1] && w < bp[2]) return 'md'; 43164 return 'lg'; 43165 }; 43166 43167 // Get and cache initial position of all elements 43168 var cacheBlocks = function() { 43169 for (var i = 0; i < self.elems.length; i++){ 43170 var block = createBlock(self.elems[i]); 43171 blocks.push(block); 43172 } 43173 }; 43174 43175 43176 // Let's kick this script off 43177 // Build array for cached element values 43178 var init = function() { 43179 for (var i = 0; i < blocks.length; i++){ 43180 self.elems[i].style.cssText = blocks[i].style; 43181 } 43182 43183 blocks = []; 43184 43185 screenY = window.innerHeight; 43186 screenX = window.innerWidth; 43187 currentBreakpoint = getCurrentBreakpoint(screenX); 43188 43189 setPosition(); 43190 43191 cacheBlocks(); 43192 43193 animate(); 43194 43195 // If paused, unpause and set listener for window resizing events 43196 if (pause) { 43197 window.addEventListener('resize', init); 43198 pause = false; 43199 // Start the loop 43200 update(); 43201 } 43202 }; 43203 43204 // We want to cache the parallax blocks' 43205 // values: base, top, height, speed 43206 // el: is dom object, return: el cache values 43207 var createBlock = function(el) { 43208 var dataPercentage = el.getAttribute( 'data-rellax-percentage' ); 43209 var dataSpeed = el.getAttribute( 'data-rellax-speed' ); 43210 var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' ); 43211 var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' ); 43212 var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' ); 43213 var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' ); 43214 var dataVerticalSpeed = el.getAttribute('data-rellax-vertical-speed'); 43215 var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed'); 43216 var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis'); 43217 var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis'); 43218 var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0; 43219 var dataMin = el.getAttribute( 'data-rellax-min' ); 43220 var dataMax = el.getAttribute( 'data-rellax-max' ); 43221 var dataMinX = el.getAttribute('data-rellax-min-x'); 43222 var dataMaxX = el.getAttribute('data-rellax-max-x'); 43223 var dataMinY = el.getAttribute('data-rellax-min-y'); 43224 var dataMaxY = el.getAttribute('data-rellax-max-y'); 43225 var mapBreakpoints; 43226 var breakpoints = true; 43227 43228 if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) { 43229 breakpoints = false; 43230 } else { 43231 mapBreakpoints = { 43232 'xs': dataXsSpeed, 43233 'sm': dataMobileSpeed, 43234 'md': dataTabletSpeed, 43235 'lg': dataDesktopSpeed 43236 }; 43237 } 43238 43239 // initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser) 43240 // ensures elements are positioned based on HTML layout. 43241 // 43242 // If the element has the percentage attribute, the posY and posX needs to be 43243 // the current scroll position's value, so that the elements are still positioned based on HTML layout 43244 var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 43245 // If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll. 43246 if (self.options.relativeToWrapper) { 43247 var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); 43248 wrapperPosY = scrollPosY - self.options.wrapper.offsetTop; 43249 } 43250 var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0; 43251 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; 43252 43253 var blockTop = posY + el.getBoundingClientRect().top; 43254 var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight; 43255 43256 var blockLeft = posX + el.getBoundingClientRect().left; 43257 var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth; 43258 43259 // apparently parallax equation everyone uses 43260 var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY); 43261 var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX); 43262 if(self.options.center){ percentageX = 0.5; percentageY = 0.5; } 43263 43264 // Optional individual block speed as data attr, otherwise global speed 43265 var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed); 43266 var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed; 43267 var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed; 43268 43269 // Optional individual block movement axis direction as data attr, otherwise global movement direction 43270 var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis; 43271 var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis; 43272 43273 var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed); 43274 43275 // ~~Store non-translate3d transforms~~ 43276 // Store inline styles and extract transforms 43277 var style = el.style.cssText; 43278 var transform = ''; 43279 43280 // Check if there's an inline styled transform 43281 var searchResult = /transform\s*:/i.exec(style); 43282 if (searchResult) { 43283 // Get the index of the transform 43284 var index = searchResult.index; 43285 43286 // Trim the style to the transform point and get the following semi-colon index 43287 var trimmedStyle = style.slice(index); 43288 var delimiter = trimmedStyle.indexOf(';'); 43289 43290 // Remove "transform" string and save the attribute 43291 if (delimiter) { 43292 transform = " " + trimmedStyle.slice(11, delimiter).replace(/\s/g,''); 43293 } else { 43294 transform = " " + trimmedStyle.slice(11).replace(/\s/g,''); 43295 } 43296 } 43297 43298 return { 43299 baseX: bases.x, 43300 baseY: bases.y, 43301 top: blockTop, 43302 left: blockLeft, 43303 height: blockHeight, 43304 width: blockWidth, 43305 speed: speed, 43306 verticalSpeed: verticalSpeed, 43307 horizontalSpeed: horizontalSpeed, 43308 verticalScrollAxis: verticalScrollAxis, 43309 horizontalScrollAxis: horizontalScrollAxis, 43310 style: style, 43311 transform: transform, 43312 zindex: dataZindex, 43313 min: dataMin, 43314 max: dataMax, 43315 minX: dataMinX, 43316 maxX: dataMaxX, 43317 minY: dataMinY, 43318 maxY: dataMaxY 43319 }; 43320 }; 43321 43322 // set scroll position (posY, posX) 43323 // side effect method is not ideal, but okay for now 43324 // returns true if the scroll changed, false if nothing happened 43325 var setPosition = function() { 43326 var oldY = posY; 43327 var oldX = posX; 43328 43329 posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 43330 posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset; 43331 // If option relativeToWrapper is true, use relative wrapper value instead. 43332 if (self.options.relativeToWrapper) { 43333 var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset; 43334 posY = scrollPosY - self.options.wrapper.offsetTop; 43335 } 43336 43337 43338 if (oldY != posY && self.options.vertical) { 43339 // scroll changed, return true 43340 return true; 43341 } 43342 43343 if (oldX != posX && self.options.horizontal) { 43344 // scroll changed, return true 43345 return true; 43346 } 43347 43348 // scroll did not change 43349 return false;
43350 }; 43351 43352 // Ahh a pure function, gets new transform value 43353 // based on scrollPosition and speed 43354 // Allow for decimal pixel values 43355 var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) { 43356 var result = {}; 43357 var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX))); 43358 var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY))); 43359 43360 result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100; 43361 result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100; 43362 43363 return result; 43364 }; 43365 43366 // Remove event listeners and loop again 43367 var deferredUpdate = function() { 43368 window.removeEventListener('resize', deferredUpdate); 43369 window.removeEventListener('orientationchange', deferredUpdate); 43370 (self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate); 43371 (self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate); 43372 43373 // loop again 43374 loopId = loop(update); 43375 }; 43376 43377 // Loop 43378 var update = function() { 43379 if (setPosition() && pause === false) { 43380 animate(); 43381 43382 // loop again 43383 loopId = loop(update); 43384 } else { 43385 loopId = null; 43386 43387 // Don't animate until we get a position updating event 43388 window.addEventListener('resize', deferredUpdate); 43389 window.addEventListener('orientationchange', deferredUpdate); 43390 (self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false); 43391 (self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false); 43392 } 43393 }; 43394 43395 // Transform3d on parallax element 43396 var animate = function() { 43397 var positions; 43398 for (var i = 0; i < self.elems.length; i++){ 43399 // Determine relevant movement directions 43400 var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase(); 43401 var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase(); 43402 var verticalScrollX = verticalScrollAxis.indexOf("x") != -1 ? posY : 0; 43403 var verticalScrollY = verticalScrollAxis.indexOf("y") != -1 ? posY : 0; 43404 var horizontalScrollX = horizontalScrollAxis.indexOf("x") != -1 ? posX : 0; 43405 var horizontalScrollY = horizontalScrollAxis.indexOf("y") != -1 ? posX : 0; 43406 43407 var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY)); 43408 var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX)); 43409 43410 // Subtracting initialize value, so element stays in same spot as HTML 43411 positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed); 43412 var positionY = positions.y - blocks[i].baseY; 43413 var positionX = positions.x - blocks[i].baseX; 43414 43415 // The next two "if" blocks go like this: 43416 // Check if a limit is defined (first "min", then "max"); 43417 // Check if we need to change the Y or the X 43418 // (Currently working only if just one of the axes is enabled) 43419 // Then, check if the new position is inside the allowed limit 43420 // If so, use new position. If not, set position to limit. 43421 43422 // Check if a min limit is defined 43423 if (blocks[i].min !== null) { 43424 if (self.options.vertical && !self.options.horizontal) { 43425 positionY = positionY <= blocks[i].min ? blocks[i].min : positionY; 43426 } 43427 if (self.options.horizontal && !self.options.vertical) { 43428 positionX = positionX <= blocks[i].min ? blocks[i].min : positionX; 43429 } 43430 } 43431 43432 // Check if directional min limits are defined 43433 if (blocks[i].minY != null) { 43434 positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY; 43435 } 43436 if (blocks[i].minX != null) { 43437 positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX; 43438 } 43439 43440 // Check if a max limit is defined 43441 if (blocks[i].max !== null) { 43442 if (self.options.vertical && !self.options.horizontal) { 43443 positionY = positionY >= blocks[i].max ? blocks[i].max : positionY; 43444 } 43445 if (self.options.horizontal && !self.options.vertical) { 43446 positionX = positionX >= blocks[i].max ? blocks[i].max : positionX; 43447 } 43448 } 43449 43450 // Check if directional max limits are defined 43451 if (blocks[i].maxY != null) { 43452 positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY; 43453 } 43454 if (blocks[i].maxX != null) { 43455 positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX; 43456 } 43457 43458 var zindex = blocks[i].zindex; 43459 43460 // Move that element 43461 // (Set the new translation and append initial inline transforms.) 43462 var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform; 43463 self.elems[i].style[transformProp] = translate; 43464 } 43465 self.options.callback(positions); 43466 }; 43467 43468 self.destroy = function() { 43469 for (var i = 0; i < self.elems.length; i++){ 43470 self.elems[i].style.cssText = blocks[i].style; 43471 } 43472 43473 // Remove resize event listener if not pause, and pause 43474 if (!pause) { 43475 window.removeEventListener('resize', init); 43476 pause = true; 43477 } 43478 43479 // Clear the animation loop to prevent possible memory leak 43480 clearLoop(loopId); 43481 loopId = null; 43482 }; 43483 43484 // Init 43485 init(); 43486 43487 // Allow to recalculate the initial values whenever we want 43488 self.refresh = init; 43489 43490 return self; 43491 }; 43492 return Rellax; 43493})); 43494 43495/* 43496 * OKVideo by OKFocus v2.3.2 43497 * http://okfoc.us 43498 * 43499 * Copyright 2014, OKFocus 43500 * Licensed under the MIT license. 43501 * 43502 */ 43503var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array(); 43504// youtube player ready 43505function onYouTubeIframeAPIReady() { 43506 YTplayers = new Array(); 43507 jQuery('.uncode-video-container.video').each(function() { 43508 var playerY; 43509 if (jQuery(this).attr('data-provider') == 'youtube') { 43510 var id = jQuery(this).attr('data-id'), 43511 start = jQuery(this).attr('data-start'), 43512 end = jQuery(this).attr('data-end'); 43513 start = typeof start && start !== null ? start : 0; 43514 end = typeof end && end !== null ? end : 0; 43515 options = jQuery(window).data('okoptions-' + id); 43516 if ( typeof options === 'undefined' ) { 43517 return true; 43518 } 43519 options.time = jQuery(this).attr('data-t'); 43520 playerY = new YT.Player('okplayer-' + id, { 43521 videoId: options.video ? options.video.id : null, 43522 playerVars: { 43523 'autohide': 1, 43524 'autoplay': jQuery(this).hasClass('is-no-control') ? options.autoplay : 0, //options.autoplay, 43525 'disablekb': 1, 43526 'cc_load_policy': options.captions, 43527 'controls': 0, 43528 'enablejsapi': 1, 43529 'fs': 0, 43530 'modestbranding': 1, 43531 'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname), 43532 'iv_load_policy': options.annotations, 43533 'loop': options.loop, 43534 'showinfo': 0, 43535 'rel': 0, 43536 'wmode': 'opaque', 43537 'hd': options.hd, 43538 'mute': 1, 43539 'start': start, 43540 'end': end 43541 }, 43542 events: { 43543 'onReady': OKEvents.yt.ready, 43544 'onStateChange': OKEvents.yt.onStateChange, 43545 'onError': OKEvents.yt.error 43546 } 43547 }); 43548 YTplayers[id] = playerY; 43549 playerY.videoId = id; 43550 } 43551 43552 }); 43553} 43554// vimeo player ready 43555function vimeoPlayerReady(id) { 43556 options = jQuery(window).data('okoptions-' + id); 43557 if ( typeof options === 'undefined' ) { 43558 return true; 43559 }
43560 var jIframe = options.jobject, 43561 iframe = jIframe[0]; 43562 43563 jIframe.attr('src', jIframe.data('src')); 43564 var playerV = new Vimeo.Player(iframe); 43565 // hide player until Vimeo hides controls... 43566 playerV.on('loaded', function(e) { 43567 OKEvents.v.onReady(iframe); 43568 var carouselContainer = jQuery(iframe).closest('.owl-carousel'); 43569 if (carouselContainer.length) { 43570 UNCODE.owlPlayVideo(carouselContainer); 43571 } 43572 // "Do not try to add listeners or call functions before receiving this event." 43573 if (OKEvents.utils.isMobile()) { 43574 // mobile devices cannot listen for play event 43575 OKEvents.v.onPlay(playerV); 43576 } else { 43577 playerV.on('play', function(){ 43578 OKEvents.v.onPlay(playerV); 43579 jQuery(window).trigger('okevents.v.play', [playerV]); 43580 }); 43581 playerV.on('pause', function(){ 43582 OKEvents.v.onPause; 43583 jQuery(window).trigger('okevents.v.pause', [playerV]); 43584 }); 43585 playerV.on('ended', function(){ 43586 OKEvents.v.onFinish 43587 jQuery(window).trigger('okevents.v.ended', [playerV]); 43588 }); 43589 } 43590 if (options.time != null) { 43591 var optsTimeStr = (options.time).replace('t=', ''), 43592 timeV = ''; 43593 43594 if ( /[a-zA-Z]/g.test(optsTimeStr) ) { 43595 var timeArr = optsTimeStr.split(/([^\d.-])/); 43596 for ( var i = 0; i < timeArr.length; i++ ) { 43597 if ( timeArr[i] === 'h' ) { 43598 timeV += parseFloat(timeArr[i-1]) * 3600; 43599 } else if ( timeArr[i] === 'm' ) { 43600 timeV += parseFloat(timeArr[i-1]) * 60; 43601 } else if ( timeArr[i] === 's' ) { 43602 timeV += parseFloat(timeArr[i-1]); 43603 } 43604 } 43605 } else { 43606 timeV = optsTimeStr; 43607 } 43608 43609 playerV.setCurrentTime(timeV); 43610 } 43611 43612 playerV.setVolume(0); 43613 playerV.play(); 43614 jQuery(iframe).css({ 43615 visibility: 'visible', 43616 opacity: 1 43617 }); 43618 jQuery(iframe).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 43619 jQuery(iframe).closest('#page-header').addClass('video-started'); 43620 jQuery(iframe).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 43621 43622 jQuery(window).trigger('okevents.v.loaded', [playerV]); 43623 }); 43624} 43625OKEvents = { 43626 yt: { 43627 ready: function(event) { 43628 var id = event.target.videoId, 43629 $video = jQuery('#okplayer-' + id), 43630 options = jQuery(window).data('okoptions-' + id); 43631 if ( typeof options === 'undefined' ) { 43632 return true; 43633 } 43634 youtubePlayers[id] = event.target; 43635 event.target.setVolume(options.volume); 43636 if (options.autoplay === 1) { 43637 if (options.playlist.list) { 43638 player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality); 43639 } else { 43640 var inCarousel = $video.closest('.owl-item'); 43641 if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) { 43642 if (options.time != null) { 43643 event.target.seekTo(parseInt(options.time)); 43644 } 43645 event.target.playVideo(); 43646 } else { 43647 event.target.pauseVideo(); 43648 } 43649 } 43650 } 43651 OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target); 43652 43653 $video.closest('[data-provider]').on('uncode-resume', function(){ 43654 if (options.time != null) { 43655 event.target.seekTo(parseInt(options.time)).playVideo(); 43656 } else { 43657 event.target.seekTo(0).playVideo(); 43658 } 43659 }); 43660 43661 $video.closest('[data-provider]').on('uncode-pause', function(){ 43662 if (options.time != null) { 43663 event.target.seekTo(parseInt(options.time)).pauseVideo(); 43664 } else { 43665 event.target.seekTo(0).pauseVideo(); 43666 } 43667 }); 43668 jQuery(window).trigger('okevents.y.loaded', [event]); 43669 }, 43670 onStateChange: function(event) { 43671 var id = event.target.videoId, 43672 $video = jQuery('#okplayer-' + id), 43673 options = jQuery(window).data('okoptions-' + id); 43674 if ( typeof options === 'undefined' || typeof event.target.setVolume === 'undefined' ) { 43675 return true; 43676 } 43677 youtubePlayers[id] = event.target; 43678 event.target.setVolume(options.volume); 43679 var $fluid = $video.closest('.fluid-object'), 43680 $tmb = $video.closest('.tmb'), 43681 setTime; 43682 switch (event.data) { 43683 case -1: 43684 OKEvents.utils.isFunction(options.unstarted) && options.unstarted(); 43685 break; 43686 case 0: 43687 OKEvents.utils.isFunction(options.onFinished) && options.onFinished(); 43688 options.loop && event.target.playVideo(); 43689 break; 43690 case 1: 43691 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 43692 setTimeout(function() { 43693 UNCODE.initVideoComponent(document.body, '.uncode-video-container.video:not(.drop-move), .uncode-video-container.self-video:not(.drop-move)'); 43694 jQuery('#okplayer-' + id).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 43695 jQuery('#okplayer-' + id).closest('#page-header').addClass('video-started'); 43696 jQuery('#okplayer-' + id).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 43697 }, 300); 43698 break; 43699 case 2: 43700 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 43701 break; 43702 case 3: 43703 OKEvents.utils.isFunction(options.buffering) && options.buffering(); 43704 break; 43705 case 5: 43706 OKEvents.utils.isFunction(options.cued) && options.cued(); 43707 break; 43708 default:
43709 throw "OKVideo: received invalid data from YT player."; 43710 } 43711 43712 jQuery(window).trigger('okevents.y.change', [event]); 43713 }, 43714 error: function(event) { 43715 throw event; 43716 } 43717 }, 43718 v: { 43719 onReady: function(target) { 43720 if ( typeof options === 'undefined' ) { 43721 return true; 43722 } 43723 OKEvents.utils.isFunction(options.onReady) && options.onReady(target); 43724 }, 43725 onPlay: function(player) { 43726 if ( typeof options === 'undefined' ) { 43727 return true; 43728 } 43729 if (!OKEvents.utils.isMobile()) player.setVolume(options.volume); 43730 OKEvents.utils.isFunction(options.onPlay) && options.onPlay(); 43731 jQuery(player.element).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1'); 43732 jQuery(player.element).closest('#page-header').addClass('video-started'); 43733 jQuery(player.element).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1'); 43734 }, 43735 onPause: function() { 43736 if ( typeof options === 'undefined' ) { 43737 return true; 43738 } 43739 OKEvents.utils.isFunction(options.onPause) && options.onPause(); 43740 }, 43741 onFinish: function() { 43742 if ( typeof options === 'undefined' ) { 43743 return true; 43744 } 43745 OKEvents.utils.isFunction(options.onFinish) && options.onFinish(); 43746 } 43747 }, 43748 utils: { 43749 isFunction: function(func) { 43750 if (typeof func === 'function') { 43751 return true; 43752 } else { 43753 return false; 43754 } 43755 }, 43756 isMobile: function() { 43757 if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) { 43758 return true; 43759 } else { 43760 return false; 43761 } 43762 } 43763 } 43764}; 43765/** 43766 * vivus - JavaScript library to make drawing animation on SVG 43767 * @version v0.4.4 43768 * @link https://github.com/maxwellito/vivus 43769 * @license MIT 43770 */ 43771 43772'use strict'; 43773 43774(function () { 43775 43776 'use strict'; 43777 43778/** 43779 * Pathformer 43780 * Beta version 43781 * 43782 * Take any SVG version 1.1 and transform 43783 * child elements to 'path' elements 43784 * 43785 * This code is purely forked from 43786 * https://github.com/Waest/SVGPathConverter 43787 */ 43788 43789/** 43790 * Class constructor 43791 * 43792 * @param {DOM|String} element Dom element of the SVG or id of it 43793 */ 43794function Pathformer(element) { 43795 // Test params 43796 if (typeof element === 'undefined') { 43797 throw new Error('Pathformer [constructor]: "element" parameter is required'); 43798 } 43799 43800 // Set the element 43801 if (element.constructor === String) { 43802 element = document.getElementById(element); 43803 if (!element) { 43804 throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID'); 43805 } 43806 } 43807 if (element instanceof window.SVGElement || 43808 element instanceof window.SVGGElement || 43809 /^svg$/i.test(element.nodeName)) { 43810 this.el = element; 43811 } else { 43812 throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement'); 43813 } 43814 43815 // Start 43816 this.scan(element); 43817} 43818 43819/** 43820 * List of tags which can be transformed 43821 * to path elements 43822 * 43823 * @type {Array} 43824 */ 43825Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect']; 43826 43827/** 43828 * List of attribute names which contain 43829 * data. This array list them to check if 43830 * they contain bad values, like percentage. 43831 * 43832 * @type {Array} 43833 */ 43834Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', '
vendor: 24,640 bytes, lines 43834-44632
43834y1', 'y2']; 43835 43836/** 43837 * Finds the elements compatible for transform 43838 * and apply the liked method 43839 * 43840 * @param {object} options Object from the constructor 43841 */ 43842Pathformer.prototype.scan = function (svg) { 43843 var fn, element, pathData, pathDom, 43844 elements = svg.querySelectorAll(this.TYPES.join(',')); 43845 43846 for (var i = 0; i < elements.length; i++) { 43847 element = elements[i]; 43848 fn = this[element.tagName.toLowerCase() + 'ToPath']; 43849 pathData = fn(this.parseAttr(element.attributes)); 43850 pathDom = this.pathMaker(element, pathData); 43851 element.parentNode.replaceChild(pathDom, element); 43852 } 43853}; 43854 43855 43856/** 43857 * Read `line` element to extract and transform 43858 * data, to make it ready for a `path` object. 43859 * 43860 * @param {DOMelement} element Line element to transform 43861 * @return {object} Data for a `path` element 43862 */ 43863Pathformer.prototype.lineToPath = function (element) { 43864 var newElement = {}, 43865 x1 = element.x1 || 0, 43866 y1 = element.y1 || 0, 43867 x2 = element.x2 || 0, 43868 y2 = element.y2 || 0; 43869 43870 newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2; 43871 return newElement; 43872}; 43873 43874/** 43875 * Read `rect` element to extract and transform 43876 * data, to make it ready for a `path` object. 43877 * The radius-border is not taken in charge yet. 43878 * (your help is more than welcomed) 43879 * 43880 * @param {DOMelement} element Rect element to transform 43881 * @return {object} Data for a `path` element 43882 */ 43883Pathformer.prototype.rectToPath = function (element) { 43884 var newElement = {}, 43885 x = parseFloat(element.x) || 0, 43886 y = parseFloat(element.y) || 0, 43887 width = parseFloat(element.width) || 0, 43888 height = parseFloat(element.height) || 0; 43889 43890 if (element.rx || element.ry) { 43891 var rx = parseInt(element.rx, 10) || -1, 43892 ry = parseInt(element.ry, 10) || -1; 43893 rx = Math.min(Math.max(rx < 0 ? ry : rx, 0), width/2); 43894 ry = Math.min(Math.max(ry < 0 ? rx : ry, 0), height/2); 43895 43896 newElement.d = 'M ' + (x + rx) + ',' + y + ' ' + 43897 'L ' + (x + width - rx) + ',' + y + ' ' + 43898 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width) + ',' + (y + ry) + ' ' + 43899 'L ' + (x + width) + ',' + (y + height - ry) + ' ' + 43900 'A ' + rx + ',' + ry + ',0,0,1,' + (x + width - rx) + ',' + (y + height) + ' ' + 43901 'L ' + (x + rx) + ',' + (y + height) + ' ' + 43902 'A ' + rx + ',' + ry + ',0,0,1,' + x + ',' + (y + height - ry) + ' ' + 43903 'L ' + x + ',' + (y + ry) + ' ' + 43904 'A ' + rx + ',' + ry + ',0,0,1,' + (x + rx) + ',' + y; 43905 } 43906 else { 43907 newElement.d = 'M' + x + ' ' + y + ' ' + 43908 'L' + (x + width) + ' ' + y + ' ' + 43909 'L' + (x + width) + ' ' + (y + height) + ' ' + 43910 'L' + x + ' ' + (y + height) + ' Z'; 43911 } 43912 return newElement; 43913}; 43914 43915/** 43916 * Read `polyline` element to extract and transform 43917 * data, to make it ready for a `path` object. 43918 * 43919 * @param {DOMelement} element Polyline element to transform 43920 * @return {object} Data for a `path` element 43921 */ 43922Pathformer.prototype.polylineToPath = function (element) { 43923 var newElement = {}, 43924 points = element.points.trim().split(' '), 43925 i, path; 43926 43927 // Reformatting if points are defined without commas 43928 if (element.points.indexOf(',') === -1) { 43929 var formattedPoints = []; 43930 for (i = 0; i < points.length; i+=2) { 43931 formattedPoints.push(points[i] + ',' + points[i+1]); 43932 } 43933 points = formattedPoints; 43934 } 43935 43936 // Generate the path.d value 43937 path = 'M' + points[0]; 43938 for(i = 1; i < points.length; i++) { 43939 if (points[i].indexOf(',') !== -1) { 43940 path += 'L' + points[i]; 43941 } 43942 } 43943 newElement.d = path; 43944 return newElement; 43945}; 43946 43947/** 43948 * Read `polygon` element to extract and transform 43949 * data, to make it ready for a `path` object. 43950 * This method rely on polylineToPath, because the 43951 * logic is similar. The path created is just closed, 43952 * so it needs an 'Z' at the end. 43953 * 43954 * @param {DOMelement} element Polygon element to transform 43955 * @return {object} Data for a `path` element 43956 */ 43957Pathformer.prototype.polygonToPath = function (element) { 43958 var newElement = Pathformer.prototype.polylineToPath(element); 43959 43960 newElement.d += 'Z'; 43961 return newElement; 43962}; 43963 43964/** 43965 * Read `ellipse` element to extract and transform 43966 * data, to make it ready for a `path` object. 43967 * 43968 * @param {DOMelement} element ellipse element to transform 43969 * @return {object} Data for a `path` element 43970 */ 43971Pathformer.prototype.ellipseToPath = function (element) { 43972 var newElement = {}, 43973 rx = parseFloat(element.rx) || 0, 43974 ry = parseFloat(element.ry) || 0, 43975 cx = parseFloat(element.cx) || 0, 43976 cy = parseFloat(element.cy) || 0, 43977 startX = cx - rx, 43978 startY = cy, 43979 endX = parseFloat(cx) + parseFloat(rx), 43980 endY = cy; 43981 43982 newElement.d = 'M' + startX + ',' + startY + 43983 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY + 43984 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY; 43985 return newElement; 43986}; 43987 43988/** 43989 * Read `circle` element to extract and transform 43990 * data, to make it ready for a `path` object. 43991 * 43992 * @param {DOMelement} element Circle element to transform 43993 * @return {object} Data for a `path` element 43994 */ 43995Pathformer.prototype.circleToPath = function (element) { 43996 var newElement = {}, 43997 r = parseFloat(element.r) || 0, 43998 cx = parseFloat(element.cx) || 0, 43999 cy = parseFloat(element.cy) || 0, 44000 startX = cx - r, 44001 startY = cy, 44002 endX = parseFloat(cx) + parseFloat(r), 44003 endY = cy; 44004 44005 newElement.d = 'M' + startX + ',' + startY + 44006 'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY + 44007 'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY; 44008 return newElement; 44009}; 44010 44011/** 44012 * Create `path` elements form original element 44013 * and prepared objects 44014 * 44015 * @param {DOMelement} element Original element to transform 44016 * @param {object} pathData Path data (from `toPath` methods) 44017 * @return {DOMelement} Path element 44018 */ 44019Pathformer.prototype.pathMaker = function (element, pathData) { 44020 var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path'); 44021 for(i = 0; i < element.attributes.length; i++) { 44022 attr = element.attributes[i]; 44023 if (this.ATTR_WATCH.indexOf(attr.name) === -1) { 44024 pathTag.setAttribute(attr.name, attr.value); 44025 } 44026 } 44027 for(i in pathData) { 44028 pathTag.setAttribute(i, pathData[i]); 44029 } 44030 return pathTag; 44031}; 44032 44033/** 44034 * Parse attributes of a DOM element to 44035 * get an object of attribute => value 44036 * 44037 * @param {NamedNodeMap} attributes Attributes object from DOM element to parse 44038 * @return {object} Object of attributes 44039 */ 44040Pathformer.prototype.parseAttr = function (element) { 44041 var attr, output = {}; 44042 for (var i = 0; i < element.length; i++) { 44043 attr = element[i]; 44044 // Check if no data attribute contains '%', or the transformation is impossible 44045 if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) { 44046 throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.'); 44047 } 44048 output[attr.name] = attr.value; 44049 } 44050 return output; 44051}; 44052 44053 'use strict'; 44054 44055var setupEnv, requestAnimFrame, cancelAnimFrame, parsePositiveInt; 44056 44057/** 44058 * Vivus 44059 * Beta version 44060 * 44061 * Take any SVG and make the animation 44062 * to give give the impression of live drawing 44063 * 44064 * This in more than just inspired from codrops 44065 * At that point, it's a pure fork. 44066 */ 44067 44068/** 44069 * Class constructor 44070 * option structure 44071 * type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed) 44072 * duration: <int> (in frames) 44073 * start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport) 44074 * delay: <int> (delay between the drawing of first and last path) 44075 * dashGap <integer> whitespace extra margin between dashes 44076 * pathTimingFunction <function> timing animation function for each path element of the SVG 44077 * animTimingFunction <function> timing animation function for the complete SVG 44078 * forceRender <boolean> force the browser to re-render all updated path items 44079 * selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original 44080 * 44081 * The attribute 'type' is by default on 'delayed'. 44082 * - 'delayed' 44083 * all paths are draw at the same time but with a 44084 * little delay between them before start 44085 * - 'sync' 44086 * all path are start and finish at the same time 44087 * - 'oneByOne' 44088 * only one path is draw at the time 44089 * the end of the first one will trigger the draw 44090 * of the next one 44091 * 44092 * All these values can be overwritten individually 44093 * for each path item in the SVG 44094 * The value of frames will always take the advantage of 44095 * the duration value. 44096 * If you fail somewhere, an error will be thrown. 44097 * Good luck. 44098 * 44099 * @constructor 44100 * @this {Vivus} 44101 * @param {DOM|String} element Dom element of the SVG or id of it 44102 * @param {Object} options Options about the animation 44103 * @param {Function} callback Callback for the end of the animation 44104 */ 44105function Vivus (element, options, callback) { 44106 44107 setupEnv(); 44108 44109 // Setup 44110 this.isReady = false; 44111 this.setElement(element, options); 44112 this.setOptions(options); 44113 this.setCallback(callback); 44114 44115 if (this.isReady) { 44116 this.init(); 44117 } 44118} 44119 44120/** 44121 * Timing functions 44122 ************************************** 44123 * 44124 * Default functions to help developers. 44125 * It always take a number as parameter (between 0 to 1) then 44126 * return a number (between 0 and 1) 44127 */ 44128Vivus.LINEAR = function (x) {return x;}; 44129Vivus.EASE = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;}; 44130Vivus.EASE_OUT = function (x) {return 1 - Math.pow(1-x, 3);}; 44131Vivus.EASE_IN = function (x) {return Math.pow(x, 3);}; 44132Vivus.EASE_OUT_BOUNCE = function (x) { 44133 var base = -Math.cos(x * (0.5 * Math.PI)) + 1, 44134 rate = Math.pow(base,1.5), 44135 rateR = Math.pow(1 - x, 2), 44136 progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1; 44137 return (1- rateR) + (progress * rateR); 44138}; 44139 44140 44141/** 44142 * Setters 44143 ************************************** 44144 */ 44145 44146/** 44147 * Check and set the element in the instance 44148 * The method will not return anything, but will throw an 44149 * error if the parameter is invalid 44150 * 44151 * @param {DOM|String} element SVG Dom element or id of it 44152 */ 44153Vivus.prototype.setElement = function (element, options) { 44154 var onLoad, self; 44155 44156 // Basic check 44157 if (typeof element === 'undefined') { 44158 throw new Error('Vivus [constructor]: "element" parameter is required'); 44159 } 44160 44161 // Set the element 44162 if (element.constructor === String) { 44163 element = document.getElementById(element); 44164 if (!element) { 44165 throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID'); 44166 } 44167 } 44168 this.parentEl = element; 44169 44170 // Load the SVG with XMLHttpRequest and extract the SVG 44171 if (options && options.file) { 44172 var self = this; 44173 onLoad = function (e) { 44174 var domSandbox = document.createElement('div'); 44175 domSandbox.innerHTML = this.responseText; 44176 44177 var svgTag = domSandbox.querySelector('svg'); 44178 if (!svgTag) { 44179 throw new Error('Vivus [load]: Cannot find the SVG in the loaded file : ' + options.file); 44180 } 44181 44182 self.el = svgTag 44183 self.el.setAttribute('width', '100%'); 44184 self.el.setAttribute('height', '100%'); 44185 self.parentEl.appendChild(self.el) 44186 self.isReady = true; 44187 self.init(); 44188 self = null; 44189 } 44190 44191 var oReq = new window.XMLHttpRequest(); 44192 oReq.addEventListener('load', onLoad); 44193 oReq.open('GET', options.file); 44194 oReq.send(); 44195 return; 44196 } 44197 44198 switch (element.constructor) { 44199 case window.SVGSVGElement: 44200 case window.SVGElement: 44201 case window.SVGGElement: 44202 this.el = element; 44203 this.isReady = true; 44204 break; 44205 44206 case window.HTMLObjectElement: 44207 self = this; 44208 onLoad = function (e) { 44209 if (self.isReady) { 44210 return; 44211 } 44212 self.el = element.contentDocument && element.contentDocument.querySelector('svg'); 44213 if (!self.el && e) { 44214 throw new Error('Vivus [constructor]: object loaded does not contain any SVG'); 44215 } 44216 else if (self.el) { 44217 if (element.getAttribute('built-by-vivus')) { 44218 self.parentEl.insertBefore(self.el, element); 44219 self.parentEl.removeChild(element); 44220 self.el.setAttribute('width', '100%'); 44221 self.el.setAttribute('height', '100%'); 44222 } 44223 self.isReady = true; 44224 self.init(); 44225 self = null; 44226 } 44227 }; 44228 44229 if (!onLoad()) { 44230 element.addEventListener('load', onLoad); 44231 } 44232 break; 44233 44234 default: 44235 throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)'); 44236 } 44237}; 44238 44239/** 44240 * Set up user option to the instance 44241 * The method will not return anything, but will throw an 44242 * error if the parameter is invalid 44243 * 44244 * @param {object} options Object from the constructor 44245 */ 44246Vivus.prototype.setOptions = function (options) { 44247 var allowedTypes = ['delayed', 'sync', 'async', 'nsync', 'oneByOne', 'scenario', 'scenario-sync']; 44248 var allowedStarts = ['inViewport', 'manual', 'autostart']; 44249 44250 // Basic check 44251 if (options !== undefined && options.constructor !== Object) { 44252 throw new Error('Vivus [constructor]: "options" parameter must be an object'); 44253 } 44254 else { 44255 options = options || {}; 44256 } 44257 44258 // Set the animation type 44259 if (options.type && allowedTypes.indexOf(options.type) === -1) { 44260 throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`'); 44261 } 44262 else { 44263 this.type = options.type || allowedTypes[0]; 44264 } 44265 44266 // Set the start type 44267 if (options.start && allowedStarts.indexOf(options.start) === -1) { 44268 throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option'); 44269 } 44270 else { 44271 this.start = options.start || allowedStarts[0]; 44272 } 44273 44274 this.isIE = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 ); 44275 this.duration = parsePositiveInt(options.duration, 120); 44276 this.delay = parsePositiveInt(options.delay, null); 44277 //Uncode addition 44278 this.delayStart = parsePositiveInt(options.delayStart, null); 44279 //#END 44280 this.dashGap = parsePositiveInt(options.dashGap, 1); 44281 this.forceRender = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE; 44282 this.reverseStack = !!options.reverseStack; 44283 this.selfDestroy = !!options.selfDestroy; 44284 this.onReady = options.onReady; 44285 this.map = []; 44286 this.frameLength = this.currentFrame = this.delayUnit = this.speed = this.handle = null; 44287 44288 this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false; 44289 44290 this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR; 44291 this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR; 44292 44293 if (this.delay >= this.duration) { 44294 throw new Error('Vivus [constructor]: delay must be shorter than duration'); 44295 } 44296}; 44297 44298/** 44299 * Set up callback to the instance 44300 * The method will not return enything, but will throw an 44301 * error if the parameter is invalid 44302 * 44303 * @param {Function} callback Callback for the animation end 44304 */ 44305Vivus.prototype.setCallback = function (callback) { 44306 // Basic check 44307 if (!!callback && callback.constructor !== Function) { 44308 throw new Error('Vivus [constructor]: "callback" parameter must be a function'); 44309 } 44310 this.callback = callback || function () {}; 44311}; 44312 44313 44314/** 44315 * Core 44316 ************************************** 44317 */ 44318 44319/** 44320 * Map the svg, path by path. 44321 * The method return nothing, it just fill the 44322 * `map` array. Each item in this array represent 44323 * a path element from the SVG, with informations for 44324 * the animation. 44325 * 44326 * ``` 44327 * [ 44328 * { 44329 * el: <DOMobj> the path element 44330 * length: <number> length of the path line 44331 * startAt: <number> time start of the path animation (in frames) 44332 * duration: <number> path animation duration (in frames) 44333 * }, 44334 * ... 44335 * ] 44336 * ``` 44337 * 44338 */ 44339Vivus.prototype.mapping = function () { 44340 var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint; 44341 timePoint = totalLength = lengthMeter = 0; 44342 paths = this.el.querySelectorAll('path'); 44343 44344 for (i = 0; i < paths.length; i++) { 44345 path = paths[i]; 44346 if (this.isInvisible(path)) { 44347 continue; 44348 } 44349 pathObj = { 44350 el: path, 44351 length: Math.ceil(path.getTotalLength()) 44352 }; 44353 // Test if the path length is correct 44354 if (isNaN(pathObj.length)) { 44355 if (window.console && console.warn) { 44356 console.warn('Vivus [mapping]: cannot retrieve a path element length', path); 44357 } 44358 continue; 44359 } 44360 this.map.push(pathObj); 44361 path.style.strokeDasharray = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2); 44362 path.style.strokeDashoffset = pathObj.length + this.dashGap; 44363 pathObj.length += this.dashGap; 44364 totalLength += pathObj.length; 44365 44366 this.renderPath(i); 44367 } 44368 44369 totalLength = totalLength === 0 ? 1 : totalLength; 44370 this.delay = this.delay === null ? this.duration / 3 : this.delay; 44371 this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1); 44372 44373 // Reverse stack if asked 44374 if (this.reverseStack) { 44375 this.map.reverse(); 44376 } 44377 44378 for (i = 0; i < this.map.length; i++) { 44379 pathObj = this.map[i]; 44380 44381 switch (this.type) { 44382 case 'delayed': 44383 pathObj.startAt = this.delayUnit * i; 44384 pathObj.duration = this.duration - this.delay; 44385 break; 44386 44387 case 'oneByOne': 44388 pathObj.startAt = lengthMeter / totalLength * this.duration; 44389 pathObj.duration = pathObj.length / totalLength * this.duration; 44390 break; 44391 44392 case 'sync': 44393 case 'async': 44394 case 'nsync': 44395 pathObj.startAt = 0; 44396 pathObj.duration = this.duration; 44397 break; 44398 44399 case 'scenario-sync': 44400 path = pathObj.el; 44401 pAttrs = this.parseAttr(path); 44402 pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0); 44403 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 44404 timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration; 44405 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 44406 break; 44407 44408 case 'scenario': 44409 path = pathObj.el; 44410 pAttrs = this.parseAttr(path); 44411 pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0; 44412 pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration); 44413 this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration)); 44414 break; 44415 } 44416 lengthMeter += pathObj.length; 44417 this.frameLength = this.frameLength || this.duration; 44418 } 44419}; 44420 44421/** 44422 * Interval method to draw the SVG from current 44423 * position of the animation. It update the value of 44424 * `currentFrame` and re-trace the SVG. 44425 * 44426 * It use this.handle to store the requestAnimationFrame 44427 * and clear it one the animation is stopped. So this 44428 * attribute can be used to know if the animation is 44429 * playing. 44430 * 44431 * Once the animation at the end, this method will 44432 * trigger the Vivus callback. 44433 * 44434 */ 44435Vivus.prototype.drawer = function () { 44436 var self = this; 44437 this.currentFrame += this.speed; 44438 44439 if (this.currentFrame <= 0) { 44440 this.stop(); 44441 this.reset(); 44442 } else if (this.currentFrame >= this.frameLength) { 44443 this.stop(); 44444 this.currentFrame = this.frameLength; 44445 this.trace(); 44446 if (this.selfDestroy) { 44447 this.destroy(); 44448 } 44449 } else { 44450 this.trace(); 44451 this.handle = requestAnimFrame(function () { 44452 self.drawer(); 44453 }); 44454 return; 44455 } 44456 44457 this.callback(this); 44458 if (this.instanceCallback) { 44459 this.instanceCallback(this); 44460 this.instanceCallback = null; 44461 } 44462}; 44463 44464/** 44465 * Draw the SVG at the current instant from the 44466 * `currentFrame` value. Here is where most of the magic is. 44467 * The trick is to use the `strokeDashoffset` style property. 44468 * 44469 * For optimisation reasons, a new property called `progress` 44470 * is added in each item of `map`. This one contain the current 44471 * progress of the path element. Only if the new value is different 44472 * the new value will be applied to the DOM element. This 44473 * method save a lot of resources to re-render the SVG. And could 44474 * be improved if the animation couldn't be played forward. 44475 * 44476 */ 44477Vivus.prototype.trace = function () { 44478 var i, progress, path, currentFrame; 44479 currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength; 44480 for (i = 0; i < this.map.length; i++) { 44481 path = this.map[i]; 44482 progress = (currentFrame - path.startAt) / path.duration; 44483 progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress))); 44484 if (path.progress !== progress) { 44485 path.progress = progress; 44486 path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress)); 44487 this.renderPath(i); 44488 } 44489 } 44490}; 44491 44492/** 44493 * Method forcing the browser to re-render a path element 44494 * from it's index in the map. Depending on the `forceRender` 44495 * value. 44496 * The trick is to replace the path element by it's clone. 44497 * This practice is not recommended because it's asking more 44498 * ressources, too much DOM manupulation.. 44499 * but it's the only way to let the magic happen on IE. 44500 * By default, this fallback is only applied on IE. 44501 * 44502 * @param {Number} index Path index 44503 */ 44504Vivus.prototype.renderPath = function (index) { 44505 if (this.forceRender && this.map && this.map[index]) { 44506 var pathObj = this.map[index], 44507 newPath = pathObj.el.cloneNode(true); 44508 pathObj.el.parentNode.replaceChild(newPath, pathObj.el); 44509 pathObj.el = newPath; 44510 } 44511}; 44512 44513/** 44514 * When the SVG object is loaded and ready, 44515 * this method will continue the initialisation. 44516 * 44517 * This this mainly due to the case of passing an 44518 * object tag in the constructor. It will wait 44519 * the end of the loading to initialise. 44520 * 44521 */ 44522Vivus.prototype.init = function () { 44523 // Set object variables 44524 this.frameLength = 0; 44525 this.currentFrame = 0; 44526 this.map = []; 44527 44528 // Start 44529 new Pathformer(this.el); 44530 this.mapping(); 44531 this.starter(); 44532 44533 if (this.onReady) { 44534 this.onReady(this); 44535 } 44536}; 44537 44538/** 44539 * Trigger to start of the animation. 44540 * Depending on the `start` value, a different script 44541 * will be applied. 44542 * 44543 * If the `start` value is not valid, an error will be thrown. 44544 * Even if technically, this is impossible. 44545 * 44546 */ 44547Vivus.prototype.starter = function () { 44548 switch (this.start) { 44549 case 'manual': 44550 return; 44551 44552 case 'autostart': 44553 this.play(); 44554 break; 44555 44556 case 'inViewport': 44557 var self = this, 44558 listener = function () { 44559 if (self.isInViewport(self.parentEl, 1)) { 44560 self.play(); 44561 window.removeEventListener('scroll', listener); 44562 //Uncode addition 44563 window.removeEventListener('fp-slide-changed', listener); 44564 window.removeEventListener('fp-slide-scroll', listener); 44565 //#END 44566 } 44567 }; 44568 window.addEventListener('scroll', listener); 44569 //Uncode addition 44570 window.addEventListener('fp-slide-changed', listener); 44571 window.addEventListener('fp-slide-scroll', listener); 44572 //#END 44573 listener(); 44574 break; 44575 } 44576}; 44577 44578 44579/** 44580 * Controls 44581 ************************************** 44582 */ 44583 44584/** 44585 * Get the current status of the animation between 44586 * three different states: 'start', 'progress', 'end'. 44587 * @return {string} Instance status 44588 */ 44589Vivus.prototype.getStatus = function () { 44590 return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress'; 44591}; 44592 44593/** 44594 * Reset the instance to the initial state : undraw 44595 * Be careful, it just reset the animation, if you're 44596 * playing the animation, this won't stop it. But just 44597 * make it start from start. 44598 * 44599 */ 44600Vivus.prototype.reset = function () { 44601 return this.setFrameProgress(0); 44602}; 44603 44604/** 44605 * Set the instance to the final state : drawn 44606 * Be careful, it just set the animation, if you're 44607 * playing the animation on rewind, this won't stop it. 44608 * But just make it start from the end. 44609 * 44610 */ 44611Vivus.prototype.finish = function () { 44612 return this.setFrameProgress(1); 44613}; 44614 44615/** 44616 * Set the level of progress of the drawing. 44617 * 44618 * @param {number} progress Level of progress to set 44619 */ 44620Vivus.prototype.setFrameProgress = function (progress) { 44621 progress = Math.min(1, Math.max(0, progress)); 44622 this.currentFrame = Math.round(this.frameLength * progress); 44623 this.trace(); 44624 return this; 44625}; 44626 44627/** 44628 * Play the animation at the desired speed. 44629 * Speed must be a valid number (no zero). 44630 * By default, the speed value is 1. 44631 * But a negative value is accepted to go forward. 44632 *
44633 * And works with float too. 44634 * But don't forget we are in JavaScript, se be nice 44635 * with him and give him a 1/2^x value. 44636 * 44637 * @param {number} speed Animation speed [optional] 44638 */ 44639Vivus.prototype.play = function (speed, callback) { 44640 this.instanceCallback = null; 44641 44642 if (speed && typeof speed === 'function') { 44643 this.instanceCallback = speed; // first parameter is actually the callback function 44644 speed = null; 44645 } 44646 else if (speed && typeof speed !== 'number') { 44647 throw new Error('Vivus [play]: invalid speed'); 44648 } 44649 // if the first parameter wasn't the callback, check if the seconds was 44650 if (callback && typeof(callback) === 'function' && !this.instanceCallback) { 44651 this.instanceCallback = callback; 44652 } 44653 44654 44655 this.speed = speed || 1; 44656 //Uncode addition 44657 if (!this.handle) { 44658 var $this = this, 44659 delay = (this.delayStart != null) ? this.delayStart : 0; 44660 setTimeout(function() { 44661 $this.drawer(); 44662 }, delay); 44663 } 44664 //#END 44665 return this; 44666}; 44667 44668/** 44669 * Stop the current animation, if on progress. 44670 * Should not trigger any error. 44671 * 44672 */ 44673Vivus.prototype.stop = function () { 44674 if (this.handle) { 44675 cancelAnimFrame(this.handle); 44676 this.handle = null; 44677 } 44678 return this; 44679}; 44680 44681/** 44682 * Destroy the instance. 44683 * Remove all bad styling attributes on all 44684 * path tags 44685 * 44686 */ 44687Vivus.prototype.destroy = function () { 44688 this.stop(); 44689 var i, path; 44690 for (i = 0; i < this.map.length; i++) { 44691 path = this.map[i]; 44692 path.el.style.strokeDashoffset = null; 44693 path.el.style.strokeDasharray = null; 44694 this.renderPath(i); 44695 } 44696}; 44697 44698 44699/** 44700 * Utils methods 44701 * include methods from Codrops 44702 ************************************** 44703 */ 44704 44705/** 44706 * Method to best guess if a path should added into 44707 * the animation or not. 44708 * 44709 * 1. Use the `data-vivus-ignore` attribute if set 44710 * 2. Check if the instance must ignore invisible paths 44711 * 3. Check if the path is visible 44712 * 44713 * For now the visibility checking is unstable. 44714 * It will be used for a beta phase. 44715 * 44716 * Other improvments are planned. Like detecting 44717 * is the path got a stroke or a valid opacity. 44718 */ 44719Vivus.prototype.isInvisible = function (el) { 44720 var rect, 44721 ignoreAttr = el.getAttribute('data-ignore'); 44722 44723 if (ignoreAttr !== null) { 44724 return ignoreAttr !== 'false'; 44725 } 44726 44727 if (this.ignoreInvisible) { 44728 rect = el.getBoundingClientRect(); 44729 return !rect.width && !rect.height; 44730 } 44731 else { 44732 return false; 44733 } 44734}; 44735 44736/** 44737 * Parse attributes of a DOM element to 44738 * get an object of {attributeName => attributeValue} 44739 * 44740 * @param {object} element DOM element to parse 44741 * @return {object} Object of attributes 44742 */ 44743Vivus.prototype.parseAttr = function (element) { 44744 var attr, output = {}; 44745 if (element && element.attributes) { 44746 for (var i = 0; i < element.attributes.length; i++) { 44747 attr = element.attributes[i]; 44748 output[attr.name] = attr.value; 44749 } 44750 } 44751 return output; 44752}; 44753 44754/** 44755 * Reply if an element is in the page viewport 44756 * 44757 * @param {object} el Element to observe 44758 * @param {number} h Percentage of height 44759 * @return {boolean} 44760 */ 44761Vivus.prototype.isInViewport = function (el, h) { 44762 var scrolled = this.scrollY(), 44763 viewed = scrolled + this.getViewportH(), 44764 elBCR = el.getBoundingClientRect(), 44765 elHeight = elBCR.height, 44766 elTop = scrolled + elBCR.top, 44767 elBottom = elTop + elHeight; 44768 44769 // if 0, the element is considered in the viewport as soon as it enters. 44770 // if 1, the element is considered in the viewport only when it's fully inside 44771 // value in percentage (1 >= h >= 0) 44772 h = h || 0; 44773 44774 return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled; 44775}; 44776 44777 44778/** 44779 * Get the viewport height in pixels 44780 * 44781 * @return {integer} Viewport height 44782 */ 44783Vivus.prototype.getViewportH = function () { 44784 var client = this.docElem.clientHeight, 44785 inner = window.innerHeight; 44786 44787 if (client < inner) { 44788 return inner; 44789 } 44790 else { 44791 return client; 44792 } 44793}; 44794 44795/** 44796 * Get the page Y offset 44797 * 44798 * @return {integer} Page Y offset 44799 */ 44800Vivus.prototype.scrollY = function () { 44801 return window.pageYOffset || this.docElem.scrollTop; 44802}; 44803 44804setupEnv = function () { 44805 44806 if (Vivus.prototype.docElem) { 44807 return; 44808 } 44809 44810 /** 44811 * Alias for document element 44812 * 44813 * @type {DOMelement} 44814 */ 44815 Vivus.prototype.docElem = window.document.documentElement; 44816 44817 /** 44818 * Alias for `requestAnimationFrame` or 44819 * `setTimeout` function for deprecated browsers. 44820 * 44821 */ 44822 requestAnimFrame = (function () { 44823 return ( 44824 window.requestAnimationFrame || 44825 window.webkitRequestAnimationFrame || 44826 window.mozRequestAnimationFrame || 44827 window.oRequestAnimationFrame || 44828 window.msRequestAnimationFrame || 44829 function(/* function */ callback){ 44830 return window.setTimeout(callback, 1000 / 60); 44831 } 44832 ); 44833 })(); 44834 44835 /** 44836 * Alias for `cancelAnimationFrame` or 44837 * `cancelTimeout` function for deprecated browsers. 44838 * 44839 */ 44840 cancelAnimFrame = (function () { 44841 return ( 44842 window.cancelAnimationFrame || 44843 window.webkitCancelAnimationFrame || 44844 window.mozCancelAnimationFrame || 44845 window.oCancelAnimationFrame || 44846 window.msCancelAnimationFrame || 44847 function(id){ 44848 return window.clearTimeout(id); 44849 } 44850 ); 44851 })(); 44852}; 44853 44854/** 44855 * Parse string to integer. 44856 * If the number is not positive or null 44857 * the method will return the default value 44858 * or 0 if undefined 44859 * 44860 * @param {string} value String to parse 44861 * @param {*}
44861 defaultValue Value to return if the result parsed is invalid 44862 * @return {number} 44863 * 44864 */ 44865parsePositiveInt = function (value, defaultValue) { 44866 var output = parseInt(value, 10); 44867 return (output >= 0) ? output : defaultValue; 44868}; 44869 44870 44871 if (typeof define === 'function' && define.amd) { 44872 // AMD. Register as an anonymous module. 44873 define([], function() { 44874 return Vivus; 44875 }); 44876 } else if (typeof exports === 'object') { 44877 // Node. Does not work with strict CommonJS, but 44878 // only CommonJS-like environments that support module.exports, 44879 // like Node. 44880 module.exports = Vivus; 44881 } else { 44882 // Browser globals 44883 window.Vivus = Vivus; 44884 } 44885 44886}()); 44887 44888//Noise.js 44889!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)}
44889var 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.