diff --git a/.gitignore b/.gitignore index f77bc38f..76461092 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,7 @@ -jquery.bxslider.zip \ No newline at end of file +jscs.report.txt +/docs/ +/bower_components/ +.DS_Store +/node_modules +jquery.bxslider.zip +npm-debug.log diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..3acf1f2c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,118 @@ +# Contributing to this project + +Please take a moment to review this document in order to make the contribution +process easy and effective for everyone involved. + +Following these guidelines helps to communicate that you respect the time of +the developers managing and developing this open source project. In return, +they should reciprocate that respect in addressing your issue or assessing +patches and features. + + +## Using the issue tracker + +The issue tracker is the preferred channel for [bug reports](#bugs), +[features requests](#features) and [submitting pull +requests](#pull-requests), but please respect the following restrictions: + +* Please **do not** use the issue tracker for personal support requests. + +* Please **do not** derail or troll issues. Keep the discussion on topic and + respect the opinions of others. + + + +## Bug reports + +A bug is a _demonstrable problem_ that is caused by the code in the repository. +Good bug reports are extremely helpful - thank you! + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been + reported. + +2. **Check if the issue has been fixed** — try to reproduce it using the + latest `master` or development branch in the repository. + +3. **Isolate the problem** — make sure that the code in the repository is +_definitely_ responsible for the issue. + +A good bug report shouldn't leave others needing to chase you up for more +information. Please try to be as detailed as possible in your report. Examples are +important, please try to provide them. + + + +## Feature requests + +Feature requests are welcome. But take a moment to find out whether your idea +fits with the scope and aims of the project. It's up to *you* to make a strong +case to convince the developers of the merits of this feature. Please +provide as much detail and context as possible. + + + +## Pull requests + +Good pull requests - patches, improvements, new features - are a fantastic +help. They should remain focused in scope and avoid containing unrelated +commits. + +**Please ask first** before embarking on any significant pull request (e.g. +implementing features, refactoring code), otherwise you risk spending a lot of +time working on something that the developers might not want to merge into the +project. + +Please adhere to the coding conventions used throughout the project (indentation, +comments, etc.). + +Adhering to the following this process is the best way to get your work +merged: + +1. [Fork](http://help.github.com/fork-a-repo/) the repo, clone your fork, + and configure the remotes: + + ```bash + # Clone your fork of the repo into the current directory + git clone https://github.com// + # Navigate to the newly cloned directory + cd + # Assign the original repo to a remote called "upstream" + git remote add upstream https://github.com// + ``` + +2. If you cloned a while ago, get the latest changes from upstream: + + ```bash + git checkout + git pull upstream + ``` + +3. Create a new topic branch (off the main project development branch) to + contain your feature, change, or fix: + + ```bash + git checkout -b + ``` + +4. Commit your changes in logical chunks. Please adhere to these [git commit + message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) + or your code is unlikely be merged into the main project. Use Git's + [interactive rebase](https://help.github.com/articles/interactive-rebase) + feature to tidy up your commits before making them public. + +5. Locally merge (or rebase) the upstream development branch into your topic branch: + + ```bash + git pull [--rebase] upstream + ``` + +6. Push your topic branch up to your fork: + + ```bash + git push origin + ``` + +10. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) + with a clear title and description. diff --git a/Gulpfile.js b/Gulpfile.js new file mode 100644 index 00000000..e433bf47 --- /dev/null +++ b/Gulpfile.js @@ -0,0 +1,65 @@ +var gulp = require('gulp') +var uglify = require('gulp-uglify'); +var cssmin = require('gulp-cssmin'); +var rename = require('gulp-rename'); + +gulp.task('js-minify', function (done) { + gulp.src('./src/js/jquery.bxslider.js') + .pipe(uglify({ + preserveComments: 'license' + })) + .pipe(rename({ suffix: '.min' })) + .pipe(gulp.dest('./dist')); + done(); +}); + +gulp.task('js-copy-src', function (done) { + gulp.src('./src/js/jquery.bxslider.js') + .pipe(gulp.dest('./dist')); + done(); +}); + +gulp.task('css-minify', function (done) { + gulp.src('./src/css/jquery.bxslider.css') + .pipe(cssmin()) + .pipe(rename({ suffix: '.min' })) + .pipe(gulp.dest('./dist')); + done(); +}); + +gulp.task('css-copy-src', function (done) { + gulp.src('./src/css/jquery.bxslider.css') + .pipe(gulp.dest('./dist')); + done(); +}); + +gulp.task('vendor-copy-src', function (done) { + gulp.src('./src/vendor/*') + .pipe(gulp.dest('./dist/vendor')); + done(); +}); + +gulp.task('images-copy-src', function (done) { + gulp.src('./src/images/*') + .pipe(gulp.dest('./dist/images')); + done(); +}); + +gulp.task('docs-copy-src', function (done) { + gulp.src([ + './readme.md', + './LICENSE.md' + ]) + .pipe(gulp.dest('./dist')); + done(); +}); + +gulp.task('default', gulp.series( + 'js-minify', + 'js-copy-src', + 'css-minify', + 'css-copy-src', + 'vendor-copy-src', + 'images-copy-src', + 'docs-copy-src' +)); diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..c117d6d3 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,12 @@ +License +------- + +The MIT License (MIT) + +Copyright © 2014 [Steven Wanderski](https://twitter.com/stevenwanderski) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/bower.json b/bower.json new file mode 100644 index 00000000..d63dd210 --- /dev/null +++ b/bower.json @@ -0,0 +1,28 @@ +{ + "name": "bxslider-4", + "homepage": "http://bxslider.com", + "license": "MIT", + "main": [ + "dist/jquery.bxslider.js", + "dist/jquery.bxslider.css", + "dist/images/bx_loader.gif", + "dist/images/controls.png" + ], + "ignore": [ + "docs_src/*", + "docs/*" + ], + "keywords": [ + "bxslider", + "javascript", + "jquery", + "library" + ], + "dependencies": { + "jquery": ">= 1.8.3" + }, + "devDependencies": { + "bootstrap": ">= 3.3.2", + "highlightjs": "~8.4.0" + } +} diff --git a/dist/LICENSE.md b/dist/LICENSE.md new file mode 100644 index 00000000..c117d6d3 --- /dev/null +++ b/dist/LICENSE.md @@ -0,0 +1,12 @@ +License +------- + +The MIT License (MIT) + +Copyright © 2014 [Steven Wanderski](https://twitter.com/stevenwanderski) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/dist/README.md b/dist/README.md new file mode 100644 index 00000000..352f9917 --- /dev/null +++ b/dist/README.md @@ -0,0 +1,867 @@ +# bxSlider 4.2.17 +## The fully-loaded, responsive jQuery content slider + +### Why should I use this slider? +* Fully responsive - will adapt to any device +* Horizontal, vertical, and fade modes +* Slides can contain images, video, or HTML content +* Full callback API and public methods +* Small file size, fully themed, simple to implement +* Browser support: Firefox, Chrome, Safari, iOS, Android, IE7+ +* Tons of configuration options + +For complete documentation, tons of examples, and a good time, visit: [http://bxslider.com](http://bxslider.com) + +Written by: Steven Wanderski - [http://stevenwanderski.com](http://stevenwanderski.com) + +### License +Released under the MIT license - http://opensource.org/licenses/MIT + +Let's get on with it! + +## Installation + +### Step 1: Link required files + +First and most important, the jQuery library needs to be included (no need to download - link directly from Google). Next, download the package from this site and link the bxSlider CSS file (for the theme) and the bxSlider Javascript file. + +```html + + + + + + +``` + +Or, if you prefer, you can get the bxSlider's resources from the **CDN**: + +```html + + +``` + +### Step 2: Create HTML markup + +Create a `
    ` element, with a `
  • ` for each slide. Slides can contain images, video, or any other HTML content! + +```html +
      +
    • +
    • +
    • +
    • +
    +``` + +### Step 3: Call the bxSlider + +Call .bxSlider() on `
      `. Note that the call must be made inside of a $(document).ready() call, or the plugin will not work! + +```javascript +$(document).ready(function(){ + $('.bxslider').bxSlider(); +}); +``` + +## Configuration options + +### General + +**mode** + +Type of transition between slides +``` +default: 'horizontal' +options: 'horizontal', 'vertical', 'fade' +``` + +**speed** + +Slide transition duration (in ms) +``` +default: 500 +options: integer +``` + +**slideMargin** + +Margin between each slide +``` +default: 0 +options: integer +``` + +**startSlide** + +Starting slide index (zero-based) +``` +default: 0 +options: integer +``` + +**randomStart** + +Start slider on a random slide +``` +default: false +options: boolean (true / false) +``` + +**slideSelector** + +Element to use as slides (ex. 'div.slide').
      Note: by default, bxSlider will use all immediate children of the slider element +``` +default: '' +options: jQuery selector +``` + +**infiniteLoop** + +If true, clicking "Next" while on the last slide will transition to the first slide and vice-versa +``` +default: true +options: boolean (true / false) +``` + +**hideControlOnEnd** + +If true, "Prev" and "Next" controls will receive a class disabled when slide is the first or the last
      Note: Only used when infiniteLoop: false +``` +default: false +options: boolean (true / false) +``` + +**easing** + +The type of "easing" to use during transitions. If using CSS transitions, include a value for the transition-timing-function property. If not using CSS transitions, you may include plugins/jquery.easing.1.3.js for many options.
      See http://gsgd.co.uk/sandbox/jquery/easing/ for more info. +``` +default: null +options: if using CSS: 'linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'cubic-bezier(n,n,n,n)'. If not using CSS: 'swing', 'linear' (see the above file for more options) +``` + +**captions** + +Include image captions. Captions are derived from the image's title attribute +``` +default: false +options: boolean (true / false) +``` + +**ticker** + +Use slider in ticker mode (similar to a news ticker) +``` +default: false +options: boolean (true / false) +``` + +**tickerHover** + +Ticker will pause when mouse hovers over slider. Note: this functionality does NOT work if using CSS transitions! +``` +default: false +options: boolean (true / false) +``` + +**adaptiveHeight** + +Dynamically adjust slider height based on each slide's height +``` +default: false +options: boolean (true / false) +``` + +**adaptiveHeightSpeed** + +Slide height transition duration (in ms). Note: only used if adaptiveHeight: true +``` +default: 500 +options: integer +``` + +**video** + +If any slides contain video, set this to true. Also, include plugins/jquery.fitvids.js
      See http://fitvidsjs.com/ for more info +``` +default: false +options: boolean (true / false) +``` + +**responsive** + +Enable or disable auto resize of the slider. Useful if you need to use fixed width sliders. +``` +default: true +options: boolean (true /false) +``` + +**useCSS** + +If true, CSS transitions will be used for horizontal and vertical slide animations (this uses native hardware acceleration). If false, jQuery animate() will be used. +``` +default: true +options: boolean (true / false) +``` + +**preloadImages** + +If 'all', preloads all images before starting the slider. If 'visible', preloads only images in the initially visible slides before starting the slider (tip: use 'visible' if all slides are identical dimensions) +``` +default: 'visible' +options: 'all', 'visible', 'none' +``` + +**touchEnabled** + +If true, slider will allow touch swipe transitions +``` +default: true +options: boolean (true / false) +``` + +**swipeThreshold** + +Amount of pixels a touch swipe needs to exceed in order to execute a slide transition. Note: only used if touchEnabled: true +``` +default: 50 +options: integer +``` + +**oneToOneTouch** + +If true, non-fade slides follow the finger as it swipes +``` +default: true +options: boolean (true / false) +``` + +**preventDefaultSwipeX** + +If true, touch screen will not move along the x-axis as the finger swipes +``` +default: true +options: boolean (true / false) +``` + +**preventDefaultSwipeY** + +If true, touch screen will not move along the y-axis as the finger swipes +``` +default: false +options: boolean (true / false) +``` + +**wrapperClass** + +Class to wrap the slider in. Change to prevent from using default bxSlider styles. +``` +default: 'bx-wrapper' +options: string +``` + +### Pager + +**pager** + +If true, a pager will be added +``` +default: true +options: boolean (true / false) +``` + +**pagerType** + +If 'full', a pager link will be generated for each slide. If 'short', a x / y pager will be used (ex. 1 / 5) +``` +default: 'full' +options: 'full', 'short' +``` + +**pagerShortSeparator** + +If pagerType: 'short', pager will use this value as the separating character +``` +default: ' / ' +options: string +``` + +**pagerSelector** + +Element used to populate the populate the pager. By default, the pager is appended to the bx-viewport +``` +default: '' +options: jQuery selector +``` + +**pagerCustom** + +Parent element to be used as the pager. Parent element must contain a <a data-slide-index="x"> element for each slide. See example here. Not for use with dynamic carousels. +``` +default: null +options: jQuery selector +``` + +**buildPager** + +If supplied, function is called on every slide element, and the returned value is used as the pager item markup.
      See examples for detailed implementation +``` +default: null +options: function(slideIndex) +``` + +### Controls + +**controls** + +If true, "Next" / "Prev" controls will be added +``` +default: true +options: boolean (true / false) +``` + +**nextText** + +Text to be used for the "Next" control +``` +default: 'Next' +options: string +``` + +**prevText** + +Text to be used for the "Prev" control +``` +default: 'Prev' +options: string +``` + +**nextSelector** + +Element used to populate the "Next" control +``` +default: null +options: jQuery selector +``` + +**prevSelector** + +Element used to populate the "Prev" control +``` +default: null +options: jQuery selector +``` + +**autoControls** + +If true, "Start" / "Stop" controls will be added +``` +default: false +options: boolean (true / false) +``` + +**startText** + +Text to be used for the "Start" control +``` +default: 'Start' +options: string +``` + +**stopText** + +Text to be used for the "Stop" control +``` +default: 'Stop' +options: string +``` + +**autoControlsCombine** + +When slideshow is playing only "Stop" control is displayed and vice-versa +``` +default: false +options: boolean (true / false) +``` + +**autoControlsSelector** + +Element used to populate the auto controls +``` +default: null +options: jQuery selector +``` + +**keyboardEnabled** + +Enable keyboard navigation for visible sliders +``` +default: false +options: boolean (true / false) +``` + +### Auto + +**auto** + +Slides will automatically transition +``` +default: false +options: boolean (true / false) +``` +**stopAutoOnClick** + +Auto will stop on interaction with controls +``` +default: false +options: boolean (true / false) +``` + +**pause** + +The amount of time (in ms) between each auto transition +``` +default: 4000 +options: integer +``` + +**autoStart** + +Auto show starts playing on load. If false, slideshow will start when the "Start" control is clicked +``` +default: true +options: boolean (true / false) +``` + +**autoDirection** + +The direction of auto show slide transitions +``` +default: 'next' +options: 'next', 'prev' +``` + +**autoHover** + +Auto show will pause when mouse hovers over slider +``` +default: false +options: boolean (true / false) +``` + +**autoDelay** + +Time (in ms) auto show should wait before starting +``` +default: 0 +options: integer +``` + +### Carousel + +**minSlides** + +The minimum number of slides to be shown. Slides will be sized down if carousel becomes smaller than the original size. +``` +default: 1 +options: integer +``` + +**maxSlides** + +The maximum number of slides to be shown. Slides will be sized up if carousel becomes larger than the original size. +``` +default: 1 +options: integer +``` + +**moveSlides** + +The number of slides to move on transition. This value must be `>= minSlides`, and `<= maxSlides`. If zero (default), the number of fully-visible slides will be used. +``` +default: 0 +options: integer +``` + +**slideWidth** + +The width of each slide. This setting is required for all horizontal carousels! +``` +default: 0 +options: integer +``` + +**shrinkItems** + +The Carousel will only show whole items and shrink the images to fit the viewport based on maxSlides/MinSlides. +``` +default: false +options: boolean (true / false) +``` + +### Keyboard + +**keyboardEnabled** + +Allows for keyboard control of visible slider. Keypress ignored if slider not visible. +``` +default: false +options: boolean (true / false) +``` + +### Accessibility + +**ariaLive** + +Adds Aria Live attribute to slider. +``` +default: true +options: boolean (true / false) +``` + +**ariaHidden** + +Adds Aria Hidden attribute to any nonvisible slides. +``` +default: true +options: boolean (true / false) +``` + +### Callbacks + +**onSliderLoad** + +Executes immediately after the slider is fully loaded +``` +default: function(){} +options: function(currentIndex){ // your code here } +arguments: + currentIndex: element index of the current slide +``` + +**onSliderResize** + +Executes immediately after the slider is resized +``` +default: function(){} +options: function(currentIndex){ // your code here } +arguments: + currentIndex: element index of the current slide +``` + +**onSlideBefore** + +Executes immediately before each slide transition. +``` +default: function(){} +options: function($slideElement, oldIndex, newIndex){ // your code here } +arguments: + $slideElement: jQuery element of the destination element + oldIndex: element index of the previous slide (before the transition) + newIndex: element index of the destination slide (after the transition) +``` + +**onSlideAfter** + +Executes immediately after each slide transition. Function argument is the current slide element (when transition completes). +``` +default: function(){} +options: function($slideElement, oldIndex, newIndex){ // your code here } +arguments: + $slideElement: jQuery element of the destination element + oldIndex: element index of the previous slide (before the transition) + newIndex: element index of the destination slide (after the transition) +``` + +**onSlideNext** + +Executes immediately before each "Next" slide transition. Function argument is the target (next) slide element. +``` +default: function(){} +options: function($slideElement, oldIndex, newIndex){ // your code here } +arguments: + $slideElement: jQuery element of the destination element + oldIndex: element index of the previous slide (before the transition) + newIndex: element index of the destination slide (after the transition) +``` + +**onSlidePrev** + +Executes immediately before each "Prev" slide transition. Function argument is the target (prev) slide element. +``` +default: function(){} +options: function($slideElement, oldIndex, newIndex){ // your code here } +arguments: + $slideElement: jQuery element of the destination element + oldIndex: element index of the previous slide (before the transition) + newIndex: element index of the destination slide (after the transition) +``` + +**onAutoChange** + +Executes immediately after auto transtion starts or stops. +``` +default: function(){} +options: function(state){ // your code here } +arguments: + state: the new state of "auto": boolean (true / false) +``` + +### Public methods + +**goToSlide** + +Performs a slide transition to the supplied slide index (zero-based) +``` +example: +slider = $('.bxslider').bxSlider(); +slider.goToSlide(3); +``` + +**goToNextSlide** + +Performs a "Next" slide transition +``` +example: +slider = $('.bxslider').bxSlider(); +slider.goToNextSlide(); +``` + +**goToPrevSlide** + +Performs a "Prev" slide transition +``` +example: +slider = $('.bxslider').bxSlider(); +slider.goToPrevSlide(); +``` + +**startAuto** +Starts the auto show. Provide an argument `false` to prevent the auto controls from being updated. +``` +example: +slider = $('.bxslider').bxSlider(); +slider.startAuto(); +``` + +**stopAuto** + +Stops the auto show. Provide an argument `false` to prevent the auto controls from being updated. +``` +example: +slider = $('.bxslider').bxSlider(); +slider.stopAuto(); +``` + +**getCurrentSlide** + +Returns the current active slide +``` +example: +slider = $('.bxslider').bxSlider(); +var current = slider.getCurrentSlide(); +``` + +**getSlideCount** + +Returns the total number of slides in the slider +``` +example: +slider = $('.bxslider').bxSlider(); +var slideQty = slider.getSlideCount(); +``` + +**redrawSlider** + +Redraw the slider. Useful when needing to redraw a hidden slider after it is unhidden. +``` +example: +slider = $('.bxslider').bxSlider(); +slider.redrawSlider(); +``` + +**reloadSlider** + +Reload the slider. Useful when adding slides on the fly. Accepts an optional settings object. +``` +example: +slider = $('.bxslider').bxSlider(); +slider.reloadSlider(); +``` + +**destroySlider** + +Destroy the slider. This reverts all slider elements back to their original state (before calling the slider). +``` +example: +slider = $('.bxslider').bxSlider(); +slider.destroySlider(); +``` + +### Local Development with Gulp + +**Unfamiliar with npm? Don't have node installed?** [Download and install node.js](http://nodejs.org/download/) before proceeding. + +From the command line: + +1. Install the CLI: `npm install --global gulp-cli` +2. Run `npm install` to install local development tools +3. Run `gulp` which will build the project + +## Contributing + +Everyone is welcome to help [contribute](CONTRIBUTING.md) and improve this project. There are several ways you can contribute: + +* Reporting issues (please read [issue guidelines](https://github.com/necolas/issue-guidelines)) +* Suggesting new features +* Writing or refactoring code +* Fixing [issues](https://github.com/roots/roots/issues) + +## Changelog + +### Version 4.2.14 +* Fixing flickering (on -webkit) when used background-image to instead of +* FIX calling API method stopAuto() +* InvalidPointerId on Android 6 +* Use jQuery.fn.on instead of jQuery.fn.bind #1126 +* InvalidPointerId on Android 6 + +### Version 4.2.13 +* Fix error pagerqty +* Fix the problem #48 in the version 4.2.5 when using YUI Compressor +* Fix division by 0 +* Ensure that slider.working is set to false at the end of goToSlide(), regardless of what happened with position. +* Add Callback for when Auto changes... +* Fix for Firefox59 and PointerEvent standard compatibility +* Fix for middle mouse click +* Fix typo +* Format the license in package.json to match the SPDX standard +* Code formatting + +### Version 4.2.12 +* Fixes auto control theme + +### Version 4.2.11 +* Removes auto-centering for sliders with no pager or controls + +### Version 4.2.10 +* Bumps npm and bower versions + +### Version 4.2.9 +* Removes node engine version requirement + +### Version 4.2.8 +* Removes auto-centering from the theme file (`jquery.bxslider.css`) + +### Version 4.2.7 +* Allows new version to be published to NPM + +### Version 4.2.6 +* Fix: jQuery 3 support +* Adds Gulp and removes Grunt (for easier local development) + +### Version 4.2.5 +* Fix: Vertical carousel minSlides not working #840 +* Fix: slider breaks with css animations if settings.speed set to 0 #838 +* Fix: Slider runs into undefined state when reloadSlider is called before initialization was finished #833 + +### Version 4.2.4 + +NOTICE: We have switched to a Grunt based build process in order to leverage [Assemble](http://assemble.io) for local documentation building. Please review the above notes about Grunt for the commands available. + +* Fix: Fixed transition from first to last slide during infinite loop #778 +* Fix: Reload on multiple sliders doesn't work? #755 +* Fix: bxSlider with text only #746 +* Fix: bower missing main and ignore entries #738 +* Fix: Tickermode transitionend event bubbling #737 +* Fix: Initializing before destroyed breaks slider #748 +* Enhancement: Added shrinkItems carousel setting #772 +* Enhancement: Maintain auto display of slides after a manual selection #594 +* Enhancement: Slider getter through jquery object #739 +* Enhancement: Add aria attributes #751 +* Enhancement: Slider element in every callback and a new method getSliderElement (#780) +* Enhancement: Local Documentiation and examples. I have added buildable documentation to the repo. This will expand over time and allow for community corrections as needed. Please see above Grunt notes on how to build. + + +### Version 4.2.3 +* Minor bug fix + +### Version 4.2.2 +* Fix: Remove unused plugin variable (#733) +* Fix: `updateAfterSlideTransition` not being called (#704) +* Fix: Slider stops auto advancing (#702) +* Fix: Refresh page, slider show the last item at the first in mode: 'horizontal' (#694) +* Fix: horizintal ticker stutters on loop (#669) +* Fix: Wrong bx-wrapper bottom margin with controls=true and pager=false (#647) +* Fix: add css tickerHover. (#629) +* Fix: Slider refusing to scale down, only up (#611) +* Fix: bxSlider freezes on touch devices (#540) +* Fix: Multiple fixes and improvements for Windows Mobile Devices (#596) +* Fix: Accessing bxslider's slider object inside its “onSliderLoad” callback returns undefined (#475) +* Fix: infiniteLoop glitch when scrolling from first to last slide (#429) +* Enhancement: Cancel transitions on callbacks by returning false. (#411) +* Enhancement: Added Keyboard arrow left and right support (#239) + +### Version 4.2.1 +* Fix: Merge Conflict in dist +* Fix: modified bower.json + +### Version 4.2.0 +* Fix: Reverse #714, fixes #722. +* Fix: Repo Tag #729 +* Fix: #720 pagerCustom issues + +4.2.0 Introduces a streamlined build process using [gulp](www.gulpjs.com). Along with this new build process the projects folder structure has been changed. You will find a `dist` folder with all assets ready to use, including both minified and unminified versions of the javascript. These assets should be ready to go. In `src` you will find the uncompiled assets, including a new less version of the css for bxslider. This is an important step for bxslider. It will help speed development up and keep work clean. It also paves the way for a big revamp we have planned in the future. + +**Unfamiliar with npm? Don't have node installed?** [Download and install node.js](http://nodejs.org/download/) before proceeding. + +From the command line: + +1. Install [gulp](http://gulpjs.com) globally with `npm install -g gulp` +2. Navigate to the project directory, then run `npm install` + +You now have all the necessary dependencies to run the build process. + +### Available gulp commands + +* `gulp` — Compile and optimize all files to `dist` +* `gulp styles` — Compile css assets only to `dist` +* `gulp scripts` — Compile js assets only to `dist` +* `gulp images` - Run lossless compression on all the images and copy to `dist` +* `gulp jshint` — Checks JS and JSON code for errors based on our .jshintrc settings + + +### Version 4.1.3 +* Fix: responsive issue for horizontal mode for issue #611, #714 +* Fix: extra space on the left when using fade mode. #715 +* Fix: wrongly removing custom pager in destroySlider #610 +* Fix: bug with reloading slider with custom pager #545 +* Fix: Issue with infinite scroll sometimes returning to 0 #481 +* Fix: When "infiniteLoop" is used, true is not passed to a clone method. #346 +* Fix: "pagerCustom" won't work when using reloadSlider #171 +* Fix: Remove vendor prefix for translateZ(0) #565 +* Fix: give styles on focus for accessibility #228 +* Fix: Minified Version out of sync. +* Fix: Remove -5px left #517 +* Enhancement: Invert order call of appendControls() and appendPager() #226 +* Enhancement: Various Indentation and typos in docs fixed. #551, #578 +* Enhancement: Update jsDelivr with update.json for autoupdate of CDN +* Enhancement: Tag Repo so it can be included in CDNJS +* Created development branch to work from. Eventually will restructure entire repo to follow best practice setup. + + +### Version 4.1.2 +* Added `bower.json` configuration file. Manage bxSlider as a dependency using [bower](http://bower.io/). + +### Version 4.1.1 +* Removed imagesLoaded library and added iframe preloading support +* Added responsive option - setting to false will prevent $(window).resize binding + +### Version 4.1 +* Carousel mode (minSlides / maxSlides) was re-written to be more intuitive. +* SlideWidth now acts as it should (slides respect the width value). +* SlideWidth now properly parsed: accepts string ("600px") or integer (600). +* Slider now only needs to load visible slides (by default) in order to initialize which results in much faster loading. A "preloadImages" setting allows for configuration. + + +Long live Zep. diff --git a/images/bx_loader.gif b/dist/images/bx_loader.gif similarity index 100% rename from images/bx_loader.gif rename to dist/images/bx_loader.gif diff --git a/images/controls.png b/dist/images/controls.png similarity index 100% rename from images/controls.png rename to dist/images/controls.png diff --git a/dist/index.html b/dist/index.html new file mode 100644 index 00000000..cd6e1d39 --- /dev/null +++ b/dist/index.html @@ -0,0 +1,29 @@ + + + +
        +
      • +
      • +
      • +
      • +
      • +
      + + + + + + diff --git a/dist/jquery-3.1.1.min.js b/dist/jquery-3.1.1.min.js new file mode 100644 index 00000000..4c5be4c0 --- /dev/null +++ b/dist/jquery-3.1.1.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.1.1 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):C.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/[^\x20\t\r\n\f]+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R), +a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,ka=/^$|\/(?:java|ecma)script/i,la={option:[1,""],thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};la.optgroup=la.option,la.tbody=la.tfoot=la.colgroup=la.caption=la.thead,la.th=la.td;function ma(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function na(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=ma(l.appendChild(f),"script"),j&&na(g),c){k=0;while(f=g[k++])ka.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var qa=d.documentElement,ra=/^key/,sa=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ta=/^([^.]*)(?:\.(.+)|)/;function ua(){return!0}function va(){return!1}function wa(){try{return d.activeElement}catch(a){}}function xa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)xa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=va;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(qa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,za=/\s*$/g;function Da(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Ea(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Fa(a){var b=Ba.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ga(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Aa.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ia(f,b,c,d)});if(m&&(e=pa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(ma(e,"script"),Ea),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=ma(h),f=ma(a),d=0,e=f.length;d0&&na(g,!i&&ma(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ja(this,a,!0)},remove:function(a){return Ja(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.appendChild(a)}})},prepend:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(ma(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!za.test(a)&&!la[(ja.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function Ya(a,b,c,d,e){return new Ya.prototype.init(a,b,c,d,e)}r.Tween=Ya,Ya.prototype={constructor:Ya,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Ya.propHooks[this.prop];return a&&a.get?a.get(this):Ya.propHooks._default.get(this)},run:function(a){var b,c=Ya.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ya.propHooks._default.set(this),this}},Ya.prototype.init.prototype=Ya.prototype,Ya.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Ya.propHooks.scrollTop=Ya.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Ya.prototype.init,r.fx.step={};var Za,$a,_a=/^(?:toggle|show|hide)$/,ab=/queueHooks$/;function bb(){$a&&(a.requestAnimationFrame(bb),r.fx.tick())}function cb(){return a.setTimeout(function(){Za=void 0}),Za=r.now()}function db(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ba[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function eb(a,b,c){for(var d,e=(hb.tweeners[b]||[]).concat(hb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?ib:void 0)), +void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),ib={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=jb[b]||r.find.attr;jb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=jb[g],jb[g]=e,e=null!=c(a,b,d)?g:null,jb[g]=f),e}});var kb=/^(?:input|select|textarea|button)$/i,lb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):kb.test(a.nodeName)||lb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function mb(a){var b=a.match(K)||[];return b.join(" ")}function nb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,nb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,nb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,nb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=nb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(nb(c))+" ").indexOf(b)>-1)return!0;return!1}});var ob=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(ob,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:mb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ia.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,"$1"),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" + ``` -###Step 2: Create HTML markup +Or, if you prefer, you can get the bxSlider's resources from the **CDN**: + +```html + + +``` + +### Step 2: Create HTML markup Create a `
        ` element, with a `
      • ` for each slide. Slides can contain images, video, or any other HTML content! @@ -46,9 +54,9 @@ Create a `
          ` element, with a `
        • ` for each slide. Slides c
        ``` -###Step 3: Call the bxSlider +### Step 3: Call the bxSlider -Call .bxslider() on `
          `. Note that the call must be made inside of a $(document).ready() call, or the plugin will not work! +Call .bxSlider() on `
            `. Note that the call must be made inside of a $(document).ready() call, or the plugin will not work! ```javascript $(document).ready(function(){ @@ -56,481 +64,804 @@ $(document).ready(function(){ }); ``` -##Configuration options +## Configuration options + +### General -###General +**mode** -**mode** Type of transition between slides ``` -default: 'horizontal' +default: 'horizontal' options: 'horizontal', 'vertical', 'fade' ``` -**speed** +**speed** + Slide transition duration (in ms) ``` -default: 500 +default: 500 options: integer ``` -**slideMargin** +**slideMargin** + Margin between each slide ``` -default: 0 +default: 0 options: integer ``` -**startSlide** +**startSlide** + Starting slide index (zero-based) ``` -default: 0 +default: 0 options: integer ``` -**randomStart** +**randomStart** + Start slider on a random slide ``` -default: false +default: false options: boolean (true / false) ``` -**slideSelector** +**slideSelector** + Element to use as slides (ex. 'div.slide').
            Note: by default, bxSlider will use all immediate children of the slider element ``` -default: '' +default: '' options: jQuery selector ``` -**infiniteLoop** +**infiniteLoop** + If true, clicking "Next" while on the last slide will transition to the first slide and vice-versa ``` -default: true +default: true options: boolean (true / false) ``` -**hideControlOnEnd** -If true, "Next" control will be hidden on last slide and vice-versa
            Note: Only used when infiniteLoop: false +**hideControlOnEnd** + +If true, "Prev" and "Next" controls will receive a class disabled when slide is the first or the last
            Note: Only used when infiniteLoop: false ``` -default: false +default: false options: boolean (true / false) ``` -**easing** +**easing** + The type of "easing" to use during transitions. If using CSS transitions, include a value for the transition-timing-function property. If not using CSS transitions, you may include plugins/jquery.easing.1.3.js for many options.
            See http://gsgd.co.uk/sandbox/jquery/easing/ for more info. ``` -default: null +default: null options: if using CSS: 'linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'cubic-bezier(n,n,n,n)'. If not using CSS: 'swing', 'linear' (see the above file for more options) ``` -**captions** +**captions** + Include image captions. Captions are derived from the image's title attribute ``` -default: false +default: false options: boolean (true / false) ``` -**ticker** +**ticker** + Use slider in ticker mode (similar to a news ticker) ``` -default: false +default: false options: boolean (true / false) ``` -**tickerHover** +**tickerHover** + Ticker will pause when mouse hovers over slider. Note: this functionality does NOT work if using CSS transitions! ``` -default: false +default: false options: boolean (true / false) ``` -**adaptiveHeight** +**adaptiveHeight** + Dynamically adjust slider height based on each slide's height ``` -default: false +default: false options: boolean (true / false) ``` -**adaptiveHeightSpeed** +**adaptiveHeightSpeed** + Slide height transition duration (in ms). Note: only used if adaptiveHeight: true ``` -default: 500 +default: 500 options: integer ``` -**video** +**video** + If any slides contain video, set this to true. Also, include plugins/jquery.fitvids.js
            See http://fitvidsjs.com/ for more info ``` -default: false +default: false options: boolean (true / false) ``` -**useCSS** +**responsive** + +Enable or disable auto resize of the slider. Useful if you need to use fixed width sliders. +``` +default: true +options: boolean (true /false) +``` + +**useCSS** + If true, CSS transitions will be used for horizontal and vertical slide animations (this uses native hardware acceleration). If false, jQuery animate() will be used. ``` -default: true +default: true options: boolean (true / false) ``` -**preloadImages** +**preloadImages** + If 'all', preloads all images before starting the slider. If 'visible', preloads only images in the initially visible slides before starting the slider (tip: use 'visible' if all slides are identical dimensions) ``` -default: all -options: 'all', 'visible' +default: 'visible' +options: 'all', 'visible', 'none' ``` -**touchEnabled** +**touchEnabled** + If true, slider will allow touch swipe transitions ``` -default: true +default: true options: boolean (true / false) ``` -**swipeThreshold** +**swipeThreshold** + Amount of pixels a touch swipe needs to exceed in order to execute a slide transition. Note: only used if touchEnabled: true ``` -default: 50 +default: 50 options: integer ``` -**oneToOneTouch** +**oneToOneTouch** + If true, non-fade slides follow the finger as it swipes ``` -default: true +default: true options: boolean (true / false) ``` -**preventDefaultSwipeX** +**preventDefaultSwipeX** + If true, touch screen will not move along the x-axis as the finger swipes ``` -default: true +default: true options: boolean (true / false) ``` -**preventDefaultSwipeY** +**preventDefaultSwipeY** + If true, touch screen will not move along the y-axis as the finger swipes ``` -default: false +default: false options: boolean (true / false) ``` -###Pager +**wrapperClass** + +Class to wrap the slider in. Change to prevent from using default bxSlider styles. +``` +default: 'bx-wrapper' +options: string +``` + +### Pager + +**pager** -**pager** If true, a pager will be added ``` -default: true +default: true options: boolean (true / false) ``` -**pagerType** +**pagerType** + If 'full', a pager link will be generated for each slide. If 'short', a x / y pager will be used (ex. 1 / 5) ``` -default: 'full' +default: 'full' options: 'full', 'short' ``` -**pagerShortSeparator** +**pagerShortSeparator** + If pagerType: 'short', pager will use this value as the separating character ``` -default: ' / ' +default: ' / ' options: string ``` -**pagerSelector** +**pagerSelector** + Element used to populate the populate the pager. By default, the pager is appended to the bx-viewport ``` -default: '' +default: '' options: jQuery selector ``` -**pagerCustom** +**pagerCustom** + Parent element to be used as the pager. Parent element must contain a <a data-slide-index="x"> element for each slide. See example here. Not for use with dynamic carousels. ``` -default: null +default: null options: jQuery selector ``` -**buildPager** +**buildPager** + If supplied, function is called on every slide element, and the returned value is used as the pager item markup.
            See examples for detailed implementation ``` -default: null +default: null options: function(slideIndex) ``` -###Controls +### Controls + +**controls** -**controls** If true, "Next" / "Prev" controls will be added ``` -default: true +default: true options: boolean (true / false) ``` -**nextText** +**nextText** + Text to be used for the "Next" control ``` -default: 'Next' +default: 'Next' options: string ``` -**prevText** +**prevText** + Text to be used for the "Prev" control ``` -default: 'Prev' +default: 'Prev' options: string ``` -**nextSelector** +**nextSelector** + Element used to populate the "Next" control ``` -default: null +default: null options: jQuery selector ``` -**prevSelector** +**prevSelector** + Element used to populate the "Prev" control ``` -default: null +default: null options: jQuery selector ``` -**autoControls** +**autoControls** + If true, "Start" / "Stop" controls will be added ``` -default: false +default: false options: boolean (true / false) ``` -**startText** +**startText** + Text to be used for the "Start" control ``` -default: 'Start' +default: 'Start' options: string ``` -**stopText** +**stopText** + Text to be used for the "Stop" control ``` -default: 'Stop' +default: 'Stop' options: string ``` -**autoControlsCombine** +**autoControlsCombine** + When slideshow is playing only "Stop" control is displayed and vice-versa ``` -default: false +default: false options: boolean (true / false) ``` -**autoControlsSelector** +**autoControlsSelector** + Element used to populate the auto controls ``` -default: null +default: null options: jQuery selector ``` -###Auto +**keyboardEnabled** + +Enable keyboard navigation for visible sliders +``` +default: false +options: boolean (true / false) +``` + +### Auto + +**auto** -**auto** Slides will automatically transition ``` -default: false +default: false options: boolean (true / false) ``` +**stopAutoOnClick** + +Auto will stop on interaction with controls +``` +default: false +options: boolean (true / false) +``` + +**pause** -**pause** The amount of time (in ms) between each auto transition ``` -default: 4000 +default: 4000 options: integer ``` -**autoStart** +**autoStart** + Auto show starts playing on load. If false, slideshow will start when the "Start" control is clicked ``` -default: true +default: true options: boolean (true / false) ``` -**autoDirection** +**autoDirection** + The direction of auto show slide transitions ``` -default: 'next' +default: 'next' options: 'next', 'prev' ``` -**autoHover** +**autoHover** + Auto show will pause when mouse hovers over slider ``` -default: false +default: false options: boolean (true / false) ``` -**autoDelay** +**autoDelay** + Time (in ms) auto show should wait before starting ``` -default: 0 +default: 0 options: integer ``` -###Carousel +### Carousel + +**minSlides** -**minSlides** The minimum number of slides to be shown. Slides will be sized down if carousel becomes smaller than the original size. ``` -default: 1 +default: 1 options: integer ``` -**maxSlides** +**maxSlides** + The maximum number of slides to be shown. Slides will be sized up if carousel becomes larger than the original size. ``` -default: 1 +default: 1 options: integer ``` -**moveSlides** -The number of slides to move on transition. This value must be >= minSlides, and <= maxSlides. If zero (default), the number of fully-visible slides will be used. +**moveSlides** + +The number of slides to move on transition. This value must be `>= minSlides`, and `<= maxSlides`. If zero (default), the number of fully-visible slides will be used. ``` -default: 0 +default: 0 options: integer ``` -**slideWidth** +**slideWidth** + The width of each slide. This setting is required for all horizontal carousels! ``` -default: 0 +default: 0 options: integer ``` -###Callbacks +**shrinkItems** + +The Carousel will only show whole items and shrink the images to fit the viewport based on maxSlides/MinSlides. +``` +default: false +options: boolean (true / false) +``` + +### Keyboard + +**keyboardEnabled** + +Allows for keyboard control of visible slider. Keypress ignored if slider not visible. +``` +default: false +options: boolean (true / false) +``` + +### Accessibility + +**ariaLive** + +Adds Aria Live attribute to slider. +``` +default: true +options: boolean (true / false) +``` + +**ariaHidden** + +Adds Aria Hidden attribute to any nonvisible slides. +``` +default: true +options: boolean (true / false) +``` + +### Callbacks + +**onSliderLoad** -**onSliderLoad** Executes immediately after the slider is fully loaded ``` -default: function(){} +default: function(){} +options: function(currentIndex){ // your code here } +arguments: + currentIndex: element index of the current slide +``` + +**onSliderResize** + +Executes immediately after the slider is resized +``` +default: function(){} options: function(currentIndex){ // your code here } -arguments: +arguments: currentIndex: element index of the current slide ``` -**onSlideBefore** +**onSlideBefore** + Executes immediately before each slide transition. ``` -default: function(){} +default: function(){} options: function($slideElement, oldIndex, newIndex){ // your code here } -arguments: +arguments: $slideElement: jQuery element of the destination element oldIndex: element index of the previous slide (before the transition) newIndex: element index of the destination slide (after the transition) ``` -**onSlideAfter** +**onSlideAfter** + Executes immediately after each slide transition. Function argument is the current slide element (when transition completes). ``` -default: function(){} +default: function(){} options: function($slideElement, oldIndex, newIndex){ // your code here } -arguments: +arguments: $slideElement: jQuery element of the destination element oldIndex: element index of the previous slide (before the transition) newIndex: element index of the destination slide (after the transition) ``` -**onSlideNext** +**onSlideNext** + Executes immediately before each "Next" slide transition. Function argument is the target (next) slide element. ``` -default: function(){} +default: function(){} options: function($slideElement, oldIndex, newIndex){ // your code here } -arguments: +arguments: $slideElement: jQuery element of the destination element oldIndex: element index of the previous slide (before the transition) newIndex: element index of the destination slide (after the transition) ``` -**onSlidePrev** +**onSlidePrev** + Executes immediately before each "Prev" slide transition. Function argument is the target (prev) slide element. ``` -default: function(){} +default: function(){} options: function($slideElement, oldIndex, newIndex){ // your code here } -arguments: +arguments: $slideElement: jQuery element of the destination element oldIndex: element index of the previous slide (before the transition) newIndex: element index of the destination slide (after the transition) ``` -###Public methods +**onAutoChange** + +Executes immediately after auto transtion starts or stops. +``` +default: function(){} +options: function(state){ // your code here } +arguments: + state: the new state of "auto": boolean (true / false) +``` + +### Public methods + +**goToSlide** -**goToSlide** Performs a slide transition to the supplied slide index (zero-based) ``` -example: +example: slider = $('.bxslider').bxSlider(); -slider.goToSlide(3); +slider.goToSlide(3); ``` -**goToNextSlide** +**goToNextSlide** + Performs a "Next" slide transition ``` -example: +example: slider = $('.bxslider').bxSlider(); -slider.goToNextSlide(); +slider.goToNextSlide(); ``` -**goToPrevSlide** +**goToPrevSlide** + Performs a "Prev" slide transition ``` -example: +example: slider = $('.bxslider').bxSlider(); -slider.goToPrevSlide(); +slider.goToPrevSlide(); ``` -**startAuto** -Starts the auto show. Provide an argument false to prevent the auto controls from being updated. +**startAuto** +Starts the auto show. Provide an argument `false` to prevent the auto controls from being updated. ``` -example: +example: slider = $('.bxslider').bxSlider(); -slider.startAuto(); +slider.startAuto(); ``` -**stopAuto** -Stops the auto show. Provide an argument false to prevent the auto controls from being updated. +**stopAuto** + +Stops the auto show. Provide an argument `false` to prevent the auto controls from being updated. ``` -example: +example: slider = $('.bxslider').bxSlider(); -slider.stopAuto(); +slider.stopAuto(); ``` -**getCurrentSlide** +**getCurrentSlide** + Returns the current active slide ``` -example: +example: slider = $('.bxslider').bxSlider(); -var current = slider.getCurrentSlide(); +var current = slider.getCurrentSlide(); ``` -**getSlideCount** +**getSlideCount** + Returns the total number of slides in the slider ``` -example: +example: +slider = $('.bxslider').bxSlider(); +var slideQty = slider.getSlideCount(); +``` + +**redrawSlider** + +Redraw the slider. Useful when needing to redraw a hidden slider after it is unhidden. +``` +example: slider = $('.bxslider').bxSlider(); -var slideQty = slider.getSlideCount(); +slider.redrawSlider(); ``` -**reloadSlider** -Reload the slider. Useful when adding slides on the fly. Accepts an optional settings object. See here for an example. +**reloadSlider** + +Reload the slider. Useful when adding slides on the fly. Accepts an optional settings object. ``` -example: +example: slider = $('.bxslider').bxSlider(); -slider.reloadSlider(); +slider.reloadSlider(); ``` -**destroySlider** +**destroySlider** + Destroy the slider. This reverts all slider elements back to their original state (before calling the slider). ``` -example: +example: slider = $('.bxslider').bxSlider(); -slider.destroySlider(); +slider.destroySlider(); ``` -Long live Zep. \ No newline at end of file +### Local Development with Gulp + +**Unfamiliar with npm? Don't have node installed?** [Download and install node.js](http://nodejs.org/download/) before proceeding. + +From the command line: + +1. Install the CLI: `npm install --global gulp-cli` +2. Run `npm install` to install local development tools +3. Run `gulp` which will build the project + +## Contributing + +Everyone is welcome to help [contribute](CONTRIBUTING.md) and improve this project. There are several ways you can contribute: + +* Reporting issues (please read [issue guidelines](https://github.com/necolas/issue-guidelines)) +* Suggesting new features +* Writing or refactoring code +* Fixing [issues](https://github.com/roots/roots/issues) + +## Changelog + +### Version 4.2.14 +* Fixing flickering (on -webkit) when used background-image to instead of +* FIX calling API method stopAuto() +* InvalidPointerId on Android 6 +* Use jQuery.fn.on instead of jQuery.fn.bind #1126 +* InvalidPointerId on Android 6 + +### Version 4.2.13 +* Fix error pagerqty +* Fix the problem #48 in the version 4.2.5 when using YUI Compressor +* Fix division by 0 +* Ensure that slider.working is set to false at the end of goToSlide(), regardless of what happened with position. +* Add Callback for when Auto changes... +* Fix for Firefox59 and PointerEvent standard compatibility +* Fix for middle mouse click +* Fix typo +* Format the license in package.json to match the SPDX standard +* Code formatting + +### Version 4.2.12 +* Fixes auto control theme + +### Version 4.2.11 +* Removes auto-centering for sliders with no pager or controls + +### Version 4.2.10 +* Bumps npm and bower versions + +### Version 4.2.9 +* Removes node engine version requirement + +### Version 4.2.8 +* Removes auto-centering from the theme file (`jquery.bxslider.css`) + +### Version 4.2.7 +* Allows new version to be published to NPM + +### Version 4.2.6 +* Fix: jQuery 3 support +* Adds Gulp and removes Grunt (for easier local development) + +### Version 4.2.5 +* Fix: Vertical carousel minSlides not working #840 +* Fix: slider breaks with css animations if settings.speed set to 0 #838 +* Fix: Slider runs into undefined state when reloadSlider is called before initialization was finished #833 + +### Version 4.2.4 + +NOTICE: We have switched to a Grunt based build process in order to leverage [Assemble](http://assemble.io) for local documentation building. Please review the above notes about Grunt for the commands available. + +* Fix: Fixed transition from first to last slide during infinite loop #778 +* Fix: Reload on multiple sliders doesn't work? #755 +* Fix: bxSlider with text only #746 +* Fix: bower missing main and ignore entries #738 +* Fix: Tickermode transitionend event bubbling #737 +* Fix: Initializing before destroyed breaks slider #748 +* Enhancement: Added shrinkItems carousel setting #772 +* Enhancement: Maintain auto display of slides after a manual selection #594 +* Enhancement: Slider getter through jquery object #739 +* Enhancement: Add aria attributes #751 +* Enhancement: Slider element in every callback and a new method getSliderElement (#780) +* Enhancement: Local Documentiation and examples. I have added buildable documentation to the repo. This will expand over time and allow for community corrections as needed. Please see above Grunt notes on how to build. + + +### Version 4.2.3 +* Minor bug fix + +### Version 4.2.2 +* Fix: Remove unused plugin variable (#733) +* Fix: `updateAfterSlideTransition` not being called (#704) +* Fix: Slider stops auto advancing (#702) +* Fix: Refresh page, slider show the last item at the first in mode: 'horizontal' (#694) +* Fix: horizintal ticker stutters on loop (#669) +* Fix: Wrong bx-wrapper bottom margin with controls=true and pager=false (#647) +* Fix: add css tickerHover. (#629) +* Fix: Slider refusing to scale down, only up (#611) +* Fix: bxSlider freezes on touch devices (#540) +* Fix: Multiple fixes and improvements for Windows Mobile Devices (#596) +* Fix: Accessing bxslider's slider object inside its “onSliderLoad” callback returns undefined (#475) +* Fix: infiniteLoop glitch when scrolling from first to last slide (#429) +* Enhancement: Cancel transitions on callbacks by returning false. (#411) +* Enhancement: Added Keyboard arrow left and right support (#239) + +### Version 4.2.1 +* Fix: Merge Conflict in dist +* Fix: modified bower.json + +### Version 4.2.0 +* Fix: Reverse #714, fixes #722. +* Fix: Repo Tag #729 +* Fix: #720 pagerCustom issues + +4.2.0 Introduces a streamlined build process using [gulp](www.gulpjs.com). Along with this new build process the projects folder structure has been changed. You will find a `dist` folder with all assets ready to use, including both minified and unminified versions of the javascript. These assets should be ready to go. In `src` you will find the uncompiled assets, including a new less version of the css for bxslider. This is an important step for bxslider. It will help speed development up and keep work clean. It also paves the way for a big revamp we have planned in the future. + +**Unfamiliar with npm? Don't have node installed?** [Download and install node.js](http://nodejs.org/download/) before proceeding. + +From the command line: + +1. Install [gulp](http://gulpjs.com) globally with `npm install -g gulp` +2. Navigate to the project directory, then run `npm install` + +You now have all the necessary dependencies to run the build process. + +### Available gulp commands + +* `gulp` — Compile and optimize all files to `dist` +* `gulp styles` — Compile css assets only to `dist` +* `gulp scripts` — Compile js assets only to `dist` +* `gulp images` - Run lossless compression on all the images and copy to `dist` +* `gulp jshint` — Checks JS and JSON code for errors based on our .jshintrc settings + + +### Version 4.1.3 +* Fix: responsive issue for horizontal mode for issue #611, #714 +* Fix: extra space on the left when using fade mode. #715 +* Fix: wrongly removing custom pager in destroySlider #610 +* Fix: bug with reloading slider with custom pager #545 +* Fix: Issue with infinite scroll sometimes returning to 0 #481 +* Fix: When "infiniteLoop" is used, true is not passed to a clone method. #346 +* Fix: "pagerCustom" won't work when using reloadSlider #171 +* Fix: Remove vendor prefix for translateZ(0) #565 +* Fix: give styles on focus for accessibility #228 +* Fix: Minified Version out of sync. +* Fix: Remove -5px left #517 +* Enhancement: Invert order call of appendControls() and appendPager() #226 +* Enhancement: Various Indentation and typos in docs fixed. #551, #578 +* Enhancement: Update jsDelivr with update.json for autoupdate of CDN +* Enhancement: Tag Repo so it can be included in CDNJS +* Created development branch to work from. Eventually will restructure entire repo to follow best practice setup. + + +### Version 4.1.2 +* Added `bower.json` configuration file. Manage bxSlider as a dependency using [bower](http://bower.io/). + +### Version 4.1.1 +* Removed imagesLoaded library and added iframe preloading support +* Added responsive option - setting to false will prevent $(window).resize binding + +### Version 4.1 +* Carousel mode (minSlides / maxSlides) was re-written to be more intuitive. +* SlideWidth now acts as it should (slides respect the width value). +* SlideWidth now properly parsed: accepts string ("600px") or integer (600). +* Slider now only needs to load visible slides (by default) in order to initialize which results in much faster loading. A "preloadImages" setting allows for configuration. + + +Long live Zep. diff --git a/src/css/jquery.bxslider.css b/src/css/jquery.bxslider.css new file mode 100644 index 00000000..71f6f750 --- /dev/null +++ b/src/css/jquery.bxslider.css @@ -0,0 +1,179 @@ +/** VARIABLES +===================================*/ +/** RESET AND LAYOUT +===================================*/ +.bx-wrapper { + position: relative; + margin-bottom: 60px; + padding: 0; + *zoom: 1; + -ms-touch-action: pan-y; + touch-action: pan-y; +} +.bx-wrapper img { + max-width: 100%; + display: block; +} +.bxslider { + margin: 0; + padding: 0; + /*fix flickering when used background-image instead of (on Chrome)*/ + -webkit-perspective: 1000; +} +ul.bxslider { + list-style: none; +} +.bx-viewport { + /* fix other elements on the page moving (in Chrome) */ + -webkit-transform: translateZ(0); +} +/** THEME +===================================*/ +.bx-wrapper { + -moz-box-shadow: 0 0 5px #ccc; + -webkit-box-shadow: 0 0 5px #ccc; + box-shadow: 0 0 5px #ccc; + border: 5px solid #fff; + background: #fff; +} +.bx-wrapper .bx-pager, +.bx-wrapper .bx-controls-auto { + position: absolute; + bottom: -30px; + width: 100%; +} +/* LOADER */ +.bx-wrapper .bx-loading { + min-height: 50px; + background: url('images/bx_loader.gif') center center no-repeat #ffffff; + height: 100%; + width: 100%; + position: absolute; + top: 0; + left: 0; + z-index: 2000; +} +/* PAGER */ +.bx-wrapper .bx-pager { + text-align: center; + font-size: .85em; + font-family: Arial; + font-weight: bold; + color: #666; + padding-top: 20px; +} +.bx-wrapper .bx-pager.bx-default-pager a { + background: #666; + text-indent: -9999px; + display: block; + width: 10px; + height: 10px; + margin: 0 5px; + outline: 0; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} +.bx-wrapper .bx-pager.bx-default-pager a:hover, +.bx-wrapper .bx-pager.bx-default-pager a.active, +.bx-wrapper .bx-pager.bx-default-pager a:focus { + background: #000; +} +.bx-wrapper .bx-pager-item, +.bx-wrapper .bx-controls-auto .bx-controls-auto-item { + display: inline-block; + vertical-align: bottom; + *zoom: 1; + *display: inline; +} +.bx-wrapper .bx-pager-item { + font-size: 0; + line-height: 0; +} +/* DIRECTION CONTROLS (NEXT / PREV) */ +.bx-wrapper .bx-prev { + left: 10px; + background: url('images/controls.png') no-repeat 0 -32px; +} +.bx-wrapper .bx-prev:hover, +.bx-wrapper .bx-prev:focus { + background-position: 0 0; +} +.bx-wrapper .bx-next { + right: 10px; + background: url('images/controls.png') no-repeat -43px -32px; +} +.bx-wrapper .bx-next:hover, +.bx-wrapper .bx-next:focus { + background-position: -43px 0; +} +.bx-wrapper .bx-controls-direction a { + position: absolute; + top: 50%; + margin-top: -16px; + outline: 0; + width: 32px; + height: 32px; + text-indent: -9999px; + z-index: 9999; +} +.bx-wrapper .bx-controls-direction a.disabled { + display: none; +} +/* AUTO CONTROLS (START / STOP) */ +.bx-wrapper .bx-controls-auto { + text-align: center; +} +.bx-wrapper .bx-controls-auto .bx-start { + display: block; + text-indent: -9999px; + width: 10px; + height: 11px; + outline: 0; + background: url('images/controls.png') -86px -11px no-repeat; + margin: 0 3px; +} +.bx-wrapper .bx-controls-auto .bx-start:hover, +.bx-wrapper .bx-controls-auto .bx-start.active, +.bx-wrapper .bx-controls-auto .bx-start:focus { + background-position: -86px 0; +} +.bx-wrapper .bx-controls-auto .bx-stop { + display: block; + text-indent: -9999px; + width: 9px; + height: 11px; + outline: 0; + background: url('images/controls.png') -86px -44px no-repeat; + margin: 0 3px; +} +.bx-wrapper .bx-controls-auto .bx-stop:hover, +.bx-wrapper .bx-controls-auto .bx-stop.active, +.bx-wrapper .bx-controls-auto .bx-stop:focus { + background-position: -86px -33px; +} +/* PAGER WITH AUTO-CONTROLS HYBRID LAYOUT */ +.bx-wrapper .bx-controls.bx-has-controls-auto.bx-has-pager .bx-pager { + text-align: left; + width: 80%; +} +.bx-wrapper .bx-controls.bx-has-controls-auto.bx-has-pager .bx-controls-auto { + right: 0; + width: 35px; +} +/* IMAGE CAPTIONS */ +.bx-wrapper .bx-caption { + position: absolute; + bottom: 0; + left: 0; + background: #666; + background: rgba(80, 80, 80, 0.75); + width: 100%; +} +.bx-wrapper .bx-caption span { + color: #fff; + font-family: Arial; + display: block; + font-size: .85em; + padding: 10px; +} diff --git a/src/images/bx_loader.gif b/src/images/bx_loader.gif new file mode 100644 index 00000000..f4ff40ed Binary files /dev/null and b/src/images/bx_loader.gif differ diff --git a/src/images/controls.png b/src/images/controls.png new file mode 100644 index 00000000..28918dde Binary files /dev/null and b/src/images/controls.png differ diff --git a/src/js/jquery.bxslider.js b/src/js/jquery.bxslider.js new file mode 100644 index 00000000..aaa59b1c --- /dev/null +++ b/src/js/jquery.bxslider.js @@ -0,0 +1,1669 @@ +/** + * bxSlider v4.2.17 + * Copyright 2013-2017 Steven Wanderski + * Written while drinking Belgian ales and listening to jazz + * Licensed under MIT (http://opensource.org/licenses/MIT) + */ + +;(function($) { + + var defaults = { + + // GENERAL + mode: 'horizontal', + slideSelector: '', + infiniteLoop: true, + hideControlOnEnd: false, + speed: 500, + easing: null, + slideMargin: 0, + startSlide: 0, + randomStart: false, + captions: false, + ticker: false, + tickerHover: false, + adaptiveHeight: false, + adaptiveHeightSpeed: 500, + video: false, + useCSS: true, + preloadImages: 'visible', + responsive: true, + slideZIndex: 50, + wrapperClass: 'bx-wrapper', + + // TOUCH + touchEnabled: true, + swipeThreshold: 50, + oneToOneTouch: true, + preventDefaultSwipeX: true, + preventDefaultSwipeY: false, + + // ACCESSIBILITY + ariaLive: true, + ariaHidden: true, + + // KEYBOARD + keyboardEnabled: false, + + // PAGER + pager: true, + pagerType: 'full', + pagerShortSeparator: ' / ', + pagerSelector: null, + buildPager: null, + pagerCustom: null, + + // CONTROLS + controls: true, + nextText: 'Next', + prevText: 'Prev', + nextSelector: null, + prevSelector: null, + autoControls: false, + startText: 'Start', + stopText: 'Stop', + autoControlsCombine: false, + autoControlsSelector: null, + + // AUTO + auto: false, + pause: 4000, + autoStart: true, + autoDirection: 'next', + stopAutoOnClick: false, + autoHover: false, + autoDelay: 0, + autoSlideForOnePage: false, + + // CAROUSEL + minSlides: 1, + maxSlides: 1, + moveSlides: 0, + slideWidth: 0, + shrinkItems: false, + + // CALLBACKS + onSliderLoad: function() { return true; }, + onSlideBefore: function() { return true; }, + onSlideAfter: function() { return true; }, + onSlideNext: function() { return true; }, + onSlidePrev: function() { return true; }, + onSliderResize: function() { return true; }, + onAutoChange: function() { return true; } //calls when auto slides starts and stops + }; + + $.fn.bxSlider = function(options) { + + if (this.length === 0) { + return this; + } + + // support multiple elements + if (this.length > 1) { + this.each(function() { + $(this).bxSlider(options); + }); + return this; + } + + // create a namespace to be used throughout the plugin + var slider = {}, + // set a reference to our slider element + el = this, + // get the original window dimens (thanks a lot IE) + windowWidth = $(window).width(), + windowHeight = $(window).height(); + + // Return if slider is already initialized + if ($(el).data('bxSlider')) { return; } + + /** + * =================================================================================== + * = PRIVATE FUNCTIONS + * =================================================================================== + */ + + /** + * Initializes namespace settings to be used throughout plugin + */ + var init = function() { + // Return if slider is already initialized + if ($(el).data('bxSlider')) { return; } + // merge user-supplied options with the defaults + slider.settings = $.extend({}, defaults, options); + // parse slideWidth setting + slider.settings.slideWidth = parseInt(slider.settings.slideWidth); + // store the original children + slider.children = el.children(slider.settings.slideSelector); + // check if actual number of slides is less than minSlides / maxSlides + if (slider.children.length < slider.settings.minSlides) { slider.settings.minSlides = slider.children.length; } + if (slider.children.length < slider.settings.maxSlides) { slider.settings.maxSlides = slider.children.length; } + // if random start, set the startSlide setting to random number + if (slider.settings.randomStart) { slider.settings.startSlide = Math.floor(Math.random() * slider.children.length); } + // store active slide information + slider.active = { index: slider.settings.startSlide }; + // store if the slider is in carousel mode (displaying / moving multiple slides) + slider.carousel = slider.settings.minSlides > 1 || slider.settings.maxSlides > 1; + // if carousel, force preloadImages = 'all' + if (slider.carousel) { slider.settings.preloadImages = 'all'; } + // calculate the min / max width thresholds based on min / max number of slides + // used to setup and update carousel slides dimensions + slider.minThreshold = (slider.settings.minSlides * slider.settings.slideWidth) + ((slider.settings.minSlides - 1) * slider.settings.slideMargin); + slider.maxThreshold = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin); + // store the current state of the slider (if currently animating, working is true) + slider.working = false; + // initialize the controls object + slider.controls = {}; + // initialize an auto interval + slider.interval = null; + // determine which property to use for transitions + slider.animProp = slider.settings.mode === 'vertical' ? 'top' : 'left'; + // determine if hardware acceleration can be used + slider.usingCSS = slider.settings.useCSS && slider.settings.mode !== 'fade' && (function() { + // create our test div element + var div = document.createElement('div'), + // css transition properties + props = ['WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']; + // test for each property + for (var i = 0; i < props.length; i++) { + if (div.style[props[i]] !== undefined) { + slider.cssPrefix = props[i].replace('Perspective', '').toLowerCase(); + slider.animProp = '-' + slider.cssPrefix + '-transform'; + return true; + } + } + return false; + }()); + // if vertical mode always make maxSlides and minSlides equal + if (slider.settings.mode === 'vertical') { slider.settings.maxSlides = slider.settings.minSlides; } + // save original style data + el.data('origStyle', el.attr('style')); + el.children(slider.settings.slideSelector).each(function() { + $(this).data('origStyle', $(this).attr('style')); + }); + + // perform all DOM / CSS modifications + setup(); + }; + + /** + * Performs all DOM and CSS modifications + */ + var setup = function() { + var preloadSelector = slider.children.eq(slider.settings.startSlide); // set the default preload selector (visible) + + // wrap el in a wrapper + el.wrap('
            '); + // store a namespace reference to .bx-viewport + slider.viewport = el.parent(); + + // add aria-live if the setting is enabled and ticker mode is disabled + if (slider.settings.ariaLive && !slider.settings.ticker) { + slider.viewport.attr('aria-live', 'polite'); + } + // add a loading div to display while images are loading + slider.loader = $('
            '); + slider.viewport.prepend(slider.loader); + // set el to a massive width, to hold any needed slides + // also strip any margin and padding from el + el.css({ + width: slider.settings.mode === 'horizontal' ? (slider.children.length * 1000 + 215) + '%' : 'auto', + position: 'relative' + }); + // if using CSS, add the easing property + if (slider.usingCSS && slider.settings.easing) { + el.css('-' + slider.cssPrefix + '-transition-timing-function', slider.settings.easing); + // if not using CSS and no easing value was supplied, use the default JS animation easing (swing) + } else if (!slider.settings.easing) { + slider.settings.easing = 'swing'; + } + // make modifications to the viewport (.bx-viewport) + slider.viewport.css({ + width: '100%', + overflow: 'hidden', + position: 'relative' + }); + slider.viewport.parent().css({ + maxWidth: getViewportMaxWidth() + }); + // apply css to all slider children + slider.children.css({ + // the float attribute is a reserved word in compressors like YUI compressor and need to be quoted #48 + 'float': slider.settings.mode === 'horizontal' ? 'left' : 'none', + listStyle: 'none', + position: 'relative' + }); + // apply the calculated width after the float is applied to prevent scrollbar interference + slider.children.css('width', getSlideWidth()); + // if slideMargin is supplied, add the css + if (slider.settings.mode === 'horizontal' && slider.settings.slideMargin > 0) { slider.children.css('marginRight', slider.settings.slideMargin); } + if (slider.settings.mode === 'vertical' && slider.settings.slideMargin > 0) { slider.children.css('marginBottom', slider.settings.slideMargin); } + // if "fade" mode, add positioning and z-index CSS + if (slider.settings.mode === 'fade') { + slider.children.css({ + position: 'absolute', + zIndex: 0, + display: 'none' + }); + // prepare the z-index on the showing element + slider.children.eq(slider.settings.startSlide).css({zIndex: slider.settings.slideZIndex, display: 'block'}); + } + // create an element to contain all slider controls (pager, start / stop, etc) + slider.controls.el = $('
            '); + // if captions are requested, add them + if (slider.settings.captions) { appendCaptions(); } + // check if startSlide is last slide + slider.active.last = slider.settings.startSlide === getPagerQty() - 1; + // if video is true, set up the fitVids plugin + if (slider.settings.video) { el.fitVids(); } + //preloadImages + if (slider.settings.preloadImages === 'none') { + preloadSelector = null; + } + else if (slider.settings.preloadImages === 'all' || slider.settings.ticker) { + preloadSelector = slider.children; + } + // only check for control addition if not in "ticker" mode + if (!slider.settings.ticker) { + // if controls are requested, add them + if (slider.settings.controls) { appendControls(); } + // if auto is true, and auto controls are requested, add them + if (slider.settings.auto && slider.settings.autoControls) { appendControlsAuto(); } + // if pager is requested, add it + if (slider.settings.pager) { appendPager(); } + // if any control option is requested, add the controls wrapper + if (slider.settings.controls || slider.settings.autoControls || slider.settings.pager) { slider.viewport.after(slider.controls.el); } + // if ticker mode, do not allow a pager + } else { + slider.settings.pager = false; + } + if (preloadSelector === null) { + start(); + } else { + loadElements(preloadSelector, start); + } + }; + + var loadElements = function(selector, callback) { + var total = selector.find('img:not([src=""]), iframe').length, + count = 0; + if (total === 0) { + callback(); + return; + } + selector.find('img:not([src=""]), iframe').each(function() { + $(this).one('load error', function() { + if (++count === total) { callback(); } + }).each(function() { + if (this.complete || this.src == '') { $(this).trigger('load'); } + }); + }); + }; + + /** + * Start the slider + */ + var start = function() { + // if infinite loop, prepare additional slides + if (slider.settings.infiniteLoop && slider.settings.mode !== 'fade' && !slider.settings.ticker) { + var slice = slider.settings.mode === 'vertical' ? slider.settings.minSlides : slider.settings.maxSlides, + sliceAppend = slider.children.slice(0, slice).clone(true).addClass('bx-clone'), + slicePrepend = slider.children.slice(-slice).clone(true).addClass('bx-clone'); + if (slider.settings.ariaHidden) { + sliceAppend.attr('aria-hidden', true); + slicePrepend.attr('aria-hidden', true); + } + el.append(sliceAppend).prepend(slicePrepend); + } + // remove the loading DOM element + slider.loader.remove(); + // set the left / top position of "el" + setSlidePosition(); + // if "vertical" mode, always use adaptiveHeight to prevent odd behavior + if (slider.settings.mode === 'vertical') { slider.settings.adaptiveHeight = true; } + // set the viewport height + slider.viewport.height(getViewportHeight()); + // make sure everything is positioned just right (same as a window resize) + el.redrawSlider(); + // onSliderLoad callback + slider.settings.onSliderLoad.call(el, slider.active.index); + // slider has been fully initialized + slider.initialized = true; + // add the resize call to the window + if (slider.settings.responsive) { $(window).on('resize', resizeWindow); } + // if auto is true and has more than 1 page, start the show + if (slider.settings.auto && slider.settings.autoStart && (getPagerQty() > 1 || slider.settings.autoSlideForOnePage)) { initAuto(); } + // if ticker is true, start the ticker + if (slider.settings.ticker) { initTicker(); } + // if pager is requested, make the appropriate pager link active + if (slider.settings.pager) { updatePagerActive(slider.settings.startSlide); } + // check for any updates to the controls (like hideControlOnEnd updates) + if (slider.settings.controls) { updateDirectionControls(); } + // if touchEnabled is true, setup the touch events + if (slider.settings.touchEnabled && !slider.settings.ticker) { initTouch(); } + // if keyboardEnabled is true, setup the keyboard events + if (slider.settings.keyboardEnabled && !slider.settings.ticker) { + $(document).keydown(keyPress); + } + }; + + /** + * Returns the calculated height of the viewport, used to determine either adaptiveHeight or the maxHeight value + */ + var getViewportHeight = function() { + var height = 0; + // first determine which children (slides) should be used in our height calculation + var children = $(); + // if mode is not "vertical" and adaptiveHeight is false, include all children + if (slider.settings.mode !== 'vertical' && !slider.settings.adaptiveHeight) { + children = slider.children; + } else { + // if not carousel, return the single active child + if (!slider.carousel) { + children = slider.children.eq(slider.active.index); + // if carousel, return a slice of children + } else { + // get the individual slide index + var currentIndex = slider.settings.moveSlides === 1 ? slider.active.index : slider.active.index * getMoveBy(); + // add the current slide to the children + children = slider.children.eq(currentIndex); + // cycle through the remaining "showing" slides + for (i = 1; i <= slider.settings.maxSlides - 1; i++) { + // if looped back to the start + if (currentIndex + i >= slider.children.length) { + children = children.add(slider.children.eq(i - 1)); + } else { + children = children.add(slider.children.eq(currentIndex + i)); + } + } + } + } + // if "vertical" mode, calculate the sum of the heights of the children + if (slider.settings.mode === 'vertical') { + children.each(function(index) { + height += $(this).outerHeight(); + }); + // add user-supplied margins + if (slider.settings.slideMargin > 0) { + height += slider.settings.slideMargin * (slider.settings.minSlides - 1); + } + // if not "vertical" mode, calculate the max height of the children + } else { + height = Math.max.apply(Math, children.map(function() { + return $(this).outerHeight(false); + }).get()); + } + + if (slider.viewport.css('box-sizing') === 'border-box') { + height += parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom')) + + parseFloat(slider.viewport.css('border-top-width')) + parseFloat(slider.viewport.css('border-bottom-width')); + } else if (slider.viewport.css('box-sizing') === 'padding-box') { + height += parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom')); + } + + return height; + }; + + /** + * Returns the calculated width to be used for the outer wrapper / viewport + */ + var getViewportMaxWidth = function() { + var width = '100%'; + if (slider.settings.slideWidth > 0) { + if (slider.settings.mode === 'horizontal') { + width = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin); + } else { + width = slider.settings.slideWidth; + } + } + return width; + }; + + /** + * Returns the calculated width to be applied to each slide + */ + var getSlideWidth = function() { + var newElWidth = slider.settings.slideWidth, // start with any user-supplied slide width + wrapWidth = slider.viewport.width(); // get the current viewport width + // if slide width was not supplied, or is larger than the viewport use the viewport width + if (slider.settings.slideWidth === 0 || + (slider.settings.slideWidth > wrapWidth && !slider.carousel) || + slider.settings.mode === 'vertical') { + newElWidth = wrapWidth; + // if carousel, use the thresholds to determine the width + } else if (slider.settings.maxSlides > 1 && slider.settings.mode === 'horizontal') { + if (wrapWidth > slider.maxThreshold) { + return newElWidth; + } else if (wrapWidth < slider.minThreshold) { + newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.minSlides - 1))) / slider.settings.minSlides; + } else if (slider.settings.shrinkItems) { + newElWidth = Math.floor((wrapWidth + slider.settings.slideMargin) / (Math.ceil((wrapWidth + slider.settings.slideMargin) / (newElWidth + slider.settings.slideMargin))) - slider.settings.slideMargin); + } + } + return newElWidth; + }; + + /** + * Returns the number of slides currently visible in the viewport (includes partially visible slides) + */ + var getNumberSlidesShowing = function() { + var slidesShowing = 1, + childWidth = null; + if (slider.settings.mode === 'horizontal' && slider.settings.slideWidth > 0) { + // if viewport is smaller than minThreshold, return minSlides + if (slider.viewport.width() < slider.minThreshold) { + slidesShowing = slider.settings.minSlides; + // if viewport is larger than maxThreshold, return maxSlides + } else if (slider.viewport.width() > slider.maxThreshold) { + slidesShowing = slider.settings.maxSlides; + // if viewport is between min / max thresholds, divide viewport width by first child width + } else { + childWidth = slider.children.first().width() + slider.settings.slideMargin; + slidesShowing = Math.floor((slider.viewport.width() + + slider.settings.slideMargin) / childWidth) || 1; + } + // if "vertical" mode, slides showing will always be minSlides + } else if (slider.settings.mode === 'vertical') { + slidesShowing = slider.settings.minSlides; + } + return slidesShowing; + }; + + /** + * Returns the number of pages (one full viewport of slides is one "page") + */ + var getPagerQty = function() { + var pagerQty = 0, + breakPoint = 0, + counter = 0; + // if moveSlides is specified by the user + if (slider.settings.moveSlides > 0) { + if (slider.settings.infiniteLoop) { + pagerQty = Math.ceil(slider.children.length / getMoveBy()); + } else { + // when breakpoint goes above children length, counter is the number of pages + while (breakPoint < slider.children.length) { + ++pagerQty; + breakPoint = counter + getNumberSlidesShowing(); + counter += slider.settings.moveSlides <= getNumberSlidesShowing() ? slider.settings.moveSlides : getNumberSlidesShowing(); + } + return counter; + } + // if moveSlides is 0 (auto) divide children length by sides showing, then round up + } else { + pagerQty = Math.ceil(slider.children.length / getNumberSlidesShowing()); + } + return pagerQty; + }; + + /** + * Returns the number of individual slides by which to shift the slider + */ + var getMoveBy = function() { + // if moveSlides was set by the user and moveSlides is less than number of slides showing + if (slider.settings.moveSlides > 0 && slider.settings.moveSlides <= getNumberSlidesShowing()) { + return slider.settings.moveSlides; + } + // if moveSlides is 0 (auto) + return getNumberSlidesShowing(); + }; + + /** + * Sets the slider's (el) left or top position + */ + var setSlidePosition = function() { + var position, lastChild, lastShowingIndex; + // if last slide, not infinite loop, and number of children is larger than specified maxSlides + if (slider.children.length > slider.settings.maxSlides && slider.active.last && !slider.settings.infiniteLoop) { + if (slider.settings.mode === 'horizontal') { + // get the last child's position + lastChild = slider.children.last(); + position = lastChild.position(); + // set the left position + setPositionProperty(-(position.left - (slider.viewport.width() - lastChild.outerWidth())), 'reset', 0); + } else if (slider.settings.mode === 'vertical') { + // get the last showing index's position + lastShowingIndex = slider.children.length - slider.settings.minSlides; + position = slider.children.eq(lastShowingIndex).position(); + // set the top position + setPositionProperty(-position.top, 'reset', 0); + } + // if not last slide + } else { + // get the position of the first showing slide + position = slider.children.eq(slider.active.index * getMoveBy()).position(); + // check for last slide + if (slider.active.index === getPagerQty() - 1) { slider.active.last = true; } + // set the respective position + if (position !== undefined) { + if (slider.settings.mode === 'horizontal') { setPositionProperty(-position.left, 'reset', 0); } + else if (slider.settings.mode === 'vertical') { setPositionProperty(-position.top, 'reset', 0); } + } + } + }; + + /** + * Sets the el's animating property position (which in turn will sometimes animate el). + * If using CSS, sets the transform property. If not using CSS, sets the top / left property. + * + * @param value (int) + * - the animating property's value + * + * @param type (string) 'slide', 'reset', 'ticker' + * - the type of instance for which the function is being + * + * @param duration (int) + * - the amount of time (in ms) the transition should occupy + * + * @param params (array) optional + * - an optional parameter containing any variables that need to be passed in + */ + var setPositionProperty = function(value, type, duration, params) { + var animateObj, propValue; + // use CSS transform + if (slider.usingCSS) { + // determine the translate3d value + propValue = slider.settings.mode === 'vertical' ? 'translate3d(0, ' + value + 'px, 0)' : 'translate3d(' + value + 'px, 0, 0)'; + // add the CSS transition-duration + el.css('-' + slider.cssPrefix + '-transition-duration', duration / 1000 + 's'); + if (type === 'slide') { + // set the property value + el.css(slider.animProp, propValue); + if (duration !== 0) { + // add a callback method - executes when CSS transition completes + el.on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(e) { + //make sure it's the correct one + if (!$(e.target).is(el)) { return; } + // remove the callback + el.off('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd'); + updateAfterSlideTransition(); + }); + } else { //duration = 0 + updateAfterSlideTransition(); + } + } else if (type === 'reset') { + el.css(slider.animProp, propValue); + } else if (type === 'ticker') { + // make the transition use 'linear' + el.css('-' + slider.cssPrefix + '-transition-timing-function', 'linear'); + el.css(slider.animProp, propValue); + if (duration !== 0) { + el.on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(e) { + //make sure it's the correct one + if (!$(e.target).is(el)) { return; } + // remove the callback + el.off('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd'); + // reset the position + setPositionProperty(params.resetValue, 'reset', 0); + // start the loop again + tickerLoop(); + }); + } else { //duration = 0 + setPositionProperty(params.resetValue, 'reset', 0); + tickerLoop(); + } + } + // use JS animate + } else { + animateObj = {}; + animateObj[slider.animProp] = value; + if (type === 'slide') { + el.animate(animateObj, duration, slider.settings.easing, function() { + updateAfterSlideTransition(); + }); + } else if (type === 'reset') { + el.css(slider.animProp, value); + } else if (type === 'ticker') { + el.animate(animateObj, duration, 'linear', function() { + setPositionProperty(params.resetValue, 'reset', 0); + // run the recursive loop after animation + tickerLoop(); + }); + } + } + }; + + /** + * Populates the pager with proper amount of pages + */ + var populatePager = function() { + var pagerHtml = '', + linkContent = '', + pagerQty = getPagerQty(); + // loop through each pager item + for (var i = 0; i < pagerQty; i++) { + linkContent = ''; + // if a buildPager function is supplied, use it to get pager link value, else use index + 1 + if (slider.settings.buildPager && $.isFunction(slider.settings.buildPager) || slider.settings.pagerCustom) { + linkContent = slider.settings.buildPager(i); + slider.pagerEl.addClass('bx-custom-pager'); + } else { + linkContent = i + 1; + slider.pagerEl.addClass('bx-default-pager'); + } + // var linkContent = slider.settings.buildPager && $.isFunction(slider.settings.buildPager) ? slider.settings.buildPager(i) : i + 1; + // add the markup to the string + pagerHtml += ''; + } + // populate the pager element with pager links + slider.pagerEl.html(pagerHtml); + }; + + /** + * Appends the pager to the controls element + */ + var appendPager = function() { + if (!slider.settings.pagerCustom) { + // create the pager DOM element + slider.pagerEl = $('
            '); + // if a pager selector was supplied, populate it with the pager + if (slider.settings.pagerSelector) { + $(slider.settings.pagerSelector).html(slider.pagerEl); + // if no pager selector was supplied, add it after the wrapper + } else { + slider.controls.el.addClass('bx-has-pager').append(slider.pagerEl); + } + // populate the pager + populatePager(); + } else { + slider.pagerEl = $(slider.settings.pagerCustom); + } + // assign the pager click binding + slider.pagerEl.on('click touchend', 'a', clickPagerBind); + }; + + /** + * Appends prev / next controls to the controls element + */ + var appendControls = function() { + slider.controls.next = $('' + slider.settings.nextText + ''); + slider.controls.prev = $('' + slider.settings.prevText + ''); + // add click actions to the controls + slider.controls.next.on('click touchend', clickNextBind); + slider.controls.prev.on('click touchend', clickPrevBind); + // if nextSelector was supplied, populate it + if (slider.settings.nextSelector) { + $(slider.settings.nextSelector).append(slider.controls.next); + } + // if prevSelector was supplied, populate it + if (slider.settings.prevSelector) { + $(slider.settings.prevSelector).append(slider.controls.prev); + } + // if no custom selectors were supplied + if (!slider.settings.nextSelector && !slider.settings.prevSelector) { + // add the controls to the DOM + slider.controls.directionEl = $('
            '); + // add the control elements to the directionEl + slider.controls.directionEl.append(slider.controls.prev).append(slider.controls.next); + // slider.viewport.append(slider.controls.directionEl); + slider.controls.el.addClass('bx-has-controls-direction').append(slider.controls.directionEl); + } + }; + + /** + * Appends start / stop auto controls to the controls element + */ + var appendControlsAuto = function() { + slider.controls.start = $(''); + slider.controls.stop = $(''); + // add the controls to the DOM + slider.controls.autoEl = $('
            '); + // on click actions to the controls + slider.controls.autoEl.on('click', '.bx-start', clickStartBind); + slider.controls.autoEl.on('click', '.bx-stop', clickStopBind); + // if autoControlsCombine, insert only the "start" control + if (slider.settings.autoControlsCombine) { + slider.controls.autoEl.append(slider.controls.start); + // if autoControlsCombine is false, insert both controls + } else { + slider.controls.autoEl.append(slider.controls.start).append(slider.controls.stop); + } + // if auto controls selector was supplied, populate it with the controls + if (slider.settings.autoControlsSelector) { + $(slider.settings.autoControlsSelector).html(slider.controls.autoEl); + // if auto controls selector was not supplied, add it after the wrapper + } else { + slider.controls.el.addClass('bx-has-controls-auto').append(slider.controls.autoEl); + } + // update the auto controls + updateAutoControls(slider.settings.autoStart ? 'stop' : 'start'); + }; + + /** + * Appends image captions to the DOM + */ + var appendCaptions = function() { + // cycle through each child + slider.children.each(function(index) { + // get the image title attribute + var title = $(this).find('img:first').attr('title'); + // append the caption + if (title !== undefined && ('' + title).length) { + $(this).append('
            ' + title + '
            '); + } + }); + }; + + /** + * Click next binding + * + * @param e (event) + * - DOM event object + */ + var clickNextBind = function(e) { + e.preventDefault(); + if (slider.controls.el.hasClass('disabled')) { return; } + // if auto show is running, stop it + if (slider.settings.auto && slider.settings.stopAutoOnClick) { el.stopAuto(); } + el.goToNextSlide(); + }; + + /** + * Click prev binding + * + * @param e (event) + * - DOM event object + */ + var clickPrevBind = function(e) { + e.preventDefault(); + if (slider.controls.el.hasClass('disabled')) { return; } + // if auto show is running, stop it + if (slider.settings.auto && slider.settings.stopAutoOnClick) { el.stopAuto(); } + el.goToPrevSlide(); + }; + + /** + * Click start binding + * + * @param e (event) + * - DOM event object + */ + var clickStartBind = function(e) { + el.startAuto(); + e.preventDefault(); + }; + + /** + * Click stop binding + * + * @param e (event) + * - DOM event object + */ + var clickStopBind = function(e) { + el.stopAuto(); + e.preventDefault(); + }; + + /** + * Click pager binding + * + * @param e (event) + * - DOM event object + */ + var clickPagerBind = function(e) { + var pagerLink, pagerIndex; + e.preventDefault(); + if (slider.controls.el.hasClass('disabled')) { + return; + } + // if auto show is running, stop it + if (slider.settings.auto && slider.settings.stopAutoOnClick) { el.stopAuto(); } + pagerLink = $(e.currentTarget); + if (pagerLink.attr('data-slide-index') !== undefined) { + pagerIndex = parseInt(pagerLink.attr('data-slide-index')); + // if clicked pager link is not active, continue with the goToSlide call + if (pagerIndex !== slider.active.index) { el.goToSlide(pagerIndex); } + } + }; + + /** + * Updates the pager links with an active class + * + * @param slideIndex (int) + * - index of slide to make active + */ + var updatePagerActive = function(slideIndex) { + // if "short" pager type + var len = slider.children.length; // nb of children + if (slider.settings.pagerType === 'short') { + if (slider.settings.maxSlides > 1) { + len = Math.ceil(slider.children.length / slider.settings.maxSlides); + } + slider.pagerEl.html((slideIndex + 1) + slider.settings.pagerShortSeparator + len); + return; + } + // remove all pager active classes + slider.pagerEl.find('a').removeClass('active'); + // apply the active class for all pagers + slider.pagerEl.each(function(i, el) { $(el).find('a').eq(slideIndex).addClass('active'); }); + }; + + /** + * Performs needed actions after a slide transition + */ + var updateAfterSlideTransition = function() { + // if infinite loop is true + if (slider.settings.infiniteLoop) { + var position = ''; + // first slide + if (slider.active.index === 0) { + // set the new position + position = slider.children.eq(0).position(); + // carousel, last slide + } else if (slider.active.index === getPagerQty() - 1 && slider.carousel) { + position = slider.children.eq((getPagerQty() - 1) * getMoveBy()).position(); + // last slide + } else if (slider.active.index === slider.children.length - 1) { + position = slider.children.eq(slider.children.length - 1).position(); + } + if (position) { + if (slider.settings.mode === 'horizontal') { setPositionProperty(-position.left, 'reset', 0); } + else if (slider.settings.mode === 'vertical') { setPositionProperty(-position.top, 'reset', 0); } + } + } + // declare that the transition is complete + slider.working = false; + // onSlideAfter callback + slider.settings.onSlideAfter.call(el, slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); + }; + + /** + * Updates the auto controls state (either active, or combined switch) + * + * @param state (string) "start", "stop" + * - the new state of the auto show + */ + var updateAutoControls = function(state) { + // if autoControlsCombine is true, replace the current control with the new state + if (slider.settings.autoControlsCombine) { + slider.controls.autoEl.html(slider.controls[state]); + // if autoControlsCombine is false, apply the "active" class to the appropriate control + } else { + slider.controls.autoEl.find('a').removeClass('active'); + slider.controls.autoEl.find('a:not(.bx-' + state + ')').addClass('active'); + } + }; + + /** + * Updates the direction controls (checks if either should be hidden) + */ + var updateDirectionControls = function() { + if (getPagerQty() === 1) { + slider.controls.prev.addClass('disabled'); + slider.controls.next.addClass('disabled'); + } else if (!slider.settings.infiniteLoop && slider.settings.hideControlOnEnd) { + // if first slide + if (slider.active.index === 0) { + slider.controls.prev.addClass('disabled'); + slider.controls.next.removeClass('disabled'); + // if last slide + } else if (slider.active.index === getPagerQty() - 1) { + slider.controls.next.addClass('disabled'); + slider.controls.prev.removeClass('disabled'); + // if any slide in the middle + } else { + slider.controls.prev.removeClass('disabled'); + slider.controls.next.removeClass('disabled'); + } + } + }; + /* auto start and stop functions */ + var windowFocusHandler = function() { el.startAuto(); }; + var windowBlurHandler = function() { el.stopAuto(); }; + /** + * Initializes the auto process + */ + var initAuto = function() { + // if autoDelay was supplied, launch the auto show using a setTimeout() call + if (slider.settings.autoDelay > 0) { + setTimeout(el.startAuto, slider.settings.autoDelay); + // if autoDelay was not supplied, start the auto show normally + } else { + el.startAuto(); + + //add focus and blur events to ensure its running if timeout gets paused + $(window).focus(windowFocusHandler).blur(windowBlurHandler); + } + // if autoHover is requested + if (slider.settings.autoHover) { + // on el hover + el.hover(function() { + // if the auto show is currently playing (has an active interval) + if (slider.interval) { + // stop the auto show and pass true argument which will prevent control update + el.stopAuto(true); + // create a new autoPaused value which will be used by the relative "mouseout" event + slider.autoPaused = true; + } + }, function() { + // if the autoPaused value was created be the prior "mouseover" event + if (slider.autoPaused) { + // start the auto show and pass true argument which will prevent control update + el.startAuto(true); + // reset the autoPaused value + slider.autoPaused = null; + } + }); + } + }; + + /** + * Initializes the ticker process + */ + var initTicker = function() { + var startPosition = 0, + position, transform, value, idx, ratio, property, newSpeed, totalDimens; + // if autoDirection is "next", append a clone of the entire slider + if (slider.settings.autoDirection === 'next') { + el.append(slider.children.clone().addClass('bx-clone')); + // if autoDirection is "prev", prepend a clone of the entire slider, and set the left position + } else { + el.prepend(slider.children.clone().addClass('bx-clone')); + position = slider.children.first().position(); + startPosition = slider.settings.mode === 'horizontal' ? -position.left : -position.top; + } + setPositionProperty(startPosition, 'reset', 0); + // do not allow controls in ticker mode + slider.settings.pager = false; + slider.settings.controls = false; + slider.settings.autoControls = false; + // if autoHover is requested + if (slider.settings.tickerHover) { + if (slider.usingCSS) { + idx = slider.settings.mode === 'horizontal' ? 4 : 5; + slider.viewport.hover(function() { + transform = el.css('-' + slider.cssPrefix + '-transform'); + value = parseFloat(transform.split(',')[idx]); + setPositionProperty(value, 'reset', 0); + }, function() { + totalDimens = 0; + slider.children.each(function(index) { + totalDimens += slider.settings.mode === 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true); + }); + // calculate the speed ratio (used to determine the new speed to finish the paused animation) + ratio = slider.settings.speed / totalDimens; + // determine which property to use + property = slider.settings.mode === 'horizontal' ? 'left' : 'top'; + // calculate the new speed + newSpeed = ratio * (totalDimens - (Math.abs(parseInt(value)))); + tickerLoop(newSpeed); + }); + } else { + // on el hover + slider.viewport.hover(function() { + el.stop(); + }, function() { + // calculate the total width of children (used to calculate the speed ratio) + totalDimens = 0; + slider.children.each(function(index) { + totalDimens += slider.settings.mode === 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true); + }); + // calculate the speed ratio (used to determine the new speed to finish the paused animation) + ratio = slider.settings.speed / totalDimens; + // determine which property to use + property = slider.settings.mode === 'horizontal' ? 'left' : 'top'; + // calculate the new speed + newSpeed = ratio * (totalDimens - (Math.abs(parseInt(el.css(property))))); + tickerLoop(newSpeed); + }); + } + } + // start the ticker loop + tickerLoop(); + }; + + /** + * Runs a continuous loop, news ticker-style + */ + var tickerLoop = function(resumeSpeed) { + var speed = resumeSpeed ? resumeSpeed : slider.settings.speed, + position = {left: 0, top: 0}, + reset = {left: 0, top: 0}, + animateProperty, resetValue, params; + + // if "next" animate left position to last child, then reset left to 0 + if (slider.settings.autoDirection === 'next') { + position = el.find('.bx-clone').first().position(); + // if "prev" animate left position to 0, then reset left to first non-clone child + } else { + reset = slider.children.first().position(); + } + animateProperty = slider.settings.mode === 'horizontal' ? -position.left : -position.top; + resetValue = slider.settings.mode === 'horizontal' ? -reset.left : -reset.top; + params = {resetValue: resetValue}; + setPositionProperty(animateProperty, 'ticker', speed, params); + }; + + /** + * Check if el is on screen + */ + var isOnScreen = function(el) { + var win = $(window), + viewport = { + top: win.scrollTop(), + left: win.scrollLeft() + }, + bounds = el.offset(); + + viewport.right = viewport.left + win.width(); + viewport.bottom = viewport.top + win.height(); + bounds.right = bounds.left + el.outerWidth(); + bounds.bottom = bounds.top + el.outerHeight(); + + return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom)); + }; + + /** + * Initializes keyboard events + */ + var keyPress = function(e) { + var activeElementTag = document.activeElement.tagName.toLowerCase(), + tagFilters = 'input|textarea', + p = new RegExp(activeElementTag,['i']), + result = p.exec(tagFilters); + + if (result == null && isOnScreen(el)) { + if (e.keyCode === 39) { + clickNextBind(e); + return false; + } else if (e.keyCode === 37) { + clickPrevBind(e); + return false; + } + } + }; + + /** + * Initializes touch events + */ + var initTouch = function() { + // initialize object to contain all touch values + slider.touch = { + start: {x: 0, y: 0}, + end: {x: 0, y: 0} + }; + slider.viewport.on('touchstart MSPointerDown pointerdown', onTouchStart); + + //for browsers that have implemented pointer events and fire a click after + //every pointerup regardless of whether pointerup is on same screen location as pointerdown or not + slider.viewport.on('click', '.bxslider a', function(e) { + if (slider.viewport.hasClass('click-disabled')) { + e.preventDefault(); + slider.viewport.removeClass('click-disabled'); + } + }); + }; + + /** + * Event handler for "touchstart" + * + * @param e (event) + * - DOM event object + */ + var onTouchStart = function(e) { + // if the target is a link allow it to click through and + // follow the URL + if ($(e.target).is('a')) { + return; + } + + // watch only for left mouse, touch contact and pen contact + // touchstart event object doesn`t have button property + if (e.type !== 'touchstart' && e.button !== 0) { + return; + } + e.preventDefault(); + //disable slider controls while user is interacting with slides to avoid slider freeze that happens on touch devices when a slide swipe happens immediately after interacting with slider controls + slider.controls.el.addClass('disabled'); + + if (slider.working) { + slider.controls.el.removeClass('disabled'); + } else { + // record the original position when touch starts + slider.touch.originalPos = el.position(); + var orig = e.originalEvent, + touchPoints = (typeof orig.changedTouches !== 'undefined') ? orig.changedTouches : [orig]; + var chromePointerEvents = typeof PointerEvent === 'function'; + if (chromePointerEvents) { + if (orig.pointerId === undefined) { + return; + } + } + // record the starting touch x, y coordinates + slider.touch.start.x = touchPoints[0].pageX; + slider.touch.start.y = touchPoints[0].pageY; + + if (slider.viewport.get(0).setPointerCapture) { + slider.pointerId = orig.pointerId; + slider.viewport.get(0).setPointerCapture(slider.pointerId); + } + // store original event data for click fixation + slider.originalClickTarget = orig.originalTarget || orig.target; + slider.originalClickButton = orig.button; + slider.originalClickButtons = orig.buttons; + slider.originalEventType = orig.type; + // at this moment we don`t know what it is click or swipe + slider.hasMove = false; + // on a "touchmove" event to the viewport + slider.viewport.on('touchmove MSPointerMove pointermove', onTouchMove); + // on a "touchend" event to the viewport + slider.viewport.on('touchend MSPointerUp pointerup', onTouchEnd); + slider.viewport.on('MSPointerCancel pointercancel', onPointerCancel); + } + }; + + /** + * Cancel Pointer for Windows Phone + * + * @param e (event) + * - DOM event object + */ + var onPointerCancel = function(e) { + e.preventDefault(); + /* onPointerCancel handler is needed to deal with situations when a touchend + doesn't fire after a touchstart (this happens on windows phones only) */ + setPositionProperty(slider.touch.originalPos.left, 'reset', 0); + + //remove handlers + slider.controls.el.removeClass('disabled'); + slider.viewport.off('MSPointerCancel pointercancel', onPointerCancel); + slider.viewport.off('touchmove MSPointerMove pointermove', onTouchMove); + slider.viewport.off('touchend MSPointerUp pointerup', onTouchEnd); + if (slider.viewport.get(0).releasePointerCapture) { + slider.viewport.get(0).releasePointerCapture(slider.pointerId); + } + }; + + /** + * Event handler for "touchmove" + * + * @param e (event) + * - DOM event object + */ + var onTouchMove = function(e) { + var orig = e.originalEvent, + touchPoints = (typeof orig.changedTouches !== 'undefined') ? orig.changedTouches : [orig], + // if scrolling on y axis, do not prevent default + xMovement = Math.abs(touchPoints[0].pageX - slider.touch.start.x), + yMovement = Math.abs(touchPoints[0].pageY - slider.touch.start.y), + value = 0, + change = 0; + // this is swipe + slider.hasMove = true; + + // x axis swipe + if ((xMovement * 3) > yMovement && slider.settings.preventDefaultSwipeX) { + e.preventDefault(); + // y axis swipe + } else if ((yMovement * 3) > xMovement && slider.settings.preventDefaultSwipeY) { + e.preventDefault(); + } + if (e.type !== 'touchmove') { + e.preventDefault(); + } + + if (slider.settings.mode !== 'fade' && slider.settings.oneToOneTouch) { + // if horizontal, drag along x axis + if (slider.settings.mode === 'horizontal') { + change = touchPoints[0].pageX - slider.touch.start.x; + value = slider.touch.originalPos.left + change; + // if vertical, drag along y axis + } else { + change = touchPoints[0].pageY - slider.touch.start.y; + value = slider.touch.originalPos.top + change; + } + setPositionProperty(value, 'reset', 0); + } + }; + + /** + * Event handler for "touchend" + * + * @param e (event) + * - DOM event object + */ + var onTouchEnd = function(e) { + e.preventDefault(); + slider.viewport.off('touchmove MSPointerMove pointermove', onTouchMove); + //enable slider controls as soon as user stops interacing with slides + slider.controls.el.removeClass('disabled'); + var orig = e.originalEvent, + touchPoints = (typeof orig.changedTouches !== 'undefined') ? orig.changedTouches : [orig], + value = 0, + distance = 0; + // record end x, y positions + slider.touch.end.x = touchPoints[0].pageX; + slider.touch.end.y = touchPoints[0].pageY; + // if fade mode, check if absolute x distance clears the threshold + if (slider.settings.mode === 'fade') { + distance = Math.abs(slider.touch.start.x - slider.touch.end.x); + if (distance >= slider.settings.swipeThreshold) { + if (slider.touch.start.x > slider.touch.end.x) { + el.goToNextSlide(); + } else { + el.goToPrevSlide(); + } + el.stopAuto(); + } + // not fade mode + } else { + // calculate distance and el's animate property + if (slider.settings.mode === 'horizontal') { + distance = slider.touch.end.x - slider.touch.start.x; + value = slider.touch.originalPos.left; + } else { + distance = slider.touch.end.y - slider.touch.start.y; + value = slider.touch.originalPos.top; + } + // if not infinite loop and first / last slide, do not attempt a slide transition + if (!slider.settings.infiniteLoop && ((slider.active.index === 0 && distance > 0) || (slider.active.last && distance < 0))) { + setPositionProperty(value, 'reset', 200); + } else { + // check if distance clears threshold + if (Math.abs(distance) >= slider.settings.swipeThreshold) { + if (distance < 0) { + el.goToNextSlide(); + } else { + el.goToPrevSlide(); + } + el.stopAuto(); + } else { + // el.animate(property, 200); + setPositionProperty(value, 'reset', 200); + } + } + } + slider.viewport.off('touchend MSPointerUp pointerup', onTouchEnd); + + if (slider.viewport.get(0).releasePointerCapture) { + slider.viewport.get(0).releasePointerCapture(slider.pointerId); + } + // if slider had swipe with left mouse, touch contact and pen contact + if (slider.hasMove === false && (slider.originalClickButton === 0 || slider.originalEventType === 'touchstart')) { + // trigger click event (fix for Firefox59 and PointerEvent standard compatibility) + $(slider.originalClickTarget).trigger({ + type: 'click', + button: slider.originalClickButton, + buttons: slider.originalClickButtons + }); + } + }; + + /** + * Window resize event callback + */ + var resizeWindow = function(e) { + // don't do anything if slider isn't initialized. + if (!slider.initialized) { return; } + // Delay if slider working. + if (slider.working) { + window.setTimeout(resizeWindow, 10); + } else { + // get the new window dimens (again, thank you IE) + var windowWidthNew = $(window).width(), + windowHeightNew = $(window).height(); + // make sure that it is a true window resize + // *we must check this because our dinosaur friend IE fires a window resize event when certain DOM elements + // are resized. Can you just die already?* + if (windowWidth !== windowWidthNew || windowHeight !== windowHeightNew) { + // set the new window dimens + windowWidth = windowWidthNew; + windowHeight = windowHeightNew; + // update all dynamic elements + el.redrawSlider(); + // Call user resize handler + slider.settings.onSliderResize.call(el, slider.active.index); + } + } + }; + + /** + * Adds an aria-hidden=true attribute to each element + * + * @param startVisibleIndex (int) + * - the first visible element's index + */ + var applyAriaHiddenAttributes = function(startVisibleIndex) { + var numberOfSlidesShowing = getNumberSlidesShowing(); + // only apply attributes if the setting is enabled and not in ticker mode + if (slider.settings.ariaHidden && !slider.settings.ticker) { + // add aria-hidden=true to all elements + slider.children.attr('aria-hidden', 'true'); + // get the visible elements and change to aria-hidden=false + slider.children.slice(startVisibleIndex, startVisibleIndex + numberOfSlidesShowing).attr('aria-hidden', 'false'); + } + }; + + /** + * Returns index according to present page range + * + * @param slideOndex (int) + * - the desired slide index + */ + var setSlideIndex = function(slideIndex) { + if (slideIndex < 0) { + if (slider.settings.infiniteLoop) { + return getPagerQty() - 1; + }else { + //we don't go to undefined slides + return slider.active.index; + } + // if slideIndex is greater than children length, set active index to 0 (this happens during infinite loop) + } else if (slideIndex >= getPagerQty()) { + if (slider.settings.infiniteLoop) { + return 0; + } else { + //we don't move to undefined pages + return slider.active.index; + } + // set active index to requested slide + } else { + return slideIndex; + } + }; + + /** + * =================================================================================== + * = PUBLIC FUNCTIONS + * =================================================================================== + */ + + /** + * Performs slide transition to the specified slide + * + * @param slideIndex (int) + * - the destination slide's index (zero-based) + * + * @param direction (string) + * - INTERNAL USE ONLY - the direction of travel ("prev" / "next") + */ + el.goToSlide = function(slideIndex, direction) { + // onSlideBefore, onSlideNext, onSlidePrev callbacks + // Allow transition canceling based on returned value + var performTransition = true, + moveBy = 0, + position = {left: 0, top: 0}, + lastChild = null, + lastShowingIndex, eq, value, requestEl; + // store the old index + slider.oldIndex = slider.active.index; + //set new index + slider.active.index = setSlideIndex(slideIndex); + + // if plugin is currently in motion, ignore request + if (slider.working || slider.active.index === slider.oldIndex) { return; } + // declare that plugin is in motion + slider.working = true; + + performTransition = slider.settings.onSlideBefore.call(el, slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index); + + // If transitions canceled, reset and return + if (typeof (performTransition) !== 'undefined' && !performTransition) { + slider.active.index = slider.oldIndex; // restore old index + slider.working = false; // is not in motion + return; + } + + if (direction === 'next') { + // Prevent canceling in future functions or lack there-of from negating previous commands to cancel + if (!slider.settings.onSlideNext.call(el, slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index)) { + performTransition = false; + } + } else if (direction === 'prev') { + // Prevent canceling in future functions or lack there-of from negating previous commands to cancel + if (!slider.settings.onSlidePrev.call(el, slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index)) { + performTransition = false; + } + } + + // check if last slide + slider.active.last = slider.active.index >= getPagerQty() - 1; + // update the pager with active class + if (slider.settings.pager || slider.settings.pagerCustom) { updatePagerActive(slider.active.index); } + // // check for direction control update + if (slider.settings.controls) { updateDirectionControls(); } + // if slider is set to mode: "fade" + if (slider.settings.mode === 'fade') { + // if adaptiveHeight is true and next height is different from current height, animate to the new height + if (slider.settings.adaptiveHeight && slider.viewport.height() !== getViewportHeight()) { + slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed); + } + // fade out the visible child and reset its z-index value + slider.children.filter(':visible').fadeOut(slider.settings.speed).css({zIndex: 0}); + // fade in the newly requested slide + slider.children.eq(slider.active.index).css('zIndex', slider.settings.slideZIndex + 1).fadeIn(slider.settings.speed, function() { + $(this).css('zIndex', slider.settings.slideZIndex); + updateAfterSlideTransition(); + }); + // slider mode is not "fade" + } else { + // if adaptiveHeight is true and next height is different from current height, animate to the new height + if (slider.settings.adaptiveHeight && slider.viewport.height() !== getViewportHeight()) { + slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed); + } + // if carousel and not infinite loop + if (!slider.settings.infiniteLoop && slider.carousel && slider.active.last) { + if (slider.settings.mode === 'horizontal') { + // get the last child position + lastChild = slider.children.eq(slider.children.length - 1); + position = lastChild.position(); + // calculate the position of the last slide + moveBy = slider.viewport.width() - lastChild.outerWidth(); + } else { + // get last showing index position + lastShowingIndex = slider.children.length - slider.settings.minSlides; + position = slider.children.eq(lastShowingIndex).position(); + } + // horizontal carousel, going previous while on first slide (infiniteLoop mode) + } else if (slider.carousel && slider.active.last && direction === 'prev') { + // get the last child position + eq = slider.settings.moveSlides === 1 ? slider.settings.maxSlides - getMoveBy() : ((getPagerQty() - 1) * getMoveBy()) - (slider.children.length - slider.settings.maxSlides); + lastChild = el.children('.bx-clone').eq(eq); + position = lastChild.position(); + // if infinite loop and "Next" is clicked on the last slide + } else if (direction === 'next' && slider.active.index === 0) { + // get the last clone position + position = el.find('> .bx-clone').eq(slider.settings.maxSlides).position(); + slider.active.last = false; + // normal non-zero requests + } else if (slideIndex >= 0) { + //parseInt is applied to allow floats for slides/page + requestEl = slideIndex * parseInt(getMoveBy()); + position = slider.children.eq(requestEl).position(); + } + + /* If the position doesn't exist + * (e.g. if you destroy the slider on a next click), + * it doesn't throw an error. + */ + if (typeof (position) !== 'undefined') { + value = slider.settings.mode === 'horizontal' ? -(position.left - moveBy) : -position.top; + // plugin values to be animated + setPositionProperty(value, 'slide', slider.settings.speed); + } + slider.working = false; + } + if (slider.settings.ariaHidden) { applyAriaHiddenAttributes(slider.active.index * getMoveBy()); } + }; + + /** + * Transitions to the next slide in the show + */ + el.goToNextSlide = function() { + // if infiniteLoop is false and last page is showing, disregard call + if (!slider.settings.infiniteLoop && slider.active.last) { return; } + if (slider.working === true){ return ;} + var pagerIndex = parseInt(slider.active.index) + 1; + el.goToSlide(pagerIndex, 'next'); + }; + + /** + * Transitions to the prev slide in the show + */ + el.goToPrevSlide = function() { + // if infiniteLoop is false and last page is showing, disregard call + if (!slider.settings.infiniteLoop && slider.active.index === 0) { return; } + if (slider.working === true){ return ;} + var pagerIndex = parseInt(slider.active.index) - 1; + el.goToSlide(pagerIndex, 'prev'); + }; + + /** + * Starts the auto show + * + * @param preventControlUpdate (boolean) + * - if true, auto controls state will not be updated + */ + el.startAuto = function(preventControlUpdate) { + // if an interval already exists, disregard call + if (slider.interval) { return; } + // create an interval + slider.interval = setInterval(function() { + if (slider.settings.autoDirection === 'next') { + el.goToNextSlide(); + } else { + el.goToPrevSlide(); + } + }, slider.settings.pause); + //allback for when the auto rotate status changes + slider.settings.onAutoChange.call(el, true); + // if auto controls are displayed and preventControlUpdate is not true + if (slider.settings.autoControls && preventControlUpdate !== true) { updateAutoControls('stop'); } + }; + + /** + * Stops the auto show + * + * @param preventControlUpdate (boolean) + * - if true, auto controls state will not be updated + */ + el.stopAuto = function(preventControlUpdate) { + // if slider is auto paused, just clear that state + if (slider.autoPaused) slider.autoPaused = false; + // if no interval exists, disregard call + if (!slider.interval) { return; } + // clear the interval + clearInterval(slider.interval); + slider.interval = null; + //allback for when the auto rotate status changes + slider.settings.onAutoChange.call(el, false); + // if auto controls are displayed and preventControlUpdate is not true + if (slider.settings.autoControls && preventControlUpdate !== true) { updateAutoControls('start'); } + }; + + /** + * Returns current slide index (zero-based) + */ + el.getCurrentSlide = function() { + return slider.active.index; + }; + + /** + * Returns current slide element + */ + el.getCurrentSlideElement = function() { + return slider.children.eq(slider.active.index); + }; + + /** + * Returns a slide element + * @param index (int) + * - The index (zero-based) of the element you want returned. + */ + el.getSlideElement = function(index) { + return slider.children.eq(index); + }; + + /** + * Returns number of slides in show + */ + el.getSlideCount = function() { + return slider.children.length; + }; + + /** + * Return slider.working variable + */ + el.isWorking = function() { + return slider.working; + }; + + /** + * Update all dynamic slider elements + */ + el.redrawSlider = function() { + // resize all children in ratio to new screen size + slider.children.add(el.find('.bx-clone')).outerWidth(getSlideWidth()); + // adjust the height + slider.viewport.css('height', getViewportHeight()); + // update the slide position + if (!slider.settings.ticker) { setSlidePosition(); } + // if active.last was true before the screen resize, we want + // to keep it last no matter what screen size we end on + if (slider.active.last) { slider.active.index = getPagerQty() - 1; } + // if the active index (page) no longer exists due to the resize, simply set the index as last + if (slider.active.index >= getPagerQty()) { slider.active.last = true; } + // if a pager is being displayed and a custom pager is not being used, update it + if (slider.settings.pager && !slider.settings.pagerCustom) { + populatePager(); + updatePagerActive(slider.active.index); + } + if (slider.settings.ariaHidden) { applyAriaHiddenAttributes(slider.active.index * getMoveBy()); } + }; + + /** + * Destroy the current instance of the slider (revert everything back to original state) + */ + el.destroySlider = function() { + // don't do anything if slider has already been destroyed + if (!slider.initialized) { return; } + slider.initialized = false; + $('.bx-clone', this).remove(); + slider.children.each(function() { + if ($(this).data('origStyle') !== undefined) { + $(this).attr('style', $(this).data('origStyle')); + } else { + $(this).removeAttr('style'); + } + }); + if ($(this).data('origStyle') !== undefined) { + this.attr('style', $(this).data('origStyle')); + } else { + $(this).removeAttr('style'); + } + $(this).unwrap().unwrap(); + if (slider.controls.el) { slider.controls.el.remove(); } + if (slider.controls.next) { slider.controls.next.remove(); } + if (slider.controls.prev) { slider.controls.prev.remove(); } + if (slider.pagerEl && slider.settings.controls && !slider.settings.pagerCustom) { slider.pagerEl.remove(); } + $('.bx-caption', this).remove(); + if (slider.controls.autoEl) { slider.controls.autoEl.remove(); } + clearInterval(slider.interval); + if (slider.settings.responsive) { $(window).off('resize', resizeWindow); } + if (slider.settings.keyboardEnabled) { $(document).off('keydown', keyPress); } + //remove self reference in data + $(this).removeData('bxSlider'); + // remove global window handlers + $(window).off('blur', windowBlurHandler).off('focus', windowFocusHandler); + }; + + /** + * Reload the slider (revert all DOM changes, and re-initialize) + */ + el.reloadSlider = function(settings) { + if (settings !== undefined) { options = settings; } + el.destroySlider(); + init(); + //store reference to self in order to access public functions later + $(el).data('bxSlider', this); + }; + + init(); + + $(el).data('bxSlider', this); + + // returns the current jQuery object + return this; + }; + +})(jQuery); diff --git a/src/vendor/jquery.easing.1.3.js b/src/vendor/jquery.easing.1.3.js new file mode 100644 index 00000000..ef743210 --- /dev/null +++ b/src/vendor/jquery.easing.1.3.js @@ -0,0 +1,205 @@ +/* + * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ + * + * Uses the built in easing capabilities added In jQuery 1.1 + * to offer multiple easing options + * + * TERMS OF USE - jQuery Easing + * + * Open source under the BSD License. + * + * Copyright © 2008 George McGinley Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +// t: current time, b: begInnIng value, c: change In value, d: duration +jQuery.easing['jswing'] = jQuery.easing['swing']; + +jQuery.extend( jQuery.easing, +{ + def: 'easeOutQuad', + swing: function (x, t, b, c, d) { + //alert(jQuery.easing.default); + return jQuery.easing[jQuery.easing.def](x, t, b, c, d); + }, + easeInQuad: function (x, t, b, c, d) { + return c*(t/=d)*t + b; + }, + easeOutQuad: function (x, t, b, c, d) { + return -c *(t/=d)*(t-2) + b; + }, + easeInOutQuad: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t + b; + return -c/2 * ((--t)*(t-2) - 1) + b; + }, + easeInCubic: function (x, t, b, c, d) { + return c*(t/=d)*t*t + b; + }, + easeOutCubic: function (x, t, b, c, d) { + return c*((t=t/d-1)*t*t + 1) + b; + }, + 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; + }, + easeInQuart: function (x, t, b, c, d) { + return c*(t/=d)*t*t*t + b; + }, + easeOutQuart: function (x, t, b, c, d) { + return -c * ((t=t/d-1)*t*t*t - 1) + b; + }, + easeInOutQuart: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t*t*t + b; + return -c/2 * ((t-=2)*t*t*t - 2) + b; + }, + easeInQuint: function (x, t, b, c, d) { + return c*(t/=d)*t*t*t*t + b; + }, + easeOutQuint: function (x, t, b, c, d) { + return c*((t=t/d-1)*t*t*t*t + 1) + b; + }, + easeInOutQuint: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; + return c/2*((t-=2)*t*t*t*t + 2) + b; + }, + easeInSine: function (x, t, b, c, d) { + return -c * Math.cos(t/d * (Math.PI/2)) + c + b; + }, + easeOutSine: function (x, t, b, c, d) { + return c * Math.sin(t/d * (Math.PI/2)) + b; + }, + easeInOutSine: function (x, t, b, c, d) { + return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; + }, + easeInExpo: function (x, t, b, c, d) { + return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; + }, + easeOutExpo: function (x, t, b, c, d) { + return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; + }, + easeInOutExpo: function (x, t, b, c, d) { + if (t==0) return b; + if (t==d) return b+c; + if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; + return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; + }, + easeInCirc: function (x, t, b, c, d) { + return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; + }, + easeOutCirc: function (x, t, b, c, d) { + return c * Math.sqrt(1 - (t=t/d-1)*t) + b; + }, + easeInOutCirc: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; + return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; + }, + easeInElastic: function (x, t, b, c, d) { + var s=1.70158;var p=0;var a=c; + if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; + if (a < Math.abs(c)) { a=c; var s=p/4; } + else var s = p/(2*Math.PI) * Math.asin (c/a); + return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; + }, + easeOutElastic: function (x, t, b, c, d) { + var s=1.70158;var p=0;var a=c; + if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; + if (a < Math.abs(c)) { a=c; var s=p/4; } + else var s = p/(2*Math.PI) * Math.asin (c/a); + return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; + }, + easeInOutElastic: function (x, t, b, c, d) { + var s=1.70158;var p=0;var a=c; + if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); + if (a < Math.abs(c)) { a=c; var s=p/4; } + else var s = p/(2*Math.PI) * Math.asin (c/a); + if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; + return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; + }, + easeInBack: function (x, t, b, c, d, s) { + if (s == undefined) s = 1.70158; + return c*(t/=d)*t*((s+1)*t - s) + b; + }, + easeOutBack: function (x, t, b, c, d, s) { + if (s == undefined) s = 1.70158; + return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; + }, + easeInOutBack: function (x, t, b, c, d, s) { + if (s == undefined) s = 1.70158; + if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; + return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; + }, + easeInBounce: function (x, t, b, c, d) { + return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b; + }, + easeOutBounce: function (x, t, b, c, d) { + if ((t/=d) < (1/2.75)) { + return c*(7.5625*t*t) + b; + } else if (t < (2/2.75)) { + return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; + } else if (t < (2.5/2.75)) { + return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; + } else { + return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; + } + }, + easeInOutBounce: function (x, t, b, c, d) { + if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; + return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; + } +}); + +/* + * + * TERMS OF USE - EASING EQUATIONS + * + * Open source under the BSD License. + * + * Copyright © 2001 Robert Penner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ \ No newline at end of file diff --git a/src/vendor/jquery.fitvids.js b/src/vendor/jquery.fitvids.js new file mode 100644 index 00000000..d464f93f --- /dev/null +++ b/src/vendor/jquery.fitvids.js @@ -0,0 +1,80 @@ +/*global jQuery */ +/*jshint multistr:true browser:true */ +/*! +* FitVids 1.0 +* +* Copyright 2011, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com +* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/ +* Released under the WTFPL license - http://sam.zoy.org/wtfpl/ +* +* Date: Thu Sept 01 18:00:00 2011 -0500 +*/ + +(function( $ ){ + + "use strict"; + + $.fn.fitVids = function( options ) { + var settings = { + customSelector: null + }; + + var div = document.createElement('div'), + ref = document.getElementsByTagName('base')[0] || document.getElementsByTagName('script')[0]; + + div.className = 'fit-vids-style'; + div.innerHTML = '­'; + + ref.parentNode.insertBefore(div,ref); + + if ( options ) { + $.extend( settings, options ); + } + + return this.each(function(){ + var selectors = [ + "iframe[src*='player.vimeo.com']", + "iframe[src*='www.youtube.com']", + "iframe[src*='www.kickstarter.com']", + "object", + "embed" + ]; + + if (settings.customSelector) { + selectors.push(settings.customSelector); + } + + var $allVideos = $(this).find(selectors.join(',')); + + $allVideos.each(function(){ + var $this = $(this); + if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; } + var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(), + width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(), + aspectRatio = height / width; + if(!$this.attr('id')){ + var videoID = 'fitvid' + Math.floor(Math.random()*999999); + $this.attr('id', videoID); + } + $this.wrap('
            ').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+"%"); + $this.removeAttr('height').removeAttr('width'); + }); + }); + }; +})( jQuery );