diff --git a/.gitignore b/.gitignore
index 207ff55..3fc0a6e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,4 @@
-.DS_Store
node_modules/
-localConfig.json
-build/bellows.zip
-build/bellows-style.css
-build/bellows.css
-build/bellows.js
+bower_components/
+.DS_Store
+/.sass-cache/
diff --git a/Gruntfile.js b/Gruntfile.js
index cceb06a..4145392 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,110 +1,55 @@
+'use strict'
+
+var path = require('path');
+
module.exports = function(grunt) {
+ var _ = grunt.util._;
+
+ // By default, we load all local tasks from the tasks directory.
+ grunt.file.expand('tasks/*').forEach(function(task) {
+ grunt.loadTasks(task);
+ });
+
+ // Populate the config object
+ var config = {};
+ grunt.file.expand('tasks/config/*').forEach(function(configPath) {
+ // Get the grunt-task name to put in the config which is based on the
+ // name of the config file
+ var configName = configPath.match(/\/([^\/]*)\.js/)[1];
+ var option = require(path.join(__dirname + '/' + configPath))(grunt);
+ config[configName] = _.extend(config[configName] || {}, option);
+ });
- // Project configuration.
- grunt.initConfig({
+ grunt.initConfig(_.extend({
pkg: grunt.file.readJSON('package.json'),
- localConfig: (function(){
- try {
- return grunt.file.readJSON('localConfig.json')
- } catch(e) {
- return {};
- }
- })(),
releaseName: '<%= pkg.name %>-<%= pkg.version %>',
- releaseMessage: '<%= pkg.name %> release <%= pkg.version %>',
- clean: {
- buildProducts: "build/"
- },
- connect: {
- server: {
- options: {
- hostname: '0.0.0.0',
- port: 3000,
- base: '.'
- }
- }
- },
- watch: {
- files: ["src/**/*"],
- tasks: ['build']
- },
- copy: {
- main: {
- files: [
- {expand: true, flatten: true, src: ['src/**'], dest: 'build/', filter: 'isFile'}
- ]
- }
- },
- uglify: {
- options: {
- banner: '/*! <%= pkg.name %> <%= pkg.version %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
- },
- build: {
- src: 'src/bellows.js',
- dest: 'build/bellows.min.js'
- }
- },
- cssmin: {
- core: {
- src: 'src/bellows.css',
- dest: 'build/bellows.min.css'
- },
- style: {
- src: 'src/bellows-style.css',
- dest: 'build/bellows-style.min.css'
- }
- },
- zip: {
- "build/bellows.zip": ["src/bellows.js", "src/bellows.css",
- "src/bellows-style.css"]
- },
- s3: {
- key: '<%= localConfig.aws.key %>',
- secret: '<%= localConfig.aws.secret %>',
- bucket: '<%= localConfig.aws.bucket %>',
- access: "public-read",
- headers: { "Cache-Control": "max-age=1200" },
- upload: [
- { // build
- src: "build/*",
- dest: "modules/bellows/<%= pkg.version %>/",
- rel: "build"
- }
- ]
- },
- release: {
- options: {
- folder: '.',
- npm: false,
- bump: false,
- add: false,
- commit: false,
- file: 'bower.json',
- github: {
- repo: 'mobify/bellows',
- usernameVar: 'GITHUB_USERNAME',
- passwordVar: 'GITHUB_TOKEN'
- }
- }
- }
- });
+ releaseMessage: '<%= pkg.name %> release <%= pkg.version %>'
+ }, config));
- // Load the task plugins
- grunt.loadNpmTasks('grunt-contrib-uglify');
- grunt.loadNpmTasks('grunt-contrib-watch');
- grunt.loadNpmTasks('grunt-contrib-connect');
- grunt.loadNpmTasks('grunt-css');
- grunt.loadNpmTasks('grunt-shell');
- grunt.loadNpmTasks('grunt-zip');
- grunt.loadNpmTasks('grunt-s3');
- grunt.loadNpmTasks('grunt-clean');
- grunt.loadNpmTasks('grunt-contrib-copy');
- grunt.loadNpmTasks('grunt-release');
+ // load npm tasks
+ var npmTasks = [
+ 'grunt-contrib-uglify',
+ 'grunt-contrib-watch',
+ 'grunt-contrib-connect',
+ 'grunt-css',
+ 'grunt-shell',
+ 'grunt-contrib-clean',
+ 'grunt-contrib-copy',
+ 'grunt-autoprefixer',
+ 'grunt-contrib-sass',
+ 'grunt-mocha-phantomjs'
+ ];
- // Default task(s).
- grunt.registerTask('serve', ['connect', 'watch']);
- grunt.registerTask('build', ['copy', 'uglify', 'cssmin', 'zip']);
- grunt.registerTask('publish', ['build', 'release', 's3'])
- grunt.registerTask('default', 'build');
+ npmTasks.forEach(function(taskName) {
+ if (!grunt.task._tasks[taskName]) {
+ grunt.loadNpmTasks(taskName);
+ }
+ });
+ grunt.registerTask('serve', ['build-dist', 'connect:server', 'watch']);
+ grunt.registerTask('build-dist', ['copy', 'uglify', 'sass', 'autoprefixer', 'cssmin']);
+ grunt.registerTask('release', ['test', 'shell:tagRelease']);
+ grunt.registerTask('test', ['build-dist', 'connect:test', 'mocha_phantomjs']);
+ grunt.registerTask('test:browser', ['build-dist', 'connect:test:keepalive']);
+ grunt.registerTask('default', 'build-dist');
};
diff --git a/LICENSE b/LICENSE
index 0f37219..648b279 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2013 Mobify Research & Development Inc.
+Copyright (c) 2014 Mobify Research & Development Inc.
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
diff --git a/README.md b/README.md
index ae89efa..a21ca1b 100644
--- a/README.md
+++ b/README.md
@@ -1,200 +1,298 @@
# Mobify Bellows
-A responsive, mobile-first accordion UI module for progressive disclosure on the web.
+A mobile-first accordion UI module for progressive disclosure on the web.
-## Docs
+## Documentation
-You can find docs and examples here: http://mobify.github.io/bellows.
+You can find full documentation and examples here: http://mobify.github.io/bellows.
-Checkout the `gh-pages` branch to make changes to the docs.
+## Requirements
+
+* [Zepto](http://zeptojs.com/)
+* [Velocity.js](http://velocityjs.org)
+
+### Velocity Shim
+
+If you are using Zepto you will need to include the velocity shim **before** velocity. If Velocity.js ever stops requiring jQuery, we will be able to stop using this shim.
+
+### jQuery Support
+
+Bellows supports jQuery but is not actively developed for it. You should be able to use Bellows directly with jQuery 2.0 and simply drop the Velocity.js shim in those cases. While we don't actively support jQuery for Bellows, we welcome any and all issues and PRs to help us make it work.
+
+
+## Installation
+
+Bellows can be installed using bower:
+
+```
+bower install bellows
+```
## Usage
-
-
-
-
-
-
-
-
-
-
-
-
-
Content 1
- Lorem Ipsum
-
+At a bare minimum, your markup structure should follow the above structure. You should have at least one `bellows__item`. Content within `bellows__header` and `bellows__content` can be whatever you want. You may also style either of those however you need. Our default theme will give you some standard styling for those sections but, if you want to theme Bellows yourself, we recommend not including the theme file and starting from scratch.
+
+```html
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
Content 2
-
Lorem Ipsum
-
+
+
-
-
-
-
-
-
Content 3
-
Lorem Ipsum
-
+
+
+
+
-
-
-
-
-
-
+
+
+
-## Methods
+
+
+
+
+
+```
+
+## Initializing the plugin
### bellows()
Initializes the bellows.
- $('.m-bellows').bellows();
+```js
+$('.bellows').bellows();
+```
### bellows(options)
Initialize with options.
- $('.m-bellows').bellows({
- {
- ...
- options (refer below)
- ...
- }
- });
+```js
+$('.bellows').bellows({
+ singleItemOpen: false,
+ duration: 200,
+ easing: 'swing',
+ open: function(e, ui) {},
+ opened: function(e, ui) {},
+ close: function(e, ui) {},
+ closed: function(e, ui) {}
+});
+```
-### Storing bellows object for future use
+#### Options
- var $bellows = $(".m-bellows"); // A Zepto element array is returned
- var bellows = $bellows[0].bellows; // We access the appropriate bellows from the above array
+##### singleItemOpen
-### unbind()
+default: `false`
-Removes any tap, mouse, and other event handlers from the bellows.
+When set to `true` will force only one item open at a time.
- bellows.unbind();
+```js
+$('.bellows').bellows({
+ singleItemOpen: true
+});
+```
-### bind()
+##### duration
-Restores the tap, mouse, and other event handlers for the bellows.
+default: `200`
- bellows.bind();
+Sets the duration for the animation.
-### destroy()
+```js
+$('.bellows').bellows({
+ duration: 600
+});
+```
-Unbinds the events from the bellows, and removes it from the DOM.
+##### easing
- bellows.destroy(); // destroys the DOM element and the jQuery bindings
- bellows = null; // destroys the Mobify bellows object as well
+default: `swing`
-### open($item)
+Sets the easing for the animation. Bellows takes all of the same easing properties that [Velocity.js](http://julian.com/research/velocity) accepts.
-Open the selected bellows item
+> * [jQuery UI's easings](http://easings.net/) and CSS3's easings ("ease", "ease-in", "ease-out", and "ease-in-out"), which are pre-packaged into Velocity. A bonus "spring" easing (sampled in the CSS Support pane) is also included.
+* CSS3's bezier curves: Pass in a four-item array of bezier points. (Refer to [Cubic-Bezier.com](http://cubic-bezier.com/) for crafing custom bezier curves.)
+* Spring physics: Pass a two-item array in the form of [ tension, friction ]. A higher tension (default: 600) increases total speed and bounciness. A lower friction (default: 20) increases ending vibration speed.
+* Step easing: Pass a one-item array in the form of [ steps ]. The animation will jump toward its end values using the specified number of steps.
- bellows.open($(".m-item").eq(2));
+For more information, check out [Velocity's docs on easing](http://julian.com/research/velocity/#easing).
-### close($item)
-
-Close the selected bellows item
+```js
+$('.bellows').bellows({
+ easing: 'ease-in-out'
+});
+```
+
+##### open
+
+default: `function(e, ui) {}`
+
+Triggered every time the selected bellows item is starting to open.
- bellows.close($("#some-item"));
+**Parameters**
-### recalculateItemHeight($item)
+| Parameter name | Description |
+|----------------|-------------|
+| **e** | An Event object passed to the callback |
+| **ui** | An object containing any associated data for use inside the callback |
-Recalculate the heights of bellows item elements. This is used when the heights of the content have changed after creation of the bellows.
+```js
+$('.bellows').bellows({
+ open: function(e, ui) {
+ // ui.item contains the item opening
+ }
+});
+```
- bellows.recalculateItemHeight($(".m-item"));
+##### opened
-## Class names
+default: `function(e, ui) {}`
-Set the class names for the different elements, if deviating from the defaults.
-
- $(".m-bellows").bellows({
- closedClass: 'm-closed',
- openedClass: 'm-opened',
- activeClass: 'm-active',
- contentClass: 'm-content',
- innerContentClass: 'm-inner-content',
- headerClass: 'm-header',
- itemClass: 'm-item'
- });
+Triggered every time the selected bellows item has finished opening.
-## Event hooks
+**Parameters**
-### onTransitionDone: functionName
+| Parameter name | Description |
+|----------------|-------------|
+| **e** | An Event object passed to the callback |
+| **ui** | An object containing any associated data for use inside the callback |
-Execute this function every time the selected bellows item is opened or closed.
+```js
+$('.bellows').bellows({
+ opened: function(e, ui) {
+ // ui.item contains the item that opened
+ }
+});
+```
- $(".m-bellows").bellows({
- onTransitionDone: function() { console.log("Animation done"); }
- });
+##### close
-### onOpened: functionName
+default: `function(e, ui) {}`
-Execute this function every time the selected bellows item is opened.
+Triggered every time an bellows item is starting to close.
- $(".m-bellows").bellows({
- onOpened: function() { console.log("Opened"); }
- });
+| Parameter name | Description |
+|----------------|-------------|
+| **e** | An Event object passed to the callback |
+| **ui** | An object containing any associated data for use inside the callback |
-### onClosed: functionName
+```js
+$('.bellows').bellows({
+ close: function(e, ui) {
+ // ui.item contains the item closing
+ }
+});
+```
-Execute this function every time an bellows item is closed
+##### closed
+
+default: `function(e, ui) {}`
+
+Triggered every time an bellows item is finished closing.
+
+| Parameter name | Description |
+|----------------|-------------|
+| **e** | An Event object passed to the callback |
+| **ui** | An object containing any associated data for use inside the callback |
+
+```js
+$('.bellows').bellows({
+ closed: function(e, ui) {
+ // ui.item contains the item that closed
+ }
+});
+```
+
+### Storing bellows object for future use
+
+```js
+var $bellows = $('.bellows');
+```
+
+## Methods
+
+### Open
+
+Open the selected bellows item by element reference
+
+```js
+$bellows.bellows('open', $('.bellows__item'));
+```
+
+or by index
+
+```js
+$bellows.bellows('open', 1);
+```
+
+### Close
- $(".m-bellows").bellows({
- onClosed: function() { console.log("Closed"); }
- });
+Close the selected bellows item by element reference
-## Browser Compatibility
+```js
+$bellows.bellows('close', $('.bellows__item'));
+```
+
+or by index
+```js
+$bellows.bellows('close', 1);
+```
+
+## Browser Compatibility
| Browser | Version | Support |
|-------------------|---------|----------------------------|
-| Safari | 4.0+ | Supported. |
-| Firefox | 3.5-3.6 | Degraded. No transitions. |
-| Firefox | 4.0+ | Supported |
-| Chrome | 9.0+ | Supported |
-| Opera | 12.0+ | Supported. |
-| Internet Explorer | 6-7.0 | Not Supported |
-| Internet Explorer | 8.0 | Degraded. No transitions. |
-| Internet Explorer | 9.0 | Degraded. No transitions. |
-| Internet Explorer | 10.0 | Supported |
-| Mobile Safari | 3.1.x | Degraded. No transitions |
-| Mobile Safari | 4.0+ | Supported |
-| Android Browser | 2.1+ | Supported |
-| Chrome (Android) | 1.0+ | Supported |
-| Firefox (Android) | 1.0+ | Supported |
-| Windows Phone | 7.5 | Degraded. No transitions. |
-
-## Building
+| Mobile Safari | 4.0.x | Degraded. No transitions. |
+| Mobile Safari | 5.0+ | Supported. |
+| Android Browser | 4.0+ | Supported. |
+| Android Browser | 2.3.x | Degraded. No transitions. |
+| Chrome (Android) | 1.0+ | Supported. |
+
+
+## Building a distribution
+
### Requirements
-* [node.js 0.8.x/npm](http://nodejs.org/download/)
+* [node.js 0.10.x/npm](http://nodejs.org/download/)
+* [Grunt](http://gruntjs.com/)
+ * Install with `npm install -g grunt-cli`
+* [Bower](http://bower.io/)
+ * Install with `npm install -g bower`
### Steps
-1. `npm install -g grunt-cli`
-2. `npm install`
-3. `grunt`
+1. `npm install`
+1. `bower install`
+1. `grunt build-dist`
+
+The `dist` directory will be populated with minified versions of the css and javascript files for distribution and use with whatever build system you might use. The `src` directory has our raw unminified Sass and Javascript files if you prefer to work with those.
-The build directory will be populated with minified versions of the css and
-javascript files and a .zip of the original source files (for distribution and
-use with whatever build system you might use).
+## License
+_MIT License. Bellows is Copyright © 2014 Mobify. It is free software and may be redistributed under the terms specified in the LICENSE file._
diff --git a/bower.json b/bower.json
index 0be375b..fc679e5 100644
--- a/bower.json
+++ b/bower.json
@@ -1,24 +1,26 @@
{
"name": "bellows",
- "version": "0.3.4",
+ "version": "2.0.0",
"homepage": "https://github.com/mobify/bellows",
"authors": [
"Mobify "
],
- "description": "A responsive, mobile first accordion UI module",
- "main": "build/bellows.min.js",
+ "description": "A mobile first accordion UI plugin",
+ "main": "dist/bellows.min.js",
"keywords": [
"bellows",
"accordion",
"toggle",
- "responsive",
"mobile",
"mobify"
],
"license": "MIT",
"ignore": [
- "**/.*",
- "node_modules",
- "bower_components"
- ]
+ "./!(src|dist|lib|templates)"
+ ],
+ "dependencies": {
+ "velocity": "0.11.7",
+ "requirejs-text": "~2.0.12",
+ "requirejs": "~2.1.14"
+ }
}
diff --git a/build/bellows-style.min.css b/build/bellows-style.min.css
deleted file mode 100644
index ce23be4..0000000
--- a/build/bellows-style.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.m-bello{color:#000}.m-bellows .m-header{height:54px;line-height:52px;padding:0 20px;border:solid 1px #ededed;border-width:1px 0;position:relative;cursor:pointer;z-index:5;background:#fff;background:-moz-linear-gradient(top,#fff 0,#f6f6f6 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#fff),color-stop(100%,#f6f6f6));background:-webkit-linear-gradient(top,#fff 0,#f6f6f6 100%);background:-o-linear-gradient(top,#fff 0,#f6f6f6 100%);background:-ms-linear-gradient(top,#fff 0,#f6f6f6 100%);background:linear-gradient(to bottom,#fff 0,#f6f6f6 100%)}.m-bellows .m-header:hover,.m-bellows .hm-eader:focus{z-index:2;background:#fff;background:-moz-linear-gradient(top,#fff 0,#f6f6f6 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#fff),color-stop(100%,#f6f6f6));background:-webkit-linear-gradient(top,#f6f6f6 0,#e6e6e6 100%);background:-o-linear-gradient(top,#fff 0,#f6f6f6 100%);background:-ms-linear-gradient(top,#fff 0,#f6f6f6 100%);background:linear-gradient(to bottom,#f6f6f6 0,#f0f0f0 100%);border-bottom-color:#d6d6d6}.m-bellows .m-item:first-child .m-header{-webkit-border-top-left-radius:9px;-webkit-border-top-right-radius:9px;-moz-border-radius-topleft:9px;-moz-border-radius-topright:9px;border-top-left-radius:9px;border-top-right-radius:9px}.m-bellows .m-item:last-child .m-header,.m-bellows .m-active:last-child .m-inner-content{-webkit-border-bottom-left-radius:9px;-webkit-border-bottom-right-radius:9px;-moz-border-radius-bottomleft:9px;-moz-border-radius-bottomright:9px;border-bottom-left-radius:9px;border-bottom-right-radius:9px}.m-bellows .m-active:last-child .m-header{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.m-bellows .m-header a{color:#000}.m-bellows .m-inner-content{padding:10px 20px;background:#fff}.m-bellows h2{margin:0;color:#000;text-shadow:none}.m-indicators-images .m-header:after{content:"";display:block;position:absolute;top:50%;right:10px;margin-top:-11px;z-index:4;width:22px;height:22px;background:url(../img/bellows.png) 0 -20px no-repeat}.m-indicators-images .m-active .m-header:after{background-position:0 -43px}@media only screen and (-moz-min-device-pixel-ratio:1.5),only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-devicepixel-ratio:1.5),only screen and (min-resolution:1.5dppx){.m-indicators-images .m-header:after{background-position:-11px 0;background-size:33px 43px}.m-indicators-images .m-active .m-header:after{background-position:-11px -22px}}.m-arrows .m-active .m-header:after{top:100%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none;border-top-color:#f6f6f6;border-width:20px;left:50%;margin-left:-20px;z-index:9}.m-arrows .m-active .m-header:hover:after{border-top-color:#e6e6e6}.m-indicators-css .m-header:after{content:"+";color:#999;text-shadow:#fff 0 1px 0;display:block;position:absolute;top:50%;right:15px;margin-top:-13px;z-index:9;font-size:26px;line-height:22px;font-weight:700}.m-indicators-css .m-active .m-header:after{content:"\2212"}.m-css-advanced .m-header:after{color:rgba(255,255,255,.9);font-weight:400;text-align:center;text-shadow:none;background:#c5c5c5;background:-moz-linear-gradient(top,#c5c5c5 0,#acacac 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#c5c5c5),color-stop(100%,#acacac));background:-webkit-linear-gradient(top,#c5c5c5 0,#acacac 100%);background:-o-linear-gradient(top,#c5c5c5 0,#acacac 100%);background:-ms-linear-gradient(top,#c5c5c5 0,#acacac 100%);background:linear-gradient(to bottom,#c5c5c5 0,#acacac 100%);font-size:22px;line-height:16px;width:20px;height:20px;margin-top:-10px;-webkit-border-radius:25px;-moz-border-radius:25px;border-radius:25px;-webkit-box-shadow:#fff 0 1px 0;-moz-box-shadow:#fff 0 1px 0;box-shadow:#fff 0 1px 0}.m-css-advanced .m-header:hover:after{color:#fff;background:#b4b4b4;background:-moz-linear-gradient(top,#b4b4b4 0,#a3a3a3 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#b4b4b4),color-stop(100%,#a3a3a3));background:-webkit-linear-gradient(top,#b4b4b4 0,#a3a3a3 100%);background:-o-linear-gradient(top,#b4b4b4 0,#a3a3a3 100%);background:-ms-linear-gradient(top,#b4b4b4 0,#a3a3a3 100%);background:linear-gradient(to bottom,#b4b4b4 0,#a3a3a3 100%)}.m-css-advanced .m-active .m-header:after{background:#8a8a8a;background:-moz-linear-gradient(top,#8a8a8a 0,#a3a3a3 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#8a8a8a),color-stop(100%,#a3a3a3));background:-webkit-linear-gradient(top,#8a8a8a 0,#a3a3a3 100%);background:-o-linear-gradient(top,#8a8a8a 0,#a3a3a3 100%);background:-ms-linear-gradient(top,#8a8a8a 0,#a3a3a3 100%);background:linear-gradient(to bottom,#8a8a8a 0,#a3a3a3 100%);-webkit-box-shadow:#fff 0 -1px 0;-moz-box-shadow:#fff 0 -1px 0;box-shadow:#fff 0 -1px 0}
\ No newline at end of file
diff --git a/build/bellows.min.css b/build/bellows.min.css
deleted file mode 100644
index 9bb422f..0000000
--- a/build/bellows.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.m-bellows{list-style:none}.m-bellows li{list-style:none;margin:0}.m-bellows .m-content{-webkit-transition:max-height .5s ease;-moz-transition:max-height .5s ease;-o-transition:max-height .5s ease;transition:max-height .5s ease;overflow:hidden;max-height:0}.m-bellows .m-active>.m-content{max-height:10000px}.m-bellows .m-header{z-index:1;position:relative;margin-top:-1px;pointer-events:cursor}.m-bellows h3{margin:0}.m-bellows .m-header>a{pointer-events:none}
\ No newline at end of file
diff --git a/build/bellows.min.js b/build/bellows.min.js
deleted file mode 100644
index 6424ca8..0000000
--- a/build/bellows.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! bellows 0.3.4 2014-04-10 */
-var Mobify=window.Mobify=window.Mobify||{};Mobify.$=Mobify.$||window.Zepto||window.jQuery,Mobify.UI=Mobify.UI||{},function(n,e){n.support=n.support||{},n.extend(n.support,{touch:"ontouchend"in e})}(Mobify.$,document),Mobify.UI.Utils=function(n){function e(){if(/iPhone\ OS\ 3_1/.test(navigator.userAgent))return void 0;var n,e=document.createElement("fakeelement"),t={transition:"transitionEnd transitionend",OTransition:"oTransitionEnd",MSTransition:"msTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(n in t)if(void 0!==e.style[n])return t[n]}var t={},o=n.support;return t.events=o.touch?{down:"touchstart",move:"touchmove",up:"touchend"}:{down:"mousedown",move:"mousemove",up:"mouseup"},t.getCursorPosition=o.touch?function(n){return n=n.originalEvent||n,{x:n.touches[0].clientX,y:n.touches[0].clientY}}:function(n){return{x:n.clientX,y:n.clientY}},t.getProperty=function(n){for(var e=["Webkit","Moz","O","ms",""],t=document.createElement("div").style,o=0;e.length>o;++o)if(void 0!==t[e[o]+n])return e[o]+n},n.extend(t.events,{transitionend:e()}),t}(Mobify.$),Mobify.UI.Bellows=function(n,e){n.support;var t=function(e,t){return this.settings=n.extend({dragRadius:10,closedClass:"m-closed",openedClass:"m-opened",activeClass:"m-active",contentClass:"m-content",innerContentClass:"m-inner-content",headerClass:"m-header",itemClass:"m-item",moduleClass:"m-bellows",onTransitionDone:null,onOpened:null,onClosed:null},t||{}),this.$element=n(e),n.extend(this,this.bind()),this};return t.prototype.bind=function(){function t(){var e=n(this).parent();e.hasClass(g)&&n(this).parent().removeClass(C),s(e.hasClass(g)?"closing":"opening"),o(p)}function o(e){var t=0;e.children("."+M).each(function(){var e=n(this);t+=e.height()}),e.css("min-height",t+"px")}function i(n){var t=n.children("."+b),s=t.children(),r="outerHeight"in s?s.outerHeight():s.height();t.css("max-height",1.5*r+"px"),e.events.transitionend&&p.css("min-height",p.height()+"px"),setTimeout(function(){$currentBellows=n.closest("."+x),o($currentBellows),$parentBellows=$currentBellows.parent().closest("."+x),$parentBellows.length>0&&i(n.parent().closest("."+M))},150)}function s(n){"opening"===n&&"function"==typeof m.onOpened&&m.onOpened.apply(this,arguments),"closing"===n&&"function"==typeof m.onClosed&&m.onClosed.apply(this,arguments),"function"==typeof m.onTransitionDone&&m.onTransitionDone.apply(this,arguments)}function r(n){n.hasClass(g)&&s("closing"),n.removeClass(y),n.addClass(g),e.events.transitionend||n.removeClass(C),n.children("."+b).css("max-height","0px")}function a(n){n.hasClass(y)&&s("opening"),n.addClass(C),n.removeClass(g),n.addClass(y),i(n)}function l(n){h=e.getCursorPosition(n)}function u(n){f=e.getCursorPosition(n)}function c(){if(!(f&&(dx=h.x-f.x,dy=h.y-f.y,f=void 0,dx*dx+dy*dy>v*v))){var e=n(this).parent();e.hasClass(C)?r(e):a(e)}}function d(n){n.preventDefault()}var h,f,p=this.$element,m=this.settings,v=m.dragRadius,y=m.openedClass,g=m.closedClass,C=m.activeClass,b=m.contentClass,w=m.headerClass,M=m.itemClass,x=m.moduleClass,$=location.hash,T=p.find("."+w+' a[href="'+$+'"]');T.length?a(T.parent()):p.find("."+y).length&&a(p.find("."+y));var U=p.children("."+M).children("."+w);return U.on(e.events.down,l).on(e.events.move,u).on(e.events.up,c).on("click",d),e.events.transitionend&&p.on(e.events.transitionend,"."+b,t),{settings:m,open:a,close:r,recalculateItemHeight:i}},t.prototype.unbind=function(){this.$element.off()},t.prototype.destroy=function(){this.unbind(),this.$element.remove()},t}(Mobify.$,Mobify.UI.Utils),function(n){n.fn.bellows=function(e){return this.each(function(){var t=(n(this),this.bellows);t||(t=new Mobify.UI.Bellows(this,e)),this.bellows=t})}}(Mobify.$);
\ No newline at end of file
diff --git a/circle.yml b/circle.yml
new file mode 100644
index 0000000..abc2cfc
--- /dev/null
+++ b/circle.yml
@@ -0,0 +1,10 @@
+machine:
+ node:
+ version: 0.10.21
+
+test:
+ pre:
+ - npm install
+ - bower install
+ override:
+ - grunt test
diff --git a/dist/bellows-theme.css b/dist/bellows-theme.css
new file mode 100644
index 0000000..35a6a93
--- /dev/null
+++ b/dist/bellows-theme.css
@@ -0,0 +1,59 @@
+.bellows {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box; }
+
+.bellows__header {
+ position: relative;
+ padding: 15px 20px;
+ border: 1px solid #2980b9;
+ border-width: 0 0 1px;
+ background: #3498db;
+ color: white;
+ -webkit-tap-highlight-color: transparent; }
+ .bellows__header:active {
+ background: #2980b9; }
+ .bellows__header::before, .bellows__header::after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ right: 20px;
+ z-index: 2;
+ display: block;
+ width: 16px;
+ height: 4px;
+ margin-top: -2px;
+ background: white;
+ pointer-events: none;
+ -webkit-transition: -webkit-transform 0.25s ease-in-out;
+ transition: transform 0.25s ease-in-out; }
+ .bellows__header::before {
+ content: '';
+ -webkit-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ transform: rotate(0deg); }
+ .bellows__header::after {
+ -webkit-transform: rotate(90deg);
+ -ms-transform: rotate(90deg);
+ transform: rotate(90deg); }
+ .bellows__item.bellows--is-open > .bellows__header::before, .bellows__item.bellows--is-opening > .bellows__header::before {
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ transform: rotate(180deg); }
+ .bellows__item.bellows--is-open > .bellows__header::after, .bellows__item.bellows--is-opening > .bellows__header::after {
+ -webkit-transform: rotate(360deg);
+ -ms-transform: rotate(360deg);
+ transform: rotate(360deg); }
+ .bellows__item:last-child > .bellows__header {
+ border-bottom: 0; }
+ .bellows__header h1,
+ .bellows__header h2,
+ .bellows__header h3,
+ .bellows__header h4 {
+ margin: 0; }
+
+.bellows__content {
+ padding: 20px;
+ border: 1px solid #ecf0f1; }
+ .bellows__content .bellows {
+ margin-top: 20px; }
diff --git a/dist/bellows-theme.min.css b/dist/bellows-theme.min.css
new file mode 100644
index 0000000..1a68f4b
--- /dev/null
+++ b/dist/bellows-theme.min.css
@@ -0,0 +1 @@
+.bellows{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bellows__header{position:relative;padding:15px 20px;border:1px solid #2980b9;border-width:0 0 1px;background:#3498db;color:#fff;-webkit-tap-highlight-color:transparent}.bellows__header:active{background:#2980b9}.bellows__header::before,.bellows__header::after{content:'';position:absolute;top:50%;right:20px;z-index:2;display:block;width:16px;height:4px;margin-top:-2px;background:#fff;pointer-events:none;-webkit-transition:-webkit-transform .25s ease-in-out;transition:transform .25s ease-in-out}.bellows__header::before{content:'';-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}.bellows__header::after{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.bellows__item.bellows--is-open>.bellows__header::before,.bellows__item.bellows--is-opening>.bellows__header::before{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.bellows__item.bellows--is-open>.bellows__header::after,.bellows__item.bellows--is-opening>.bellows__header::after{-webkit-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}.bellows__item:last-child>.bellows__header{border-bottom:0}.bellows__header h1,.bellows__header h2,.bellows__header h3,.bellows__header h4{margin:0}.bellows__content{padding:20px;border:1px solid #ecf0f1}.bellows__content .bellows{margin-top:20px}
\ No newline at end of file
diff --git a/dist/bellows.css b/dist/bellows.css
new file mode 100644
index 0000000..3120fa2
--- /dev/null
+++ b/dist/bellows.css
@@ -0,0 +1,9 @@
+.bellows__item:not(.bellows--is-open) > .bellows__content {
+ display: none; }
+
+.bellows__item.bellows--is-open > .bellows__content-wrapper,
+.bellows__item.bellows--is-closing > .bellows__content-wrapper {
+ display: block; }
+
+.bellows__content-wrapper {
+ display: none; }
diff --git a/dist/bellows.js b/dist/bellows.js
new file mode 100644
index 0000000..7fe7057
--- /dev/null
+++ b/dist/bellows.js
@@ -0,0 +1,236 @@
+/*
+ Bellows.js v2.0.0
+ */
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ /*
+ In AMD environments, you will need to define an alias
+ to your selector engine. i.e. either zepto or jQuery.
+ */
+ define([
+ '$',
+ 'velocity'
+ ], factory);
+ } else {
+ /*
+ Browser globals
+ */
+ var framework = window.Zepto || window.jQuery;
+ factory(framework, framework.Velocity);
+ }
+}(function($, Velocity) {
+ var PLUGIN_NAME = 'bellows';
+ var noop = function() {};
+
+ var ITEM_CLASS = 'bellows__item';
+ var OPENED_CLASS = 'bellows--is-open';
+ var OPENING_CLASS = 'bellows--is-opening';
+ var CLOSING_CLASS = 'bellows--is-closing';
+
+ var selectors = {
+ ITEM_HEADER: '> .bellows__item > .bellows__header',
+ ITEM_CONTENT_WRAPPER: '> .bellows__content-wrapper',
+ ITEM_CONTENT: '> .bellows__item > .bellows__content'
+ };
+
+ function Bellows(element, options) {
+ this._init(element, options);
+ }
+
+ Bellows.VERSION = '2.0.0';
+
+ Bellows.DEFAULTS = {
+ singleItemOpen: false,
+ event: 'click',
+ duration: 200,
+ easing: 'swing',
+ open: noop,
+ opened: noop,
+ close: noop,
+ closed: noop
+ };
+
+ Bellows.prototype._init = function(element, options) {
+ this.options = $.extend(true, {}, Bellows.DEFAULTS, options);
+
+ this.$bellows = $(element);
+
+ this.$bellows
+ .find(selectors.ITEM_CONTENT)
+ // wrap content section of each item to facilitate padding
+ .wrap('
')
+ // add aria-hidden attribute to all hidden content wrappers
+ .parents('.bellows__item:not(.bellows--is-open)')
+ .find('.bellows__content-wrapper')
+ .attr('aria-hidden', true);
+
+ this._bindEvents();
+ };
+
+ Bellows.prototype._bindEvents = function() {
+ var plugin = this;
+
+ // We use tappy here to eliminate the 300ms delay on clicking elements
+ this.$bellows
+ .find(selectors.ITEM_HEADER)
+ .bind(this.options.event, function(e) {
+ e.preventDefault();
+
+ plugin.toggle($(this).parent());
+ });
+ };
+
+ /*
+ Gets an element's height using Velocity's built-in property cache.
+ Used for getting heights before animations, for animating into an
+ element's space.
+ */
+ Bellows.prototype._getHeight = function($element) {
+ return parseFloat(Velocity.CSS.getPropertyValue($element[0], 'height'));
+ };
+
+ /*
+ Sets the height of bellows so we animate into
+ the space rather than re-flowing the entire document
+ */
+ Bellows.prototype._setHeight = function(height) {
+ this.$bellows.css('height', height || '');
+ };
+
+ /*
+ Allow items to be found using an index
+ */
+ Bellows.prototype._item = function(item) {
+ if (typeof item === 'number') {
+ item = this.$bellows.find('.' + ITEM_CLASS).eq(item);
+ }
+
+ return item;
+ };
+
+ Bellows.prototype._trigger = function(eventName, data) {
+ eventName in this.options && this.options[eventName].call(this, $.Event(PLUGIN_NAME + ':' + eventName, { bubbles: false }), data);
+ };
+
+ Bellows.prototype.toggle = function($item) {
+ $item = this._item($item);
+
+ this[$item.hasClass(OPENED_CLASS) ? 'close' : 'open']($item);
+ };
+
+ Bellows.prototype.open = function($item) {
+ $item = this._item($item);
+
+ if ($item.hasClass(OPENED_CLASS)) {
+ return;
+ }
+
+ var plugin = this;
+ var $contentWrapper = $item.find(selectors.ITEM_CONTENT_WRAPPER);
+
+ if (this.options.singleItemOpen) {
+ this.closeAll();
+ }
+
+ this._trigger('open', { item: $item });
+
+ Velocity
+ .animate($contentWrapper, 'slideDown', {
+ begin: function() {
+ plugin._setHeight(plugin._getHeight(plugin.$bellows) + plugin._getHeight($contentWrapper));
+ $item.addClass(OPENING_CLASS);
+ },
+ duration: this.options.duration,
+ easing: this.options.easing,
+ complete: function() {
+ $item
+ .removeClass(OPENING_CLASS)
+ .addClass(OPENED_CLASS)
+ .attr('aria-hidden', true);
+
+ plugin._setHeight();
+
+ plugin._trigger('opened', { item: $item });
+ }
+ });
+ };
+
+ Bellows.prototype.close = function($item) {
+ $item = this._item($item);
+
+ if (!$item.hasClass(OPENED_CLASS)) {
+ return;
+ }
+
+ var plugin = this;
+ var $contentWrapper = $item.find(selectors.ITEM_CONTENT_WRAPPER);
+
+ this._trigger('close', { item: $item });
+
+ Velocity
+ .animate($contentWrapper, 'slideUp', {
+ begin: function() {
+ plugin._setHeight(plugin._getHeight(plugin.$bellows));
+ $item
+ .removeClass(OPENED_CLASS)
+ .addClass(CLOSING_CLASS);
+ },
+ duration: this.options.duration,
+ easing: this.options.easing,
+ complete: function() {
+ $item
+ .removeClass(CLOSING_CLASS)
+ .removeAttr('aria-hidden');
+
+ plugin._setHeight();
+
+ plugin._trigger('closed', { item: $item });
+ }
+ });
+ };
+
+ Bellows.prototype.closeAll = function() {
+ var plugin = this;
+
+ this.$bellows.find('.' + OPENED_CLASS).each(function() {
+ plugin.close($(this));
+ });
+ };
+
+ /*
+ Bellows plugin definition
+ */
+ $.fn.bellows = function(option) {
+ var args = Array.prototype.slice.call(arguments);
+
+ return this.each(function() {
+ var $this = $(this);
+ var bellows = $this.data(PLUGIN_NAME);
+ var isMethodCall = typeof option === 'string';
+
+ // If bellows isn't initialized, we lazy-load initialize it. If it's
+ // already initialized, we can safely ignore the call.
+ if (!bellows) {
+ if (isMethodCall) {
+ throw 'cannot call methods on bellows prior to initialization; attempted to call method "' + option + '"';
+ }
+ $this.data(PLUGIN_NAME, (bellows = new Bellows(this, option)));
+ }
+
+ // invoke a public method on bellows, and skip private methods
+ if (isMethodCall) {
+ if (option.charAt(0) === '_' || typeof bellows[option] !== 'function') {
+ throw 'no such method "' + option + '" for bellows';
+ }
+
+ bellows[option].apply(bellows, args.length > 1 ? args.slice(1) : null);
+ }
+ });
+ };
+
+ $.fn.bellows.Constructor = Bellows;
+
+ $('[data-bellows]').bellows();
+
+ return $;
+}));
diff --git a/dist/bellows.min.css b/dist/bellows.min.css
new file mode 100644
index 0000000..c42509a
--- /dev/null
+++ b/dist/bellows.min.css
@@ -0,0 +1 @@
+.bellows__item:not(.bellows--is-open)>.bellows__content{display:none}.bellows__item.bellows--is-open>.bellows__content-wrapper,.bellows__item.bellows--is-closing>.bellows__content-wrapper{display:block}.bellows__content-wrapper{display:none}
\ No newline at end of file
diff --git a/dist/bellows.min.js b/dist/bellows.min.js
new file mode 100644
index 0000000..1846938
--- /dev/null
+++ b/dist/bellows.min.js
@@ -0,0 +1,2 @@
+/*! bellows 2.0.0 2014-08-26 */
+(function(t){if("function"==typeof define&&define.amd)define(["$","velocity"],t);else{var e=window.Zepto||window.jQuery;t(e,e.Velocity)}})(function(t,e){function i(t,e){this._init(t,e)}var o="bellows",n=function(){},s="bellows__item",l="bellows--is-open",r="bellows--is-opening",a="bellows--is-closing",p={ITEM_HEADER:"> .bellows__item > .bellows__header",ITEM_CONTENT_WRAPPER:"> .bellows__content-wrapper",ITEM_CONTENT:"> .bellows__item > .bellows__content"};return i.VERSION="2.0.0",i.DEFAULTS={singleItemOpen:!1,event:"click",duration:200,easing:"swing",open:n,opened:n,close:n,closed:n},i.prototype._init=function(e,o){this.options=t.extend(!0,{},i.DEFAULTS,o),this.$bellows=t(e),this.$bellows.find(p.ITEM_CONTENT).wrap('
').parents(".bellows__item:not(.bellows--is-open)").find(".bellows__content-wrapper").attr("aria-hidden",!0),this._bindEvents()},i.prototype._bindEvents=function(){var e=this;this.$bellows.find(p.ITEM_HEADER).bind(this.options.event,function(i){i.preventDefault(),e.toggle(t(this).parent())})},i.prototype._getHeight=function(t){return parseFloat(e.CSS.getPropertyValue(t[0],"height"))},i.prototype._setHeight=function(t){this.$bellows.css("height",t||"")},i.prototype._item=function(t){return"number"==typeof t&&(t=this.$bellows.find("."+s).eq(t)),t},i.prototype._trigger=function(e,i){e in this.options&&this.options[e].call(this,t.Event(o+":"+e,{bubbles:!1}),i)},i.prototype.toggle=function(t){t=this._item(t),this[t.hasClass(l)?"close":"open"](t)},i.prototype.open=function(t){if(t=this._item(t),!t.hasClass(l)){var i=this,o=t.find(p.ITEM_CONTENT_WRAPPER);this.options.singleItemOpen&&this.closeAll(),this._trigger("open",{item:t}),e.animate(o,"slideDown",{begin:function(){i._setHeight(i._getHeight(i.$bellows)+i._getHeight(o)),t.addClass(r)},duration:this.options.duration,easing:this.options.easing,complete:function(){t.removeClass(r).addClass(l).attr("aria-hidden",!0),i._setHeight(),i._trigger("opened",{item:t})}})}},i.prototype.close=function(t){if(t=this._item(t),t.hasClass(l)){var i=this,o=t.find(p.ITEM_CONTENT_WRAPPER);this._trigger("close",{item:t}),e.animate(o,"slideUp",{begin:function(){i._setHeight(i._getHeight(i.$bellows)),t.removeClass(l).addClass(a)},duration:this.options.duration,easing:this.options.easing,complete:function(){t.removeClass(a).removeAttr("aria-hidden"),i._setHeight(),i._trigger("closed",{item:t})}})}},i.prototype.closeAll=function(){var e=this;this.$bellows.find("."+l).each(function(){e.close(t(this))})},t.fn.bellows=function(e){var n=Array.prototype.slice.call(arguments);return this.each(function(){var s=t(this),l=s.data(o),r="string"==typeof e;if(!l){if(r)throw'cannot call methods on bellows prior to initialization; attempted to call method "'+e+'"';s.data(o,l=new i(this,e))}if(r){if("_"===e.charAt(0)||"function"!=typeof l[e])throw'no such method "'+e+'" for bellows';l[e].apply(l,n.length>1?n.slice(1):null)}})},t.fn.bellows.Constructor=i,t("[data-bellows]").bellows(),t});
\ No newline at end of file
diff --git a/examples/animation.html b/examples/animation.html
new file mode 100644
index 0000000..f908f3e
--- /dev/null
+++ b/examples/animation.html
@@ -0,0 +1,59 @@
+
+
+
+ Examples of Bellows in action
+
+
+
+
+
+
+
+
+
+
+ Bellows Examples
+
+ Different Animation Timings
+
+ You can pass Bellows alternate animation duration
and easing
when you initialize it. The different easings available are described in the readme
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
+
+
diff --git a/examples/assets/css/examples.css b/examples/assets/css/examples.css
new file mode 100644
index 0000000..d342043
--- /dev/null
+++ b/examples/assets/css/examples.css
@@ -0,0 +1,16 @@
+* {
+ box-sizing: border-box;
+}
+
+html {
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ -webkit-text-size-adjust: 100%;
+}
+
+.bellows p {
+ margin: 0;
+}
+
+p + p {
+ margin-bottom: 10px;
+}
\ No newline at end of file
diff --git a/examples/assets/js/config.js b/examples/assets/js/config.js
new file mode 100644
index 0000000..5d4524a
--- /dev/null
+++ b/examples/assets/js/config.js
@@ -0,0 +1,16 @@
+require.config({
+ baseUrl: '../',
+ almond: true,
+ paths: {
+ 'text': 'bower_components/requirejs-text/text',
+ '$': 'lib/zeptojs/dist/zepto',
+ 'velocity': 'bower_components/velocity/velocity',
+ 'bellows': 'dist/bellows',
+ 'setup-bellows': 'examples/assets/js/setup-bellows'
+ },
+ 'shim': {
+ '$': {
+ exports: '$'
+ }
+ }
+});
diff --git a/examples/assets/js/main.js b/examples/assets/js/main.js
new file mode 100644
index 0000000..5e3e058
--- /dev/null
+++ b/examples/assets/js/main.js
@@ -0,0 +1,9 @@
+require(['config'], function() {
+ require([
+ '$',
+ 'setup-bellows'
+ ],
+ function($, setupBellows) {
+ setupBellows.init();
+ });
+});
diff --git a/examples/assets/js/setup-bellows.js b/examples/assets/js/setup-bellows.js
new file mode 100644
index 0000000..4835e3d
--- /dev/null
+++ b/examples/assets/js/setup-bellows.js
@@ -0,0 +1,36 @@
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['bellows'], factory);
+ } else {
+ // Browser globals
+ root.setupBellows = factory(window.Zepto || window.jQuery);
+ }
+}(this, function ($) {
+
+ // Default bellows initialization (/examples/default.html)
+ function init() {
+ $('.bellows.default').bellows();
+
+ // Bellows with custom animation duration and easing (/examples/animation.html)
+ $('.bellows.animation').bellows({
+ duration: 1000,
+ easing: "easeInOutCubic"
+ });
+
+ // Bellows within bellows within bellows... (/examples/inception.html)
+ $('.bellows.inception, .bellows.inception .bellows').bellows();
+
+ // Bellows with single item open (/examples/single.html)
+ $('.bellows.single').bellows({
+ singleItemOpen: true
+ });
+
+ // Enable active states
+ $(document).on('touchstart', function() {});
+ }
+
+ return {
+ init: init
+ };
+}));
\ No newline at end of file
diff --git a/examples/dataattr.html b/examples/dataattr.html
new file mode 100644
index 0000000..9ae139a
--- /dev/null
+++ b/examples/dataattr.html
@@ -0,0 +1,59 @@
+
+
+
+ Examples of Bellows in action
+
+
+
+
+
+
+
+
+
+
+ Bellows Examples
+
+ Auto-initialization with Data Attribute
+
+ This example shows how you can initialize a bellows with default settings without needing to call it in your JS.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
+
+
diff --git a/examples/default.html b/examples/default.html
new file mode 100644
index 0000000..332482e
--- /dev/null
+++ b/examples/default.html
@@ -0,0 +1,61 @@
+
+
+
+ Examples of Bellows in action
+
+
+
+
+
+
+
+
+
+
+ Bellows Examples
+
+ Default Bellows
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+ Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+ Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
diff --git a/examples/inception.html b/examples/inception.html
new file mode 100644
index 0000000..bc54fe4
--- /dev/null
+++ b/examples/inception.html
@@ -0,0 +1,117 @@
+
+
+
+ Examples of Bellows in action
+
+
+
+
+
+
+
+
+
+
+ Bellows Examples
+
+ Bellows within Bellows
+
+ Bellows, unlike the rules of Inception, will allow you to go as many levels deep as you'd like. You can insert Bellows within Bellows to your heart's content.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
+
+
diff --git a/examples/index.html b/examples/index.html
new file mode 100644
index 0000000..eb276a1
--- /dev/null
+++ b/examples/index.html
@@ -0,0 +1,27 @@
+
+
+
+ Examples of Bellows in action
+
+
+
+
+
+
+
+ Bellows Examples
+
+
+
+
+
+
+
+
diff --git a/examples/norequire.html b/examples/norequire.html
new file mode 100644
index 0000000..c3dfc12
--- /dev/null
+++ b/examples/norequire.html
@@ -0,0 +1,65 @@
+
+
+
+ Examples of Bellows in action
+
+
+
+
+
+
+
+
+
+
+ Bellows Examples
+
+ Default Bellows
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+ Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+ Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
+
+
+
diff --git a/examples/single.html b/examples/single.html
new file mode 100644
index 0000000..d5716b0
--- /dev/null
+++ b/examples/single.html
@@ -0,0 +1,59 @@
+
+
+
+ Examples of Bellows in action
+
+
+
+
+
+
+
+
+
+
+ Bellows Examples
+
+ Single Item Open
+
+ The singleItemOpen
option enables you to set Bellows to only have one of its items open at any given time.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
Lorem honeyed locusts sit amet, none so wise, sed do eiusmod never resting ut labore et dolore magna aliqua. Manhood death before disgrace warrior, feed it to the goats spare me your false courtesy commodo consequat. Mace aute irure dolor in reprehenderit poison is a woman's weapon lord of light tower dwarf. The last of the dragons royal, godswood garron sister betrothed officia deserunt mollit anim id est snow.
+
+
+
+
+
+
+
+
diff --git a/index.html b/index.html
deleted file mode 100644
index 823850b..0000000
--- a/index.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
- Examples of Bellows in action
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Item 2 content
- Item 2 content
-
-
-
-
-
-
-
- Item 3 content
- Item 3 content
- Item 3 content
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Item 2 content
- Item 2 content
-
-
-
-
-
-
-
- Item 3 content
- Item 3 content
- Item 3 content
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/zeptojs/.bower.json b/lib/zeptojs/.bower.json
new file mode 100644
index 0000000..d2c508d
--- /dev/null
+++ b/lib/zeptojs/.bower.json
@@ -0,0 +1,14 @@
+{
+ "name": "zeptojs",
+ "homepage": "https://github.com/madrobby/zepto",
+ "version": "1.1.3",
+ "_release": "1.1.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.1.3",
+ "commit": "fef90efe1c98f43f6ce1e1f2f793077e1c6994c5"
+ },
+ "_source": "git://github.com/madrobby/zepto.git",
+ "_target": "1.1.3",
+ "_originalSource": "zeptojs"
+}
\ No newline at end of file
diff --git a/lib/zeptojs/.gitignore b/lib/zeptojs/.gitignore
new file mode 100644
index 0000000..c5963fd
--- /dev/null
+++ b/lib/zeptojs/.gitignore
@@ -0,0 +1,10 @@
+.DS_Store
+pkg
+*.swp
+docs/*
+.jhw-cache
+.rbenv-version
+public
+node_modules
+temp/
+npm-debug.log
\ No newline at end of file
diff --git a/lib/zeptojs/.travis.yml b/lib/zeptojs/.travis.yml
new file mode 100644
index 0000000..b2f29ef
--- /dev/null
+++ b/lib/zeptojs/.travis.yml
@@ -0,0 +1,9 @@
+script: script/test
+language: node_js
+notifications:
+ campfire:
+ template: '%{message} [%{branch}] %{repository}/%{commit} %{author} %{build_url}'
+ rooms:
+ secure: VR6rWk0YhezBWnD8jPjSD8h/Q83S3NT0F34Au1vswt+/+Ku19S8X44vGVUG+NYdYyhg7uOqUaPN1Jr3KCpdcXgHEpUYiyBGJ8ebltavcjeHYWqK6ghcqgSnbDkifuC7Eu/9LcrOMOXgt+zkXjiVXW3+zyGVDcrs4cQ2vGY2DTYA=
+node_js:
+- 0.10
diff --git a/lib/zeptojs/CONTRIBUTING.md b/lib/zeptojs/CONTRIBUTING.md
new file mode 100644
index 0000000..a554d7a
--- /dev/null
+++ b/lib/zeptojs/CONTRIBUTING.md
@@ -0,0 +1,45 @@
+## Contributing to Zepto
+
+**Thanks for helping out!**
+
+In order for your code to make it in, several conditions must be met:
+
+* It's more likely your pull request will make it in if you adhere to **Zepto's
+ project goals**. Be sure to read the README in its entirety before setting out
+ to code.
+* Please talk to the maintainers (@madrobby and @mislav) first if you want
+ to write a plugin, those are better kept in their own repositories.
+* Fix only ONE thing or have only ONE feature in your pull request.
+ If you have multiple unrelated code updates, please submit a separate pull request for each one.
+* **Your pull request must be written in English and be accompanied by a
+ detailed description**, ideally something we can use as documentation.
+ If you're not fluent in English, try your best and let us know so we'll help!
+* Changes to jQuery-based API methods **must match their jQuery counterparts**.
+* Please **do not just copy code from jQuery**. Zepto strives for API compatibility,
+ but has different goals for code style and size and target platforms.
+ In case you do copy code, you must clearly indicate the origin of the code, and
+ which license applies to it. However, it is likely your patch will be denied.
+* **All code must have tests, and all tests must pass.** See the README on running the test suite.
+* Please **also test manually** on as many target platforms you have access to,
+ but at least on latest Chrome (desktop) and Firefox (desktop).
+ See http://zeptojs.com for a full list of platforms.
+* It's required that you follow Zepto's **code style guidelines** (see below)
+
+Whew, now that we have that out of the way thanks again!
+
+## Code style guidelines
+
+* Two spaces "soft tabs" indentation
+* Remove any trailing whitespace from the end of lines
+* `function name() { }` for named functions
+* `function(){ }` for anonymous functions
+* No curly braces for single-line control flow statements such as `if` & friends
+* Don't write [semicolons that are optional][optional]
+* Put a single semicolon _before_ statements that start with `(` or `[`
+ (see above article as for why it's needed)
+* Use long, descriptive variable and method names
+* Use blank lines to separate "paragraphs" of code for readability
+* Use comments to describe non-obvious code behavior
+
+
+ [optional]: http://mislav.uniqpath.com/2010/05/semicolons/
diff --git a/lib/zeptojs/MIT-LICENSE b/lib/zeptojs/MIT-LICENSE
new file mode 100644
index 0000000..5a62a30
--- /dev/null
+++ b/lib/zeptojs/MIT-LICENSE
@@ -0,0 +1,21 @@
+Copyright (c) 2010-2014 Thomas Fuchs
+http://zeptojs.com/
+
+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.
diff --git a/lib/zeptojs/README.md b/lib/zeptojs/README.md
new file mode 100644
index 0000000..b00bceb
--- /dev/null
+++ b/lib/zeptojs/README.md
@@ -0,0 +1,225 @@
+# Zepto.js – a minimalist JavaScript library
+
+Zepto is a minimalist JavaScript library for modern browsers with a
+largely jQuery-compatible API. If you use jQuery, you already know how to use Zepto.
+
+See [zeptojs.com][] for an extended introduction, downloads
+and documentation.
+
+Zepto.js is licensed under the terms of the MIT License.
+
+Want to give us money or a tip? Don't.
+Instead please donate to [charity: water](http://charitywater.org/).
+
+## Building
+
+[![Build Status](https://secure.travis-ci.org/madrobby/zepto.png?branch=master)](http://travis-ci.org/madrobby/zepto)
+
+The official site offers a download of the default distribution of Zepto. This
+is good for starting out. However, at some point you might want to add some
+optional modules and remove some of the default ones you don't need, to keep the
+size at a minimum. That's when you need to check out Zepto's source code and use
+the build commands.
+
+You will need Node.js installed on your system.
+
+~~~ sh
+$ npm install
+$ npm run-script dist
+
+# do a custom build
+$ MODULES="zepto event data" npm run-script dist
+~~~
+
+The resulting files are:
+
+1. `dist/zepto.js`
+2. `dist/zepto.min.js`
+
+If you install CoffeeScript globally, you can run `make` directly:
+
+~~~ sh
+$ coffee make dist
+$ MODULES="zepto event data ..." ./make dist
+~~~
+
+## Zepto modules
+
+Zepto modules are individual files in the "src/" directory.
+
+
+
+ module default description
+
+
+
+ zepto
+ ✔
+ Core module; contains most methods
+
+
+ event
+ ✔
+ Event handling via on()
& off()
+
+
+ ajax
+ ✔
+ XMLHttpRequest and JSONP functionality
+
+
+ form
+ ✔
+ Serialize & submit web forms
+
+
+ ie
+ ✔
+ Support for Internet Explorer 10+ on the desktop and Windows Phone 8
+
+
+ detect
+
+ Provides $.os
and $.browser
information
+
+
+ fx
+
+ The animate()
method
+
+
+ fx_methods
+
+
+ Animated show
, hide
, toggle
,
+ and fade*()
methods.
+
+
+
+ assets
+
+
+ Experimental support for cleaning up iOS memory after removing
+ image elements from the DOM.
+
+
+
+ data
+
+
+ A full-blown data()
method, capable of storing arbitrary
+ objects in memory.
+
+
+
+ deferred
+
+
+ Provides $.Deferred
promises API.
+ Depends on the "callbacks" module.
+
+
+
+ callbacks
+
+
+ Provides $.Callbacks
for use in "deferred" module.
+
+
+
+ selector
+
+
+ Experimental jQuery
+ CSS extensions support for functionality such as $('div:first')
and
+ el.is(':visible')
.
+
+
+
+ touch
+
+
+ Fires tap– and swipe–related events on touch devices. This works with both
+ `touch` (iOS, Android) and `pointer` events (Windows Phone).
+
+
+
+ gesture
+
+ Fires pinch gesture events on touch devices
+
+
+ stack
+
+ Provides andSelf
& end()
chaining methods
+
+
+ ios3
+
+
+ String.prototype.trim and Array.prototype.reduce methods
+ (if they are missing) for compatibility with iOS 3.x.
+
+
+
+
+
+## Contributing
+
+Please read our [contribution guidelines](https://github.com/madrobby/zepto/blob/master/CONTRIBUTING.md)
+for information on how to contribute.
+
+Get in touch:
+
+* @[zeptojs](http://twitter.com/zeptojs)
+
+### Write documentation
+
+Zepto docs are written in Markdown and live in the ["gh-pages" branch][docs].
+They are published on [zeptojs.com][].
+
+You can use GitHub's web interface to make quick changes to documentation for
+specific Zepto features
+([example: ajaxSettings](https://github.com/madrobby/zepto/blob/gh-pages/ajax/_posts/1900-01-01-Z-ajaxSettings.md)).
+This will submit a pull request to us that we can review.
+
+### Report a bug
+
+1. Check if the bug is already fixed in the [master branch][master] since the
+ last release.
+2. Check [existing issues][issues]. Open a new one, including exact browser &
+ platform information. For better formatting of your report, see
+ [GitHub-flavored Markdown][mkd].
+
+### Running tests
+
+You will need to install [PhantomJS][]. On OS X, that's easy:
+
+~~~ sh
+$ brew install phantomjs
+~~~
+
+To run the automated tests:
+
+~~~ sh
+$ npm test
+~~~
+
+To run a test server, which you can hit with your browsers and devices:
+
+~~~ sh
+$ npm start
+~~~
+
+Go to `http://your-ip-address:3000/` on your browser and follow the
+instructions. For your convenience test failures and exceptions will be
+reported to the the console you started the test server in (as well as
+the browser console if available).
+
+ [zeptojs.com]: http://zeptojs.com
+ [master]: https://github.com/madrobby/zepto/commits/master
+ [issues]: https://github.com/madrobby/zepto/issues
+ [docs]: https://github.com/madrobby/zepto/tree/gh-pages#readme
+ [mkd]: http://github.github.com/github-flavored-markdown/
+ [evidence.js]: https://github.com/tobie/Evidence
+ [phantomjs]: http://code.google.com/p/phantomjs/wiki/Installation
diff --git a/lib/zeptojs/dist/zepto.js b/lib/zeptojs/dist/zepto.js
new file mode 100644
index 0000000..25c6bbe
--- /dev/null
+++ b/lib/zeptojs/dist/zepto.js
@@ -0,0 +1,1811 @@
+/* Zepto 1.1.3 - zepto event ajax form fx selector stack data - zeptojs.com/license */
+
+
+var Zepto = (function() {
+ var undefined, key, $, classList, emptyArray = [], slice = emptyArray.slice, filter = emptyArray.filter,
+ document = window.document,
+ elementDisplay = {}, classCache = {},
+ cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 },
+ fragmentRE = /^\s*<(\w+|!)[^>]*>/,
+ singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
+ tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
+ rootNodeRE = /^(?:body|html)$/i,
+ capitalRE = /([A-Z])/g,
+
+ // special attributes that should be get/set via method calls
+ methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
+
+ adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ],
+ table = document.createElement('table'),
+ tableRow = document.createElement('tr'),
+ containers = {
+ 'tr': document.createElement('tbody'),
+ 'tbody': table, 'thead': table, 'tfoot': table,
+ 'td': tableRow, 'th': tableRow,
+ '*': document.createElement('div')
+ },
+ readyRE = /complete|loaded|interactive/,
+ simpleSelectorRE = /^[\w-]*$/,
+ class2type = {},
+ toString = class2type.toString,
+ zepto = {},
+ camelize, uniq,
+ tempParent = document.createElement('div'),
+ propMap = {
+ 'tabindex': 'tabIndex',
+ 'readonly': 'readOnly',
+ 'for': 'htmlFor',
+ 'class': 'className',
+ 'maxlength': 'maxLength',
+ 'cellspacing': 'cellSpacing',
+ 'cellpadding': 'cellPadding',
+ 'rowspan': 'rowSpan',
+ 'colspan': 'colSpan',
+ 'usemap': 'useMap',
+ 'frameborder': 'frameBorder',
+ 'contenteditable': 'contentEditable'
+ },
+ isArray = Array.isArray ||
+ function(object){ return object instanceof Array }
+
+ zepto.matches = function(element, selector) {
+ if (!selector || !element || element.nodeType !== 1) return false
+ var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector ||
+ element.oMatchesSelector || element.matchesSelector
+ if (matchesSelector) return matchesSelector.call(element, selector)
+ // fall back to performing a selector:
+ var match, parent = element.parentNode, temp = !parent
+ if (temp) (parent = tempParent).appendChild(element)
+ match = ~zepto.qsa(parent, selector).indexOf(element)
+ temp && tempParent.removeChild(element)
+ return match
+ }
+
+ function type(obj) {
+ return obj == null ? String(obj) :
+ class2type[toString.call(obj)] || "object"
+ }
+
+ function isFunction(value) { return type(value) == "function" }
+ function isWindow(obj) { return obj != null && obj == obj.window }
+ function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }
+ function isObject(obj) { return type(obj) == "object" }
+ function isPlainObject(obj) {
+ return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype
+ }
+ function likeArray(obj) { return typeof obj.length == 'number' }
+
+ function compact(array) { return filter.call(array, function(item){ return item != null }) }
+ function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array }
+ camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }
+ function dasherize(str) {
+ return str.replace(/::/g, '/')
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
+ .replace(/([a-z\d])([A-Z])/g, '$1_$2')
+ .replace(/_/g, '-')
+ .toLowerCase()
+ }
+ uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) }
+
+ function classRE(name) {
+ return name in classCache ?
+ classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)'))
+ }
+
+ function maybeAddPx(name, value) {
+ return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value
+ }
+
+ function defaultDisplay(nodeName) {
+ var element, display
+ if (!elementDisplay[nodeName]) {
+ element = document.createElement(nodeName)
+ document.body.appendChild(element)
+ display = getComputedStyle(element, '').getPropertyValue("display")
+ element.parentNode.removeChild(element)
+ display == "none" && (display = "block")
+ elementDisplay[nodeName] = display
+ }
+ return elementDisplay[nodeName]
+ }
+
+ function children(element) {
+ return 'children' in element ?
+ slice.call(element.children) :
+ $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node })
+ }
+
+ // `$.zepto.fragment` takes a html string and an optional tag name
+ // to generate DOM nodes nodes from the given html string.
+ // The generated DOM nodes are returned as an array.
+ // This function can be overriden in plugins for example to make
+ // it compatible with browsers that don't support the DOM fully.
+ zepto.fragment = function(html, name, properties) {
+ var dom, nodes, container
+
+ // A special case optimization for a single tag
+ if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1))
+
+ if (!dom) {
+ if (html.replace) html = html.replace(tagExpanderRE, "<$1>$2>")
+ if (name === undefined) name = fragmentRE.test(html) && RegExp.$1
+ if (!(name in containers)) name = '*'
+
+ container = containers[name]
+ container.innerHTML = '' + html
+ dom = $.each(slice.call(container.childNodes), function(){
+ container.removeChild(this)
+ })
+ }
+
+ if (isPlainObject(properties)) {
+ nodes = $(dom)
+ $.each(properties, function(key, value) {
+ if (methodAttributes.indexOf(key) > -1) nodes[key](value)
+ else nodes.attr(key, value)
+ })
+ }
+
+ return dom
+ }
+
+ // `$.zepto.Z` swaps out the prototype of the given `dom` array
+ // of nodes with `$.fn` and thus supplying all the Zepto functions
+ // to the array. Note that `__proto__` is not supported on Internet
+ // Explorer. This method can be overriden in plugins.
+ zepto.Z = function(dom, selector) {
+ dom = dom || []
+ dom.__proto__ = $.fn
+ dom.selector = selector || ''
+ return dom
+ }
+
+ // `$.zepto.isZ` should return `true` if the given object is a Zepto
+ // collection. This method can be overriden in plugins.
+ zepto.isZ = function(object) {
+ return object instanceof zepto.Z
+ }
+
+ // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and
+ // takes a CSS selector and an optional context (and handles various
+ // special cases).
+ // This method can be overriden in plugins.
+ zepto.init = function(selector, context) {
+ var dom
+ // If nothing given, return an empty Zepto collection
+ if (!selector) return zepto.Z()
+ // Optimize for string selectors
+ else if (typeof selector == 'string') {
+ selector = selector.trim()
+ // If it's a html fragment, create nodes from it
+ // Note: In both Chrome 21 and Firefox 15, DOM error 12
+ // is thrown if the fragment doesn't begin with <
+ if (selector[0] == '<' && fragmentRE.test(selector))
+ dom = zepto.fragment(selector, RegExp.$1, context), selector = null
+ // If there's a context, create a collection on that context first, and select
+ // nodes from there
+ else if (context !== undefined) return $(context).find(selector)
+ // If it's a CSS selector, use it to select nodes.
+ else dom = zepto.qsa(document, selector)
+ }
+ // If a function is given, call it when the DOM is ready
+ else if (isFunction(selector)) return $(document).ready(selector)
+ // If a Zepto collection is given, just return it
+ else if (zepto.isZ(selector)) return selector
+ else {
+ // normalize array if an array of nodes is given
+ if (isArray(selector)) dom = compact(selector)
+ // Wrap DOM nodes.
+ else if (isObject(selector))
+ dom = [selector], selector = null
+ // If it's a html fragment, create nodes from it
+ else if (fragmentRE.test(selector))
+ dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null
+ // If there's a context, create a collection on that context first, and select
+ // nodes from there
+ else if (context !== undefined) return $(context).find(selector)
+ // And last but no least, if it's a CSS selector, use it to select nodes.
+ else dom = zepto.qsa(document, selector)
+ }
+ // create a new Zepto collection from the nodes found
+ return zepto.Z(dom, selector)
+ }
+
+ // `$` will be the base `Zepto` object. When calling this
+ // function just call `$.zepto.init, which makes the implementation
+ // details of selecting nodes and creating Zepto collections
+ // patchable in plugins.
+ $ = function(selector, context){
+ return zepto.init(selector, context)
+ }
+
+ function extend(target, source, deep) {
+ for (key in source)
+ if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
+ if (isPlainObject(source[key]) && !isPlainObject(target[key]))
+ target[key] = {}
+ if (isArray(source[key]) && !isArray(target[key]))
+ target[key] = []
+ extend(target[key], source[key], deep)
+ }
+ else if (source[key] !== undefined) target[key] = source[key]
+ }
+
+ // Copy all but undefined properties from one or more
+ // objects to the `target` object.
+ $.extend = function(target){
+ var deep, args = slice.call(arguments, 1)
+ if (typeof target == 'boolean') {
+ deep = target
+ target = args.shift()
+ }
+ args.forEach(function(arg){ extend(target, arg, deep) })
+ return target
+ }
+
+ // `$.zepto.qsa` is Zepto's CSS selector implementation which
+ // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`.
+ // This method can be overriden in plugins.
+ zepto.qsa = function(element, selector){
+ var found,
+ maybeID = selector[0] == '#',
+ maybeClass = !maybeID && selector[0] == '.',
+ nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked
+ isSimple = simpleSelectorRE.test(nameOnly)
+ return (isDocument(element) && isSimple && maybeID) ?
+ ( (found = element.getElementById(nameOnly)) ? [found] : [] ) :
+ (element.nodeType !== 1 && element.nodeType !== 9) ? [] :
+ slice.call(
+ isSimple && !maybeID ?
+ maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class
+ element.getElementsByTagName(selector) : // Or a tag
+ element.querySelectorAll(selector) // Or it's not simple, and we need to query all
+ )
+ }
+
+ function filtered(nodes, selector) {
+ return selector == null ? $(nodes) : $(nodes).filter(selector)
+ }
+
+ $.contains = function(parent, node) {
+ return parent !== node && parent.contains(node)
+ }
+
+ function funcArg(context, arg, idx, payload) {
+ return isFunction(arg) ? arg.call(context, idx, payload) : arg
+ }
+
+ function setAttribute(node, name, value) {
+ value == null ? node.removeAttribute(name) : node.setAttribute(name, value)
+ }
+
+ // access className property while respecting SVGAnimatedString
+ function className(node, value){
+ var klass = node.className,
+ svg = klass && klass.baseVal !== undefined
+
+ if (value === undefined) return svg ? klass.baseVal : klass
+ svg ? (klass.baseVal = value) : (node.className = value)
+ }
+
+ // "true" => true
+ // "false" => false
+ // "null" => null
+ // "42" => 42
+ // "42.5" => 42.5
+ // "08" => "08"
+ // JSON => parse if valid
+ // String => self
+ function deserializeValue(value) {
+ var num
+ try {
+ return value ?
+ value == "true" ||
+ ( value == "false" ? false :
+ value == "null" ? null :
+ !/^0/.test(value) && !isNaN(num = Number(value)) ? num :
+ /^[\[\{]/.test(value) ? $.parseJSON(value) :
+ value )
+ : value
+ } catch(e) {
+ return value
+ }
+ }
+
+ $.type = type
+ $.isFunction = isFunction
+ $.isWindow = isWindow
+ $.isArray = isArray
+ $.isPlainObject = isPlainObject
+
+ $.isEmptyObject = function(obj) {
+ var name
+ for (name in obj) return false
+ return true
+ }
+
+ $.inArray = function(elem, array, i){
+ return emptyArray.indexOf.call(array, elem, i)
+ }
+
+ $.camelCase = camelize
+ $.trim = function(str) {
+ return str == null ? "" : String.prototype.trim.call(str)
+ }
+
+ // plugin compatibility
+ $.uuid = 0
+ $.support = { }
+ $.expr = { }
+
+ $.map = function(elements, callback){
+ var value, values = [], i, key
+ if (likeArray(elements))
+ for (i = 0; i < elements.length; i++) {
+ value = callback(elements[i], i)
+ if (value != null) values.push(value)
+ }
+ else
+ for (key in elements) {
+ value = callback(elements[key], key)
+ if (value != null) values.push(value)
+ }
+ return flatten(values)
+ }
+
+ $.each = function(elements, callback){
+ var i, key
+ if (likeArray(elements)) {
+ for (i = 0; i < elements.length; i++)
+ if (callback.call(elements[i], i, elements[i]) === false) return elements
+ } else {
+ for (key in elements)
+ if (callback.call(elements[key], key, elements[key]) === false) return elements
+ }
+
+ return elements
+ }
+
+ $.grep = function(elements, callback){
+ return filter.call(elements, callback)
+ }
+
+ if (window.JSON) $.parseJSON = JSON.parse
+
+ // Populate the class2type map
+ $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase()
+ })
+
+ // Define methods that will be available on all
+ // Zepto collections
+ $.fn = {
+ // Because a collection acts like an array
+ // copy over these useful array functions.
+ forEach: emptyArray.forEach,
+ reduce: emptyArray.reduce,
+ push: emptyArray.push,
+ sort: emptyArray.sort,
+ indexOf: emptyArray.indexOf,
+ concat: emptyArray.concat,
+
+ // `map` and `slice` in the jQuery API work differently
+ // from their array counterparts
+ map: function(fn){
+ return $($.map(this, function(el, i){ return fn.call(el, i, el) }))
+ },
+ slice: function(){
+ return $(slice.apply(this, arguments))
+ },
+
+ ready: function(callback){
+ // need to check if document.body exists for IE as that browser reports
+ // document ready when it hasn't yet created the body element
+ if (readyRE.test(document.readyState) && document.body) callback($)
+ else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false)
+ return this
+ },
+ get: function(idx){
+ return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]
+ },
+ toArray: function(){ return this.get() },
+ size: function(){
+ return this.length
+ },
+ remove: function(){
+ return this.each(function(){
+ if (this.parentNode != null)
+ this.parentNode.removeChild(this)
+ })
+ },
+ each: function(callback){
+ emptyArray.every.call(this, function(el, idx){
+ return callback.call(el, idx, el) !== false
+ })
+ return this
+ },
+ filter: function(selector){
+ if (isFunction(selector)) return this.not(this.not(selector))
+ return $(filter.call(this, function(element){
+ return zepto.matches(element, selector)
+ }))
+ },
+ add: function(selector,context){
+ return $(uniq(this.concat($(selector,context))))
+ },
+ is: function(selector){
+ return this.length > 0 && zepto.matches(this[0], selector)
+ },
+ not: function(selector){
+ var nodes=[]
+ if (isFunction(selector) && selector.call !== undefined)
+ this.each(function(idx){
+ if (!selector.call(this,idx)) nodes.push(this)
+ })
+ else {
+ var excludes = typeof selector == 'string' ? this.filter(selector) :
+ (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)
+ this.forEach(function(el){
+ if (excludes.indexOf(el) < 0) nodes.push(el)
+ })
+ }
+ return $(nodes)
+ },
+ has: function(selector){
+ return this.filter(function(){
+ return isObject(selector) ?
+ $.contains(this, selector) :
+ $(this).find(selector).size()
+ })
+ },
+ eq: function(idx){
+ return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1)
+ },
+ first: function(){
+ var el = this[0]
+ return el && !isObject(el) ? el : $(el)
+ },
+ last: function(){
+ var el = this[this.length - 1]
+ return el && !isObject(el) ? el : $(el)
+ },
+ find: function(selector){
+ var result, $this = this
+ if (typeof selector == 'object')
+ result = $(selector).filter(function(){
+ var node = this
+ return emptyArray.some.call($this, function(parent){
+ return $.contains(parent, node)
+ })
+ })
+ else if (this.length == 1) result = $(zepto.qsa(this[0], selector))
+ else result = this.map(function(){ return zepto.qsa(this, selector) })
+ return result
+ },
+ closest: function(selector, context){
+ var node = this[0], collection = false
+ if (typeof selector == 'object') collection = $(selector)
+ while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector)))
+ node = node !== context && !isDocument(node) && node.parentNode
+ return $(node)
+ },
+ parents: function(selector){
+ var ancestors = [], nodes = this
+ while (nodes.length > 0)
+ nodes = $.map(nodes, function(node){
+ if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) {
+ ancestors.push(node)
+ return node
+ }
+ })
+ return filtered(ancestors, selector)
+ },
+ parent: function(selector){
+ return filtered(uniq(this.pluck('parentNode')), selector)
+ },
+ children: function(selector){
+ return filtered(this.map(function(){ return children(this) }), selector)
+ },
+ contents: function() {
+ return this.map(function() { return slice.call(this.childNodes) })
+ },
+ siblings: function(selector){
+ return filtered(this.map(function(i, el){
+ return filter.call(children(el.parentNode), function(child){ return child!==el })
+ }), selector)
+ },
+ empty: function(){
+ return this.each(function(){ this.innerHTML = '' })
+ },
+ // `pluck` is borrowed from Prototype.js
+ pluck: function(property){
+ return $.map(this, function(el){ return el[property] })
+ },
+ show: function(){
+ return this.each(function(){
+ this.style.display == "none" && (this.style.display = '')
+ if (getComputedStyle(this, '').getPropertyValue("display") == "none")
+ this.style.display = defaultDisplay(this.nodeName)
+ })
+ },
+ replaceWith: function(newContent){
+ return this.before(newContent).remove()
+ },
+ wrap: function(structure){
+ var func = isFunction(structure)
+ if (this[0] && !func)
+ var dom = $(structure).get(0),
+ clone = dom.parentNode || this.length > 1
+
+ return this.each(function(index){
+ $(this).wrapAll(
+ func ? structure.call(this, index) :
+ clone ? dom.cloneNode(true) : dom
+ )
+ })
+ },
+ wrapAll: function(structure){
+ if (this[0]) {
+ $(this[0]).before(structure = $(structure))
+ var children
+ // drill down to the inmost element
+ while ((children = structure.children()).length) structure = children.first()
+ $(structure).append(this)
+ }
+ return this
+ },
+ wrapInner: function(structure){
+ var func = isFunction(structure)
+ return this.each(function(index){
+ var self = $(this), contents = self.contents(),
+ dom = func ? structure.call(this, index) : structure
+ contents.length ? contents.wrapAll(dom) : self.append(dom)
+ })
+ },
+ unwrap: function(){
+ this.parent().each(function(){
+ $(this).replaceWith($(this).children())
+ })
+ return this
+ },
+ clone: function(){
+ return this.map(function(){ return this.cloneNode(true) })
+ },
+ hide: function(){
+ return this.css("display", "none")
+ },
+ toggle: function(setting){
+ return this.each(function(){
+ var el = $(this)
+ ;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide()
+ })
+ },
+ prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') },
+ next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') },
+ html: function(html){
+ return arguments.length === 0 ?
+ (this.length > 0 ? this[0].innerHTML : null) :
+ this.each(function(idx){
+ var originHtml = this.innerHTML
+ $(this).empty().append( funcArg(this, html, idx, originHtml) )
+ })
+ },
+ text: function(text){
+ return arguments.length === 0 ?
+ (this.length > 0 ? this[0].textContent : null) :
+ this.each(function(){ this.textContent = (text === undefined) ? '' : ''+text })
+ },
+ attr: function(name, value){
+ var result
+ return (typeof name == 'string' && value === undefined) ?
+ (this.length == 0 || this[0].nodeType !== 1 ? undefined :
+ (name == 'value' && this[0].nodeName == 'INPUT') ? this.val() :
+ (!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result
+ ) :
+ this.each(function(idx){
+ if (this.nodeType !== 1) return
+ if (isObject(name)) for (key in name) setAttribute(this, key, name[key])
+ else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name)))
+ })
+ },
+ removeAttr: function(name){
+ return this.each(function(){ this.nodeType === 1 && setAttribute(this, name) })
+ },
+ prop: function(name, value){
+ name = propMap[name] || name
+ return (value === undefined) ?
+ (this[0] && this[0][name]) :
+ this.each(function(idx){
+ this[name] = funcArg(this, value, idx, this[name])
+ })
+ },
+ data: function(name, value){
+ var data = this.attr('data-' + name.replace(capitalRE, '-$1').toLowerCase(), value)
+ return data !== null ? deserializeValue(data) : undefined
+ },
+ val: function(value){
+ return arguments.length === 0 ?
+ (this[0] && (this[0].multiple ?
+ $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') :
+ this[0].value)
+ ) :
+ this.each(function(idx){
+ this.value = funcArg(this, value, idx, this.value)
+ })
+ },
+ offset: function(coordinates){
+ if (coordinates) return this.each(function(index){
+ var $this = $(this),
+ coords = funcArg(this, coordinates, index, $this.offset()),
+ parentOffset = $this.offsetParent().offset(),
+ props = {
+ top: coords.top - parentOffset.top,
+ left: coords.left - parentOffset.left
+ }
+
+ if ($this.css('position') == 'static') props['position'] = 'relative'
+ $this.css(props)
+ })
+ if (this.length==0) return null
+ var obj = this[0].getBoundingClientRect()
+ return {
+ left: obj.left + window.pageXOffset,
+ top: obj.top + window.pageYOffset,
+ width: Math.round(obj.width),
+ height: Math.round(obj.height)
+ }
+ },
+ css: function(property, value){
+ if (arguments.length < 2) {
+ var element = this[0], computedStyle = getComputedStyle(element, '')
+ if(!element) return
+ if (typeof property == 'string')
+ return element.style[camelize(property)] || computedStyle.getPropertyValue(property)
+ else if (isArray(property)) {
+ var props = {}
+ $.each(isArray(property) ? property: [property], function(_, prop){
+ props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop))
+ })
+ return props
+ }
+ }
+
+ var css = ''
+ if (type(property) == 'string') {
+ if (!value && value !== 0)
+ this.each(function(){ this.style.removeProperty(dasherize(property)) })
+ else
+ css = dasherize(property) + ":" + maybeAddPx(property, value)
+ } else {
+ for (key in property)
+ if (!property[key] && property[key] !== 0)
+ this.each(function(){ this.style.removeProperty(dasherize(key)) })
+ else
+ css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';'
+ }
+
+ return this.each(function(){ this.style.cssText += ';' + css })
+ },
+ index: function(element){
+ return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0])
+ },
+ hasClass: function(name){
+ if (!name) return false
+ return emptyArray.some.call(this, function(el){
+ return this.test(className(el))
+ }, classRE(name))
+ },
+ addClass: function(name){
+ if (!name) return this
+ return this.each(function(idx){
+ classList = []
+ var cls = className(this), newName = funcArg(this, name, idx, cls)
+ newName.split(/\s+/g).forEach(function(klass){
+ if (!$(this).hasClass(klass)) classList.push(klass)
+ }, this)
+ classList.length && className(this, cls + (cls ? " " : "") + classList.join(" "))
+ })
+ },
+ removeClass: function(name){
+ return this.each(function(idx){
+ if (name === undefined) return className(this, '')
+ classList = className(this)
+ funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){
+ classList = classList.replace(classRE(klass), " ")
+ })
+ className(this, classList.trim())
+ })
+ },
+ toggleClass: function(name, when){
+ if (!name) return this
+ return this.each(function(idx){
+ var $this = $(this), names = funcArg(this, name, idx, className(this))
+ names.split(/\s+/g).forEach(function(klass){
+ (when === undefined ? !$this.hasClass(klass) : when) ?
+ $this.addClass(klass) : $this.removeClass(klass)
+ })
+ })
+ },
+ scrollTop: function(value){
+ if (!this.length) return
+ var hasScrollTop = 'scrollTop' in this[0]
+ if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset
+ return this.each(hasScrollTop ?
+ function(){ this.scrollTop = value } :
+ function(){ this.scrollTo(this.scrollX, value) })
+ },
+ scrollLeft: function(value){
+ if (!this.length) return
+ var hasScrollLeft = 'scrollLeft' in this[0]
+ if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset
+ return this.each(hasScrollLeft ?
+ function(){ this.scrollLeft = value } :
+ function(){ this.scrollTo(value, this.scrollY) })
+ },
+ position: function() {
+ if (!this.length) return
+
+ var elem = this[0],
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent(),
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset()
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= parseFloat( $(elem).css('margin-top') ) || 0
+ offset.left -= parseFloat( $(elem).css('margin-left') ) || 0
+
+ // Add offsetParent borders
+ parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0
+ parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0
+
+ // Subtract the two offsets
+ return {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ }
+ },
+ offsetParent: function() {
+ return this.map(function(){
+ var parent = this.offsetParent || document.body
+ while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static")
+ parent = parent.offsetParent
+ return parent
+ })
+ }
+ }
+
+ // for now
+ $.fn.detach = $.fn.remove
+
+ // Generate the `width` and `height` functions
+ ;['width', 'height'].forEach(function(dimension){
+ var dimensionProperty =
+ dimension.replace(/./, function(m){ return m[0].toUpperCase() })
+
+ $.fn[dimension] = function(value){
+ var offset, el = this[0]
+ if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] :
+ isDocument(el) ? el.documentElement['scroll' + dimensionProperty] :
+ (offset = this.offset()) && offset[dimension]
+ else return this.each(function(idx){
+ el = $(this)
+ el.css(dimension, funcArg(this, value, idx, el[dimension]()))
+ })
+ }
+ })
+
+ function traverseNode(node, fun) {
+ fun(node)
+ for (var key in node.childNodes) traverseNode(node.childNodes[key], fun)
+ }
+
+ // Generate the `after`, `prepend`, `before`, `append`,
+ // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods.
+ adjacencyOperators.forEach(function(operator, operatorIndex) {
+ var inside = operatorIndex % 2 //=> prepend, append
+
+ $.fn[operator] = function(){
+ // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings
+ var argType, nodes = $.map(arguments, function(arg) {
+ argType = type(arg)
+ return argType == "object" || argType == "array" || arg == null ?
+ arg : zepto.fragment(arg)
+ }),
+ parent, copyByClone = this.length > 1
+ if (nodes.length < 1) return this
+
+ return this.each(function(_, target){
+ parent = inside ? target : target.parentNode
+
+ // convert all methods to a "before" operation
+ target = operatorIndex == 0 ? target.nextSibling :
+ operatorIndex == 1 ? target.firstChild :
+ operatorIndex == 2 ? target :
+ null
+
+ nodes.forEach(function(node){
+ if (copyByClone) node = node.cloneNode(true)
+ else if (!parent) return $(node).remove()
+
+ traverseNode(parent.insertBefore(node, target), function(el){
+ if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&
+ (!el.type || el.type === 'text/javascript') && !el.src)
+ window['eval'].call(window, el.innerHTML)
+ })
+ })
+ })
+ }
+
+ // after => insertAfter
+ // prepend => prependTo
+ // before => insertBefore
+ // append => appendTo
+ $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){
+ $(html)[operator](this)
+ return this
+ }
+ })
+
+ zepto.Z.prototype = $.fn
+
+ // Export internal API functions in the `$.zepto` namespace
+ zepto.uniq = uniq
+ zepto.deserializeValue = deserializeValue
+ $.zepto = zepto
+
+ return $
+})()
+
+window.Zepto = Zepto
+window.$ === undefined && (window.$ = Zepto)
+
+;(function($){
+ var _zid = 1, undefined,
+ slice = Array.prototype.slice,
+ isFunction = $.isFunction,
+ isString = function(obj){ return typeof obj == 'string' },
+ handlers = {},
+ specialEvents={},
+ focusinSupported = 'onfocusin' in window,
+ focus = { focus: 'focusin', blur: 'focusout' },
+ hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' }
+
+ specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'
+
+ function zid(element) {
+ return element._zid || (element._zid = _zid++)
+ }
+ function findHandlers(element, event, fn, selector) {
+ event = parse(event)
+ if (event.ns) var matcher = matcherFor(event.ns)
+ return (handlers[zid(element)] || []).filter(function(handler) {
+ return handler
+ && (!event.e || handler.e == event.e)
+ && (!event.ns || matcher.test(handler.ns))
+ && (!fn || zid(handler.fn) === zid(fn))
+ && (!selector || handler.sel == selector)
+ })
+ }
+ function parse(event) {
+ var parts = ('' + event).split('.')
+ return {e: parts[0], ns: parts.slice(1).sort().join(' ')}
+ }
+ function matcherFor(ns) {
+ return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)')
+ }
+
+ function eventCapture(handler, captureSetting) {
+ return handler.del &&
+ (!focusinSupported && (handler.e in focus)) ||
+ !!captureSetting
+ }
+
+ function realEvent(type) {
+ return hover[type] || (focusinSupported && focus[type]) || type
+ }
+
+ function add(element, events, fn, data, selector, delegator, capture){
+ var id = zid(element), set = (handlers[id] || (handlers[id] = []))
+ events.split(/\s/).forEach(function(event){
+ if (event == 'ready') return $(document).ready(fn)
+ var handler = parse(event)
+ handler.fn = fn
+ handler.sel = selector
+ // emulate mouseenter, mouseleave
+ if (handler.e in hover) fn = function(e){
+ var related = e.relatedTarget
+ if (!related || (related !== this && !$.contains(this, related)))
+ return handler.fn.apply(this, arguments)
+ }
+ handler.del = delegator
+ var callback = delegator || fn
+ handler.proxy = function(e){
+ e = compatible(e)
+ if (e.isImmediatePropagationStopped()) return
+ e.data = data
+ var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args))
+ if (result === false) e.preventDefault(), e.stopPropagation()
+ return result
+ }
+ handler.i = set.length
+ set.push(handler)
+ if ('addEventListener' in element)
+ element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
+ })
+ }
+ function remove(element, events, fn, selector, capture){
+ var id = zid(element)
+ ;(events || '').split(/\s/).forEach(function(event){
+ findHandlers(element, event, fn, selector).forEach(function(handler){
+ delete handlers[id][handler.i]
+ if ('removeEventListener' in element)
+ element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))
+ })
+ })
+ }
+
+ $.event = { add: add, remove: remove }
+
+ $.proxy = function(fn, context) {
+ if (isFunction(fn)) {
+ var proxyFn = function(){ return fn.apply(context, arguments) }
+ proxyFn._zid = zid(fn)
+ return proxyFn
+ } else if (isString(context)) {
+ return $.proxy(fn[context], fn)
+ } else {
+ throw new TypeError("expected function")
+ }
+ }
+
+ $.fn.bind = function(event, data, callback){
+ return this.on(event, data, callback)
+ }
+ $.fn.unbind = function(event, callback){
+ return this.off(event, callback)
+ }
+ $.fn.one = function(event, selector, data, callback){
+ return this.on(event, selector, data, callback, 1)
+ }
+
+ var returnTrue = function(){return true},
+ returnFalse = function(){return false},
+ ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$)/,
+ eventMethods = {
+ preventDefault: 'isDefaultPrevented',
+ stopImmediatePropagation: 'isImmediatePropagationStopped',
+ stopPropagation: 'isPropagationStopped'
+ }
+
+ function compatible(event, source) {
+ if (source || !event.isDefaultPrevented) {
+ source || (source = event)
+
+ $.each(eventMethods, function(name, predicate) {
+ var sourceMethod = source[name]
+ event[name] = function(){
+ this[predicate] = returnTrue
+ return sourceMethod && sourceMethod.apply(source, arguments)
+ }
+ event[predicate] = returnFalse
+ })
+
+ if (source.defaultPrevented !== undefined ? source.defaultPrevented :
+ 'returnValue' in source ? source.returnValue === false :
+ source.getPreventDefault && source.getPreventDefault())
+ event.isDefaultPrevented = returnTrue
+ }
+ return event
+ }
+
+ function createProxy(event) {
+ var key, proxy = { originalEvent: event }
+ for (key in event)
+ if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]
+
+ return compatible(proxy, event)
+ }
+
+ $.fn.delegate = function(selector, event, callback){
+ return this.on(event, selector, callback)
+ }
+ $.fn.undelegate = function(selector, event, callback){
+ return this.off(event, selector, callback)
+ }
+
+ $.fn.live = function(event, callback){
+ $(document.body).delegate(this.selector, event, callback)
+ return this
+ }
+ $.fn.die = function(event, callback){
+ $(document.body).undelegate(this.selector, event, callback)
+ return this
+ }
+
+ $.fn.on = function(event, selector, data, callback, one){
+ var autoRemove, delegator, $this = this
+ if (event && !isString(event)) {
+ $.each(event, function(type, fn){
+ $this.on(type, selector, data, fn, one)
+ })
+ return $this
+ }
+
+ if (!isString(selector) && !isFunction(callback) && callback !== false)
+ callback = data, data = selector, selector = undefined
+ if (isFunction(data) || data === false)
+ callback = data, data = undefined
+
+ if (callback === false) callback = returnFalse
+
+ return $this.each(function(_, element){
+ if (one) autoRemove = function(e){
+ remove(element, e.type, callback)
+ return callback.apply(this, arguments)
+ }
+
+ if (selector) delegator = function(e){
+ var evt, match = $(e.target).closest(selector, element).get(0)
+ if (match && match !== element) {
+ evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})
+ return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1)))
+ }
+ }
+
+ add(element, event, callback, data, selector, delegator || autoRemove)
+ })
+ }
+ $.fn.off = function(event, selector, callback){
+ var $this = this
+ if (event && !isString(event)) {
+ $.each(event, function(type, fn){
+ $this.off(type, selector, fn)
+ })
+ return $this
+ }
+
+ if (!isString(selector) && !isFunction(callback) && callback !== false)
+ callback = selector, selector = undefined
+
+ if (callback === false) callback = returnFalse
+
+ return $this.each(function(){
+ remove(this, event, callback, selector)
+ })
+ }
+
+ $.fn.trigger = function(event, args){
+ event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event)
+ event._args = args
+ return this.each(function(){
+ // items in the collection might not be DOM elements
+ if('dispatchEvent' in this) this.dispatchEvent(event)
+ else $(this).triggerHandler(event, args)
+ })
+ }
+
+ // triggers event handlers on current element just as if an event occurred,
+ // doesn't trigger an actual event, doesn't bubble
+ $.fn.triggerHandler = function(event, args){
+ var e, result
+ this.each(function(i, element){
+ e = createProxy(isString(event) ? $.Event(event) : event)
+ e._args = args
+ e.target = element
+ $.each(findHandlers(element, event.type || event), function(i, handler){
+ result = handler.proxy(e)
+ if (e.isImmediatePropagationStopped()) return false
+ })
+ })
+ return result
+ }
+
+ // shortcut methods for `.bind(event, fn)` for each event type
+ ;('focusin focusout load resize scroll unload click dblclick '+
+ 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+
+ 'change select keydown keypress keyup error').split(' ').forEach(function(event) {
+ $.fn[event] = function(callback) {
+ return callback ?
+ this.bind(event, callback) :
+ this.trigger(event)
+ }
+ })
+
+ ;['focus', 'blur'].forEach(function(name) {
+ $.fn[name] = function(callback) {
+ if (callback) this.bind(name, callback)
+ else this.each(function(){
+ try { this[name]() }
+ catch(e) {}
+ })
+ return this
+ }
+ })
+
+ $.Event = function(type, props) {
+ if (!isString(type)) props = type, type = props.type
+ var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true
+ if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])
+ event.initEvent(type, bubbles, true)
+ return compatible(event)
+ }
+
+})(Zepto)
+
+;(function($){
+ var jsonpID = 0,
+ document = window.document,
+ key,
+ name,
+ rscript = /
+
+
+
+
diff --git a/lib/zeptojs/examples/iphone/index.html b/lib/zeptojs/examples/iphone/index.html
new file mode 100644
index 0000000..10a9bc6
--- /dev/null
+++ b/lib/zeptojs/examples/iphone/index.html
@@ -0,0 +1,57 @@
+
+
+
+ iPhone.Zepto
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/zeptojs/examples/iphone/iphone.css b/lib/zeptojs/examples/iphone/iphone.css
new file mode 100644
index 0000000..1690361
--- /dev/null
+++ b/lib/zeptojs/examples/iphone/iphone.css
@@ -0,0 +1,161 @@
+* {
+ margin: 0px;
+ padding: 0px;
+}
+.toolbar {
+ -webkit-box-sizing: border-box;
+ background: #6D84A2 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAArCAIAAAA2QHWOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEpJREFUeNpNjCEOgEAQA5v9/9eQaAQCd57L0WXTDSmimXZEse1HnNcIIINZYTPVv7Ac4/EWe7OTsC/ec+nDgcj/dpcH7EXt8up4AfRWcOjLIqWFAAAAAElFTkSuQmCC) repeat-x;
+ border-bottom: 1px solid #2D3642;
+ height: 45px;
+ padding: 10px;
+ position: relative;
+}
+body {
+ -webkit-perspective: 800;
+ -webkit-text-size-adjust: none;
+ -webkit-transform-style: preserve-3d;
+ -webkit-user-select: none;
+ font-family: Helvetica;
+ overflow-x: hidden;
+ height: 100%;
+ width: 100%;
+}
+
+body > section {
+ background: #C5CCD3 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAABCAIAAACdaSOZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpiPHrmCgMC/GNjYwNSAAEGADdNA3dnzPlQAAAAAElFTkSuQmCC);
+ display: block;
+ left: 0px;
+ position: absolute;
+ width: 100%;
+ -webkit-transform: translate3d(100%,0%,0%);
+ opacity: 0;
+ -webkit-transition: all 0.25s ease-in-out;
+ -webkit-transform-style: preserve-3d;
+ z-index: -10;
+}
+
+.reverse {
+ -webkit-transform: translate3d(-100%, 0%, 0%);
+ opacity: 0;
+}
+
+.current {
+ -webkit-transform: translate3d(0%,0%, 0%);
+ opacity: 1;
+ z-index: 1;
+}
+h1, h2 {
+ color: #4C566C;
+ font: normal normal bold 18px/normal Helvetica;
+ margin: 10px 20px 6px;
+ text-shadow: rgba(255, 255, 255, 0.19)
+}
+body.landscape .toolbar > h1 {
+ margin-left: -125px;
+ width: 250px;
+}
+
+.toolbar > h1 {
+ color: white;
+ font-size: 20px;
+ font-weight: bold;
+ height: 40px;
+ left: 50%;
+ line-height: 1em;
+ margin: 1px 0px 0px -75px;
+ overflow: hidden;
+ position: absolute;
+ text-align: center;
+ text-overflow: ellipsis;
+ text-shadow: rgba(0, 0, 0, 0.398438) 0px -1px 0px;
+ top: 10px;
+ white-space: nowrap;
+ width: 150px;
+}
+
+ul {
+ background: white;
+ border: 1px solid #B4B4B4;
+ border-bottom-left-radius: 8px 8px;
+ border-bottom-right-radius: 8px 8px;
+ border-top-left-radius: 8px 8px;
+ border-top-right-radius: 8px 8px;
+ color: black;
+ font: normal normal bold 17px/normal Helvetica;
+ margin: 15px 10px 17px;
+ padding: 0px;
+}
+
+ul li {
+ color: black;
+ font-size: 14px;
+ border-top: 1px solid #B4B4B4;
+ color: #666;
+ list-style-type: none;
+ padding: 10px;
+}
+
+li:first-child, li:first-child a {
+ border-top: 0px;
+ border-top-left-radius: 8px 8px;
+ border-top-right-radius: 8px 8px;
+}
+
+ul li.arrow {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAUCAYAAAB4d5a9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAKVJREFUeNpi/P//PwOtARMDHcDwsYQFRJSXl8P4dVC6CZvizs5O8i1BsqARid9Ei+BiQ2KDLKumhSU1QNyKxG+hlkXoEQ+yqAPNogpapK5KNIvaKbUIVxKeAsTvkPg5QCxETUukgfgAkqFPgdgBzVKKLIFZoIJmwR1qBRdNLEC2BJQpV9LCAmRL/gBxAtRwqlqAXqzcgRrOQE0LQIBxtNIiBQAEGAA7xCa2yF9zEgAAAABJRU5ErkJggg==);
+ background-position: 100% 50%;
+ background-repeat: no-repeat;
+}
+
+body > .current {
+ display: block !important;
+}
+
+body.landscape > * {
+ min-height: 320px;
+}
+
+
+ul li a, li.img a + a {
+ color: black;
+ display: block;
+ margin: -10px;
+ overflow: hidden;
+ padding: 12px 10px;
+ text-decoration: none;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+
+.button, .back, .cancel, .add {
+-webkit-border-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAeCAIAAACqmwlGAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAatJREFUeNqVlMtKw0AUhqfJSRpTk5Za1FAvxS6sgrVeFrpQdOcT+IpuBVHcuVBQpCDYjeAdkSpavDTGNJkz43FpFZz8DISZ+b75J5tJbWwfMsZuby7rh/vN5v1H+539TMZxPa84v7g0WirTFISQR/t7jdOTcqVaGp+ze50uIfDbL62H3a3NqerMwtIqXF9dnF+dL6+t9/S6hmFqut4luHns80aKpcrxwY43PKK7+f6J2ZVcYTCl6ZIxKuwatEhbpmU72UKjfgCakXFz/TwW7L8QlgIbTNtBwVAgU0g644IGZoycqYVgQGRRLBQFggEpHJUFBI4iUhYIBhSSPooCwUB0zEWiBsERlRsECJSIUlEgOHmDH3TM909FgWBgqe8oCgRrLGGADlcvIDB5A2nfQ7kD6D5J/jn5lZILBoAUQgWVUgDoWi5r8zhUEXgU5nOOVp0sB+0W+f8WEDY9MabpYNUqQ29Pd1Hoi79eA1qkLQIIY5CGIOwUvYHBQr5xdvn4/BSGnS7BstIDhexUbVo3jNarD1Ky5xfftszF+WqPZcKvp5IjfoYRoYHv0/QLHvXjAb8xkEMAAAAASUVORK5CYII=) 0 5 0 5 stretch stretch;
+background: none;
+border-width: 0px 5px;
+color: white;
+font-family: inherit;
+font-size: 12px;
+font-weight: bold;
+height: 30px;
+line-height: 30px;
+margin: 0px;
+overflow: ;
+padding: 0px 3px;
+position: absolute;
+right: 6px;
+text-decoration: none;
+text-overflow: ellipsis;
+text-shadow: rgba(0, 0, 0, 0.496094) 0px -1px 0px;
+top: 8px;
+white-space: nowrap;
+width: auto;
+}
+
+.back {
+ -webkit-border-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACsAAAAeCAIAAAA6iHCJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAArFJREFUeNrF0mtPE2EQBeB5t9vSRqEUKiAFkasggmC5x3CRECHx8sH/qMHEoKkiMUQTNJIIaAjeiFGUcEsotN22u9vtOzMKogYL39rlyfkBk3NG3HsyC8dLJhOzM8+/fvkcjexAtghRXVN/dXCkvOIcAKhEDMdY+7ESejgeqKpv7x3J9/ogS5hoc33l0YPxju6+YFefSkRwlI311cnQRM/gbd+ZUpfb43CokD2nCv2lFbVvZib9JaUqMUEGTYtNPZ7oHLpZXBJQFIUYSCJkj3A4830lrd3Di2/nVcxYwTSMift3m4LXCovKCYGQIDe8vrJveNQfTE+Fys9f8pdVSSTILeFyF/z/B8uflnSLG+qakRlRQo45XO5DHejJxOtXLzsG7yA7ME2Qe0hw6A+mn4ZqLvY4XR6UCLZAxH8rfFx6Z6BaXVJlSQS7SKSDC+JabGFurrnvBvJ+NXZBYpX4oP9AQ5eietKSAMDuDt4vLkhHfr6/XCKCvZBIjezuLMzPN/XcIhIADPYiZPXFs8lAQ7dwOA8KsL8Dr7/CoDzSDDgJCT2ljI0OOzBGKMVJACGUXU2/3h/Uo5vMDCdBQSRLcn9nox7bEgLsDoDCDKYli4p89ZXFZjJ6Ah3wvlhcb2mqPa1a0jIBhJ1RiPl3wpH4QG+bTGwDo51DKPwHMccS5mBvSzyyCcB2rgB/k5aoqK72xgo9FrbxgsMSulkZOBvwu1O6BjnGhO48p8IZfj1EsPWCR+jSMiCX0pbh9xXsrZCZrW1toOcy6mFMpyA3mNnUwi2NtQoxZwaZwzF9bKhTpHaN+C7KNGQPobTMhBZe7Wyts1iox729RNyOJkeHOj4sf19Z3YgmsraI251X6ve2BYMEIqIlVebjd0rj2la0rrrySkuDU1UhSySiYVrbkbiZ2qv2J5+53J2yzo3SAAAAAElFTkSuQmCC) 0 8 0 14 stretch stretch;
+border-width: 0px 8px 0px 14px;
+left: 6px;
+max-width: 55px;
+padding: 0px;
+right: auto;
+}
diff --git a/lib/zeptojs/examples/load_jquery_on_ie.html b/lib/zeptojs/examples/load_jquery_on_ie.html
new file mode 100644
index 0000000..8c51d74
--- /dev/null
+++ b/lib/zeptojs/examples/load_jquery_on_ie.html
@@ -0,0 +1,18 @@
+
+
+
+ Load jQuery if Zepto is not supported
+
+
+ Load jQuery if Zepto is not supported
+
+
+
+
diff --git a/lib/zeptojs/examples/snow/index.html b/lib/zeptojs/examples/snow/index.html
new file mode 100644
index 0000000..8941004
--- /dev/null
+++ b/lib/zeptojs/examples/snow/index.html
@@ -0,0 +1,51 @@
+
+
+
+ Let it snow with Zepto.js
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/zeptojs/examples/touch_events.html b/lib/zeptojs/examples/touch_events.html
new file mode 100644
index 0000000..3a5eadf
--- /dev/null
+++ b/lib/zeptojs/examples/touch_events.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+ List item 1 DELETE
+ List item 2 DELETE
+ List item 3 DELETE
+ List item 4 DELETE
+
+
+
diff --git a/lib/zeptojs/make b/lib/zeptojs/make
new file mode 100755
index 0000000..d9254ee
--- /dev/null
+++ b/lib/zeptojs/make
@@ -0,0 +1,98 @@
+#!/usr/bin/env coffee
+require 'shelljs/make'
+fs = require 'fs'
+
+version = '1.1.3'
+zepto_js = 'dist/zepto.js'
+zepto_min = 'dist/zepto.min.js'
+zepto_gz = 'dist/zepto.min.gz'
+
+port = 3999
+root = __dirname + '/'
+
+target.all = ->
+ target[zepto_js]()
+ target.test()
+
+## TASKS ##
+
+target.test = ->
+ test_app = require './test/server'
+ server = test_app.listen port
+ exec "phantomjs --disk-cache=true test/runner.coffee 'http://localhost:#{port}/'", (code) ->
+ server.close -> exit(code)
+
+target[zepto_js] = ->
+ target.build() unless test('-e', zepto_js)
+
+target[zepto_min] = ->
+ target.minify() if stale(zepto_min, zepto_js)
+
+target[zepto_gz] = ->
+ target.compress() if stale(zepto_gz, zepto_min)
+
+target.dist = ->
+ target.build()
+ target.minify()
+ target.compress()
+
+target.build = ->
+ cd __dirname
+ mkdir '-p', 'dist'
+ modules = (env['MODULES'] || 'zepto event ajax form ie').split(' ')
+ module_files = ( "src/#{module}.js" for module in modules )
+ intro = "/* Zepto #{describe_version()} - #{modules.join(' ')} - zeptojs.com/license */\n"
+ dist = intro + cat(module_files).replace(/^\/[\/*].*$/mg, '').replace(/\n{3,}/g, "\n\n")
+ dist.to(zepto_js)
+ report_size(zepto_js)
+
+target.minify = ->
+ target.build() unless test('-e', zepto_js)
+ zepto_code = cat(zepto_js)
+ intro = zepto_code.slice(0, zepto_code.indexOf("\n") + 1)
+ (intro + minify(zepto_code)).to(zepto_min)
+ report_size(zepto_min)
+
+target.compress = ->
+ gzip = require('zlib').createGzip()
+ inp = fs.createReadStream(zepto_min)
+ out = fs.createWriteStream(zepto_gz)
+ inp.pipe(gzip).pipe(out)
+ out.on 'close', ->
+ report_size(zepto_gz)
+ factor = fsize(zepto_js) / fsize(zepto_gz)
+ echo "compression factor: #{format_number(factor)}"
+
+## HELPERS ##
+
+stale = (file, source) ->
+ target[source]()
+ !test('-e', file) || mtime(file) < mtime(source)
+
+mtime = (file) ->
+ fs.statSync(file).mtime.getTime()
+
+fsize = (file) ->
+ fs.statSync(file).size
+
+format_number = (size, precision = 1) ->
+ factor = Math.pow(10, precision)
+ decimal = Math.round(size * factor) % factor
+ parseInt(size) + "." + decimal
+
+report_size = (file) ->
+ echo "#{file}: #{format_number(fsize(file) / 1024)} KiB"
+
+describe_version = ->
+ desc = exec "git --git-dir='#{root + '.git'}' describe --tags HEAD", silent: true
+ if desc.code is 0 then desc.output.replace(/\s+$/, '') else version
+
+minify = (source_code) ->
+ uglify = require('uglify-js')
+ compressor = uglify.Compressor()
+ ast = uglify.parse(source_code)
+ ast.figure_out_scope()
+ ast.compute_char_frequency();
+ ast.mangle_names();
+ ast = ast.transform(compressor)
+ return ast.print_to_string()
diff --git a/lib/zeptojs/package.json b/lib/zeptojs/package.json
new file mode 100644
index 0000000..c89f50e
--- /dev/null
+++ b/lib/zeptojs/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "zepto"
+ , "version": "1.1.3"
+ , "homepage": "http://zeptojs.com"
+ , "scripts": {
+ "test": "coffee make test"
+ , "dist": "coffee make dist"
+ , "start": "coffee test/server.coffee"
+ }
+ , "repository": {
+ "type": "git"
+ , "url": "https://github.com/madrobby/zepto.git"
+ }
+ , "licenses": [
+ {
+ "type": "MIT"
+ , "url": "http://zeptojs.com/license/"
+ }
+ ]
+ , "devDependencies": {
+ "uglify-js": "2.4.x"
+ , "express": "3.1.x"
+ , "coffee-script": "1.5.x"
+ , "shelljs": "0.1.x"
+ }
+}
diff --git a/lib/zeptojs/script/bootstrap b/lib/zeptojs/script/bootstrap
new file mode 100755
index 0000000..bd84bb1
--- /dev/null
+++ b/lib/zeptojs/script/bootstrap
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+set -e
+
+npm install
+
+if phantom_version="$(phantomjs --version)"; then
+ echo "phantomjs ${phantom_version}"
+else
+ echo "You should install PhantomJS for \`script/test' to work." >&2
+fi
diff --git a/lib/zeptojs/script/guard b/lib/zeptojs/script/guard
new file mode 100755
index 0000000..93fe00e
--- /dev/null
+++ b/lib/zeptojs/script/guard
@@ -0,0 +1,6 @@
+#!/bin/sh
+if [ -z "$BUNDLE_GEMFILE" ]; then
+ export BUNDLE_GEMFILE=shutup
+fi
+
+exec guard --no-notify "$@"
diff --git a/lib/zeptojs/script/test b/lib/zeptojs/script/test
new file mode 100755
index 0000000..2d76bc5
--- /dev/null
+++ b/lib/zeptojs/script/test
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+port=3999
+
+export PATH=node_modules/.bin:"$PATH"
+
+coffee test/server.coffee $port &
+pid=$!
+
+terminate_test_server() {
+ kill $pid
+}
+trap terminate_test_server EXIT
+
+phantomjs --disk-cache=true \
+ test/runner.coffee "http://localhost:${port}/" "$@" \
+ 2> >(grep -v "CoreText performance note" >&2)
+
+exit $?
diff --git a/lib/zeptojs/src/ajax.js b/lib/zeptojs/src/ajax.js
new file mode 100644
index 0000000..1402c5a
--- /dev/null
+++ b/lib/zeptojs/src/ajax.js
@@ -0,0 +1,344 @@
+// Zepto.js
+// (c) 2010-2014 Thomas Fuchs
+// Zepto.js may be freely distributed under the MIT license.
+
+;(function($){
+ var jsonpID = 0,
+ document = window.document,
+ key,
+ name,
+ rscript = /
+
+
+
+
+ Zepto Ajax unit tests
+
+ Running… see browser console for results
+
+
+
+
+
+