diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..55175ef --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env*.local + +# vercel +.vercel diff --git a/README.md b/README.md new file mode 100644 index 0000000..ca8a3a2 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file. + +[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`. + +The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. + +This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/components/Advantages/Advantages.jsx b/components/Advantages/Advantages.jsx new file mode 100644 index 0000000..9f5c874 --- /dev/null +++ b/components/Advantages/Advantages.jsx @@ -0,0 +1,49 @@ +import React from 'react' +const Advantages = () => { + return ( +
Traders receive financing after successfully completing one of our evaluation programs. We work hard to provide you the greatest chance possible to get finance through our own company.
+Put no money at risk in a trading account. Use our accounts to transact. Click here to see if your nation is included in the over 100 countries where our services are offered. No boundaries apply to us! Your location is irrelevant. Across the world, we deal with merchants.
++ Access the world’s largest library of fullstack components and + build better websites in hours, not days. +
+During the duration of the consumers you refer, our commission plan pays 15% monthly on all assessment plans and resets!
+{curElem.def}
+//Average Monthly Compensation To Customers Since January Of 2022
+Total Compensation To Customers Since 2022
+Total Price Action (PA's) Funded In The Last Month
+Our support team ready to help you, please contact with them
+Traders receive financing after completing one of our evaluation programs successfully. We work hard to give you the best chance to get finance through our own company. This is for traders who don't have the necessary funds or don't want to put their investments at risk.
+{curElem.desc}
+Name | +Symbol | +Exchange | +tick Size | +Point Value | +
---|---|---|---|---|
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Nekkei NKD | +ES | +CME | +5 | +$5 | +
E-mini NASDAQ 100 | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Name | +Symbol | +Exchange | +tick Size | +Point Value | +
---|---|---|---|---|
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Nekkei NKD | +ES | +CME | +5 | +$5 | +
E-mini NASDAQ 100 | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Name | +Symbol | +Exchange | +tick Size | +Point Value | +
---|---|---|---|---|
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Nekkei NKD | +ES | +CME | +5 | +$5 | +
E-mini NASDAQ 100 | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Name | +Symbol | +Exchange | +tick Size | +Point Value | +
---|---|---|---|---|
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Nekkei NKD | +ES | +CME | +5 | +$5 | +
E-mini NASDAQ 100 | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Name | +Symbol | +Exchange | +tick Size | +Point Value | +
---|---|---|---|---|
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Nekkei NKD | +ES | +CME | +5 | +$5 | +
E-mini NASDAQ 100 | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Name | +Symbol | +Exchange | +tick Size | +Point Value | +
---|---|---|---|---|
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Nekkei NKD | +ES | +CME | +5 | +$5 | +
E-mini NASDAQ 100 | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Name | +Symbol | +Exchange | +tick Size | +Point Value | +
---|---|---|---|---|
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Nekkei NKD | +ES | +CME | +5 | +$5 | +
E-mini NASDAQ 100 | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Name | +Symbol | +Exchange | +tick Size | +Point Value | +
---|---|---|---|---|
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
Nekkei NKD | +ES | +CME | +5 | +$5 | +
E-mini NASDAQ 100 | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini Midcap 400 | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
E-mini S&P | +ES | +CME | +0.25 | +$50 | +
per user/month
+Starting capital $150,000
+per user/month
+Starting capital $150,000
+per user/month
+Starting capital $150,000
+per user/month
+Starting capital $150,000
+per user/month
+Starting capital $120,000
+per user/month
+Starting capital $150,000
+' + _self.settings.labels['errorMessage'] + '
'; + }, + labels: { + 'errorMessage': 'Source could not be found...', + 'sequenceInfo.of': ' of ', + 'close': 'Close', + 'navigator.prev': 'Prev', + 'navigator.next': 'Next', + 'navigator.play': 'Play', + 'navigator.pause': 'Pause' + }, + markup: function () { + _self.objects.body.append( + _self.objects.overlay = $(''), + _self.objects.loading = $(''), + _self.objects.case = $('') + ); + _self.objects.case.after( + _self.objects.close = $('' + _self.settings.labels['close'] + ''), + _self.objects.nav = $('') + ); + _self.objects.nav.append( + _self.objects.prev = $('' + _self.settings.labels['navigator.prev'] + '').hide(), + _self.objects.next = $('' + _self.settings.labels['navigator.next'] + '').hide(), + _self.objects.play = $('' + _self.settings.labels['navigator.play'] + '').hide(), + _self.objects.pause = $('' + _self.settings.labels['navigator.pause'] + '').hide() + ); + _self.objects.case.append( + _self.objects.content = $(''), + _self.objects.info = $('') + ); + _self.objects.content.append( + _self.objects.contentInner = $('') + ); + _self.objects.info.append( + _self.objects.sequenceInfo = $(''), + _self.objects.title = $(''), + _self.objects.caption = $('') + ); + }, + onInit: {}, + onStart: {}, + onBeforeCalculateDimensions: {}, + onAfterCalculateDimensions: {}, + onBeforeShow: {}, + onFinish: {}, + onResize: {}, + onClose: {}, + onCleanup: {} + }, + options, + // Load options from data-lc-options attribute + _self.origin.data ? _self.origin.data('lc-options') : {}); + + _self.objects.document = $('html'); + _self.objects.body = $('body'); + + // Call onInit hook functions + _self._callHooks(_self.settings.onInit); + + _self.objectData = _self._setObjectData(this); + + _self._addElements(); + _self._open(); + + _self.dimensions = _self.getViewportDimensions(); + }, + + /** + * Getter method for objects + * + * @param {string} name + * @return {object} + */ + get: function (name) { + return _self.objects[name]; + }, + + /** + * Getter method for objectData + * + * @return {object} + */ + getObjectData: function () { + return _self.objectData; + }, + + /** + * Sets the object data + * + * @param {object} object + * @return {object} objectData + */ + _setObjectData: function (object) { + var $object = $(object), + objectData = { + this: $(object), + title: _self.settings.title || $object.attr(_self._prefixAttributeName('title')) || $object.attr('title'), + caption: _self.settings.caption || $object.attr(_self._prefixAttributeName('caption')) || $object.children('img').attr('alt'), + url: _self._determineUrl(), + requestType: _self.settings.ajax.type, + requestData: _self.settings.ajax.data, + requestDataType: _self.settings.ajax.dataType, + rel: $object.attr(_self._determineAttributeSelector()), + type: _self.settings.type || _self._verifyDataType(_self._determineUrl()), + isPartOfSequence: _self.settings.useAsCollection || _self._isPartOfSequence($object.attr(_self.settings.attr), ':'), + isPartOfSequenceWithSlideshow: _self._isPartOfSequence($object.attr(_self.settings.attr), ':slideshow'), + currentIndex: $(_self._determineAttributeSelector()).index($object), + sequenceLength: $(_self._determineAttributeSelector()).length + }; + + // Add sequence info to objectData + objectData.sequenceInfo = (objectData.currentIndex + 1) + _self.settings.labels['sequenceInfo.of'] + objectData.sequenceLength; + + // Add next/prev index + objectData.prevIndex = objectData.currentIndex - 1; + objectData.nextIndex = objectData.currentIndex + 1; + + return objectData; + }, + + /** + * Prefixes a data attribute name with defined name from 'settings.attrPrefix' + * to ensure more uniqueness for all lightcase related/used attributes. + * + * @param {string} name + * @return {string} + */ + _prefixAttributeName: function (name) { + return 'data-' + _self.settings.attrPrefix + name; + }, + + /** + * Determines the link target considering 'settings.href' and data attributes + * but also with a fallback to the default 'href' value. + * + * @return {string} + */ + _determineLinkTarget: function () { + return _self.settings.href || $(_self.origin).attr(_self._prefixAttributeName('href')) || $(_self.origin).attr('href'); + }, + + /** + * Determines the attribute selector to use, depending on + * whether categorized collections are beeing used or not. + * + * @return {string} selector + */ + _determineAttributeSelector: function () { + var $origin = $(_self.origin), + selector = ''; + + if (typeof _self.cache.selector !== 'undefined') { + selector = _self.cache.selector; + } else if (_self.settings.useCategories === true && $origin.attr(_self._prefixAttributeName('categories'))) { + var categories = $origin.attr(_self._prefixAttributeName('categories')).split(' '); + + $.each(categories, function (index, category) { + if (index > 0) { + selector += ','; + } + selector += '[' + _self._prefixAttributeName('categories') + '~="' + category + '"]'; + }); + } else { + selector = '[' + _self.settings.attr + '="' + $origin.attr(_self.settings.attr) + '"]'; + } + + _self.cache.selector = selector; + + return selector; + }, + + /** + * Determines the correct resource according to the + * current viewport and density. + * + * @return {string} url + */ + _determineUrl: function () { + var dataUrl = _self._verifyDataUrl(_self._determineLinkTarget()), + width = 0, + density = 0, + supportLevel = '', + url; + + $.each(dataUrl, function (index, src) { + switch (_self._verifyDataType(src.url)) { + case 'video': + var video = document.createElement('video'), + videoType = _self._verifyDataType(src.url) + '/' + _self._getFileUrlSuffix(src.url); + + // Check if browser can play this type of video format + if (supportLevel !== 'probably' && supportLevel !== video.canPlayType(videoType) && video.canPlayType(videoType) !== '') { + supportLevel = video.canPlayType(videoType); + url = src.url; + } + break; + default: + if ( + // Check density + _self._devicePixelRatio() >= src.density && + src.density >= density && + // Check viewport width + _self._matchMedia()('screen and (min-width:' + src.width + 'px)').matches && + src.width >= width + ) { + width = src.width; + density = src.density; + url = src.url; + } + break; + } + }); + + return url; + }, + + /** + * Normalizes an url and returns information about the resource path, + * the viewport width as well as density if defined. + * + * @param {string} url Path to resource in format of an url or srcset + * @return {object} + */ + _normalizeUrl: function (url) { + var srcExp = /^\d+$/; + + return url.split(',').map(function (str) { + var src = { + width: 0, + density: 0 + }; + + str.trim().split(/\s+/).forEach(function (url, i) { + if (i === 0) { + return src.url = url; + } + + var value = url.substring(0, url.length - 1), + lastChar = url[url.length - 1], + intVal = parseInt(value, 10), + floatVal = parseFloat(value); + if (lastChar === 'w' && srcExp.test(value)) { + src.width = intVal; + } else if (lastChar === 'h' && srcExp.test(value)) { + src.height = intVal; + } else if (lastChar === 'x' && !isNaN(floatVal)) { + src.density = floatVal; + } + }); + + return src; + }); + }, + + /** + * Verifies if the link is part of a sequence + * + * @param {string} rel + * @param {string} expression + * @return {boolean} + */ + _isPartOfSequence: function (rel, expression) { + var getSimilarLinks = $('[' + _self.settings.attr + '="' + rel + '"]'), + regexp = new RegExp(expression); + + return (regexp.test(rel) && getSimilarLinks.length > 1); + }, + + /** + * Verifies if the slideshow should be enabled + * + * @return {boolean} + */ + isSlideshowEnabled: function () { + return (_self.objectData.isPartOfSequence && (_self.settings.slideshow === true || _self.objectData.isPartOfSequenceWithSlideshow === true)); + }, + + /** + * Loads the new content to show + * + * @return {void} + */ + _loadContent: function () { + if (_self.cache.originalObject) { + _self._restoreObject(); + } + + _self._createObject(); + }, + + /** + * Creates a new object + * + * @return {void} + */ + _createObject: function () { + var $object; + + // Create object + switch (_self.objectData.type) { + case 'image': + $object = $(new Image()); + $object.attr({ + // The time expression is required to prevent the binding of an image load + 'src': _self.objectData.url, + 'alt': _self.objectData.title + }); + break; + case 'inline': + $object = $(''); + $object.html(_self._cloneObject($(_self.objectData.url))); + + // Add custom attributes from _self.settings + $.each(_self.settings.inline, function (name, value) { + $object.attr(_self._prefixAttributeName(name), value); + }); + break; + case 'ajax': + $object = $(''); + + // Add custom attributes from _self.settings + $.each(_self.settings.ajax, function (name, value) { + if (name !== 'data') { + $object.attr(_self._prefixAttributeName(name), value); + } + }); + break; + case 'flash': + $object = $(''); + + // Add custom attributes from _self.settings + $.each(_self.settings.flash, function (name, value) { + $object.attr(name, value); + }); + break; + case 'video': + $object = $(''); + $object.attr('src', _self.objectData.url); + + // Add custom attributes from _self.settings + $.each(_self.settings.video, function (name, value) { + $object.attr(name, value); + }); + break; + default: + $object = $(''); + $object.attr({ + 'src': _self.objectData.url + }); + + // Add custom attributes from _self.settings + $.each(_self.settings.iframe, function (name, value) { + $object.attr(name, value); + }); + break; + } + + _self._addObject($object); + _self._loadObject($object); + }, + + /** + * Adds the new object to the markup + * + * @param {object} $object + * @return {void} + */ + _addObject: function ($object) { + // Add object to content holder + _self.objects.contentInner.html($object); + + // Start loading + _self._loading('start'); + + // Call onStart hook functions + _self._callHooks(_self.settings.onStart); + + // Add sequenceInfo to the content holder or hide if its empty + if (_self.settings.showSequenceInfo === true && _self.objectData.isPartOfSequence) { + _self.objects.sequenceInfo.html(_self.objectData.sequenceInfo); + _self.objects.sequenceInfo.show(); + } else { + _self.objects.sequenceInfo.empty(); + _self.objects.sequenceInfo.hide(); + } + // Add title to the content holder or hide if its empty + if (_self.settings.showTitle === true && _self.objectData.title !== undefined && _self.objectData.title !== '') { + _self.objects.title.html(_self.objectData.title); + _self.objects.title.show(); + } else { + _self.objects.title.empty(); + _self.objects.title.hide(); + } + // Add caption to the content holder or hide if its empty + if (_self.settings.showCaption === true && _self.objectData.caption !== undefined && _self.objectData.caption !== '') { + _self.objects.caption.html(_self.objectData.caption); + _self.objects.caption.show(); + } else { + _self.objects.caption.empty(); + _self.objects.caption.hide(); + } + }, + + /** + * Loads the new object + * + * @param {object} $object + * @return {void} + */ + _loadObject: function ($object) { + // Load the object + switch (_self.objectData.type) { + case 'inline': + if ($(_self.objectData.url)) { + _self._showContent($object); + } else { + _self.error(); + } + break; + case 'ajax': + $.ajax( + $.extend({}, _self.settings.ajax, { + url: _self.objectData.url, + type: _self.objectData.requestType, + dataType: _self.objectData.requestDataType, + data: _self.objectData.requestData, + success: function (data, textStatus, jqXHR) { + // Check for X-Ajax-Location + if (jqXHR.getResponseHeader('X-Ajax-Location')) { + _self.objectData.url = jqXHR.getResponseHeader('X-Ajax-Location'); + _self._loadObject($object); + } + else { + // Unserialize if data is transferred as json + if (_self.objectData.requestDataType === 'json') { + _self.objectData.data = data; + } else { + $object.html(data); + } + _self._showContent($object); + } + }, + error: function (jqXHR, textStatus, errorThrown) { + _self.error(); + } + }) + ); + break; + case 'flash': + _self._showContent($object); + break; + case 'video': + if (typeof($object.get(0).canPlayType) === 'function' || _self.objects.case.find('video').length === 0) { + _self._showContent($object); + } else { + _self.error(); + } + break; + default: + if (_self.objectData.url) { + $object.on('load', function () { + _self._showContent($object); + }); + $object.on('error', function () { + _self.error(); + }); + } else { + _self.error(); + } + break; + } + }, + + /** + * Throws an error message if something went wrong + * + * @return {void} + */ + error: function () { + _self.objectData.type = 'error'; + var $object = $(''); + + $object.html(_self.settings.errorMessage); + _self.objects.contentInner.html($object); + + _self._showContent(_self.objects.contentInner); + }, + + /** + * Calculates the dimensions to fit content + * + * @param {object} $object + * @return {void} + */ + _calculateDimensions: function ($object) { + _self._cleanupDimensions(); + + if (!$object) return; + + // Set default dimensions + var dimensions = { + ratio: 1, + objectWidth: $object.attr('width') ? $object.attr('width') : $object.attr(_self._prefixAttributeName('width')), + objectHeight: $object.attr('height') ? $object.attr('height') : $object.attr(_self._prefixAttributeName('height')) + }; + + if (!_self.settings.disableShrink) { + // Add calculated maximum width/height to dimensions + dimensions.maxWidth = parseInt(_self.dimensions.windowWidth * _self.settings.shrinkFactor); + dimensions.maxHeight = parseInt(_self.dimensions.windowHeight * _self.settings.shrinkFactor); + + // If the auto calculated maxWidth/maxHeight greather than the user-defined one, use that. + if (dimensions.maxWidth > _self.settings.maxWidth) { + dimensions.maxWidth = _self.settings.maxWidth; + } + if (dimensions.maxHeight > _self.settings.maxHeight) { + dimensions.maxHeight = _self.settings.maxHeight; + } + + // Calculate the difference between screen width/height and image width/height + dimensions.differenceWidthAsPercent = parseInt(100 / dimensions.maxWidth * dimensions.objectWidth); + dimensions.differenceHeightAsPercent = parseInt(100 / dimensions.maxHeight * dimensions.objectHeight); + + switch (_self.objectData.type) { + case 'image': + case 'flash': + case 'video': + case 'iframe': + case 'ajax': + case 'inline': + if (_self.objectData.type === 'image' || _self.settings.fixedRatio === true) { + if (dimensions.differenceWidthAsPercent > 100 && dimensions.differenceWidthAsPercent > dimensions.differenceHeightAsPercent) { + dimensions.objectWidth = dimensions.maxWidth; + dimensions.objectHeight = parseInt(dimensions.objectHeight / dimensions.differenceWidthAsPercent * 100); + } + if (dimensions.differenceHeightAsPercent > 100 && dimensions.differenceHeightAsPercent > dimensions.differenceWidthAsPercent) { + dimensions.objectWidth = parseInt(dimensions.objectWidth / dimensions.differenceHeightAsPercent * 100); + dimensions.objectHeight = dimensions.maxHeight; + } + if (dimensions.differenceHeightAsPercent > 100 && dimensions.differenceWidthAsPercent < dimensions.differenceHeightAsPercent) { + dimensions.objectWidth = parseInt(dimensions.maxWidth / dimensions.differenceHeightAsPercent * dimensions.differenceWidthAsPercent); + dimensions.objectHeight = dimensions.maxHeight; + } + break; + } + case 'error': + if (!isNaN(dimensions.objectWidth) && dimensions.objectWidth > dimensions.maxWidth) { + dimensions.objectWidth = dimensions.maxWidth; + } + break; + default: + if ((isNaN(dimensions.objectWidth) || dimensions.objectWidth > dimensions.maxWidth) && !_self.settings.forceWidth) { + dimensions.objectWidth = dimensions.maxWidth; + } + if (((isNaN(dimensions.objectHeight) && dimensions.objectHeight !== 'auto') || dimensions.objectHeight > dimensions.maxHeight) && !_self.settings.forceHeight) { + dimensions.objectHeight = dimensions.maxHeight; + } + break; + } + } + + if (_self.settings.forceWidth) { + try { + dimensions.objectWidth = _self.settings[_self.objectData.type].width; + } catch (e) { + dimensions.objectWidth = _self.settings.width || dimensions.objectWidth; + } + + dimensions.maxWidth = null; + } + if ($object.attr(_self._prefixAttributeName('max-width'))) { + dimensions.maxWidth = $object.attr(_self._prefixAttributeName('max-width')); + } + + if (_self.settings.forceHeight) { + try { + dimensions.objectHeight = _self.settings[_self.objectData.type].height; + } catch (e) { + dimensions.objectHeight = _self.settings.height || dimensions.objectHeight; + } + + dimensions.maxHeight = null; + } + if ($object.attr(_self._prefixAttributeName('max-height'))) { + dimensions.maxHeight = $object.attr(_self._prefixAttributeName('max-height')); + } + _self._adjustDimensions($object, dimensions); + }, + + /** + * Adjusts the dimensions + * + * @param {object} $object + * @param {object} dimensions + * @return {void} + */ + _adjustDimensions: function ($object, dimensions) { + // Adjust width and height + $object.css({ + 'width': dimensions.objectWidth, + 'height': dimensions.objectHeight, + 'max-width': dimensions.maxWidth, + 'max-height': dimensions.maxHeight + }); + + _self.objects.contentInner.css({ + 'width': $object.outerWidth(), + 'height': $object.outerHeight(), + 'max-width': '100%' + }); + + _self.objects.case.css({ + 'width': _self.objects.contentInner.outerWidth(), + 'max-width': '100%' + }); + + // Adjust margin + _self.objects.case.css({ + 'margin-top': parseInt(-(_self.objects.case.outerHeight() / 2)), + 'margin-left': parseInt(-(_self.objects.case.outerWidth() / 2)) + }); + }, + + /** + * Handles the _loading + * + * @param {string} process + * @return {void} + */ + _loading: function (process) { + if (process === 'start') { + _self.objects.case.addClass(_self.settings.classPrefix + 'loading'); + _self.objects.loading.show(); + } else if (process === 'end') { + _self.objects.case.removeClass(_self.settings.classPrefix + 'loading'); + _self.objects.loading.hide(); + } + }, + + + /** + * Gets the client screen dimensions + * + * @return {object} dimensions + */ + getViewportDimensions: function () { + return { + windowWidth: $(window).innerWidth(), + windowHeight: $(window).innerHeight() + }; + }, + + /** + * Verifies the url + * + * @param {string} dataUrl + * @return {object} dataUrl Clean url for processing content + */ + _verifyDataUrl: function (dataUrl) { + if (!dataUrl || dataUrl === undefined || dataUrl === '') { + return false; + } + + if (dataUrl.indexOf('#') > -1) { + dataUrl = dataUrl.split('#'); + dataUrl = '#' + dataUrl[dataUrl.length - 1]; + } + + return _self._normalizeUrl(dataUrl.toString()); + }, + + // + /** + * Tries to get the (file) suffix of an url + * + * @param {string} url + * @return {string} + */ + _getFileUrlSuffix: function (url) { + var re = /(?:\.([^.]+))?$/; + return re.exec(url.toLowerCase())[1]; + }, + + /** + * Verifies the data type of the content to load + * + * @param {string} url + * @return {string|boolean} Array key if expression matched, else false + */ + _verifyDataType: function (url) { + var typeMapping = _self.settings.typeMapping; + + // Early abort if dataUrl couldn't be verified + if (!url) { + return false; + } + + // Verify the dataType of url according to typeMapping which + // has been defined in settings. + for (var key in typeMapping) { + if (typeMapping.hasOwnProperty(key)) { + var suffixArr = typeMapping[key].split(','); + + for (var i = 0; i < suffixArr.length; i++) { + var suffix = suffixArr[i].toLowerCase(), + regexp = new RegExp('\.(' + suffix + ')$', 'i'), + str = url.toLowerCase().split('?')[0].substr(-5); + + if (regexp.test(str) === true || (key === 'inline' && (url.indexOf(suffix) > -1))) { + return key; + } + } + } + } + + // If no expression matched, return 'iframe'. + return 'iframe'; + }, + + /** + * Extends html markup with the essential tags + * + * @return {void} + */ + _addElements: function () { + if (typeof _self.objects.case !== 'undefined' && $('#' + _self.objects.case.attr('id')).length) { + return; + } + + _self.settings.markup(); + }, + + /** + * Shows the loaded content + * + * @param {object} $object + * @return {void} + */ + _showContent: function ($object) { + // Add data attribute with the object type + _self.objects.document.attr(_self._prefixAttributeName('type'), _self.objectData.type); + + _self.cache.object = $object; + + // Call onBeforeShow hook functions + _self._callHooks(_self.settings.onBeforeShow); + + if (_self.settings.breakBeforeShow) return; + _self.show(); + }, + + /** + * Starts the 'inTransition' + * @return {void} + */ + _startInTransition: function () { + switch (_self.transition.in()) { + case 'scrollTop': + case 'scrollRight': + case 'scrollBottom': + case 'scrollLeft': + case 'scrollHorizontal': + case 'scrollVertical': + _self.transition.scroll(_self.objects.case, 'in', _self.settings.speedIn); + _self.transition.fade(_self.objects.contentInner, 'in', _self.settings.speedIn); + break; + case 'elastic': + if (_self.objects.case.css('opacity') < 1) { + _self.transition.zoom(_self.objects.case, 'in', _self.settings.speedIn); + _self.transition.fade(_self.objects.contentInner, 'in', _self.settings.speedIn); + } + case 'fade': + case 'fadeInline': + _self.transition.fade(_self.objects.case, 'in', _self.settings.speedIn); + _self.transition.fade(_self.objects.contentInner, 'in', _self.settings.speedIn); + break; + default: + _self.transition.fade(_self.objects.case, 'in', 0); + break; + } + + // End loading. + _self._loading('end'); + _self.isBusy = false; + + // Set index of the first item opened + if (!_self.cache.firstOpened) { + _self.cache.firstOpened = _self.objectData.this; + } + + // Fade in the info with delay + _self.objects.info.hide(); + setTimeout(function () { + _self.transition.fade(_self.objects.info, 'in', _self.settings.speedIn); + }, _self.settings.speedIn); + + // Call onFinish hook functions + _self._callHooks(_self.settings.onFinish); + }, + + /** + * Processes the content to show + * + * @return {void} + */ + _processContent: function () { + _self.isBusy = true; + + // Fade out the info at first + _self.transition.fade(_self.objects.info, 'out', 0); + + switch (_self.settings.transitionOut) { + case 'scrollTop': + case 'scrollRight': + case 'scrollBottom': + case 'scrollLeft': + case 'scrollVertical': + case 'scrollHorizontal': + if (_self.objects.case.is(':hidden')) { + _self.transition.fade(_self.objects.contentInner, 'out', 0); + _self.transition.fade(_self.objects.case, 'out', 0, 0, function () { + _self._loadContent(); + }); + } else { + _self.transition.scroll(_self.objects.case, 'out', _self.settings.speedOut, function () { + _self._loadContent(); + }); + } + break; + case 'fade': + if (_self.objects.case.is(':hidden')) { + _self.transition.fade(_self.objects.case, 'out', 0, 0, function () { + _self._loadContent(); + }); + } else { + _self.transition.fade(_self.objects.case, 'out', _self.settings.speedOut, 0, function () { + _self._loadContent(); + }); + } + break; + case 'fadeInline': + case 'elastic': + if (_self.objects.case.is(':hidden')) { + _self.transition.fade(_self.objects.case, 'out', 0, 0, function () { + _self._loadContent(); + }); + } else { + _self.transition.fade(_self.objects.contentInner, 'out', _self.settings.speedOut, 0, function () { + _self._loadContent(); + }); + } + break; + default: + _self.transition.fade(_self.objects.case, 'out', 0, 0, function () { + _self._loadContent(); + }); + break; + } + }, + + /** + * Handles events for gallery buttons + * + * @return {void} + */ + _handleEvents: function () { + _self._unbindEvents(); + + _self.objects.nav.children().not(_self.objects.close).hide(); + + // If slideshow is enabled, show play/pause and start timeout. + if (_self.isSlideshowEnabled()) { + // Only start the timeout if slideshow autostart is enabled and slideshow is not pausing + if ( + (_self.settings.slideshowAutoStart === true || _self.isSlideshowStarted) && + !_self.objects.nav.hasClass(_self.settings.classPrefix + 'paused') + ) { + _self._startTimeout(); + } else { + _self._stopTimeout(); + } + } + + if (_self.settings.liveResize) { + _self._watchResizeInteraction(); + } + + _self.objects.close.click(function (event) { + event.preventDefault(); + _self.close(); + }); + + if (_self.settings.closeOnOverlayClick === true) { + _self.objects.overlay.css('cursor', 'pointer').click(function (event) { + event.preventDefault(); + + _self.close(); + }); + } + + if (_self.settings.useKeys === true) { + _self._addKeyEvents(); + } + + if (_self.objectData.isPartOfSequence) { + _self.objects.nav.attr(_self._prefixAttributeName('ispartofsequence'), true); + _self.objects.nav.data('items', _self._setNavigation()); + + _self.objects.prev.click(function (event) { + event.preventDefault(); + + if (_self.settings.navigateEndless === true || !_self.item.isFirst()) { + _self.objects.prev.unbind('click'); + _self.cache.action = 'prev'; + _self.objects.nav.data('items').prev.click(); + + if (_self.isSlideshowEnabled()) { + _self._stopTimeout(); + } + } + }); + + _self.objects.next.click(function (event) { + event.preventDefault(); + + if (_self.settings.navigateEndless === true || !_self.item.isLast()) { + _self.objects.next.unbind('click'); + _self.cache.action = 'next'; + _self.objects.nav.data('items').next.click(); + + if (_self.isSlideshowEnabled()) { + _self._stopTimeout(); + } + } + }); + + if (_self.isSlideshowEnabled()) { + _self.objects.play.click(function (event) { + event.preventDefault(); + _self._startTimeout(); + }); + _self.objects.pause.click(function (event) { + event.preventDefault(); + _self._stopTimeout(); + }); + } + + // Enable swiping if activated + if (_self.settings.swipe === true) { + if ($.isPlainObject($.event.special.swipeleft)) { + _self.objects.case.on('swipeleft', function (event) { + event.preventDefault(); + _self.objects.next.click(); + if (_self.isSlideshowEnabled()) { + _self._stopTimeout(); + } + }); + } + if ($.isPlainObject($.event.special.swiperight)) { + _self.objects.case.on('swiperight', function (event) { + event.preventDefault(); + _self.objects.prev.click(); + if (_self.isSlideshowEnabled()) { + _self._stopTimeout(); + } + }); + } + } + } + }, + + /** + * Adds the key events + * + * @return {void} + */ + _addKeyEvents: function () { + $(document).bind('keyup.lightcase', function (event) { + // Do nothing if lightcase is in process + if (_self.isBusy) { + return; + } + + switch (event.keyCode) { + // Escape key + case 27: + _self.objects.close.click(); + break; + // Backward key + case 37: + if (_self.objectData.isPartOfSequence) { + _self.objects.prev.click(); + } + break; + // Forward key + case 39: + if (_self.objectData.isPartOfSequence) { + _self.objects.next.click(); + } + break; + } + }); + }, + + /** + * Starts the slideshow timeout + * + * @return {void} + */ + _startTimeout: function () { + _self.isSlideshowStarted = true; + + _self.objects.play.hide(); + _self.objects.pause.show(); + + _self.cache.action = 'next'; + _self.objects.nav.removeClass(_self.settings.classPrefix + 'paused'); + + _self.timeout = setTimeout(function () { + _self.objects.nav.data('items').next.click(); + }, _self.settings.timeout); + }, + + /** + * Stops the slideshow timeout + * + * @return {void} + */ + _stopTimeout: function () { + _self.objects.play.show(); + _self.objects.pause.hide(); + + _self.objects.nav.addClass(_self.settings.classPrefix + 'paused'); + + clearTimeout(_self.timeout); + }, + + /** + * Sets the navigator buttons (prev/next) + * + * @return {object} items + */ + _setNavigation: function () { + var $links = $((_self.cache.selector || _self.settings.attr)), + sequenceLength = _self.objectData.sequenceLength - 1, + items = { + prev: $links.eq(_self.objectData.prevIndex), + next: $links.eq(_self.objectData.nextIndex) + }; + + if (_self.objectData.currentIndex > 0) { + _self.objects.prev.show(); + } else { + items.prevItem = $links.eq(sequenceLength); + } + if (_self.objectData.nextIndex <= sequenceLength) { + _self.objects.next.show(); + } else { + items.next = $links.eq(0); + } + + if (_self.settings.navigateEndless === true) { + _self.objects.prev.show(); + _self.objects.next.show(); + } + + return items; + }, + + /** + * Item information/status + * + */ + item: { + /** + * Verifies if the current item is first item. + * + * @return {boolean} + */ + isFirst: function () { + return (_self.objectData.currentIndex === 0); + }, + + /** + * Verifies if the current item is first item opened. + * + * @return {boolean} + */ + isFirstOpened: function () { + return _self.objectData.this.is(_self.cache.firstOpened); + }, + + /** + * Verifies if the current item is last item. + * + * @return {boolean} + */ + isLast: function () { + return (_self.objectData.currentIndex === (_self.objectData.sequenceLength - 1)); + } + }, + + /** + * Clones the object for inline elements + * + * @param {object} $object + * @return {object} $clone + */ + _cloneObject: function ($object) { + var $clone = $object.clone(), + objectId = $object.attr('id'); + + // If element is hidden, cache the object and remove + if ($object.is(':hidden')) { + _self._cacheObjectData($object); + $object.attr('id', _self.settings.idPrefix + 'temp-' + objectId).empty(); + } else { + // Prevent duplicated id's + $clone.removeAttr('id'); + } + + return $clone.show(); + }, + + /** + * Verifies if it is a mobile device + * + * @return {boolean} + */ + isMobileDevice: function () { + var deviceAgent = navigator.userAgent.toLowerCase(), + agentId = deviceAgent.match(_self.settings.mobileMatchExpression); + + return agentId ? true : false; + }, + + /** + * Verifies if css transitions are supported + * + * @return {string|boolean} The transition prefix if supported, else false. + */ + isTransitionSupported: function () { + var body = _self.objects.body.get(0), + isTransitionSupported = false, + transitionMapping = { + 'transition': '', + 'WebkitTransition': '-webkit-', + 'MozTransition': '-moz-', + 'OTransition': '-o-', + 'MsTransition': '-ms-' + }; + + for (var key in transitionMapping) { + if (transitionMapping.hasOwnProperty(key) && key in body.style) { + _self.support.transition = transitionMapping[key]; + isTransitionSupported = true; + } + } + + return isTransitionSupported; + }, + + /** + * Transition types + * + */ + transition: { + /** + * Returns the correct transition type according to the status of interaction. + * + * @return {string} Transition type + */ + in: function () { + if (_self.settings.transitionOpen && !_self.cache.firstOpened) { + return _self.settings.transitionOpen; + } + return _self.settings.transitionIn; + }, + + /** + * Fades in/out the object + * + * @param {object} $object + * @param {string} type + * @param {number} speed + * @param {number} opacity + * @param {function} callback + * @return {void} Animates an object + */ + fade: function ($object, type, speed, opacity, callback) { + var isInTransition = type === 'in', + startTransition = {}, + startOpacity = $object.css('opacity'), + endTransition = {}, + endOpacity = opacity ? opacity: isInTransition ? 1 : 0; + + if (!_self.isOpen && isInTransition) return; + + startTransition['opacity'] = startOpacity; + endTransition['opacity'] = endOpacity; + + $object.css(_self.support.transition + 'transition', 'none'); + $object.css(startTransition).show(); + + // Css transition + if (_self.support.transitions) { + endTransition[_self.support.transition + 'transition'] = speed + 'ms ease'; + + setTimeout(function () { + $object.css(endTransition); + + setTimeout(function () { + $object.css(_self.support.transition + 'transition', ''); + + if (callback && (_self.isOpen || !isInTransition)) { + callback(); + } + }, speed); + }, 15); + } else { + // Fallback to js transition + $object.stop(); + $object.animate(endTransition, speed, callback); + } + }, + + /** + * Scrolls in/out the object + * + * @param {object} $object + * @param {string} type + * @param {number} speed + * @param {function} callback + * @return {void} Animates an object + */ + scroll: function ($object, type, speed, callback) { + var isInTransition = type === 'in', + transition = isInTransition ? _self.settings.transitionIn : _self.settings.transitionOut, + direction = 'left', + startTransition = {}, + startOpacity = isInTransition ? 0 : 1, + startOffset = isInTransition ? '-50%' : '50%', + endTransition = {}, + endOpacity = isInTransition ? 1 : 0, + endOffset = isInTransition ? '50%' : '-50%'; + + if (!_self.isOpen && isInTransition) return; + + switch (transition) { + case 'scrollTop': + direction = 'top'; + break; + case 'scrollRight': + startOffset = isInTransition ? '150%' : '50%'; + endOffset = isInTransition ? '50%' : '150%'; + break; + case 'scrollBottom': + direction = 'top'; + startOffset = isInTransition ? '150%' : '50%'; + endOffset = isInTransition ? '50%' : '150%'; + break; + case 'scrollHorizontal': + startOffset = isInTransition ? '150%' : '50%'; + endOffset = isInTransition ? '50%' : '-50%'; + break; + case 'scrollVertical': + direction = 'top'; + startOffset = isInTransition ? '-50%' : '50%'; + endOffset = isInTransition ? '50%' : '150%'; + break; + } + + if (_self.cache.action === 'prev') { + switch (transition) { + case 'scrollHorizontal': + startOffset = isInTransition ? '-50%' : '50%'; + endOffset = isInTransition ? '50%' : '150%'; + break; + case 'scrollVertical': + startOffset = isInTransition ? '150%' : '50%'; + endOffset = isInTransition ? '50%' : '-50%'; + break; + } + } + + startTransition['opacity'] = startOpacity; + startTransition[direction] = startOffset; + + endTransition['opacity'] = endOpacity; + endTransition[direction] = endOffset; + + $object.css(_self.support.transition + 'transition', 'none'); + $object.css(startTransition).show(); + + // Css transition + if (_self.support.transitions) { + endTransition[_self.support.transition + 'transition'] = speed + 'ms ease'; + + setTimeout(function () { + $object.css(endTransition); + + setTimeout(function () { + $object.css(_self.support.transition + 'transition', ''); + + if (callback && (_self.isOpen || !isInTransition)) { + callback(); + } + }, speed); + }, 15); + } else { + // Fallback to js transition + $object.stop(); + $object.animate(endTransition, speed, callback); + } + }, + + /** + * Zooms in/out the object + * + * @param {object} $object + * @param {string} type + * @param {number} speed + * @param {function} callback + * @return {void} Animates an object + */ + zoom: function ($object, type, speed, callback) { + var isInTransition = type === 'in', + startTransition = {}, + startOpacity = $object.css('opacity'), + startScale = isInTransition ? 'scale(0.75)' : 'scale(1)', + endTransition = {}, + endOpacity = isInTransition ? 1 : 0, + endScale = isInTransition ? 'scale(1)' : 'scale(0.75)'; + + if (!_self.isOpen && isInTransition) return; + + startTransition['opacity'] = startOpacity; + startTransition[_self.support.transition + 'transform'] = startScale; + + endTransition['opacity'] = endOpacity; + + $object.css(_self.support.transition + 'transition', 'none'); + $object.css(startTransition).show(); + + // Css transition + if (_self.support.transitions) { + endTransition[_self.support.transition + 'transform'] = endScale; + endTransition[_self.support.transition + 'transition'] = speed + 'ms ease'; + + setTimeout(function () { + $object.css(endTransition); + + setTimeout(function () { + $object.css(_self.support.transition + 'transform', ''); + $object.css(_self.support.transition + 'transition', ''); + + if (callback && (_self.isOpen || !isInTransition)) { + callback(); + } + }, speed); + }, 15); + } else { + // Fallback to js transition + $object.stop(); + $object.animate(endTransition, speed, callback); + } + } + }, + + /** + * Calls all the registered functions of a specific hook + * + * @param {object} hooks + * @return {void} + */ + _callHooks: function (hooks) { + if (typeof(hooks) === 'object') { + $.each(hooks, function(index, hook) { + if (typeof(hook) === 'function') { + hook.call(_self.origin); + } + }); + } + }, + + /** + * Caches the object data + * + * @param {object} $object + * @return {void} + */ + _cacheObjectData: function ($object) { + $.data($object, 'cache', { + id: $object.attr('id'), + content: $object.html() + }); + + _self.cache.originalObject = $object; + }, + + /** + * Restores the object from cache + * + * @return void + */ + _restoreObject: function () { + var $object = $('[id^="' + _self.settings.idPrefix + 'temp-"]'); + + $object.attr('id', $.data(_self.cache.originalObject, 'cache').id); + $object.html($.data(_self.cache.originalObject, 'cache').content); + }, + + /** + * Executes functions for a window resize. + * It stops an eventual timeout and recalculates dimensions. + * + * @param {object} dimensions + * @return {void} + */ + resize: function (event, dimensions) { + if (!_self.isOpen) return; + + if (_self.isSlideshowEnabled()) { + _self._stopTimeout(); + } + + if (typeof dimensions === 'object' && dimensions !== null) { + if (dimensions.width) { + _self.cache.object.attr( + _self._prefixAttributeName('width'), + dimensions.width + ); + } + if (dimensions.maxWidth) { + _self.cache.object.attr( + _self._prefixAttributeName('max-width'), + dimensions.maxWidth + ); + } + if (dimensions.height) { + _self.cache.object.attr( + _self._prefixAttributeName('height'), + dimensions.height + ); + } + if (dimensions.maxHeight) { + _self.cache.object.attr( + _self._prefixAttributeName('max-height'), + dimensions.maxHeight + ); + } + } + + _self.dimensions = _self.getViewportDimensions(); + _self._calculateDimensions(_self.cache.object); + + // Call onResize hook functions + _self._callHooks(_self.settings.onResize); + }, + + /** + * Watches for any resize interaction and caches the new sizes. + * + * @return {void} + */ + _watchResizeInteraction: function () { + $(window).resize(_self.resize); + }, + + /** + * Stop watching any resize interaction related to _self. + * + * @return {void} + */ + _unwatchResizeInteraction: function () { + $(window).off('resize', _self.resize); + }, + + /** + * Switches to the fullscreen mode + * + * @return {void} + */ + _switchToFullScreenMode: function () { + _self.settings.shrinkFactor = 1; + _self.settings.overlayOpacity = 1; + + $('html').addClass(_self.settings.classPrefix + 'fullScreenMode'); + }, + + /** + * Enters into the lightcase view + * + * @return {void} + */ + _open: function () { + _self.isOpen = true; + + _self.support.transitions = _self.settings.cssTransitions ? _self.isTransitionSupported() : false; + _self.support.mobileDevice = _self.isMobileDevice(); + + if (_self.support.mobileDevice) { + $('html').addClass(_self.settings.classPrefix + 'isMobileDevice'); + + if (_self.settings.fullScreenModeForMobile) { + _self._switchToFullScreenMode(); + } + } + + if (!_self.settings.transitionIn) { + _self.settings.transitionIn = _self.settings.transition; + } + if (!_self.settings.transitionOut) { + _self.settings.transitionOut = _self.settings.transition; + } + + switch (_self.transition.in()) { + case 'fade': + case 'fadeInline': + case 'elastic': + case 'scrollTop': + case 'scrollRight': + case 'scrollBottom': + case 'scrollLeft': + case 'scrollVertical': + case 'scrollHorizontal': + if (_self.objects.case.is(':hidden')) { + _self.objects.close.css('opacity', 0); + _self.objects.overlay.css('opacity', 0); + _self.objects.case.css('opacity', 0); + _self.objects.contentInner.css('opacity', 0); + } + _self.transition.fade(_self.objects.overlay, 'in', _self.settings.speedIn, _self.settings.overlayOpacity, function () { + _self.transition.fade(_self.objects.close, 'in', _self.settings.speedIn); + _self._handleEvents(); + _self._processContent(); + }); + break; + default: + _self.transition.fade(_self.objects.overlay, 'in', 0, _self.settings.overlayOpacity, function () { + _self.transition.fade(_self.objects.close, 'in', 0); + _self._handleEvents(); + _self._processContent(); + }); + break; + } + + _self.objects.document.addClass(_self.settings.classPrefix + 'open'); + _self.objects.case.attr('aria-hidden', 'false'); + }, + + /** + * Shows the lightcase by starting the transition + */ + show: function () { + // Call onCalculateDimensions hook functions + _self._callHooks(_self.settings.onBeforeCalculateDimensions); + + _self._calculateDimensions(_self.cache.object); + + // Call onAfterCalculateDimensions hook functions + _self._callHooks(_self.settings.onAfterCalculateDimensions); + + _self._startInTransition(); + }, + + /** + * Escapes from the lightcase view + * + * @return {void} + */ + close: function () { + _self.isOpen = false; + + if (_self.isSlideshowEnabled()) { + _self._stopTimeout(); + _self.isSlideshowStarted = false; + _self.objects.nav.removeClass(_self.settings.classPrefix + 'paused'); + } + + _self.objects.loading.hide(); + + _self._unbindEvents(); + + _self._unwatchResizeInteraction(); + + $('html').removeClass(_self.settings.classPrefix + 'open'); + _self.objects.case.attr('aria-hidden', 'true'); + + _self.objects.nav.children().hide(); + _self.objects.close.hide(); + + // Call onClose hook functions + _self._callHooks(_self.settings.onClose); + + // Fade out the info at first + _self.transition.fade(_self.objects.info, 'out', 0); + + switch (_self.settings.transitionClose || _self.settings.transitionOut) { + case 'fade': + case 'fadeInline': + case 'scrollTop': + case 'scrollRight': + case 'scrollBottom': + case 'scrollLeft': + case 'scrollHorizontal': + case 'scrollVertical': + _self.transition.fade(_self.objects.case, 'out', _self.settings.speedOut, 0, function () { + _self.transition.fade(_self.objects.overlay, 'out', _self.settings.speedOut, 0, function () { + _self.cleanup(); + }); + }); + break; + case 'elastic': + _self.transition.zoom(_self.objects.case, 'out', _self.settings.speedOut, function () { + _self.transition.fade(_self.objects.overlay, 'out', _self.settings.speedOut, 0, function () { + _self.cleanup(); + }); + }); + break; + default: + _self.cleanup(); + break; + } + }, + + /** + * Unbinds all given events + * + * @return {void} + */ + _unbindEvents: function () { + // Unbind overlay event + _self.objects.overlay.unbind('click'); + + // Unbind key events + $(document).unbind('keyup.lightcase'); + + // Unbind swipe events + _self.objects.case.unbind('swipeleft').unbind('swiperight'); + + // Unbind navigator events + _self.objects.prev.unbind('click'); + _self.objects.next.unbind('click'); + _self.objects.play.unbind('click'); + _self.objects.pause.unbind('click'); + + // Unbind close event + _self.objects.close.unbind('click'); + }, + + /** + * Cleans up the dimensions + * + * @return {void} + */ + _cleanupDimensions: function () { + var opacity = _self.objects.contentInner.css('opacity'); + + _self.objects.case.css({ + 'width': '', + 'height': '', + 'top': '', + 'left': '', + 'margin-top': '', + 'margin-left': '' + }); + + _self.objects.contentInner.removeAttr('style').css('opacity', opacity); + _self.objects.contentInner.children().removeAttr('style'); + }, + + /** + * Cleanup after aborting lightcase + * + * @return {void} + */ + cleanup: function () { + _self._cleanupDimensions(); + + _self.objects.loading.hide(); + _self.objects.overlay.hide(); + _self.objects.case.hide(); + _self.objects.prev.hide(); + _self.objects.next.hide(); + _self.objects.play.hide(); + _self.objects.pause.hide(); + + _self.objects.document.removeAttr(_self._prefixAttributeName('type')); + _self.objects.nav.removeAttr(_self._prefixAttributeName('ispartofsequence')); + + _self.objects.contentInner.empty().hide(); + _self.objects.info.children().empty(); + + if (_self.cache.originalObject) { + _self._restoreObject(); + } + + // Call onCleanup hook functions + _self._callHooks(_self.settings.onCleanup); + + // Restore cache + _self.cache = {}; + }, + + /** + * Returns the supported match media or undefined if the browser + * doesn't support match media. + * + * @return {mixed} + */ + _matchMedia: function () { + return window.matchMedia || window.msMatchMedia; + }, + + /** + * Returns the devicePixelRatio if supported. Else, it simply returns + * 1 as the default. + * + * @return {number} + */ + _devicePixelRatio: function () { + return window.devicePixelRatio || 1; + }, + + /** + * Checks if method is public + * + * @return {boolean} + */ + _isPublicMethod: function (method) { + return (typeof _self[method] === 'function' && method.charAt(0) !== '_'); + }, + + /** + * Exports all public methods to be accessible, callable + * from global scope. + * + * @return {void} + */ + _export: function () { + window.lightcase = {}; + + $.each(_self, function (property) { + if (_self._isPublicMethod(property)) { + lightcase[property] = _self[property]; + } + }); + } + }; + + _self._export(); + + $.fn.lightcase = function (method) { + // Method calling logic (only public methods are applied) + if (_self._isPublicMethod(method)) { + return _self[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method) { + return _self.init.apply(this, arguments); + } else { + $.error('Method ' + method + ' does not exist on jQuery.lightcase'); + } + }; +})(jQuery); diff --git a/public/assets/js/purecounter_vanilla.js b/public/assets/js/purecounter_vanilla.js new file mode 100644 index 0000000..2551e8f --- /dev/null +++ b/public/assets/js/purecounter_vanilla.js @@ -0,0 +1,9 @@ +/*! + * purecounter.js - A simple yet configurable native javascript counter which you can count on. + * Author: Stig Rex + * Version: 1.5.0 + * Url: https://github.com/srexi/purecounterjs + * License: MIT + */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.PureCounter=t():e.PureCounter=t()}(self,(function(){return e={638:function(e){function t(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function r(e){return function(e){if(Array.isArray(e))return n(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return n(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?n(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function n(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r1&&u.push(e.virtualSize-r)}if(0===u.length&&(u=[0]),0!==a.spaceBetween){const s=e.isHorizontal()&&n?"marginLeft":t("marginRight");c.filter(((e,t)=>!a.cssMode||t!==c.length-1)).css({[s]:`${x}px`})}if(a.centeredSlides&&a.centeredSlidesBounds){let e=0;m.forEach((t=>{e+=t+(a.spaceBetween?a.spaceBetween:0)})),e-=a.spaceBetween;const t=e-r;u=u.map((e=>e<0?-f:e>t?t+g:e))}if(a.centerInsufficientSlides){let e=0;if(m.forEach((t=>{e+=t+(a.spaceBetween?a.spaceBetween:0)})),e-=a.spaceBetween,e {r.wrapperEl.style.scrollSnapType="",r._swiperImmediateVirtual=!1}))}else{if(!r.support.smoothScroll)return w({swiper:r,targetPosition:s,side:e?"left":"top"}),!0;h.scrollTo({[e?"left":"top"]:s,behavior:"smooth"})}return!0}return r.setTransition(t),r.setTranslate(v),r.updateActiveIndex(n),r.updateSlidesClasses(),r.emit("beforeTransitionStart",t,a),r.transitionStart(s,b),0===t?r.transitionEnd(s,b):r.animating||(r.animating=!0,r.onSlideToWrapperTransitionEnd||(r.onSlideToWrapperTransitionEnd=function(e){r&&!r.destroyed&&e.target===this&&(r.$wrapperEl[0].removeEventListener("transitionend",r.onSlideToWrapperTransitionEnd),r.$wrapperEl[0].removeEventListener("webkitTransitionEnd",r.onSlideToWrapperTransitionEnd),r.onSlideToWrapperTransitionEnd=null,delete r.onSlideToWrapperTransitionEnd,r.transitionEnd(s,b))}),r.$wrapperEl[0].addEventListener("transitionend",r.onSlideToWrapperTransitionEnd),r.$wrapperEl[0].addEventListener("webkitTransitionEnd",r.onSlideToWrapperTransitionEnd)),!0},slideToLoop:function(e,t,s,a){void 0===e&&(e=0),void 0===t&&(t=this.params.speed),void 0===s&&(s=!0);const i=this;let r=e;return i.params.loop&&(r+=i.loopedSlides),i.slideTo(r,t,s,a)},slideNext:function(e,t,s){void 0===e&&(e=this.params.speed),void 0===t&&(t=!0);const a=this,{animating:i,enabled:r,params:n}=a;if(!r)return a;let l=n.slidesPerGroup;"auto"===n.slidesPerView&&1===n.slidesPerGroup&&n.slidesPerGroupAuto&&(l=Math.max(a.slidesPerViewDynamic("current",!0),1));const o=a.activeIndex0&&o(u(t));const a=e.children(`.${s.slidePrevClass}`);a.length>0&&o(u(a))}}function p(){const e=r();if(!t||t.destroyed)return;const s=t.params.lazy.scrollingElement?d(t.params.lazy.scrollingElement):d(e),a=s[0]===e,i=a?e.innerWidth:s[0].offsetWidth,l=a?e.innerHeight:s[0].offsetHeight,o=t.$el.offset(),{rtlTranslate:u}=t;let h=!1;u&&(o.left-=t.$el[0].scrollLeft);const m=[[o.left,o.top],[o.left+t.width,o.top],[o.left,o.top+t.height],[o.left+t.width,o.top+t.height]];for(let e=0;e