coolstrap-generator 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. data/.DS_Store +0 -0
  2. data/.gitignore +4 -0
  3. data/.rvmrc +1 -0
  4. data/Gemfile +4 -0
  5. data/Rakefile +6 -0
  6. data/bin/coolstrap +5 -0
  7. data/coolstrap-generator.gemspec +42 -0
  8. data/lib/.DS_Store +0 -0
  9. data/lib/coolstrap-generator.rb +39 -0
  10. data/lib/coolstrap-generator/.DS_Store +0 -0
  11. data/lib/coolstrap-generator/builder/middleman.rb +0 -0
  12. data/lib/coolstrap-generator/cli.rb +71 -0
  13. data/lib/coolstrap-generator/generate/project.rb +96 -0
  14. data/lib/coolstrap-generator/generate/view.rb +54 -0
  15. data/lib/coolstrap-generator/logger.rb +13 -0
  16. data/lib/coolstrap-generator/middleman/helpers.rb +176 -0
  17. data/lib/coolstrap-generator/templates/.DS_Store +0 -0
  18. data/lib/coolstrap-generator/templates/app/.DS_Store +0 -0
  19. data/lib/coolstrap-generator/templates/app/assets/.DS_Store +0 -0
  20. data/lib/coolstrap-generator/templates/app/assets/fonts/fontawesome-webfont.eot +0 -0
  21. data/lib/coolstrap-generator/templates/app/assets/fonts/fontawesome-webfont.svg +255 -0
  22. data/lib/coolstrap-generator/templates/app/assets/fonts/fontawesome-webfont.ttf +0 -0
  23. data/lib/coolstrap-generator/templates/app/assets/fonts/fontawesome-webfont.woff +0 -0
  24. data/lib/coolstrap-generator/templates/app/assets/images/.DS_Store +0 -0
  25. data/lib/coolstrap-generator/templates/app/assets/images/coolstrap/arrow-list.png +0 -0
  26. data/lib/coolstrap-generator/templates/app/assets/images/coolstrap/arrow.png +0 -0
  27. data/lib/coolstrap-generator/templates/app/assets/images/coolstrap/menu.png +0 -0
  28. data/lib/coolstrap-generator/templates/app/assets/images/coolstrap/startup/smatphone.png +0 -0
  29. data/lib/coolstrap-generator/templates/app/assets/images/coolstrap/startup/smatphone@2x.png +0 -0
  30. data/lib/coolstrap-generator/templates/app/assets/images/coolstrap/startup/tablet-landscape.png +0 -0
  31. data/lib/coolstrap-generator/templates/app/assets/images/coolstrap/startup/tablet-landscape@2x.png +0 -0
  32. data/lib/coolstrap-generator/templates/app/assets/images/coolstrap/startup/tablet-portrait.png +0 -0
  33. data/lib/coolstrap-generator/templates/app/assets/images/coolstrap/startup/tablet-portrait@2x.png +0 -0
  34. data/lib/coolstrap-generator/templates/app/assets/images/startup/smatphone.png +0 -0
  35. data/lib/coolstrap-generator/templates/app/assets/images/startup/smatphone@2x.png +0 -0
  36. data/lib/coolstrap-generator/templates/app/assets/images/startup/tablet-landscape.png +0 -0
  37. data/lib/coolstrap-generator/templates/app/assets/images/startup/tablet-landscape@2x.png +0 -0
  38. data/lib/coolstrap-generator/templates/app/assets/images/startup/tablet-portrait.png +0 -0
  39. data/lib/coolstrap-generator/templates/app/assets/images/startup/tablet-portrait@2x.png +0 -0
  40. data/lib/coolstrap-generator/templates/app/assets/javascripts/.DS_Store +0 -0
  41. data/lib/coolstrap-generator/templates/app/assets/javascripts/app.js +18 -0
  42. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/_Coolstrap.App.coffee +39 -0
  43. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/_Coolstrap.Console.coffee +49 -0
  44. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/_Coolstrap.Constants.coffee +89 -0
  45. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/_Coolstrap.js +13 -0
  46. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/build/_wrap-start.js +18 -0
  47. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/coolstrap-0.1.js +20 -0
  48. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/coolstrap-0.1.packed.js +23 -0
  49. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/fallback/_Coolstrap.Fallback.Android.coffee +53 -0
  50. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/fallback/_Coolstrap.Fallback.iOS.coffee +29 -0
  51. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/framework/_Coolstrap.Framework.Articles.coffee +34 -0
  52. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/framework/_Coolstrap.Framework.Dialogs.coffee +33 -0
  53. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/framework/_Coolstrap.Framework.Navigation.coffee +118 -0
  54. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/framework/_Coolstrap.Framework.Sections.coffee +60 -0
  55. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/lib/iscroll.js +1076 -0
  56. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/lib/modernizr-2.5.3.js +1265 -0
  57. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/lib/zepto-1.0rc1.js +1357 -0
  58. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/navigate/_Coolstrap.Navigate.History.coffee +164 -0
  59. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/navigate/_Coolstrap.Navigate.coffee +105 -0
  60. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/plugins/_Coolstrap.Plugins.coffee +157 -0
  61. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/util/_Coolstrap.Util.Core.coffee +54 -0
  62. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/util/_Coolstrap.Util.Platform.coffee +89 -0
  63. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/util/_Coolstrap.Util.UI.coffee +96 -0
  64. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/util/_Coolstrap.Util.coffee +41 -0
  65. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/view/_Coolstrap.View.Article.coffee +43 -0
  66. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/view/_Coolstrap.View.Aside.coffee +65 -0
  67. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/view/_Coolstrap.View.Dialog.coffee +129 -0
  68. data/lib/coolstrap-generator/templates/app/assets/javascripts/coolstrap/view/_Coolstrap.View.Scroll.coffee +191 -0
  69. data/lib/coolstrap-generator/templates/app/assets/stylesheets/.DS_Store +0 -0
  70. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/_structure.scss +8 -0
  71. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/coolstrap.css.scss +2 -0
  72. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/_components.scss +5 -0
  73. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/_layout.scss +4 -0
  74. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/_utilities.scss +6 -0
  75. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/components/_dialog.scss +122 -0
  76. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/components/_formelements.scss +89 -0
  77. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/components/_listview.scss +76 -0
  78. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/components/_navigations.scss +192 -0
  79. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/components/_tools.scss +169 -0
  80. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/layout/_layers.scss +57 -0
  81. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/layout/_layout.scss +62 -0
  82. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/layout/_positions.scss +38 -0
  83. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/layout/_transitions.scss +35 -0
  84. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/utilities/_animate.scss +63 -0
  85. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/utilities/_helpers.scss +82 -0
  86. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/utilities/_icons.scss +336 -0
  87. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/utilities/_mixins.scss +45 -0
  88. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/utilities/_reset.scss +367 -0
  89. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/structure/utilities/_variables.scss +176 -0
  90. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/themes/_default.scss +255 -0
  91. data/lib/coolstrap-generator/templates/app/assets/stylesheets/coolstrap/themes/coolstrap.css.scss +164 -0
  92. data/lib/coolstrap-generator/templates/app/assets/stylesheets/customtheme.css.scss +19 -0
  93. data/lib/coolstrap-generator/templates/app/components/_formelements.html.haml +130 -0
  94. data/lib/coolstrap-generator/templates/app/components/_tabbar.html.haml +343 -0
  95. data/lib/coolstrap-generator/templates/app/components/_toolbar.html.haml +463 -0
  96. data/lib/coolstrap-generator/templates/app/components/formelements.html.haml +196 -0
  97. data/lib/coolstrap-generator/templates/app/components/listview/_complexlistavatar.html.haml.erb +77 -0
  98. data/lib/coolstrap-generator/templates/app/components/listview/_simplelist.html.haml.erb +31 -0
  99. data/lib/coolstrap-generator/templates/app/components/tabbar.html.haml.erb +16 -0
  100. data/lib/coolstrap-generator/templates/app/components/toolbar.html.haml.erb +32 -0
  101. data/lib/coolstrap-generator/templates/app/index.html.haml.erb +21 -0
  102. data/lib/coolstrap-generator/templates/app/layout.haml.erb +79 -0
  103. data/lib/coolstrap-generator/templates/app/views/.DS_Store +0 -0
  104. data/lib/coolstrap-generator/templates/app/views/_home.haml.erb +31 -0
  105. data/lib/coolstrap-generator/templates/app/views/shared/_aside_onbottom.haml +2 -0
  106. data/lib/coolstrap-generator/templates/app/views/shared/_aside_onleft.haml +56 -0
  107. data/lib/coolstrap-generator/templates/app/views/shared/_aside_onright.haml +66 -0
  108. data/lib/coolstrap-generator/templates/app/views/shared/_aside_ontop.haml +19 -0
  109. data/lib/coolstrap-generator/templates/defaults/Gemfile.erb +3 -0
  110. data/lib/coolstrap-generator/templates/defaults/LICENSE.erb +1 -0
  111. data/lib/coolstrap-generator/templates/defaults/Readme.mkd.erb +1 -0
  112. data/lib/coolstrap-generator/templates/defaults/config.erb +42 -0
  113. data/lib/coolstrap-generator/templates/defaults/gitignore.erb +2 -0
  114. data/lib/coolstrap-generator/templates/rakefile +102 -0
  115. data/lib/coolstrap-generator/templates/specs/app_spec.coffee +3 -0
  116. data/lib/coolstrap-generator/utils.rb +82 -0
  117. data/lib/coolstrap-generator/version.rb +5 -0
  118. data/readme.md +107 -0
  119. data/spec/cli/command_spec.rb +88 -0
  120. data/spec/coolstrap-generator/generate/project_spec.rb +126 -0
  121. data/spec/coolstrap-generator/generate/view_spec.rb +26 -0
  122. data/spec/coolstrap-generator/logger_spec.rb +25 -0
  123. data/spec/coolstrap-generator/middleman/helpers_spec.rb +16 -0
  124. data/spec/coolstrap-generator/utils_spec.rb +120 -0
  125. data/spec/spec_helper.rb +39 -0
  126. metadata +321 -0
@@ -0,0 +1,1357 @@
1
+ /* Zepto v1.0rc1 - polyfill zepto event detect fx ajax form touch - zeptojs.com/license */
2
+ ;(function(undefined){
3
+ if (String.prototype.trim === undefined) // fix for iOS 3.2
4
+ String.prototype.trim = function(){ return this.replace(/^\s+/, '').replace(/\s+$/, '') }
5
+
6
+ // For iOS 3.x
7
+ // from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce
8
+ if (Array.prototype.reduce === undefined)
9
+ Array.prototype.reduce = function(fun){
10
+ if(this === void 0 || this === null) throw new TypeError()
11
+ var t = Object(this), len = t.length >>> 0, k = 0, accumulator
12
+ if(typeof fun != 'function') throw new TypeError()
13
+ if(len == 0 && arguments.length == 1) throw new TypeError()
14
+
15
+ if(arguments.length >= 2)
16
+ accumulator = arguments[1]
17
+ else
18
+ do{
19
+ if(k in t){
20
+ accumulator = t[k++]
21
+ break
22
+ }
23
+ if(++k >= len) throw new TypeError()
24
+ } while (true)
25
+
26
+ while (k < len){
27
+ if(k in t) accumulator = fun.call(undefined, accumulator, t[k], k, t)
28
+ k++
29
+ }
30
+ return accumulator
31
+ }
32
+
33
+ })()
34
+ var Zepto = (function() {
35
+ var undefined, key, $, classList, emptyArray = [], slice = emptyArray.slice,
36
+ document = window.document,
37
+ elementDisplay = {}, classCache = {},
38
+ getComputedStyle = document.defaultView.getComputedStyle,
39
+ cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 },
40
+ fragmentRE = /^\s*<(\w+|!)[^>]*>/,
41
+
42
+ // Used by `$.zepto.init` to wrap elements, text/comment nodes, document,
43
+ // and document fragment node types.
44
+ elementTypes = [1, 3, 8, 9, 11],
45
+
46
+ adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ],
47
+ table = document.createElement('table'),
48
+ tableRow = document.createElement('tr'),
49
+ containers = {
50
+ 'tr': document.createElement('tbody'),
51
+ 'tbody': table, 'thead': table, 'tfoot': table,
52
+ 'td': tableRow, 'th': tableRow,
53
+ '*': document.createElement('div')
54
+ },
55
+ readyRE = /complete|loaded|interactive/,
56
+ classSelectorRE = /^\.([\w-]+)$/,
57
+ idSelectorRE = /^#([\w-]+)$/,
58
+ tagSelectorRE = /^[\w-]+$/,
59
+ toString = ({}).toString,
60
+ zepto = {},
61
+ camelize, uniq,
62
+ tempParent = document.createElement('div')
63
+
64
+ zepto.matches = function(element, selector) {
65
+ if (!element || element.nodeType !== 1) return false
66
+ var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector ||
67
+ element.oMatchesSelector || element.matchesSelector
68
+ if (matchesSelector) return matchesSelector.call(element, selector)
69
+ // fall back to performing a selector:
70
+ var match, parent = element.parentNode, temp = !parent
71
+ if (temp) (parent = tempParent).appendChild(element)
72
+ match = ~zepto.qsa(parent, selector).indexOf(element)
73
+ temp && tempParent.removeChild(element)
74
+ return match
75
+ }
76
+
77
+ function isFunction(value) { return toString.call(value) == "[object Function]" }
78
+ function isObject(value) { return value instanceof Object }
79
+ function isPlainObject(value) {
80
+ var key, ctor
81
+ if (toString.call(value) !== "[object Object]") return false
82
+ ctor = (isFunction(value.constructor) && value.constructor.prototype)
83
+ if (!ctor || !hasOwnProperty.call(ctor, 'isPrototypeOf')) return false
84
+ for (key in value);
85
+ return key === undefined || hasOwnProperty.call(value, key)
86
+ }
87
+ function isArray(value) { return value instanceof Array }
88
+ function likeArray(obj) { return typeof obj.length == 'number' }
89
+
90
+ function compact(array) { return array.filter(function(item){ return item !== undefined && item !== null }) }
91
+ function flatten(array) { return array.length > 0 ? [].concat.apply([], array) : array }
92
+ camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }
93
+ function dasherize(str) {
94
+ return str.replace(/::/g, '/')
95
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
96
+ .replace(/([a-z\d])([A-Z])/g, '$1_$2')
97
+ .replace(/_/g, '-')
98
+ .toLowerCase()
99
+ }
100
+ uniq = function(array){ return array.filter(function(item, idx){ return array.indexOf(item) == idx }) }
101
+
102
+ function classRE(name) {
103
+ return name in classCache ?
104
+ classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)'))
105
+ }
106
+
107
+ function maybeAddPx(name, value) {
108
+ return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value
109
+ }
110
+
111
+ function defaultDisplay(nodeName) {
112
+ var element, display
113
+ if (!elementDisplay[nodeName]) {
114
+ element = document.createElement(nodeName)
115
+ document.body.appendChild(element)
116
+ display = getComputedStyle(element, '').getPropertyValue("display")
117
+ element.parentNode.removeChild(element)
118
+ display == "none" && (display = "block")
119
+ elementDisplay[nodeName] = display
120
+ }
121
+ return elementDisplay[nodeName]
122
+ }
123
+
124
+ // `$.zepto.fragment` takes a html string and an optional tag name
125
+ // to generate DOM nodes nodes from the given html string.
126
+ // The generated DOM nodes are returned as an array.
127
+ // This function can be overriden in plugins for example to make
128
+ // it compatible with browsers that don't support the DOM fully.
129
+ zepto.fragment = function(html, name) {
130
+ if (name === undefined) name = fragmentRE.test(html) && RegExp.$1
131
+ if (!(name in containers)) name = '*'
132
+ var container = containers[name]
133
+ container.innerHTML = '' + html
134
+ return $.each(slice.call(container.childNodes), function(){
135
+ container.removeChild(this)
136
+ })
137
+ }
138
+
139
+ // `$.zepto.Z` swaps out the prototype of the given `dom` array
140
+ // of nodes with `$.fn` and thus supplying all the Zepto functions
141
+ // to the array. Note that `__proto__` is not supported on Internet
142
+ // Explorer. This method can be overriden in plugins.
143
+ zepto.Z = function(dom, selector) {
144
+ dom = dom || []
145
+ dom.__proto__ = arguments.callee.prototype
146
+ dom.selector = selector || ''
147
+ return dom
148
+ }
149
+
150
+ // `$.zepto.isZ` should return `true` if the given object is a Zepto
151
+ // collection. This method can be overriden in plugins.
152
+ zepto.isZ = function(object) {
153
+ return object instanceof zepto.Z
154
+ }
155
+
156
+ // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and
157
+ // takes a CSS selector and an optional context (and handles various
158
+ // special cases).
159
+ // This method can be overriden in plugins.
160
+ zepto.init = function(selector, context) {
161
+ // If nothing given, return an empty Zepto collection
162
+ if (!selector) return zepto.Z()
163
+ // If a function is given, call it when the DOM is ready
164
+ else if (isFunction(selector)) return $(document).ready(selector)
165
+ // If a Zepto collection is given, juts return it
166
+ else if (zepto.isZ(selector)) return selector
167
+ else {
168
+ var dom
169
+ // normalize array if an array of nodes is given
170
+ if (isArray(selector)) dom = compact(selector)
171
+ // if a JavaScript object is given, return a copy of it
172
+ // this is a somewhat peculiar option, but supported by
173
+ // jQuery so we'll do it, too
174
+ else if (isPlainObject(selector))
175
+ dom = [$.extend({}, selector)], selector = null
176
+ // wrap stuff like `document` or `window`
177
+ else if (elementTypes.indexOf(selector.nodeType) >= 0 || selector === window)
178
+ dom = [selector], selector = null
179
+ // If it's a html fragment, create nodes from it
180
+ else if (fragmentRE.test(selector))
181
+ dom = zepto.fragment(selector.trim(), RegExp.$1), selector = null
182
+ // If there's a context, create a collection on that context first, and select
183
+ // nodes from there
184
+ else if (context !== undefined) return $(context).find(selector)
185
+ // And last but no least, if it's a CSS selector, use it to select nodes.
186
+ else dom = zepto.qsa(document, selector)
187
+ // create a new Zepto collection from the nodes found
188
+ return zepto.Z(dom, selector)
189
+ }
190
+ }
191
+
192
+ // `$` will be the base `Zepto` object. When calling this
193
+ // function just call `$.zepto.init, whichs makes the implementation
194
+ // details of selecting nodes and creating Zepto collections
195
+ // patchable in plugins.
196
+ $ = function(selector, context){
197
+ return zepto.init(selector, context)
198
+ }
199
+
200
+ // Copy all but undefined properties from one or more
201
+ // objects to the `target` object.
202
+ $.extend = function(target){
203
+ slice.call(arguments, 1).forEach(function(source) {
204
+ for (key in source)
205
+ if (source[key] !== undefined)
206
+ target[key] = source[key]
207
+ })
208
+ return target
209
+ }
210
+
211
+ // `$.zepto.qsa` is Zepto's CSS selector implementation which
212
+ // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`.
213
+ // This method can be overriden in plugins.
214
+ zepto.qsa = function(element, selector){
215
+ var found
216
+ return (element === document && idSelectorRE.test(selector)) ?
217
+ ( (found = element.getElementById(RegExp.$1)) ? [found] : emptyArray ) :
218
+ (element.nodeType !== 1 && element.nodeType !== 9) ? emptyArray :
219
+ slice.call(
220
+ classSelectorRE.test(selector) ? element.getElementsByClassName(RegExp.$1) :
221
+ tagSelectorRE.test(selector) ? element.getElementsByTagName(selector) :
222
+ element.querySelectorAll(selector)
223
+ )
224
+ }
225
+
226
+ function filtered(nodes, selector) {
227
+ return selector === undefined ? $(nodes) : $(nodes).filter(selector)
228
+ }
229
+
230
+ function funcArg(context, arg, idx, payload) {
231
+ return isFunction(arg) ? arg.call(context, idx, payload) : arg
232
+ }
233
+
234
+ $.isFunction = isFunction
235
+ $.isObject = isObject
236
+ $.isArray = isArray
237
+ $.isPlainObject = isPlainObject
238
+
239
+ $.inArray = function(elem, array, i){
240
+ return emptyArray.indexOf.call(array, elem, i)
241
+ }
242
+
243
+ $.trim = function(str) { return str.trim() }
244
+
245
+ // plugin compatibility
246
+ $.uuid = 0
247
+
248
+ $.map = function(elements, callback){
249
+ var value, values = [], i, key
250
+ if (likeArray(elements))
251
+ for (i = 0; i < elements.length; i++) {
252
+ value = callback(elements[i], i)
253
+ if (value != null) values.push(value)
254
+ }
255
+ else
256
+ for (key in elements) {
257
+ value = callback(elements[key], key)
258
+ if (value != null) values.push(value)
259
+ }
260
+ return flatten(values)
261
+ }
262
+
263
+ $.each = function(elements, callback){
264
+ var i, key
265
+ if (likeArray(elements)) {
266
+ for (i = 0; i < elements.length; i++)
267
+ if (callback.call(elements[i], i, elements[i]) === false) return elements
268
+ } else {
269
+ for (key in elements)
270
+ if (callback.call(elements[key], key, elements[key]) === false) return elements
271
+ }
272
+
273
+ return elements
274
+ }
275
+
276
+ // Define methods that will be available on all
277
+ // Zepto collections
278
+ $.fn = {
279
+ // Because a collection acts like an array
280
+ // copy over these useful array functions.
281
+ forEach: emptyArray.forEach,
282
+ reduce: emptyArray.reduce,
283
+ push: emptyArray.push,
284
+ indexOf: emptyArray.indexOf,
285
+ concat: emptyArray.concat,
286
+
287
+ // `map` and `slice` in the jQuery API work differently
288
+ // from their array counterparts
289
+ map: function(fn){
290
+ return $.map(this, function(el, i){ return fn.call(el, i, el) })
291
+ },
292
+ slice: function(){
293
+ return $(slice.apply(this, arguments))
294
+ },
295
+
296
+ ready: function(callback){
297
+ if (readyRE.test(document.readyState)) callback($)
298
+ else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false)
299
+ return this
300
+ },
301
+ get: function(idx){
302
+ return idx === undefined ? slice.call(this) : this[idx]
303
+ },
304
+ toArray: function(){ return this.get() },
305
+ size: function(){
306
+ return this.length
307
+ },
308
+ remove: function(){
309
+ return this.each(function(){
310
+ if (this.parentNode != null)
311
+ this.parentNode.removeChild(this)
312
+ })
313
+ },
314
+ each: function(callback){
315
+ this.forEach(function(el, idx){ callback.call(el, idx, el) })
316
+ return this
317
+ },
318
+ filter: function(selector){
319
+ return $([].filter.call(this, function(element){
320
+ return zepto.matches(element, selector)
321
+ }))
322
+ },
323
+ add: function(selector,context){
324
+ return $(uniq(this.concat($(selector,context))))
325
+ },
326
+ is: function(selector){
327
+ return this.length > 0 && zepto.matches(this[0], selector)
328
+ },
329
+ not: function(selector){
330
+ var nodes=[]
331
+ if (isFunction(selector) && selector.call !== undefined)
332
+ this.each(function(idx){
333
+ if (!selector.call(this,idx)) nodes.push(this)
334
+ })
335
+ else {
336
+ var excludes = typeof selector == 'string' ? this.filter(selector) :
337
+ (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)
338
+ this.forEach(function(el){
339
+ if (excludes.indexOf(el) < 0) nodes.push(el)
340
+ })
341
+ }
342
+ return $(nodes)
343
+ },
344
+ eq: function(idx){
345
+ return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1)
346
+ },
347
+ first: function(){
348
+ var el = this[0]
349
+ return el && !isObject(el) ? el : $(el)
350
+ },
351
+ last: function(){
352
+ var el = this[this.length - 1]
353
+ return el && !isObject(el) ? el : $(el)
354
+ },
355
+ find: function(selector){
356
+ var result
357
+ if (this.length == 1) result = zepto.qsa(this[0], selector)
358
+ else result = this.map(function(){ return zepto.qsa(this, selector) })
359
+ return $(result)
360
+ },
361
+ closest: function(selector, context){
362
+ var node = this[0]
363
+ while (node && !zepto.matches(node, selector))
364
+ node = node !== context && node !== document && node.parentNode
365
+ return $(node)
366
+ },
367
+ parents: function(selector){
368
+ var ancestors = [], nodes = this
369
+ while (nodes.length > 0)
370
+ nodes = $.map(nodes, function(node){
371
+ if ((node = node.parentNode) && node !== document && ancestors.indexOf(node) < 0) {
372
+ ancestors.push(node)
373
+ return node
374
+ }
375
+ })
376
+ return filtered(ancestors, selector)
377
+ },
378
+ parent: function(selector){
379
+ return filtered(uniq(this.pluck('parentNode')), selector)
380
+ },
381
+ children: function(selector){
382
+ return filtered(this.map(function(){ return slice.call(this.children) }), selector)
383
+ },
384
+ siblings: function(selector){
385
+ return filtered(this.map(function(i, el){
386
+ return slice.call(el.parentNode.children).filter(function(child){ return child!==el })
387
+ }), selector)
388
+ },
389
+ empty: function(){
390
+ return this.each(function(){ this.innerHTML = '' })
391
+ },
392
+ // `pluck` is borrowed from Prototype.js
393
+ pluck: function(property){
394
+ return this.map(function(){ return this[property] })
395
+ },
396
+ show: function(){
397
+ return this.each(function(){
398
+ this.style.display == "none" && (this.style.display = null)
399
+ if (getComputedStyle(this, '').getPropertyValue("display") == "none")
400
+ this.style.display = defaultDisplay(this.nodeName)
401
+ })
402
+ },
403
+ replaceWith: function(newContent){
404
+ return this.before(newContent).remove()
405
+ },
406
+ wrap: function(newContent){
407
+ return this.each(function(){
408
+ $(this).wrapAll($(newContent)[0].cloneNode(false))
409
+ })
410
+ },
411
+ wrapAll: function(newContent){
412
+ if (this[0]) {
413
+ $(this[0]).before(newContent = $(newContent))
414
+ newContent.append(this)
415
+ }
416
+ return this
417
+ },
418
+ unwrap: function(){
419
+ this.parent().each(function(){
420
+ $(this).replaceWith($(this).children())
421
+ })
422
+ return this
423
+ },
424
+ clone: function(){
425
+ return $(this.map(function(){ return this.cloneNode(true) }))
426
+ },
427
+ hide: function(){
428
+ return this.css("display", "none")
429
+ },
430
+ toggle: function(setting){
431
+ return (setting === undefined ? this.css("display") == "none" : setting) ? this.show() : this.hide()
432
+ },
433
+ prev: function(){ return $(this.pluck('previousElementSibling')) },
434
+ next: function(){ return $(this.pluck('nextElementSibling')) },
435
+ html: function(html){
436
+ return html === undefined ?
437
+ (this.length > 0 ? this[0].innerHTML : null) :
438
+ this.each(function(idx){
439
+ var originHtml = this.innerHTML
440
+ $(this).empty().append( funcArg(this, html, idx, originHtml) )
441
+ })
442
+ },
443
+ text: function(text){
444
+ return text === undefined ?
445
+ (this.length > 0 ? this[0].textContent : null) :
446
+ this.each(function(){ this.textContent = text })
447
+ },
448
+ attr: function(name, value){
449
+ var result
450
+ return (typeof name == 'string' && value === undefined) ?
451
+ (this.length == 0 || this[0].nodeType !== 1 ? undefined :
452
+ (name == 'value' && this[0].nodeName == 'INPUT') ? this.val() :
453
+ (!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result
454
+ ) :
455
+ this.each(function(idx){
456
+ if (this.nodeType !== 1) return
457
+ if (isObject(name)) for (key in name) this.setAttribute(key, name[key])
458
+ else this.setAttribute(name, funcArg(this, value, idx, this.getAttribute(name)))
459
+ })
460
+ },
461
+ removeAttr: function(name){
462
+ return this.each(function(){ if (this.nodeType === 1) this.removeAttribute(name) })
463
+ },
464
+ prop: function(name, value){
465
+ return (value === undefined) ?
466
+ (this[0] ? this[0][name] : undefined) :
467
+ this.each(function(idx){
468
+ this[name] = funcArg(this, value, idx, this[name])
469
+ })
470
+ },
471
+ data: function(name, value){
472
+ var data = this.attr('data-' + dasherize(name), value)
473
+ return data !== null ? data : undefined
474
+ },
475
+ val: function(value){
476
+ return (value === undefined) ?
477
+ (this.length > 0 ? this[0].value : undefined) :
478
+ this.each(function(idx){
479
+ this.value = funcArg(this, value, idx, this.value)
480
+ })
481
+ },
482
+ offset: function(){
483
+ if (this.length==0) return null
484
+ var obj = this[0].getBoundingClientRect()
485
+ return {
486
+ left: obj.left + window.pageXOffset,
487
+ top: obj.top + window.pageYOffset,
488
+ width: obj.width,
489
+ height: obj.height
490
+ }
491
+ },
492
+ css: function(property, value){
493
+ if (value === undefined && typeof property == 'string')
494
+ return (
495
+ this.length == 0
496
+ ? undefined
497
+ : this[0].style[camelize(property)] || getComputedStyle(this[0], '').getPropertyValue(property))
498
+
499
+ var css = ''
500
+ for (key in property)
501
+ if(typeof property[key] == 'string' && property[key] == '')
502
+ this.each(function(){ this.style.removeProperty(dasherize(key)) })
503
+ else
504
+ css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';'
505
+
506
+ if (typeof property == 'string')
507
+ if (value == '')
508
+ this.each(function(){ this.style.removeProperty(dasherize(property)) })
509
+ else
510
+ css = dasherize(property) + ":" + maybeAddPx(property, value)
511
+
512
+ return this.each(function(){ this.style.cssText += ';' + css })
513
+ },
514
+ index: function(element){
515
+ return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0])
516
+ },
517
+ hasClass: function(name){
518
+ if (this.length < 1) return false
519
+ else return classRE(name).test(this[0].className)
520
+ },
521
+ addClass: function(name){
522
+ return this.each(function(idx){
523
+ classList = []
524
+ var cls = this.className, newName = funcArg(this, name, idx, cls)
525
+ newName.split(/\s+/g).forEach(function(klass){
526
+ if (!$(this).hasClass(klass)) classList.push(klass)
527
+ }, this)
528
+ classList.length && (this.className += (cls ? " " : "") + classList.join(" "))
529
+ })
530
+ },
531
+ removeClass: function(name){
532
+ return this.each(function(idx){
533
+ if (name === undefined)
534
+ return this.className = ''
535
+ classList = this.className
536
+ funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){
537
+ classList = classList.replace(classRE(klass), " ")
538
+ })
539
+ this.className = classList.trim()
540
+ })
541
+ },
542
+ toggleClass: function(name, when){
543
+ return this.each(function(idx){
544
+ var newName = funcArg(this, name, idx, this.className)
545
+ ;(when === undefined ? !$(this).hasClass(newName) : when) ?
546
+ $(this).addClass(newName) : $(this).removeClass(newName)
547
+ })
548
+ }
549
+ }
550
+
551
+ // Generate the `width` and `height` functions
552
+ ;['width', 'height'].forEach(function(dimension){
553
+ $.fn[dimension] = function(value){
554
+ var offset, Dimension = dimension.replace(/./, function(m){ return m[0].toUpperCase() })
555
+ if (value === undefined) return this[0] == window ? window['inner' + Dimension] :
556
+ this[0] == document ? document.documentElement['offset' + Dimension] :
557
+ (offset = this.offset()) && offset[dimension]
558
+ else return this.each(function(idx){
559
+ var el = $(this)
560
+ el.css(dimension, funcArg(this, value, idx, el[dimension]()))
561
+ })
562
+ }
563
+ })
564
+
565
+ function insert(operator, target, node) {
566
+ var parent = (operator % 2) ? target : target.parentNode
567
+ parent ? parent.insertBefore(node,
568
+ !operator ? target.nextSibling : // after
569
+ operator == 1 ? parent.firstChild : // prepend
570
+ operator == 2 ? target : // before
571
+ null) : // append
572
+ $(node).remove()
573
+ }
574
+
575
+ function traverseNode(node, fun) {
576
+ fun(node)
577
+ for (var key in node.childNodes) traverseNode(node.childNodes[key], fun)
578
+ }
579
+
580
+ // Generate the `after`, `prepend`, `before`, `append`,
581
+ // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods.
582
+ adjacencyOperators.forEach(function(key, operator) {
583
+ $.fn[key] = function(){
584
+ // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings
585
+ var nodes = $.map(arguments, function(n){ return isObject(n) ? n : zepto.fragment(n) })
586
+ if (nodes.length < 1) return this
587
+ var size = this.length, copyByClone = size > 1, inReverse = operator < 2
588
+
589
+ return this.each(function(index, target){
590
+ for (var i = 0; i < nodes.length; i++) {
591
+ var node = nodes[inReverse ? nodes.length-i-1 : i]
592
+ traverseNode(node, function(node){
593
+ if (node.nodeName != null && node.nodeName.toUpperCase() === 'SCRIPT' && (!node.type || node.type === 'text/javascript'))
594
+ window['eval'].call(window, node.innerHTML)
595
+ })
596
+ if (copyByClone && index < size - 1) node = node.cloneNode(true)
597
+ insert(operator, target, node)
598
+ }
599
+ })
600
+ }
601
+
602
+ $.fn[(operator % 2) ? key+'To' : 'insert'+(operator ? 'Before' : 'After')] = function(html){
603
+ $(html)[key](this)
604
+ return this
605
+ }
606
+ })
607
+
608
+ zepto.Z.prototype = $.fn
609
+
610
+ // Export internal API functions in the `$.zepto` namespace
611
+ zepto.camelize = camelize
612
+ zepto.uniq = uniq
613
+ $.zepto = zepto
614
+
615
+ return $
616
+ })()
617
+
618
+ // If `$` is not yet defined, point it to `Zepto`
619
+ window.Zepto = Zepto
620
+ '$' in window || (window.$ = Zepto)
621
+ ;(function($){
622
+ var $$ = $.zepto.qsa, handlers = {}, _zid = 1, specialEvents={}
623
+
624
+ specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'
625
+
626
+ function zid(element) {
627
+ return element._zid || (element._zid = _zid++)
628
+ }
629
+ function findHandlers(element, event, fn, selector) {
630
+ event = parse(event)
631
+ if (event.ns) var matcher = matcherFor(event.ns)
632
+ return (handlers[zid(element)] || []).filter(function(handler) {
633
+ return handler
634
+ && (!event.e || handler.e == event.e)
635
+ && (!event.ns || matcher.test(handler.ns))
636
+ && (!fn || zid(handler.fn) === zid(fn))
637
+ && (!selector || handler.sel == selector)
638
+ })
639
+ }
640
+ function parse(event) {
641
+ var parts = ('' + event).split('.')
642
+ return {e: parts[0], ns: parts.slice(1).sort().join(' ')}
643
+ }
644
+ function matcherFor(ns) {
645
+ return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)')
646
+ }
647
+
648
+ function eachEvent(events, fn, iterator){
649
+ if ($.isObject(events)) $.each(events, iterator)
650
+ else events.split(/\s/).forEach(function(type){ iterator(type, fn) })
651
+ }
652
+
653
+ function add(element, events, fn, selector, getDelegate, capture){
654
+ capture = !!capture
655
+ var id = zid(element), set = (handlers[id] || (handlers[id] = []))
656
+ eachEvent(events, fn, function(event, fn){
657
+ var delegate = getDelegate && getDelegate(fn, event),
658
+ callback = delegate || fn
659
+ var proxyfn = function (event) {
660
+ var result = callback.apply(element, [event].concat(event.data))
661
+ if (result === false) event.preventDefault()
662
+ return result
663
+ }
664
+ var handler = $.extend(parse(event), {fn: fn, proxy: proxyfn, sel: selector, del: delegate, i: set.length})
665
+ set.push(handler)
666
+ element.addEventListener(handler.e, proxyfn, capture)
667
+ })
668
+ }
669
+ function remove(element, events, fn, selector){
670
+ var id = zid(element)
671
+ eachEvent(events || '', fn, function(event, fn){
672
+ findHandlers(element, event, fn, selector).forEach(function(handler){
673
+ delete handlers[id][handler.i]
674
+ element.removeEventListener(handler.e, handler.proxy, false)
675
+ })
676
+ })
677
+ }
678
+
679
+ $.event = { add: add, remove: remove }
680
+
681
+ $.proxy = function(fn, context) {
682
+ if ($.isFunction(fn)) {
683
+ var proxyFn = function(){ return fn.apply(context, arguments) }
684
+ proxyFn._zid = zid(fn)
685
+ return proxyFn
686
+ } else if (typeof context == 'string') {
687
+ return $.proxy(fn[context], fn)
688
+ } else {
689
+ throw new TypeError("expected function")
690
+ }
691
+ }
692
+
693
+ $.fn.bind = function(event, callback){
694
+ return this.each(function(){
695
+ add(this, event, callback)
696
+ })
697
+ }
698
+ $.fn.unbind = function(event, callback){
699
+ return this.each(function(){
700
+ remove(this, event, callback)
701
+ })
702
+ }
703
+ $.fn.one = function(event, callback){
704
+ return this.each(function(i, element){
705
+ add(this, event, callback, null, function(fn, type){
706
+ return function(){
707
+ var result = fn.apply(element, arguments)
708
+ remove(element, type, fn)
709
+ return result
710
+ }
711
+ })
712
+ })
713
+ }
714
+
715
+ var returnTrue = function(){return true},
716
+ returnFalse = function(){return false},
717
+ eventMethods = {
718
+ preventDefault: 'isDefaultPrevented',
719
+ stopImmediatePropagation: 'isImmediatePropagationStopped',
720
+ stopPropagation: 'isPropagationStopped'
721
+ }
722
+ function createProxy(event) {
723
+ var proxy = $.extend({originalEvent: event}, event)
724
+ $.each(eventMethods, function(name, predicate) {
725
+ proxy[name] = function(){
726
+ this[predicate] = returnTrue
727
+ return event[name].apply(event, arguments)
728
+ }
729
+ proxy[predicate] = returnFalse
730
+ })
731
+ return proxy
732
+ }
733
+
734
+ // emulates the 'defaultPrevented' property for browsers that have none
735
+ function fix(event) {
736
+ if (!('defaultPrevented' in event)) {
737
+ event.defaultPrevented = false
738
+ var prevent = event.preventDefault
739
+ event.preventDefault = function() {
740
+ this.defaultPrevented = true
741
+ prevent.call(this)
742
+ }
743
+ }
744
+ }
745
+
746
+ $.fn.delegate = function(selector, event, callback){
747
+ var capture = false
748
+ if(event == 'blur' || event == 'focus'){
749
+ if($.iswebkit)
750
+ event = event == 'blur' ? 'focusout' : event == 'focus' ? 'focusin' : event
751
+ else
752
+ capture = true
753
+ }
754
+
755
+ return this.each(function(i, element){
756
+ add(element, event, callback, selector, function(fn){
757
+ return function(e){
758
+ var evt, match = $(e.target).closest(selector, element).get(0)
759
+ if (match) {
760
+ evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})
761
+ return fn.apply(match, [evt].concat([].slice.call(arguments, 1)))
762
+ }
763
+ }
764
+ }, capture)
765
+ })
766
+ }
767
+ $.fn.undelegate = function(selector, event, callback){
768
+ return this.each(function(){
769
+ remove(this, event, callback, selector)
770
+ })
771
+ }
772
+
773
+ $.fn.live = function(event, callback){
774
+ $(document.body).delegate(this.selector, event, callback)
775
+ return this
776
+ }
777
+ $.fn.die = function(event, callback){
778
+ $(document.body).undelegate(this.selector, event, callback)
779
+ return this
780
+ }
781
+
782
+ $.fn.on = function(event, selector, callback){
783
+ return selector == undefined || $.isFunction(selector) ?
784
+ this.bind(event, selector) : this.delegate(selector, event, callback)
785
+ }
786
+ $.fn.off = function(event, selector, callback){
787
+ return selector == undefined || $.isFunction(selector) ?
788
+ this.unbind(event, selector) : this.undelegate(selector, event, callback)
789
+ }
790
+
791
+ $.fn.trigger = function(event, data){
792
+ if (typeof event == 'string') event = $.Event(event)
793
+ fix(event)
794
+ event.data = data
795
+ return this.each(function(){
796
+ // items in the collection might not be DOM elements
797
+ // (todo: possibly support events on plain old objects)
798
+ if('dispatchEvent' in this) this.dispatchEvent(event)
799
+ })
800
+ }
801
+
802
+ // triggers event handlers on current element just as if an event occurred,
803
+ // doesn't trigger an actual event, doesn't bubble
804
+ $.fn.triggerHandler = function(event, data){
805
+ var e, result
806
+ this.each(function(i, element){
807
+ e = createProxy(typeof event == 'string' ? $.Event(event) : event)
808
+ e.data = data
809
+ e.target = element
810
+ $.each(findHandlers(element, event.type || event), function(i, handler){
811
+ result = handler.proxy(e)
812
+ if (e.isImmediatePropagationStopped()) return false
813
+ })
814
+ })
815
+ return result
816
+ }
817
+
818
+ // shortcut methods for `.bind(event, fn)` for each event type
819
+ ;('focusin focusout load resize scroll unload click dblclick '+
820
+ 'mousedown mouseup mousemove mouseover mouseout '+
821
+ 'change select keydown keypress keyup error').split(' ').forEach(function(event) {
822
+ $.fn[event] = function(callback){ return this.bind(event, callback) }
823
+ })
824
+
825
+ ;['focus', 'blur'].forEach(function(name) {
826
+ $.fn[name] = function(callback) {
827
+ if (callback) this.bind(name, callback)
828
+ else if (this.length) try { this.get(0)[name]() } catch(e){}
829
+ return this
830
+ }
831
+ })
832
+
833
+ $.Event = function(type, props) {
834
+ var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true
835
+ if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])
836
+ event.initEvent(type, bubbles, true, null, null, null, null, null, null, null, null, null, null, null, null)
837
+ return event
838
+ }
839
+
840
+ })(Zepto)
841
+ ;(function($){
842
+ function detect(ua){
843
+ var os = this.os = {}, browser = this.browser = {},
844
+ webkit = ua.match(/WebKit\/([\d.]+)/),
845
+ android = ua.match(/(Android)\s+([\d.]+)/),
846
+ ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
847
+ iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/),
848
+ webos = ua.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),
849
+ touchpad = webos && ua.match(/TouchPad/),
850
+ kindle = ua.match(/Kindle\/([\d.]+)/),
851
+ silk = ua.match(/Silk\/([\d._]+)/),
852
+ blackberry = ua.match(/(BlackBerry).*Version\/([\d.]+)/)
853
+
854
+ // todo clean this up with a better OS/browser
855
+ // separation. we need to discern between multiple
856
+ // browsers on android, and decide if kindle fire in
857
+ // silk mode is android or not
858
+
859
+ if (browser.webkit = !!webkit) browser.version = webkit[1]
860
+
861
+ if (android) os.android = true, os.version = android[2]
862
+ if (iphone) os.ios = os.iphone = true, os.version = iphone[2].replace(/_/g, '.')
863
+ if (ipad) os.ios = os.ipad = true, os.version = ipad[2].replace(/_/g, '.')
864
+ if (webos) os.webos = true, os.version = webos[2]
865
+ if (touchpad) os.touchpad = true
866
+ if (blackberry) os.blackberry = true, os.version = blackberry[2]
867
+ if (kindle) os.kindle = true, os.version = kindle[1]
868
+ if (silk) browser.silk = true, browser.version = silk[1]
869
+ if (!silk && os.android && ua.match(/Kindle Fire/)) browser.silk = true
870
+ }
871
+
872
+ detect.call($, navigator.userAgent)
873
+ // make available to unit tests
874
+ $.__detect = detect
875
+
876
+ })(Zepto)
877
+ ;(function($, undefined){
878
+ var prefix = '', eventPrefix, endEventName, endAnimationName,
879
+ vendors = { Webkit: 'webkit', Moz: '', O: 'o', ms: 'MS' },
880
+ document = window.document, testEl = document.createElement('div'),
881
+ supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,
882
+ clearProperties = {}
883
+
884
+ function downcase(str) { return str.toLowerCase() }
885
+ function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : downcase(name) }
886
+
887
+ $.each(vendors, function(vendor, event){
888
+ if (testEl && testEl.style) {
889
+ if (testEl.style[vendor + 'TransitionProperty'] !== undefined) {
890
+ prefix = '-' + downcase(vendor) + '-'
891
+ eventPrefix = event
892
+ return false
893
+ }
894
+ }
895
+ })
896
+
897
+ clearProperties[prefix + 'transition-property'] =
898
+ clearProperties[prefix + 'transition-duration'] =
899
+ clearProperties[prefix + 'transition-timing-function'] =
900
+ clearProperties[prefix + 'animation-name'] =
901
+ clearProperties[prefix + 'animation-duration'] = ''
902
+
903
+ $.fx = {
904
+ off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined),
905
+ cssPrefix: prefix,
906
+ transitionEnd: normalizeEvent('TransitionEnd'),
907
+ animationEnd: normalizeEvent('AnimationEnd')
908
+ }
909
+
910
+ $.fn.animate = function(properties, duration, ease, callback){
911
+ if ($.isObject(duration))
912
+ ease = duration.easing, callback = duration.complete, duration = duration.duration
913
+ if (duration) duration = duration / 1000
914
+ return this.anim(properties, duration, ease, callback)
915
+ }
916
+
917
+ $.fn.anim = function(properties, duration, ease, callback){
918
+ var transforms, cssProperties = {}, key, that = this, wrappedCallback, endEvent = $.fx.transitionEnd
919
+ if (duration === undefined) duration = 0.4
920
+ if ($.fx.off) duration = 0
921
+
922
+ if (typeof properties == 'string') {
923
+ // keyframe animation
924
+ cssProperties[prefix + 'animation-name'] = properties
925
+ cssProperties[prefix + 'animation-duration'] = duration + 's'
926
+ endEvent = $.fx.animationEnd
927
+ } else {
928
+ // CSS transitions
929
+ for (key in properties)
930
+ if (supportedTransforms.test(key)) {
931
+ transforms || (transforms = [])
932
+ transforms.push(key + '(' + properties[key] + ')')
933
+ }
934
+ else cssProperties[key] = properties[key]
935
+
936
+ if (transforms) cssProperties[prefix + 'transform'] = transforms.join(' ')
937
+ if (!$.fx.off && typeof properties === 'object') {
938
+ cssProperties[prefix + 'transition-property'] = Object.keys(properties).join(', ')
939
+ cssProperties[prefix + 'transition-duration'] = duration + 's'
940
+ cssProperties[prefix + 'transition-timing-function'] = (ease || 'linear')
941
+ }
942
+ }
943
+
944
+ wrappedCallback = function(event){
945
+ if (typeof event !== 'undefined') {
946
+ if (event.target !== event.currentTarget) return // makes sure the event didn't bubble from "below"
947
+ $(event.target).unbind(endEvent, arguments.callee)
948
+ }
949
+ $(this).css(clearProperties)
950
+ callback && callback.call(this)
951
+ }
952
+ if (duration > 0) this.bind(endEvent, wrappedCallback)
953
+
954
+ setTimeout(function() {
955
+ that.css(cssProperties)
956
+ if (duration <= 0) setTimeout(function() {
957
+ that.each(function(){ wrappedCallback.call(this) })
958
+ }, 0)
959
+ }, 0)
960
+
961
+ return this
962
+ }
963
+
964
+ testEl = null
965
+ })(Zepto)
966
+ ;(function($){
967
+ var jsonpID = 0,
968
+ isObject = $.isObject,
969
+ document = window.document,
970
+ key,
971
+ name,
972
+ rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
973
+ scriptTypeRE = /^(?:text|application)\/javascript/i,
974
+ xmlTypeRE = /^(?:text|application)\/xml/i,
975
+ jsonType = 'application/json',
976
+ htmlType = 'text/html',
977
+ blankRE = /^\s*$/
978
+
979
+ // trigger a custom event and return false if it was cancelled
980
+ function triggerAndReturn(context, eventName, data) {
981
+ var event = $.Event(eventName)
982
+ $(context).trigger(event, data)
983
+ return !event.defaultPrevented
984
+ }
985
+
986
+ // trigger an Ajax "global" event
987
+ function triggerGlobal(settings, context, eventName, data) {
988
+ if (settings.global) return triggerAndReturn(context || document, eventName, data)
989
+ }
990
+
991
+ // Number of active Ajax requests
992
+ $.active = 0
993
+
994
+ function ajaxStart(settings) {
995
+ if (settings.global && $.active++ === 0) triggerGlobal(settings, null, 'ajaxStart')
996
+ }
997
+ function ajaxStop(settings) {
998
+ if (settings.global && !(--$.active)) triggerGlobal(settings, null, 'ajaxStop')
999
+ }
1000
+
1001
+ // triggers an extra global event "ajaxBeforeSend" that's like "ajaxSend" but cancelable
1002
+ function ajaxBeforeSend(xhr, settings) {
1003
+ var context = settings.context
1004
+ if (settings.beforeSend.call(context, xhr, settings) === false ||
1005
+ triggerGlobal(settings, context, 'ajaxBeforeSend', [xhr, settings]) === false)
1006
+ return false
1007
+
1008
+ triggerGlobal(settings, context, 'ajaxSend', [xhr, settings])
1009
+ }
1010
+ function ajaxSuccess(data, xhr, settings) {
1011
+ var context = settings.context, status = 'success'
1012
+ settings.success.call(context, data, status, xhr)
1013
+ triggerGlobal(settings, context, 'ajaxSuccess', [xhr, settings, data])
1014
+ ajaxComplete(status, xhr, settings)
1015
+ }
1016
+ // type: "timeout", "error", "abort", "parsererror"
1017
+ function ajaxError(error, type, xhr, settings) {
1018
+ var context = settings.context
1019
+ settings.error.call(context, xhr, type, error)
1020
+ triggerGlobal(settings, context, 'ajaxError', [xhr, settings, error])
1021
+ ajaxComplete(type, xhr, settings)
1022
+ }
1023
+ // status: "success", "notmodified", "error", "timeout", "abort", "parsererror"
1024
+ function ajaxComplete(status, xhr, settings) {
1025
+ var context = settings.context
1026
+ settings.complete.call(context, xhr, status)
1027
+ triggerGlobal(settings, context, 'ajaxComplete', [xhr, settings])
1028
+ ajaxStop(settings)
1029
+ }
1030
+
1031
+ // Empty function, used as default callback
1032
+ function empty() {}
1033
+
1034
+ $.ajaxJSONP = function(options){
1035
+ var callbackName = 'jsonp' + (++jsonpID),
1036
+ script = document.createElement('script'),
1037
+ abort = function(){
1038
+ $(script).remove()
1039
+ if (callbackName in window) window[callbackName] = empty
1040
+ ajaxComplete('abort', xhr, options)
1041
+ },
1042
+ xhr = { abort: abort }, abortTimeout
1043
+
1044
+ if (options.error) script.onerror = function() {
1045
+ xhr.abort()
1046
+ options.error()
1047
+ }
1048
+
1049
+ window[callbackName] = function(data){
1050
+ clearTimeout(abortTimeout)
1051
+ $(script).remove()
1052
+ delete window[callbackName]
1053
+ ajaxSuccess(data, xhr, options)
1054
+ }
1055
+
1056
+ serializeData(options)
1057
+ script.src = options.url.replace(/=\?/, '=' + callbackName)
1058
+ $('head').append(script)
1059
+
1060
+ if (options.timeout > 0) abortTimeout = setTimeout(function(){
1061
+ xhr.abort()
1062
+ ajaxComplete('timeout', xhr, options)
1063
+ }, options.timeout)
1064
+
1065
+ return xhr
1066
+ }
1067
+
1068
+ $.ajaxSettings = {
1069
+ // Default type of request
1070
+ type: 'GET',
1071
+ // Callback that is executed before request
1072
+ beforeSend: empty,
1073
+ // Callback that is executed if the request succeeds
1074
+ success: empty,
1075
+ // Callback that is executed the the server drops error
1076
+ error: empty,
1077
+ // Callback that is executed on request complete (both: error and success)
1078
+ complete: empty,
1079
+ // The context for the callbacks
1080
+ context: null,
1081
+ // Whether to trigger "global" Ajax events
1082
+ global: true,
1083
+ // Transport
1084
+ xhr: function () {
1085
+ return new window.XMLHttpRequest()
1086
+ },
1087
+ // MIME types mapping
1088
+ accepts: {
1089
+ script: 'text/javascript, application/javascript',
1090
+ json: jsonType,
1091
+ xml: 'application/xml, text/xml',
1092
+ html: htmlType,
1093
+ text: 'text/plain'
1094
+ },
1095
+ // Whether the request is to another domain
1096
+ crossDomain: false,
1097
+ // Default timeout
1098
+ timeout: 0
1099
+ }
1100
+
1101
+ function mimeToDataType(mime) {
1102
+ return mime && ( mime == htmlType ? 'html' :
1103
+ mime == jsonType ? 'json' :
1104
+ scriptTypeRE.test(mime) ? 'script' :
1105
+ xmlTypeRE.test(mime) && 'xml' ) || 'text'
1106
+ }
1107
+
1108
+ function appendQuery(url, query) {
1109
+ return (url + '&' + query).replace(/[&?]{1,2}/, '?')
1110
+ }
1111
+
1112
+ // serialize payload and append it to the URL for GET requests
1113
+ function serializeData(options) {
1114
+ if (isObject(options.data)) options.data = $.param(options.data)
1115
+ if (options.data && (!options.type || options.type.toUpperCase() == 'GET'))
1116
+ options.url = appendQuery(options.url, options.data)
1117
+ }
1118
+
1119
+ $.ajax = function(options){
1120
+ var settings = $.extend({}, options || {})
1121
+ for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key]
1122
+
1123
+ ajaxStart(settings)
1124
+
1125
+ if (!settings.crossDomain) settings.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(settings.url) &&
1126
+ RegExp.$2 != window.location.host
1127
+
1128
+ var dataType = settings.dataType, hasPlaceholder = /=\?/.test(settings.url)
1129
+ if (dataType == 'jsonp' || hasPlaceholder) {
1130
+ if (!hasPlaceholder) settings.url = appendQuery(settings.url, 'callback=?')
1131
+ return $.ajaxJSONP(settings)
1132
+ }
1133
+
1134
+ if (!settings.url) settings.url = window.location.toString()
1135
+ serializeData(settings)
1136
+
1137
+ var mime = settings.accepts[dataType],
1138
+ baseHeaders = { },
1139
+ protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol,
1140
+ xhr = $.ajaxSettings.xhr(), abortTimeout
1141
+
1142
+ if (!settings.crossDomain) baseHeaders['X-Requested-With'] = 'XMLHttpRequest'
1143
+ if (mime) {
1144
+ baseHeaders['Accept'] = mime
1145
+ if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0]
1146
+ xhr.overrideMimeType && xhr.overrideMimeType(mime)
1147
+ }
1148
+ if (settings.contentType || (settings.data && settings.type.toUpperCase() != 'GET'))
1149
+ baseHeaders['Content-Type'] = (settings.contentType || 'application/x-www-form-urlencoded')
1150
+ settings.headers = $.extend(baseHeaders, settings.headers || {})
1151
+
1152
+ xhr.onreadystatechange = function(){
1153
+ if (xhr.readyState == 4) {
1154
+ clearTimeout(abortTimeout)
1155
+ var result, error = false
1156
+ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) {
1157
+ dataType = dataType || mimeToDataType(xhr.getResponseHeader('content-type'))
1158
+ result = xhr.responseText
1159
+
1160
+ try {
1161
+ if (dataType == 'script') (1,eval)(result)
1162
+ else if (dataType == 'xml') result = xhr.responseXML
1163
+ else if (dataType == 'json') result = blankRE.test(result) ? null : JSON.parse(result)
1164
+ } catch (e) { error = e }
1165
+
1166
+ if (error) ajaxError(error, 'parsererror', xhr, settings)
1167
+ else ajaxSuccess(result, xhr, settings)
1168
+ } else {
1169
+ ajaxError(null, 'error', xhr, settings)
1170
+ }
1171
+ }
1172
+ }
1173
+
1174
+ var async = 'async' in settings ? settings.async : true
1175
+ xhr.open(settings.type, settings.url, async)
1176
+
1177
+ for (name in settings.headers) xhr.setRequestHeader(name, settings.headers[name])
1178
+
1179
+ if (ajaxBeforeSend(xhr, settings) === false) {
1180
+ xhr.abort()
1181
+ return false
1182
+ }
1183
+
1184
+ if (settings.timeout > 0) abortTimeout = setTimeout(function(){
1185
+ xhr.onreadystatechange = empty
1186
+ xhr.abort()
1187
+ ajaxError(null, 'timeout', xhr, settings)
1188
+ }, settings.timeout)
1189
+
1190
+ // avoid sending empty string (#319)
1191
+ xhr.send(settings.data ? settings.data : null)
1192
+ return xhr
1193
+ }
1194
+
1195
+ $.get = function(url, success){ return $.ajax({ url: url, success: success }) }
1196
+
1197
+ $.post = function(url, data, success, dataType){
1198
+ if ($.isFunction(data)) dataType = dataType || success, success = data, data = null
1199
+ return $.ajax({ type: 'POST', url: url, data: data, success: success, dataType: dataType })
1200
+ }
1201
+
1202
+ $.getJSON = function(url, success){
1203
+ return $.ajax({ url: url, success: success, dataType: 'json' })
1204
+ }
1205
+
1206
+ $.fn.load = function(url, success){
1207
+ if (!this.length) return this
1208
+ var self = this, parts = url.split(/\s/), selector
1209
+ if (parts.length > 1) url = parts[0], selector = parts[1]
1210
+ $.get(url, function(response){
1211
+ self.html(selector ?
1212
+ $(document.createElement('div')).html(response.replace(rscript, "")).find(selector).html()
1213
+ : response)
1214
+ success && success.call(self)
1215
+ })
1216
+ return this
1217
+ }
1218
+
1219
+ var escape = encodeURIComponent
1220
+
1221
+ function serialize(params, obj, traditional, scope){
1222
+ var array = $.isArray(obj)
1223
+ $.each(obj, function(key, value) {
1224
+ if (scope) key = traditional ? scope : scope + '[' + (array ? '' : key) + ']'
1225
+ // handle data in serializeArray() format
1226
+ if (!scope && array) params.add(value.name, value.value)
1227
+ // recurse into nested objects
1228
+ else if (traditional ? $.isArray(value) : isObject(value))
1229
+ serialize(params, value, traditional, key)
1230
+ else params.add(key, value)
1231
+ })
1232
+ }
1233
+
1234
+ $.param = function(obj, traditional){
1235
+ var params = []
1236
+ params.add = function(k, v){ this.push(escape(k) + '=' + escape(v)) }
1237
+ serialize(params, obj, traditional)
1238
+ return params.join('&').replace('%20', '+')
1239
+ }
1240
+ })(Zepto)
1241
+ ;(function ($) {
1242
+ $.fn.serializeArray = function () {
1243
+ var result = [], el
1244
+ $( Array.prototype.slice.call(this.get(0).elements) ).each(function () {
1245
+ el = $(this)
1246
+ var type = el.attr('type')
1247
+ if (this.nodeName.toLowerCase() != 'fieldset' &&
1248
+ !this.disabled && type != 'submit' && type != 'reset' && type != 'button' &&
1249
+ ((type != 'radio' && type != 'checkbox') || this.checked))
1250
+ result.push({
1251
+ name: el.attr('name'),
1252
+ value: el.val()
1253
+ })
1254
+ })
1255
+ return result
1256
+ }
1257
+
1258
+ $.fn.serialize = function () {
1259
+ var result = []
1260
+ this.serializeArray().forEach(function (elm) {
1261
+ result.push( encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value) )
1262
+ })
1263
+ return result.join('&')
1264
+ }
1265
+
1266
+ $.fn.submit = function (callback) {
1267
+ if (callback) this.bind('submit', callback)
1268
+ else if (this.length) {
1269
+ var event = $.Event('submit')
1270
+ this.eq(0).trigger(event)
1271
+ if (!event.defaultPrevented) this.get(0).submit()
1272
+ }
1273
+ return this
1274
+ }
1275
+
1276
+ })(Zepto)
1277
+ ;(function($){
1278
+ var touch = {}, touchTimeout
1279
+
1280
+ function parentIfText(node){
1281
+ return 'tagName' in node ? node : node.parentNode
1282
+ }
1283
+
1284
+ function swipeDirection(x1, x2, y1, y2){
1285
+ var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2)
1286
+ return xDelta >= yDelta ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
1287
+ }
1288
+
1289
+ var longTapDelay = 750, longTapTimeout
1290
+
1291
+ function longTap(){
1292
+ longTapTimeout = null
1293
+ if (touch.last) {
1294
+ touch.el.trigger('longTap')
1295
+ touch = {}
1296
+ }
1297
+ }
1298
+
1299
+ function cancelLongTap(){
1300
+ if (longTapTimeout) clearTimeout(longTapTimeout)
1301
+ longTapTimeout = null
1302
+ }
1303
+
1304
+ $(document).ready(function(){
1305
+ var now, delta
1306
+
1307
+ $(document.body).bind('touchstart', function(e){
1308
+ now = Date.now()
1309
+ delta = now - (touch.last || now)
1310
+ touch.el = $(parentIfText(e.touches[0].target))
1311
+ touchTimeout && clearTimeout(touchTimeout)
1312
+ touch.x1 = e.touches[0].pageX
1313
+ touch.y1 = e.touches[0].pageY
1314
+ if (delta > 0 && delta <= 250) touch.isDoubleTap = true
1315
+ touch.last = now
1316
+ longTapTimeout = setTimeout(longTap, longTapDelay)
1317
+ }).bind('touchmove', function(e){
1318
+ cancelLongTap()
1319
+ touch.x2 = e.touches[0].pageX
1320
+ touch.y2 = e.touches[0].pageY
1321
+ }).bind('touchend', function(e){
1322
+ cancelLongTap()
1323
+
1324
+ // double tap (tapped twice within 250ms)
1325
+ if (touch.isDoubleTap) {
1326
+ touch.el.trigger('doubleTap')
1327
+ touch = {}
1328
+
1329
+ // swipe
1330
+ } else if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
1331
+ (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)) {
1332
+ touch.el.trigger('swipe') &&
1333
+ touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
1334
+ touch = {}
1335
+
1336
+ // normal tap
1337
+ } else if ('last' in touch) {
1338
+ touch.el.trigger('tap')
1339
+
1340
+ touchTimeout = setTimeout(function(){
1341
+ touchTimeout = null
1342
+ touch.el.trigger('singleTap')
1343
+ touch = {}
1344
+ }, 250)
1345
+ }
1346
+ }).bind('touchcancel', function(){
1347
+ if (touchTimeout) clearTimeout(touchTimeout)
1348
+ if (longTapTimeout) clearTimeout(longTapTimeout)
1349
+ longTapTimeout = touchTimeout = null
1350
+ touch = {}
1351
+ })
1352
+ })
1353
+
1354
+ ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(m){
1355
+ $.fn[m] = function(callback){ return this.bind(m, callback) }
1356
+ })
1357
+ })(Zepto)