| /*! | 
|  * ===================================================== | 
|  * Mui v3.7.3 (http://dev.dcloud.net.cn/mui) | 
|  * ===================================================== | 
|  */ | 
| /** | 
|  * MUI核心JS | 
|  * @type _L4.$|Function | 
|  */ | 
| var mui = (function(document, undefined) { | 
|     var readyRE = /complete|loaded|interactive/; | 
|     var idSelectorRE = /^#([\w-]+)$/; | 
|     var classSelectorRE = /^\.([\w-]+)$/; | 
|     var tagSelectorRE = /^[\w-]+$/; | 
|     var translateRE = /translate(?:3d)?\((.+?)\)/; | 
|     var translateMatrixRE = /matrix(3d)?\((.+?)\)/; | 
|   | 
|     var $ = function(selector, context) { | 
|         context = context || document; | 
|         if (!selector) | 
|             return wrap(); | 
|         if (typeof selector === 'object') | 
|             if ($.isArrayLike(selector)) { | 
|                 return wrap($.slice.call(selector), null); | 
|             } else { | 
|                 return wrap([selector], null); | 
|             } | 
|         if (typeof selector === 'function') | 
|             return $.ready(selector); | 
|         if (typeof selector === 'string') { | 
|             try { | 
|                 selector = selector.trim(); | 
|                 if (idSelectorRE.test(selector)) { | 
|                     var found = document.getElementById(RegExp.$1); | 
|                     return wrap(found ? [found] : []); | 
|                 } | 
|                 return wrap($.qsa(selector, context), selector); | 
|             } catch (e) {} | 
|         } | 
|         return wrap(); | 
|     }; | 
|   | 
|     var wrap = function(dom, selector) { | 
|         dom = dom || []; | 
|         Object.setPrototypeOf(dom, $.fn); | 
|         dom.selector = selector || ''; | 
|         return dom; | 
|     }; | 
|   | 
|     $.uuid = 0; | 
|   | 
|     $.data = {}; | 
|     /** | 
|      * extend(simple) | 
|      * @param {type} target | 
|      * @param {type} source | 
|      * @param {type} deep | 
|      * @returns {unresolved} | 
|      */ | 
|     $.extend = function() { //from jquery2 | 
|         var options, name, src, copy, copyIsArray, clone, | 
|             target = arguments[0] || {}, | 
|             i = 1, | 
|             length = arguments.length, | 
|             deep = false; | 
|   | 
|         if (typeof target === "boolean") { | 
|             deep = target; | 
|   | 
|             target = arguments[i] || {}; | 
|             i++; | 
|         } | 
|   | 
|         if (typeof target !== "object" && !$.isFunction(target)) { | 
|             target = {}; | 
|         } | 
|   | 
|         if (i === length) { | 
|             target = this; | 
|             i--; | 
|         } | 
|   | 
|         for (; i < length; i++) { | 
|             if ((options = arguments[i]) != null) { | 
|                 for (name in options) { | 
|                     src = target[name]; | 
|                     copy = options[name]; | 
|   | 
|                     if (target === copy) { | 
|                         continue; | 
|                     } | 
|   | 
|                     if (deep && copy && ($.isPlainObject(copy) || (copyIsArray = $.isArray(copy)))) { | 
|                         if (copyIsArray) { | 
|                             copyIsArray = false; | 
|                             clone = src && $.isArray(src) ? src : []; | 
|   | 
|                         } else { | 
|                             clone = src && $.isPlainObject(src) ? src : {}; | 
|                         } | 
|   | 
|                         target[name] = $.extend(deep, clone, copy); | 
|   | 
|                     } else if (copy !== undefined) { | 
|                         target[name] = copy; | 
|                     } | 
|                 } | 
|             } | 
|         } | 
|   | 
|         return target; | 
|     }; | 
|     /** | 
|      * mui noop(function) | 
|      */ | 
|     $.noop = function() {}; | 
|     /** | 
|      * mui slice(array) | 
|      */ | 
|     $.slice = [].slice; | 
|     /** | 
|      * mui filter(array) | 
|      */ | 
|     $.filter = [].filter; | 
|   | 
|     $.type = function(obj) { | 
|         return obj == null ? String(obj) : class2type[{}.toString.call(obj)] || "object"; | 
|     }; | 
|     /** | 
|      * mui isArray | 
|      */ | 
|     $.isArray = Array.isArray || | 
|         function(object) { | 
|             return object instanceof Array; | 
|         }; | 
|     /** | 
|      * mui isArrayLike  | 
|      * @param {Object} obj | 
|      */ | 
|     $.isArrayLike = function(obj) { | 
|         var length = !!obj && "length" in obj && obj.length; | 
|         var type = $.type(obj); | 
|         if (type === "function" || $.isWindow(obj)) { | 
|             return false; | 
|         } | 
|         return type === "array" || length === 0 || | 
|             typeof length === "number" && length > 0 && (length - 1) in obj; | 
|     }; | 
|     /** | 
|      * mui isWindow(需考虑obj为undefined的情况) | 
|      */ | 
|     $.isWindow = function(obj) { | 
|         return obj != null && obj === obj.window; | 
|     }; | 
|     /** | 
|      * mui isObject | 
|      */ | 
|     $.isObject = function(obj) { | 
|         return $.type(obj) === "object"; | 
|     }; | 
|     /** | 
|      * mui isPlainObject | 
|      */ | 
|     $.isPlainObject = function(obj) { | 
|         return $.isObject(obj) && !$.isWindow(obj) && Object.getPrototypeOf(obj) === Object.prototype; | 
|     }; | 
|     /** | 
|      * mui isEmptyObject | 
|      * @param {Object} o | 
|      */ | 
|     $.isEmptyObject = function(o) { | 
|         for (var p in o) { | 
|             if (p !== undefined) { | 
|                 return false; | 
|             } | 
|         } | 
|         return true; | 
|     }; | 
|     /** | 
|      * mui isFunction | 
|      */ | 
|     $.isFunction = function(value) { | 
|         return $.type(value) === "function"; | 
|     }; | 
|     /** | 
|      * mui querySelectorAll | 
|      * @param {type} selector | 
|      * @param {type} context | 
|      * @returns {Array} | 
|      */ | 
|     $.qsa = function(selector, context) { | 
|         context = context || document; | 
|         return $.slice.call(classSelectorRE.test(selector) ? context.getElementsByClassName(RegExp.$1) : tagSelectorRE.test(selector) ? context.getElementsByTagName(selector) : context.querySelectorAll(selector)); | 
|     }; | 
|     /** | 
|      * ready(DOMContentLoaded) | 
|      * @param {type} callback | 
|      * @returns {_L6.$} | 
|      */ | 
|     $.ready = function(callback) { | 
|         if (readyRE.test(document.readyState)) { | 
|             callback($); | 
|         } else { | 
|             document.addEventListener('DOMContentLoaded', function() { | 
|                 callback($); | 
|             }, false); | 
|         } | 
|         return this; | 
|     }; | 
|     /** | 
|      * 将 fn 缓存一段时间后, 再被调用执行 | 
|      * 此方法为了避免在 ms 段时间内, 执行 fn 多次. 常用于 resize , scroll , mousemove 等连续性事件中; | 
|      * 当 ms 设置为 -1, 表示立即执行 fn, 即和直接调用 fn 一样; | 
|      * 调用返回函数的 stop 停止最后一次的 buffer 效果 | 
|      * @param {Object} fn | 
|      * @param {Object} ms | 
|      * @param {Object} context | 
|      */ | 
|     $.buffer = function(fn, ms, context) { | 
|         var timer; | 
|         var lastStart = 0; | 
|         var lastEnd = 0; | 
|         var ms = ms || 150; | 
|   | 
|         function run() { | 
|             if (timer) { | 
|                 timer.cancel(); | 
|                 timer = 0; | 
|             } | 
|             lastStart = $.now(); | 
|             fn.apply(context || this, arguments); | 
|             lastEnd = $.now(); | 
|         } | 
|   | 
|         return $.extend(function() { | 
|             if ( | 
|                 (!lastStart) || // 从未运行过 | 
|                 (lastEnd >= lastStart && $.now() - lastEnd > ms) || // 上次运行成功后已经超过ms毫秒 | 
|                 (lastEnd < lastStart && $.now() - lastStart > ms * 8) // 上次运行或未完成,后8*ms毫秒 | 
|             ) { | 
|                 run.apply(this, arguments); | 
|             } else { | 
|                 if (timer) { | 
|                     timer.cancel(); | 
|                 } | 
|                 timer = $.later(run, ms, null, $.slice.call(arguments)); | 
|             } | 
|         }, { | 
|             stop: function() { | 
|                 if (timer) { | 
|                     timer.cancel(); | 
|                     timer = 0; | 
|                 } | 
|             } | 
|         }); | 
|     }; | 
|     /** | 
|      * each | 
|      * @param {type} elements | 
|      * @param {type} callback | 
|      * @returns {_L8.$} | 
|      */ | 
|     $.each = function(elements, callback, hasOwnProperty) { | 
|         if (!elements) { | 
|             return this; | 
|         } | 
|         if (typeof elements.length === 'number') { | 
|             [].every.call(elements, function(el, idx) { | 
|                 return callback.call(el, idx, el) !== false; | 
|             }); | 
|         } else { | 
|             for (var key in elements) { | 
|                 if (hasOwnProperty) { | 
|                     if (elements.hasOwnProperty(key)) { | 
|                         if (callback.call(elements[key], key, elements[key]) === false) return elements; | 
|                     } | 
|                 } else { | 
|                     if (callback.call(elements[key], key, elements[key]) === false) return elements; | 
|                 } | 
|             } | 
|         } | 
|         return this; | 
|     }; | 
|     $.focus = function(element) { | 
|         if ($.os.ios) { | 
|             setTimeout(function() { | 
|                 element.focus(); | 
|             }, 10); | 
|         } else { | 
|             element.focus(); | 
|         } | 
|     }; | 
|     /** | 
|      * trigger event | 
|      * @param {type} element | 
|      * @param {type} eventType | 
|      * @param {type} eventData | 
|      * @returns {_L8.$} | 
|      */ | 
|     $.trigger = function(element, eventType, eventData) { | 
|         element.dispatchEvent(new CustomEvent(eventType, { | 
|             detail: eventData, | 
|             bubbles: true, | 
|             cancelable: true | 
|         })); | 
|         return this; | 
|     }; | 
|     /** | 
|      * getStyles | 
|      * @param {type} element | 
|      * @param {type} property | 
|      * @returns {styles} | 
|      */ | 
|     $.getStyles = function(element, property) { | 
|         var styles = element.ownerDocument.defaultView.getComputedStyle(element, null); | 
|         if (property) { | 
|             return styles.getPropertyValue(property) || styles[property]; | 
|         } | 
|         return styles; | 
|     }; | 
|     /** | 
|      * parseTranslate | 
|      * @param {type} translateString | 
|      * @param {type} position | 
|      * @returns {Object} | 
|      */ | 
|     $.parseTranslate = function(translateString, position) { | 
|         var result = translateString.match(translateRE || ''); | 
|         if (!result || !result[1]) { | 
|             result = ['', '0,0,0']; | 
|         } | 
|         result = result[1].split(","); | 
|         result = { | 
|             x: parseFloat(result[0]), | 
|             y: parseFloat(result[1]), | 
|             z: parseFloat(result[2]) | 
|         }; | 
|         if (position && result.hasOwnProperty(position)) { | 
|             return result[position]; | 
|         } | 
|         return result; | 
|     }; | 
|     /** | 
|      * parseTranslateMatrix | 
|      * @param {type} translateString | 
|      * @param {type} position | 
|      * @returns {Object} | 
|      */ | 
|     $.parseTranslateMatrix = function(translateString, position) { | 
|         var matrix = translateString.match(translateMatrixRE); | 
|         var is3D = matrix && matrix[1]; | 
|         if (matrix) { | 
|             matrix = matrix[2].split(","); | 
|             if (is3D === "3d") | 
|                 matrix = matrix.slice(12, 15); | 
|             else { | 
|                 matrix.push(0); | 
|                 matrix = matrix.slice(4, 7); | 
|             } | 
|         } else { | 
|             matrix = [0, 0, 0]; | 
|         } | 
|         var result = { | 
|             x: parseFloat(matrix[0]), | 
|             y: parseFloat(matrix[1]), | 
|             z: parseFloat(matrix[2]) | 
|         }; | 
|         if (position && result.hasOwnProperty(position)) { | 
|             return result[position]; | 
|         } | 
|         return result; | 
|     }; | 
|     $.hooks = {}; | 
|     $.addAction = function(type, hook) { | 
|         var hooks = $.hooks[type]; | 
|         if (!hooks) { | 
|             hooks = []; | 
|         } | 
|         hook.index = hook.index || 1000; | 
|         hooks.push(hook); | 
|         hooks.sort(function(a, b) { | 
|             return a.index - b.index; | 
|         }); | 
|         $.hooks[type] = hooks; | 
|         return $.hooks[type]; | 
|     }; | 
|     $.doAction = function(type, callback) { | 
|         if ($.isFunction(callback)) { //指定了callback | 
|             $.each($.hooks[type], callback); | 
|         } else { //未指定callback,直接执行 | 
|             $.each($.hooks[type], function(index, hook) { | 
|                 return !hook.handle(); | 
|             }); | 
|         } | 
|     }; | 
|     /** | 
|      * setTimeout封装 | 
|      * @param {Object} fn | 
|      * @param {Object} when | 
|      * @param {Object} context | 
|      * @param {Object} data | 
|      */ | 
|     $.later = function(fn, when, context, data) { | 
|         when = when || 0; | 
|         var m = fn; | 
|         var d = data; | 
|         var f; | 
|         var r; | 
|   | 
|         if (typeof fn === 'string') { | 
|             m = context[fn]; | 
|         } | 
|   | 
|         f = function() { | 
|             m.apply(context, $.isArray(d) ? d : [d]); | 
|         }; | 
|   | 
|         r = setTimeout(f, when); | 
|   | 
|         return { | 
|             id: r, | 
|             cancel: function() { | 
|                 clearTimeout(r); | 
|             } | 
|         }; | 
|     }; | 
|     $.now = Date.now || function() { | 
|         return +new Date(); | 
|     }; | 
|     var class2type = {}; | 
|     $.each(['Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp', 'Object', 'Error'], function(i, name) { | 
|         class2type["[object " + name + "]"] = name.toLowerCase(); | 
|     }); | 
|     if (window.JSON) { | 
|         $.parseJSON = JSON.parse; | 
|     } | 
|     /** | 
|      * $.fn | 
|      */ | 
|     $.fn = { | 
|         each: function(callback) { | 
|             [].every.call(this, function(el, idx) { | 
|                 return callback.call(el, idx, el) !== false; | 
|             }); | 
|             return this; | 
|         } | 
|     }; | 
|   | 
|     /** | 
|      * 兼容 AMD 模块 | 
|      **/ | 
|     if (typeof define === 'function' && define.amd) { | 
|         define('mui', [], function() { | 
|             return $; | 
|         }); | 
|     } | 
|   | 
|     return $; | 
| })(document); | 
| //window.mui = mui; | 
| //'$' in window || (window.$ = mui); | 
| /** | 
|  * $.os | 
|  * @param {type} $ | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window) { | 
|     function detect(ua) { | 
|         this.os = {}; | 
|         var funcs = [ | 
|   | 
|             function() { //wechat | 
|                 var wechat = ua.match(/(MicroMessenger)\/([\d\.]+)/i); | 
|                 if (wechat) { //wechat | 
|                     this.os.wechat = { | 
|                         version: wechat[2].replace(/_/g, '.') | 
|                     }; | 
|                 } | 
|                 return false; | 
|             }, | 
|             function() { //android | 
|                 var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); | 
|                 if (android) { | 
|                     this.os.android = true; | 
|                     this.os.version = android[2]; | 
|   | 
|                     this.os.isBadAndroid = !(/Chrome\/\d/.test(window.navigator.appVersion)); | 
|                 } | 
|                 return this.os.android === true; | 
|             }, | 
|             function() { //ios | 
|                 var iphone = ua.match(/(iPhone\sOS)\s([\d_]+)/); | 
|                 if (iphone) { //iphone | 
|                     this.os.ios = this.os.iphone = true; | 
|                     this.os.version = iphone[2].replace(/_/g, '.'); | 
|                 } else { | 
|                     var ipad = ua.match(/(iPad).*OS\s([\d_]+)/); | 
|                     if (ipad) { //ipad | 
|                         this.os.ios = this.os.ipad = true; | 
|                         this.os.version = ipad[2].replace(/_/g, '.'); | 
|                     } | 
|                 } | 
|                 return this.os.ios === true; | 
|             } | 
|         ]; | 
|         [].every.call(funcs, function(func) { | 
|             return !func.call($); | 
|         }); | 
|     } | 
|     detect.call($, navigator.userAgent); | 
| })(mui, window); | 
| /** | 
|  * $.os.plus | 
|  * @param {type} $ | 
|  * @returns {undefined} | 
|  */ | 
| (function($, document) { | 
|     function detect(ua) { | 
|         this.os = this.os || {}; | 
|         var plus = ua.match(/Html5Plus/i); //TODO 5\+Browser? | 
|         if (plus) { | 
|             this.os.plus = true; | 
|             $(function() { | 
|                 document.body.classList.add('mui-plus'); | 
|             }); | 
|             if (ua.match(/StreamApp/i)) { //TODO 最好有流应用自己的标识 | 
|                 this.os.stream = true; | 
|                 $(function() { | 
|                     document.body.classList.add('mui-plus-stream'); | 
|                 }); | 
|             } | 
|         } | 
|     } | 
|     detect.call($, navigator.userAgent); | 
| })(mui, document); | 
| /** | 
|  * 仅提供简单的on,off(仅支持事件委托,不支持当前元素绑定,当前元素绑定请直接使用addEventListener,removeEventListener) | 
|  * @param {Object} $ | 
|  */ | 
| (function($) { | 
|     if ('ontouchstart' in window) { | 
|         $.isTouchable = true; | 
|         $.EVENT_START = 'touchstart'; | 
|         $.EVENT_MOVE = 'touchmove'; | 
|         $.EVENT_END = 'touchend'; | 
|     } else { | 
|         $.isTouchable = false; | 
|         $.EVENT_START = 'mousedown'; | 
|         $.EVENT_MOVE = 'mousemove'; | 
|         $.EVENT_END = 'mouseup'; | 
|     } | 
|     $.EVENT_CANCEL = 'touchcancel'; | 
|     $.EVENT_CLICK = 'click'; | 
|   | 
|     var _mid = 1; | 
|     var delegates = {}; | 
|     //需要wrap的函数 | 
|     var eventMethods = { | 
|         preventDefault: 'isDefaultPrevented', | 
|         stopImmediatePropagation: 'isImmediatePropagationStopped', | 
|         stopPropagation: 'isPropagationStopped' | 
|     }; | 
|     //默认true返回函数 | 
|     var returnTrue = function() { | 
|         return true | 
|     }; | 
|     //默认false返回函数 | 
|     var returnFalse = function() { | 
|         return false | 
|     }; | 
|     //wrap浏览器事件 | 
|     var compatible = function(event, target) { | 
|         if (!event.detail) { | 
|             event.detail = { | 
|                 currentTarget: target | 
|             }; | 
|         } else { | 
|             event.detail.currentTarget = target; | 
|         } | 
|         $.each(eventMethods, function(name, predicate) { | 
|             var sourceMethod = event[name]; | 
|             event[name] = function() { | 
|                 this[predicate] = returnTrue; | 
|                 return sourceMethod && sourceMethod.apply(event, arguments) | 
|             } | 
|             event[predicate] = returnFalse; | 
|         }, true); | 
|         return event; | 
|     }; | 
|     //简单的wrap对象_mid | 
|     var mid = function(obj) { | 
|         return obj && (obj._mid || (obj._mid = _mid++)); | 
|     }; | 
|     //事件委托对象绑定的事件回调列表 | 
|     var delegateFns = {}; | 
|     //返回事件委托的wrap事件回调 | 
|     var delegateFn = function(element, event, selector, callback) { | 
|         return function(e) { | 
|             //same event | 
|             var callbackObjs = delegates[element._mid][event]; | 
|             var handlerQueue = []; | 
|             var target = e.target; | 
|             var selectorAlls = {}; | 
|             for (; target && target !== document; target = target.parentNode) { | 
|                 if (target === element) { | 
|                     break; | 
|                 } | 
|                 if (~['click', 'tap', 'doubletap', 'longtap', 'hold'].indexOf(event) && (target.disabled || target.classList.contains('mui-disabled'))) { | 
|                     break; | 
|                 } | 
|                 var matches = {}; | 
|                 $.each(callbackObjs, function(selector, callbacks) { //same selector | 
|                     selectorAlls[selector] || (selectorAlls[selector] = $.qsa(selector, element)); | 
|                     if (selectorAlls[selector] && ~(selectorAlls[selector]).indexOf(target)) { | 
|                         if (!matches[selector]) { | 
|                             matches[selector] = callbacks; | 
|                         } | 
|                     } | 
|                 }, true); | 
|                 if (!$.isEmptyObject(matches)) { | 
|                     handlerQueue.push({ | 
|                         element: target, | 
|                         handlers: matches | 
|                     }); | 
|                 } | 
|             } | 
|             selectorAlls = null; | 
|             e = compatible(e); //compatible event | 
|             $.each(handlerQueue, function(index, handler) { | 
|                 target = handler.element; | 
|                 var tagName = target.tagName; | 
|                 if (event === 'tap' && (tagName !== 'INPUT' && tagName !== 'TEXTAREA' && tagName !== 'SELECT')) { | 
|                     e.preventDefault(); | 
|                     e.detail && e.detail.gesture && e.detail.gesture.preventDefault(); | 
|                 } | 
|                 $.each(handler.handlers, function(index, handler) { | 
|                     $.each(handler, function(index, callback) { | 
|                         if (callback.call(target, e) === false) { | 
|                             e.preventDefault(); | 
|                             e.stopPropagation(); | 
|                         } | 
|                     }, true); | 
|                 }, true) | 
|                 if (e.isPropagationStopped()) { | 
|                     return false; | 
|                 } | 
|             }, true); | 
|         }; | 
|     }; | 
|     var findDelegateFn = function(element, event) { | 
|         var delegateCallbacks = delegateFns[mid(element)]; | 
|         var result = []; | 
|         if (delegateCallbacks) { | 
|             result = []; | 
|             if (event) { | 
|                 var filterFn = function(fn) { | 
|                     return fn.type === event; | 
|                 } | 
|                 return delegateCallbacks.filter(filterFn); | 
|             } else { | 
|                 result = delegateCallbacks; | 
|             } | 
|         } | 
|         return result; | 
|     }; | 
|     var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/; | 
|     /** | 
|      * mui delegate events | 
|      * @param {type} event | 
|      * @param {type} selector | 
|      * @param {type} callback | 
|      * @returns {undefined} | 
|      */ | 
|     $.fn.on = function(event, selector, callback) { //仅支持简单的事件委托,主要是tap事件使用,类似mouse,focus之类暂不封装支持 | 
|         return this.each(function() { | 
|             var element = this; | 
|             mid(element); | 
|             mid(callback); | 
|             var isAddEventListener = false; | 
|             var delegateEvents = delegates[element._mid] || (delegates[element._mid] = {}); | 
|             var delegateCallbackObjs = delegateEvents[event] || ((delegateEvents[event] = {})); | 
|             if ($.isEmptyObject(delegateCallbackObjs)) { | 
|                 isAddEventListener = true; | 
|             } | 
|             var delegateCallbacks = delegateCallbackObjs[selector] || (delegateCallbackObjs[selector] = []); | 
|             delegateCallbacks.push(callback); | 
|             if (isAddEventListener) { | 
|                 var delegateFnArray = delegateFns[mid(element)]; | 
|                 if (!delegateFnArray) { | 
|                     delegateFnArray = []; | 
|                 } | 
|                 var delegateCallback = delegateFn(element, event, selector, callback); | 
|                 delegateFnArray.push(delegateCallback); | 
|                 delegateCallback.i = delegateFnArray.length - 1; | 
|                 delegateCallback.type = event; | 
|                 delegateFns[mid(element)] = delegateFnArray; | 
|                 element.addEventListener(event, delegateCallback); | 
|                 if (event === 'tap') { //TODO 需要找个更好的解决方案 | 
|                     element.addEventListener('click', function(e) { | 
|                         if (e.target) { | 
|                             var tagName = e.target.tagName; | 
|                             if (!preventDefaultException.test(tagName)) { | 
|                                 if (tagName === 'A') { | 
|                                     var href = e.target.href; | 
|                                     if (!(href && ~href.indexOf('tel:'))) { | 
|                                         e.preventDefault(); | 
|                                     } | 
|                                 } else { | 
|                                     e.preventDefault(); | 
|                                 } | 
|                             } | 
|                         } | 
|                     }); | 
|                 } | 
|             } | 
|         }); | 
|     }; | 
|     $.fn.off = function(event, selector, callback) { | 
|         return this.each(function() { | 
|             var _mid = mid(this); | 
|             if (!event) { //mui(selector).off(); | 
|                 delegates[_mid] && delete delegates[_mid]; | 
|             } else if (!selector) { //mui(selector).off(event); | 
|                 delegates[_mid] && delete delegates[_mid][event]; | 
|             } else if (!callback) { //mui(selector).off(event,selector); | 
|                 delegates[_mid] && delegates[_mid][event] && delete delegates[_mid][event][selector]; | 
|             } else { //mui(selector).off(event,selector,callback); | 
|                 var delegateCallbacks = delegates[_mid] && delegates[_mid][event] && delegates[_mid][event][selector]; | 
|                 $.each(delegateCallbacks, function(index, delegateCallback) { | 
|                     if (mid(delegateCallback) === mid(callback)) { | 
|                         delegateCallbacks.splice(index, 1); | 
|                         return false; | 
|                     } | 
|                 }, true); | 
|             } | 
|             if (delegates[_mid]) { | 
|                 //如果off掉了所有当前element的指定的event事件,则remove掉当前element的delegate回调 | 
|                 if ((!delegates[_mid][event] || $.isEmptyObject(delegates[_mid][event]))) { | 
|                     findDelegateFn(this, event).forEach(function(fn) { | 
|                         this.removeEventListener(fn.type, fn); | 
|                         delete delegateFns[_mid][fn.i]; | 
|                     }.bind(this)); | 
|                 } | 
|             } else { | 
|                 //如果delegates[_mid]已不存在,删除所有 | 
|                 findDelegateFn(this).forEach(function(fn) { | 
|                     this.removeEventListener(fn.type, fn); | 
|                     delete delegateFns[_mid][fn.i]; | 
|                 }.bind(this)); | 
|             } | 
|         }); | 
|   | 
|     }; | 
| })(mui); | 
| /** | 
|  * mui target(action>popover>modal>tab>toggle) | 
|  */ | 
| (function($, window, document) { | 
|     /** | 
|      * targets | 
|      */ | 
|     $.targets = {}; | 
|     /** | 
|      * target handles | 
|      */ | 
|     $.targetHandles = []; | 
|     /** | 
|      * register target | 
|      * @param {type} target | 
|      * @returns {$.targets} | 
|      */ | 
|     $.registerTarget = function(target) { | 
|   | 
|         target.index = target.index || 1000; | 
|   | 
|         $.targetHandles.push(target); | 
|   | 
|         $.targetHandles.sort(function(a, b) { | 
|             return a.index - b.index; | 
|         }); | 
|   | 
|         return $.targetHandles; | 
|     }; | 
|     window.addEventListener($.EVENT_START, function(event) { | 
|         var target = event.target; | 
|         var founds = {}; | 
|         for (; target && target !== document; target = target.parentNode) { | 
|             var isFound = false; | 
|             $.each($.targetHandles, function(index, targetHandle) { | 
|                 var name = targetHandle.name; | 
|                 if (!isFound && !founds[name] && targetHandle.hasOwnProperty('handle')) { | 
|                     $.targets[name] = targetHandle.handle(event, target); | 
|                     if ($.targets[name]) { | 
|                         founds[name] = true; | 
|                         if (targetHandle.isContinue !== true) { | 
|                             isFound = true; | 
|                         } | 
|                     } | 
|                 } else { | 
|                     if (!founds[name]) { | 
|                         if (targetHandle.isReset !== false) | 
|                             $.targets[name] = false; | 
|                     } | 
|                 } | 
|             }); | 
|             if (isFound) { | 
|                 break; | 
|             } | 
|         } | 
|     }); | 
|     window.addEventListener('click', function(event) { //解决touch与click的target不一致的问题(比如链接边缘点击时,touch的target为html,而click的target为A) | 
|         var target = event.target; | 
|         var isFound = false; | 
|         for (; target && target !== document; target = target.parentNode) { | 
|             if (target.tagName === 'A') { | 
|                 $.each($.targetHandles, function(index, targetHandle) { | 
|                     var name = targetHandle.name; | 
|                     if (targetHandle.hasOwnProperty('handle')) { | 
|                         if (targetHandle.handle(event, target)) { | 
|                             isFound = true; | 
|                             event.preventDefault(); | 
|                             return false; | 
|                         } | 
|                     } | 
|                 }); | 
|                 if (isFound) { | 
|                     break; | 
|                 } | 
|             } | 
|         } | 
|     }); | 
| })(mui, window, document); | 
| /** | 
|  * fixed trim | 
|  * @param {type} undefined | 
|  * @returns {undefined} | 
|  */ | 
| (function(undefined) { | 
|     if (String.prototype.trim === undefined) { // fix for iOS 3.2 | 
|         String.prototype.trim = function() { | 
|             return this.replace(/^\s+|\s+$/g, ''); | 
|         }; | 
|     } | 
|     Object.setPrototypeOf = Object.setPrototypeOf || function(obj, proto) { | 
|         obj['__proto__'] = proto; | 
|         return obj; | 
|     }; | 
|   | 
| })(); | 
| /** | 
|  * fixed CustomEvent | 
|  */ | 
| (function() { | 
|     if (typeof window.CustomEvent === 'undefined') { | 
|         function CustomEvent(event, params) { | 
|             params = params || { | 
|                 bubbles: false, | 
|                 cancelable: false, | 
|                 detail: undefined | 
|             }; | 
|             var evt = document.createEvent('Events'); | 
|             var bubbles = true; | 
|             for (var name in params) { | 
|                 (name === 'bubbles') ? (bubbles = !!params[name]) : (evt[name] = params[name]); | 
|             } | 
|             evt.initEvent(event, bubbles, true); | 
|             return evt; | 
|         }; | 
|         CustomEvent.prototype = window.Event.prototype; | 
|         window.CustomEvent = CustomEvent; | 
|     } | 
| })(); | 
| /* | 
|     A shim for non ES5 supporting browsers. | 
|     Adds function bind to Function prototype, so that you can do partial application. | 
|     Works even with the nasty thing, where the first word is the opposite of extranet, the second one is the profession of Columbus, and the version number is 9, flipped 180 degrees. | 
| */ | 
|   | 
| Function.prototype.bind = Function.prototype.bind || function(to) { | 
|     // Make an array of our arguments, starting from second argument | 
|     var partial = Array.prototype.splice.call(arguments, 1), | 
|         // We'll need the original function. | 
|         fn = this; | 
|     var bound = function() { | 
|             // Join the already applied arguments to the now called ones (after converting to an array again). | 
|             var args = partial.concat(Array.prototype.splice.call(arguments, 0)); | 
|             // If not being called as a constructor | 
|             if (!(this instanceof bound)) { | 
|                 // return the result of the function called bound to target and partially applied. | 
|                 return fn.apply(to, args); | 
|             } | 
|             // If being called as a constructor, apply the function bound to self. | 
|             fn.apply(this, args); | 
|         } | 
|         // Attach the prototype of the function to our newly created function. | 
|     bound.prototype = fn.prototype; | 
|     return bound; | 
| }; | 
| /** | 
|  * mui fixed classList | 
|  * @param {type} document | 
|  * @returns {undefined} | 
|  */ | 
| (function(document) { | 
|     if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== 'undefined') { | 
|   | 
|         Object.defineProperty(HTMLElement.prototype, 'classList', { | 
|             get: function() { | 
|                 var self = this; | 
|                 function update(fn) { | 
|                     return function(value) { | 
|                         var classes = self.className.split(/\s+/), | 
|                                 index = classes.indexOf(value); | 
|   | 
|                         fn(classes, index, value); | 
|                         self.className = classes.join(" "); | 
|                     }; | 
|                 } | 
|   | 
|                 var ret = { | 
|                     add: update(function(classes, index, value) { | 
|                         ~index || classes.push(value); | 
|                     }), | 
|                     remove: update(function(classes, index) { | 
|                         ~index && classes.splice(index, 1); | 
|                     }), | 
|                     toggle: update(function(classes, index, value) { | 
|                         ~index ? classes.splice(index, 1) : classes.push(value); | 
|                     }), | 
|                     contains: function(value) { | 
|                         return !!~self.className.split(/\s+/).indexOf(value); | 
|                     }, | 
|                     item: function(i) { | 
|                         return self.className.split(/\s+/)[i] || null; | 
|                     } | 
|                 }; | 
|   | 
|                 Object.defineProperty(ret, 'length', { | 
|                     get: function() { | 
|                         return self.className.split(/\s+/).length; | 
|                     } | 
|                 }); | 
|   | 
|                 return ret; | 
|             } | 
|         }); | 
|     } | 
| })(document); | 
|   | 
| /** | 
|  * mui fixed requestAnimationFrame | 
|  * @param {type} window | 
|  * @returns {undefined} | 
|  */ | 
| (function(window) { | 
|     if (!window.requestAnimationFrame) { | 
|         var lastTime = 0; | 
|         window.requestAnimationFrame = window.webkitRequestAnimationFrame || function(callback, element) { | 
|             var currTime = new Date().getTime(); | 
|             var timeToCall = Math.max(0, 16.7 - (currTime - lastTime)); | 
|             var id = window.setTimeout(function() { | 
|                 callback(currTime + timeToCall); | 
|             }, timeToCall); | 
|             lastTime = currTime + timeToCall; | 
|             return id; | 
|         }; | 
|         window.cancelAnimationFrame = window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || function(id) { | 
|             clearTimeout(id); | 
|         }; | 
|     }; | 
| }(window)); | 
| /** | 
|  * fastclick(only for radio,checkbox) | 
|  */ | 
| (function($, window, name) { | 
|     if (!$.os.android && !$.os.ios) { //目前仅识别android和ios | 
|         return; | 
|     } | 
|     if (window.FastClick) { | 
|         return; | 
|     } | 
|   | 
|     var handle = function(event, target) { | 
|         if (target.tagName === 'LABEL') { | 
|             if (target.parentNode) { | 
|                 target = target.parentNode.querySelector('input'); | 
|             } | 
|         } | 
|         if (target && (target.type === 'radio' || target.type === 'checkbox')) { | 
|             if (!target.disabled) { //disabled | 
|                 return target; | 
|             } | 
|         } | 
|         return false; | 
|     }; | 
|   | 
|     $.registerTarget({ | 
|         name: name, | 
|         index: 40, | 
|         handle: handle, | 
|         target: false | 
|     }); | 
|     var dispatchEvent = function(event) { | 
|         var targetElement = $.targets.click; | 
|         if (targetElement) { | 
|             var clickEvent, touch; | 
|             // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect | 
|             if (document.activeElement && document.activeElement !== targetElement) { | 
|                 document.activeElement.blur(); | 
|             } | 
|             touch = event.detail.gesture.changedTouches[0]; | 
|             // Synthesise a click event, with an extra attribute so it can be tracked | 
|             clickEvent = document.createEvent('MouseEvents'); | 
|             clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null); | 
|             clickEvent.forwardedTouchEvent = true; | 
|             targetElement.dispatchEvent(clickEvent); | 
|             event.detail && event.detail.gesture.preventDefault(); | 
|         } | 
|     }; | 
|     window.addEventListener('tap', dispatchEvent); | 
|     window.addEventListener('doubletap', dispatchEvent); | 
|     //捕获 | 
|     window.addEventListener('click', function(event) { | 
|         if ($.targets.click) { | 
|             if (!event.forwardedTouchEvent) { //stop click | 
|                 if (event.stopImmediatePropagation) { | 
|                     event.stopImmediatePropagation(); | 
|                 } else { | 
|                     // Part of the hack for browsers that don't support Event#stopImmediatePropagation | 
|                     event.propagationStopped = true; | 
|                 } | 
|                 event.stopPropagation(); | 
|                 event.preventDefault(); | 
|                 return false; | 
|             } | 
|         } | 
|     }, true); | 
|   | 
| })(mui, window, 'click'); | 
| (function($, document) { | 
|     $(function() { | 
|         if (!$.os.ios) { | 
|             return; | 
|         } | 
|         var CLASS_FOCUSIN = 'mui-focusin'; | 
|         var CLASS_BAR_TAB = 'mui-bar-tab'; | 
|         var CLASS_BAR_FOOTER = 'mui-bar-footer'; | 
|         var CLASS_BAR_FOOTER_SECONDARY = 'mui-bar-footer-secondary'; | 
|         var CLASS_BAR_FOOTER_SECONDARY_TAB = 'mui-bar-footer-secondary-tab'; | 
|         // var content = document.querySelector('.' + CLASS_CONTENT); | 
|         // if (content) { | 
|         //     document.body.insertBefore(content, document.body.firstElementChild); | 
|         // } | 
|         document.addEventListener('focusin', function(e) { | 
|             if ($.os.plus) { //在父webview里边不fix | 
|                 if (window.plus) { | 
|                     if (plus.webview.currentWebview().children().length > 0) { | 
|                         return; | 
|                     } | 
|                 } | 
|             } | 
|             var target = e.target; | 
|             //TODO 需考虑所有键盘弹起的情况 | 
|             if (target.tagName && (target.tagName === 'TEXTAREA' || (target.tagName === 'INPUT' && (target.type === 'text' || target.type === 'search' || target.type === 'number')))) { | 
|                 if (target.disabled || target.readOnly) { | 
|                     return; | 
|                 } | 
|                 document.body.classList.add(CLASS_FOCUSIN); | 
|                 var isFooter = false; | 
|                 for (; target && target !== document; target = target.parentNode) { | 
|                     var classList = target.classList; | 
|                     if (classList && classList.contains(CLASS_BAR_TAB) || classList.contains(CLASS_BAR_FOOTER) || classList.contains(CLASS_BAR_FOOTER_SECONDARY) || classList.contains(CLASS_BAR_FOOTER_SECONDARY_TAB)) { | 
|                         isFooter = true; | 
|                         break; | 
|                     } | 
|                 } | 
|                 if (isFooter) { | 
|                     var scrollTop = document.body.scrollHeight; | 
|                     var scrollLeft = document.body.scrollLeft; | 
|                     setTimeout(function() { | 
|                         window.scrollTo(scrollLeft, scrollTop); | 
|                     }, 20); | 
|                 } | 
|             } | 
|         }); | 
|         document.addEventListener('focusout', function(e) { | 
|             var classList = document.body.classList; | 
|             if (classList.contains(CLASS_FOCUSIN)) { | 
|                 classList.remove(CLASS_FOCUSIN); | 
|                 setTimeout(function() { | 
|                     window.scrollTo(document.body.scrollLeft, document.body.scrollTop); | 
|                 }, 20); | 
|             } | 
|         }); | 
|     }); | 
| })(mui, document); | 
| /** | 
|  * mui namespace(optimization) | 
|  * @param {type} $ | 
|  * @returns {undefined} | 
|  */ | 
| (function($) { | 
|     $.namespace = 'mui'; | 
|     $.classNamePrefix = $.namespace + '-'; | 
|     $.classSelectorPrefix = '.' + $.classNamePrefix; | 
|     /** | 
|      * 返回正确的className | 
|      * @param {type} className | 
|      * @returns {String} | 
|      */ | 
|     $.className = function(className) { | 
|         return $.classNamePrefix + className; | 
|     }; | 
|     /** | 
|      * 返回正确的classSelector | 
|      * @param {type} classSelector | 
|      * @returns {String} | 
|      */ | 
|     $.classSelector = function(classSelector) { | 
|         return classSelector.replace(/\./g, $.classSelectorPrefix); | 
|     }; | 
|     /** | 
|          * 返回正确的eventName | 
|          * @param {type} event | 
|          * @param {type} module | 
|          * @returns {String} | 
|          */ | 
|     $.eventName = function(event, module) { | 
|         return event + ($.namespace ? ('.' + $.namespace) : '') + ( module ? ('.' + module) : ''); | 
|     }; | 
| })(mui); | 
|   | 
| /** | 
|  * mui gestures | 
|  * @param {type} $ | 
|  * @param {type} window | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window) { | 
|     $.gestures = { | 
|         session: {} | 
|     }; | 
|     /** | 
|      * Gesture preventDefault | 
|      * @param {type} e | 
|      * @returns {undefined} | 
|      */ | 
|     $.preventDefault = function(e) { | 
|         e.preventDefault(); | 
|     }; | 
|     /** | 
|      * Gesture stopPropagation | 
|      * @param {type} e | 
|      * @returns {undefined} | 
|      */ | 
|     $.stopPropagation = function(e) { | 
|         e.stopPropagation(); | 
|     }; | 
|   | 
|     /** | 
|      * register gesture | 
|      * @param {type} gesture | 
|      * @returns {$.gestures} | 
|      */ | 
|     $.addGesture = function(gesture) { | 
|         return $.addAction('gestures', gesture); | 
|   | 
|     }; | 
|   | 
|     var round = Math.round; | 
|     var abs = Math.abs; | 
|     var sqrt = Math.sqrt; | 
|     var atan = Math.atan; | 
|     var atan2 = Math.atan2; | 
|     /** | 
|      * distance | 
|      * @param {type} p1 | 
|      * @param {type} p2 | 
|      * @returns {Number} | 
|      */ | 
|     var getDistance = function(p1, p2, props) { | 
|         if(!props) { | 
|             props = ['x', 'y']; | 
|         } | 
|         var x = p2[props[0]] - p1[props[0]]; | 
|         var y = p2[props[1]] - p1[props[1]]; | 
|         return sqrt((x * x) + (y * y)); | 
|     }; | 
|     /** | 
|      * scale | 
|      * @param {Object} starts | 
|      * @param {Object} moves | 
|      */ | 
|     var getScale = function(starts, moves) { | 
|         if(starts.length >= 2 && moves.length >= 2) { | 
|             var props = ['pageX', 'pageY']; | 
|             return getDistance(moves[1], moves[0], props) / getDistance(starts[1], starts[0], props); | 
|         } | 
|         return 1; | 
|     }; | 
|     /** | 
|      * angle | 
|      * @param {type} p1 | 
|      * @param {type} p2 | 
|      * @returns {Number} | 
|      */ | 
|     var getAngle = function(p1, p2, props) { | 
|         if(!props) { | 
|             props = ['x', 'y']; | 
|         } | 
|         var x = p2[props[0]] - p1[props[0]]; | 
|         var y = p2[props[1]] - p1[props[1]]; | 
|         return atan2(y, x) * 180 / Math.PI; | 
|     }; | 
|     /** | 
|      * direction | 
|      * @param {Object} x | 
|      * @param {Object} y | 
|      */ | 
|     var getDirection = function(x, y) { | 
|         if(x === y) { | 
|             return ''; | 
|         } | 
|         if(abs(x) >= abs(y)) { | 
|             return x > 0 ? 'left' : 'right'; | 
|         } | 
|         return y > 0 ? 'up' : 'down'; | 
|     }; | 
|     /** | 
|      * rotation | 
|      * @param {Object} start | 
|      * @param {Object} end | 
|      */ | 
|     var getRotation = function(start, end) { | 
|         var props = ['pageX', 'pageY']; | 
|         return getAngle(end[1], end[0], props) - getAngle(start[1], start[0], props); | 
|     }; | 
|     /** | 
|      * px per ms | 
|      * @param {Object} deltaTime | 
|      * @param {Object} x | 
|      * @param {Object} y | 
|      */ | 
|     var getVelocity = function(deltaTime, x, y) { | 
|         return { | 
|             x: x / deltaTime || 0, | 
|             y: y / deltaTime || 0 | 
|         }; | 
|     }; | 
|     /** | 
|      * detect gestures | 
|      * @param {type} event | 
|      * @param {type} touch | 
|      * @returns {undefined} | 
|      */ | 
|     var detect = function(event, touch) { | 
|         if($.gestures.stoped) { | 
|             return; | 
|         } | 
|         $.doAction('gestures', function(index, gesture) { | 
|             if(!$.gestures.stoped) { | 
|                 if($.options.gestureConfig[gesture.name] !== false) { | 
|                     gesture.handle(event, touch); | 
|                 } | 
|             } | 
|         }); | 
|     }; | 
|     /** | 
|      * 暂时无用 | 
|      * @param {Object} node | 
|      * @param {Object} parent | 
|      */ | 
|     var hasParent = function(node, parent) { | 
|         while(node) { | 
|             if(node == parent) { | 
|                 return true; | 
|             } | 
|             node = node.parentNode; | 
|         } | 
|         return false; | 
|     }; | 
|   | 
|     var uniqueArray = function(src, key, sort) { | 
|         var results = []; | 
|         var values = []; | 
|         var i = 0; | 
|   | 
|         while(i < src.length) { | 
|             var val = key ? src[i][key] : src[i]; | 
|             if(values.indexOf(val) < 0) { | 
|                 results.push(src[i]); | 
|             } | 
|             values[i] = val; | 
|             i++; | 
|         } | 
|   | 
|         if(sort) { | 
|             if(!key) { | 
|                 results = results.sort(); | 
|             } else { | 
|                 results = results.sort(function sortUniqueArray(a, b) { | 
|                     return a[key] > b[key]; | 
|                 }); | 
|             } | 
|         } | 
|   | 
|         return results; | 
|     }; | 
|     var getMultiCenter = function(touches) { | 
|         var touchesLength = touches.length; | 
|         if(touchesLength === 1) { | 
|             return { | 
|                 x: round(touches[0].pageX), | 
|                 y: round(touches[0].pageY) | 
|             }; | 
|         } | 
|   | 
|         var x = 0; | 
|         var y = 0; | 
|         var i = 0; | 
|         while(i < touchesLength) { | 
|             x += touches[i].pageX; | 
|             y += touches[i].pageY; | 
|             i++; | 
|         } | 
|   | 
|         return { | 
|             x: round(x / touchesLength), | 
|             y: round(y / touchesLength) | 
|         }; | 
|     }; | 
|     var multiTouch = function() { | 
|         return $.options.gestureConfig.pinch; | 
|     }; | 
|     var copySimpleTouchData = function(touch) { | 
|         var touches = []; | 
|         var i = 0; | 
|         while(i < touch.touches.length) { | 
|             touches[i] = { | 
|                 pageX: round(touch.touches[i].pageX), | 
|                 pageY: round(touch.touches[i].pageY) | 
|             }; | 
|             i++; | 
|         } | 
|         return { | 
|             timestamp: $.now(), | 
|             gesture: touch.gesture, | 
|             touches: touches, | 
|             center: getMultiCenter(touch.touches), | 
|             deltaX: touch.deltaX, | 
|             deltaY: touch.deltaY | 
|         }; | 
|     }; | 
|   | 
|     var calDelta = function(touch) { | 
|         var session = $.gestures.session; | 
|         var center = touch.center; | 
|         var offset = session.offsetDelta || {}; | 
|         var prevDelta = session.prevDelta || {}; | 
|         var prevTouch = session.prevTouch || {}; | 
|   | 
|         if(touch.gesture.type === $.EVENT_START || touch.gesture.type === $.EVENT_END) { | 
|             prevDelta = session.prevDelta = { | 
|                 x: prevTouch.deltaX || 0, | 
|                 y: prevTouch.deltaY || 0 | 
|             }; | 
|   | 
|             offset = session.offsetDelta = { | 
|                 x: center.x, | 
|                 y: center.y | 
|             }; | 
|         } | 
|         touch.deltaX = prevDelta.x + (center.x - offset.x); | 
|         touch.deltaY = prevDelta.y + (center.y - offset.y); | 
|     }; | 
|     var calTouchData = function(touch) { | 
|         var session = $.gestures.session; | 
|         var touches = touch.touches; | 
|         var touchesLength = touches.length; | 
|   | 
|         if(!session.firstTouch) { | 
|             session.firstTouch = copySimpleTouchData(touch); | 
|         } | 
|   | 
|         if(multiTouch() && touchesLength > 1 && !session.firstMultiTouch) { | 
|             session.firstMultiTouch = copySimpleTouchData(touch); | 
|         } else if(touchesLength === 1) { | 
|             session.firstMultiTouch = false; | 
|         } | 
|   | 
|         var firstTouch = session.firstTouch; | 
|         var firstMultiTouch = session.firstMultiTouch; | 
|         var offsetCenter = firstMultiTouch ? firstMultiTouch.center : firstTouch.center; | 
|   | 
|         var center = touch.center = getMultiCenter(touches); | 
|         touch.timestamp = $.now(); | 
|         touch.deltaTime = touch.timestamp - firstTouch.timestamp; | 
|   | 
|         touch.angle = getAngle(offsetCenter, center); | 
|         touch.distance = getDistance(offsetCenter, center); | 
|   | 
|         calDelta(touch); | 
|   | 
|         touch.offsetDirection = getDirection(touch.deltaX, touch.deltaY); | 
|   | 
|         touch.scale = firstMultiTouch ? getScale(firstMultiTouch.touches, touches) : 1; | 
|         touch.rotation = firstMultiTouch ? getRotation(firstMultiTouch.touches, touches) : 0; | 
|   | 
|         calIntervalTouchData(touch); | 
|   | 
|     }; | 
|     var CAL_INTERVAL = 25; | 
|     var calIntervalTouchData = function(touch) { | 
|         var session = $.gestures.session; | 
|         var last = session.lastInterval || touch; | 
|         var deltaTime = touch.timestamp - last.timestamp; | 
|         var velocity; | 
|         var velocityX; | 
|         var velocityY; | 
|         var direction; | 
|   | 
|         if(touch.gesture.type != $.EVENT_CANCEL && (deltaTime > CAL_INTERVAL || last.velocity === undefined)) { | 
|             var deltaX = last.deltaX - touch.deltaX; | 
|             var deltaY = last.deltaY - touch.deltaY; | 
|   | 
|             var v = getVelocity(deltaTime, deltaX, deltaY); | 
|             velocityX = v.x; | 
|             velocityY = v.y; | 
|             velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y; | 
|             direction = getDirection(deltaX, deltaY) || last.direction; | 
|   | 
|             session.lastInterval = touch; | 
|         } else { | 
|             velocity = last.velocity; | 
|             velocityX = last.velocityX; | 
|             velocityY = last.velocityY; | 
|             direction = last.direction; | 
|         } | 
|   | 
|         touch.velocity = velocity; | 
|         touch.velocityX = velocityX; | 
|         touch.velocityY = velocityY; | 
|         touch.direction = direction; | 
|     }; | 
|     var targetIds = {}; | 
|     var convertTouches = function(touches) { | 
|         for(var i = 0; i < touches.length; i++) { | 
|             !touches['identifier'] && (touches['identifier'] = 0); | 
|         } | 
|         return touches; | 
|     }; | 
|     var getTouches = function(event, touch) { | 
|         var allTouches = convertTouches($.slice.call(event.touches || [event])); | 
|   | 
|         var type = event.type; | 
|   | 
|         var targetTouches = []; | 
|         var changedTargetTouches = []; | 
|   | 
|         //当touchstart或touchmove且touches长度为1,直接获得all和changed | 
|         if((type === $.EVENT_START || type === $.EVENT_MOVE) && allTouches.length === 1) { | 
|             targetIds[allTouches[0].identifier] = true; | 
|             targetTouches = allTouches; | 
|             changedTargetTouches = allTouches; | 
|             touch.target = event.target; | 
|         } else { | 
|             var i = 0; | 
|             var targetTouches = []; | 
|             var changedTargetTouches = []; | 
|             var changedTouches = convertTouches($.slice.call(event.changedTouches || [event])); | 
|   | 
|             touch.target = event.target; | 
|             var sessionTarget = $.gestures.session.target || event.target; | 
|             targetTouches = allTouches.filter(function(touch) { | 
|                 return hasParent(touch.target, sessionTarget); | 
|             }); | 
|   | 
|             if(type === $.EVENT_START) { | 
|                 i = 0; | 
|                 while(i < targetTouches.length) { | 
|                     targetIds[targetTouches[i].identifier] = true; | 
|                     i++; | 
|                 } | 
|             } | 
|   | 
|             i = 0; | 
|             while(i < changedTouches.length) { | 
|                 if(targetIds[changedTouches[i].identifier]) { | 
|                     changedTargetTouches.push(changedTouches[i]); | 
|                 } | 
|                 if(type === $.EVENT_END || type === $.EVENT_CANCEL) { | 
|                     delete targetIds[changedTouches[i].identifier]; | 
|                 } | 
|                 i++; | 
|             } | 
|   | 
|             if(!changedTargetTouches.length) { | 
|                 return false; | 
|             } | 
|         } | 
|         targetTouches = uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true); | 
|         var touchesLength = targetTouches.length; | 
|         var changedTouchesLength = changedTargetTouches.length; | 
|         if(type === $.EVENT_START && touchesLength - changedTouchesLength === 0) { //first | 
|             touch.isFirst = true; | 
|             $.gestures.touch = $.gestures.session = { | 
|                 target: event.target | 
|             }; | 
|         } | 
|         touch.isFinal = ((type === $.EVENT_END || type === $.EVENT_CANCEL) && (touchesLength - changedTouchesLength === 0)); | 
|   | 
|         touch.touches = targetTouches; | 
|         touch.changedTouches = changedTargetTouches; | 
|         return true; | 
|   | 
|     }; | 
|     var handleTouchEvent = function(event) { | 
|         var touch = { | 
|             gesture: event | 
|         }; | 
|         var touches = getTouches(event, touch); | 
|         if(!touches) { | 
|             return; | 
|         } | 
|         calTouchData(touch); | 
|         detect(event, touch); | 
|         $.gestures.session.prevTouch = touch; | 
|         if(event.type === $.EVENT_END && !$.isTouchable) { | 
|             $.gestures.touch = $.gestures.session = {}; | 
|         } | 
|     }; | 
|     var supportsPassive = (function checkPassiveListener() { | 
|         var supportsPassive = false; | 
|         try { | 
|             var opts = Object.defineProperty({}, 'passive', { | 
|                 get: function get() { | 
|                     supportsPassive = true; | 
|                 }, | 
|             }); | 
|             window.addEventListener('testPassiveListener', null, opts); | 
|         } catch(e) { | 
|             // No support | 
|         } | 
|         return supportsPassive; | 
|     }()) | 
|     window.addEventListener($.EVENT_START, handleTouchEvent); | 
|     window.addEventListener($.EVENT_MOVE, handleTouchEvent, supportsPassive ? { | 
|         passive: false, | 
|         capture: false | 
|     } : false); | 
|     window.addEventListener($.EVENT_END, handleTouchEvent); | 
|     window.addEventListener($.EVENT_CANCEL, handleTouchEvent); | 
|     //fixed hashchange(android) | 
|     window.addEventListener($.EVENT_CLICK, function(e) { | 
|         //TODO 应该判断当前target是不是在targets.popover内部,而不是非要相等 | 
|         if(($.os.android || $.os.ios) && (($.targets.popover && e.target === $.targets.popover) || ($.targets.tab) || $.targets.offcanvas || $.targets.modal)) { | 
|             e.preventDefault(); | 
|         } | 
|     }, true); | 
|   | 
|     //增加原生滚动识别 | 
|     $.isScrolling = false; | 
|     var scrollingTimeout = null; | 
|     window.addEventListener('scroll', function() { | 
|         $.isScrolling = true; | 
|         scrollingTimeout && clearTimeout(scrollingTimeout); | 
|         scrollingTimeout = setTimeout(function() { | 
|             $.isScrolling = false; | 
|         }, 250); | 
|     }); | 
| })(mui, window); | 
| /** | 
|  * mui gesture flick[left|right|up|down] | 
|  * @param {type} $ | 
|  * @param {type} name | 
|  * @returns {undefined} | 
|  */ | 
| (function($, name) { | 
|     var flickStartTime = 0; | 
|     var handle = function(event, touch) { | 
|         var session = $.gestures.session; | 
|         var options = this.options; | 
|         var now = $.now(); | 
|         switch (event.type) { | 
|             case $.EVENT_MOVE: | 
|                 if (now - flickStartTime > 300) { | 
|                     flickStartTime = now; | 
|                     session.flickStart = touch.center; | 
|                 } | 
|                 break; | 
|             case $.EVENT_END: | 
|             case $.EVENT_CANCEL: | 
|                 touch.flick = false; | 
|                 if (session.flickStart && options.flickMaxTime > (now - flickStartTime) && touch.distance > options.flickMinDistince) { | 
|                     touch.flick = true; | 
|                     touch.flickTime = now - flickStartTime; | 
|                     touch.flickDistanceX = touch.center.x - session.flickStart.x; | 
|                     touch.flickDistanceY = touch.center.y - session.flickStart.y; | 
|                     $.trigger(session.target, name, touch); | 
|                     $.trigger(session.target, name + touch.direction, touch); | 
|                 } | 
|                 break; | 
|         } | 
|   | 
|     }; | 
|     /** | 
|      * mui gesture flick | 
|      */ | 
|     $.addGesture({ | 
|         name: name, | 
|         index: 5, | 
|         handle: handle, | 
|         options: { | 
|             flickMaxTime: 200, | 
|             flickMinDistince: 10 | 
|         } | 
|     }); | 
| })(mui, 'flick'); | 
| /** | 
|  * mui gesture swipe[left|right|up|down] | 
|  * @param {type} $ | 
|  * @param {type} name | 
|  * @returns {undefined} | 
|  */ | 
| (function($, name) { | 
|     var handle = function(event, touch) { | 
|         var session = $.gestures.session; | 
|         if (event.type === $.EVENT_END || event.type === $.EVENT_CANCEL) { | 
|             var options = this.options; | 
|             touch.swipe = false; | 
|             //TODO 后续根据velocity计算 | 
|             if (touch.direction && options.swipeMaxTime > touch.deltaTime && touch.distance > options.swipeMinDistince) { | 
|                 touch.swipe = true; | 
|                 $.trigger(session.target, name, touch); | 
|                 $.trigger(session.target, name + touch.direction, touch); | 
|             } | 
|         } | 
|     }; | 
|     /** | 
|      * mui gesture swipe | 
|      */ | 
|     $.addGesture({ | 
|         name: name, | 
|         index: 10, | 
|         handle: handle, | 
|         options: { | 
|             swipeMaxTime: 300, | 
|             swipeMinDistince: 18 | 
|         } | 
|     }); | 
| })(mui, 'swipe'); | 
| /** | 
|  * mui gesture drag[start|left|right|up|down|end] | 
|  * @param {type} $ | 
|  * @param {type} name | 
|  * @returns {undefined} | 
|  */ | 
| (function($, name) { | 
|     var handle = function(event, touch) { | 
|         var session = $.gestures.session; | 
|         switch (event.type) { | 
|             case $.EVENT_START: | 
|                 break; | 
|             case $.EVENT_MOVE: | 
|                 if (!touch.direction || !session.target) { | 
|                     return; | 
|                 } | 
|                 //修正direction,可在session期间自行锁定拖拽方向,方便开发scroll类不同方向拖拽插件嵌套 | 
|                 if (session.lockDirection && session.startDirection) { | 
|                     if (session.startDirection && session.startDirection !== touch.direction) { | 
|                         if (session.startDirection === 'up' || session.startDirection === 'down') { | 
|                             touch.direction = touch.deltaY < 0 ? 'up' : 'down'; | 
|                         } else { | 
|                             touch.direction = touch.deltaX < 0 ? 'left' : 'right'; | 
|                         } | 
|                     } | 
|                 } | 
|   | 
|                 if (!session.drag) { | 
|                     session.drag = true; | 
|                     $.trigger(session.target, name + 'start', touch); | 
|                 } | 
|                 $.trigger(session.target, name, touch); | 
|                 $.trigger(session.target, name + touch.direction, touch); | 
|                 break; | 
|             case $.EVENT_END: | 
|             case $.EVENT_CANCEL: | 
|                 if (session.drag && touch.isFinal) { | 
|                     $.trigger(session.target, name + 'end', touch); | 
|                 } | 
|                 break; | 
|         } | 
|     }; | 
|     /** | 
|      * mui gesture drag | 
|      */ | 
|     $.addGesture({ | 
|         name: name, | 
|         index: 20, | 
|         handle: handle, | 
|         options: { | 
|             fingers: 1 | 
|         } | 
|     }); | 
| })(mui, 'drag'); | 
| /** | 
|  * mui gesture tap and doubleTap | 
|  * @param {type} $ | 
|  * @param {type} name | 
|  * @returns {undefined} | 
|  */ | 
| (function($, name) { | 
|     var lastTarget; | 
|     var lastTapTime; | 
|     var handle = function(event, touch) { | 
|         var session = $.gestures.session; | 
|         var options = this.options; | 
|         switch (event.type) { | 
|             case $.EVENT_END: | 
|                 if (!touch.isFinal) { | 
|                     return; | 
|                 } | 
|                 var target = session.target; | 
|                 if (!target || (target.disabled || (target.classList && target.classList.contains('mui-disabled')))) { | 
|                     return; | 
|                 } | 
|                 if (touch.distance < options.tapMaxDistance && touch.deltaTime < options.tapMaxTime) { | 
|                     if ($.options.gestureConfig.doubletap && lastTarget && (lastTarget === target)) { //same target | 
|                         if (lastTapTime && (touch.timestamp - lastTapTime) < options.tapMaxInterval) { | 
|                             $.trigger(target, 'doubletap', touch); | 
|                             lastTapTime = $.now(); | 
|                             lastTarget = target; | 
|                             return; | 
|                         } | 
|                     } | 
|                     $.trigger(target, name, touch); | 
|                     lastTapTime = $.now(); | 
|                     lastTarget = target; | 
|                 } | 
|                 break; | 
|         } | 
|     }; | 
|     /** | 
|      * mui gesture tap | 
|      */ | 
|     $.addGesture({ | 
|         name: name, | 
|         index: 30, | 
|         handle: handle, | 
|         options: { | 
|             fingers: 1, | 
|             tapMaxInterval: 300, | 
|             tapMaxDistance: 5, | 
|             tapMaxTime: 250 | 
|         } | 
|     }); | 
| })(mui, 'tap'); | 
| /** | 
|  * mui gesture longtap | 
|  * @param {type} $ | 
|  * @param {type} name | 
|  * @returns {undefined} | 
|  */ | 
| (function($, name) { | 
|     var timer; | 
|     var handle = function(event, touch) { | 
|         var session = $.gestures.session; | 
|         var options = this.options; | 
|         switch (event.type) { | 
|             case $.EVENT_START: | 
|                 clearTimeout(timer); | 
|                 timer = setTimeout(function() { | 
|                     $.trigger(session.target, name, touch); | 
|                 }, options.holdTimeout); | 
|                 break; | 
|             case $.EVENT_MOVE: | 
|                 if (touch.distance > options.holdThreshold) { | 
|                     clearTimeout(timer); | 
|                 } | 
|                 break; | 
|             case $.EVENT_END: | 
|             case $.EVENT_CANCEL: | 
|                 clearTimeout(timer); | 
|                 break; | 
|         } | 
|     }; | 
|     /** | 
|      * mui gesture longtap | 
|      */ | 
|     $.addGesture({ | 
|         name: name, | 
|         index: 10, | 
|         handle: handle, | 
|         options: { | 
|             fingers: 1, | 
|             holdTimeout: 500, | 
|             holdThreshold: 2 | 
|         } | 
|     }); | 
| })(mui, 'longtap'); | 
| /** | 
|  * mui gesture hold | 
|  * @param {type} $ | 
|  * @param {type} name | 
|  * @returns {undefined} | 
|  */ | 
| (function($, name) { | 
|     var timer; | 
|     var handle = function(event, touch) { | 
|         var session = $.gestures.session; | 
|         var options = this.options; | 
|         switch (event.type) { | 
|             case $.EVENT_START: | 
|                 if ($.options.gestureConfig.hold) { | 
|                     timer && clearTimeout(timer); | 
|                     timer = setTimeout(function() { | 
|                         touch.hold = true; | 
|                         $.trigger(session.target, name, touch); | 
|                     }, options.holdTimeout); | 
|                 } | 
|                 break; | 
|             case $.EVENT_MOVE: | 
|                 break; | 
|             case $.EVENT_END: | 
|             case $.EVENT_CANCEL: | 
|                 if (timer) { | 
|                     clearTimeout(timer) && (timer = null); | 
|                     $.trigger(session.target, 'release', touch); | 
|                 } | 
|                 break; | 
|         } | 
|     }; | 
|     /** | 
|      * mui gesture hold | 
|      */ | 
|     $.addGesture({ | 
|         name: name, | 
|         index: 10, | 
|         handle: handle, | 
|         options: { | 
|             fingers: 1, | 
|             holdTimeout: 0 | 
|         } | 
|     }); | 
| })(mui, 'hold'); | 
| /** | 
|  * mui gesture pinch | 
|  * @param {type} $ | 
|  * @param {type} name | 
|  * @returns {undefined} | 
|  */ | 
| (function($, name) { | 
|     var handle = function(event, touch) { | 
|         var options = this.options; | 
|         var session = $.gestures.session; | 
|         switch (event.type) { | 
|             case $.EVENT_START: | 
|                 break; | 
|             case $.EVENT_MOVE: | 
|                 if ($.options.gestureConfig.pinch) { | 
|                     if (touch.touches.length < 2) { | 
|                         return; | 
|                     } | 
|                     if (!session.pinch) { //start | 
|                         session.pinch = true; | 
|                         $.trigger(session.target, name + 'start', touch); | 
|                     } | 
|                     $.trigger(session.target, name, touch); | 
|                     var scale = touch.scale; | 
|                     var rotation = touch.rotation; | 
|                     var lastScale = typeof touch.lastScale === 'undefined' ? 1 : touch.lastScale; | 
|                     var scaleDiff = 0.000000000001; //防止scale与lastScale相等,不触发事件的情况。 | 
|                     if (scale > lastScale) { //out | 
|                         lastScale = scale - scaleDiff; | 
|                         $.trigger(session.target, name + 'out', touch); | 
|                     } //in | 
|                     else if (scale < lastScale) { | 
|                         lastScale = scale + scaleDiff; | 
|                         $.trigger(session.target, name + 'in', touch); | 
|                     } | 
|                     if (Math.abs(rotation) > options.minRotationAngle) { | 
|                         $.trigger(session.target, 'rotate', touch); | 
|                     } | 
|                 } | 
|                 break; | 
|             case $.EVENT_END: | 
|             case $.EVENT_CANCEL: | 
|                 if ($.options.gestureConfig.pinch && session.pinch && touch.touches.length === 2) { | 
|                     session.pinch = false; | 
|                     $.trigger(session.target, name + 'end', touch); | 
|                 } | 
|                 break; | 
|         } | 
|     }; | 
|     /** | 
|      * mui gesture pinch | 
|      */ | 
|     $.addGesture({ | 
|         name: name, | 
|         index: 10, | 
|         handle: handle, | 
|         options: { | 
|             minRotationAngle: 0 | 
|         } | 
|     }); | 
| })(mui, 'pinch'); | 
| /** | 
|  * mui.init | 
|  * @param {type} $ | 
|  * @returns {undefined} | 
|  */ | 
| (function($) { | 
|     $.global = $.options = { | 
|         gestureConfig: { | 
|             tap: true, | 
|             doubletap: false, | 
|             longtap: false, | 
|             hold: false, | 
|             flick: true, | 
|             swipe: true, | 
|             drag: true, | 
|             pinch: false | 
|         } | 
|     }; | 
|     /** | 
|      * | 
|      * @param {type} options | 
|      * @returns {undefined} | 
|      */ | 
|     $.initGlobal = function(options) { | 
|         $.options = $.extend(true, $.global, options); | 
|         return this; | 
|     }; | 
|     var inits = {}; | 
|   | 
|     /** | 
|      * 单页配置 初始化 | 
|      * @param {object} options | 
|      */ | 
|     $.init = function(options) { | 
|         $.options = $.extend(true, $.global, options || {}); | 
|         $.ready(function() { | 
|             $.doAction('inits', function(index, init) { | 
|                 var isInit = !!(!inits[init.name] || init.repeat); | 
|                 if (isInit) { | 
|                     init.handle.call($); | 
|                     inits[init.name] = true; | 
|                 } | 
|             }); | 
|         }); | 
|         return this; | 
|     }; | 
|   | 
|     /** | 
|      * 增加初始化执行流程 | 
|      * @param {function} init | 
|      */ | 
|     $.addInit = function(init) { | 
|         return $.addAction('inits', init); | 
|     }; | 
|     /** | 
|      * 处理html5版本subpages  | 
|      */ | 
|     $.addInit({ | 
|         name: 'iframe', | 
|         index: 100, | 
|         handle: function() { | 
|             var options = $.options; | 
|             var subpages = options.subpages || []; | 
|             if (!$.os.plus && subpages.length) { | 
|                 //暂时只处理单个subpage。后续可以考虑支持多个subpage | 
|                 createIframe(subpages[0]); | 
|             } | 
|         } | 
|     }); | 
|     var createIframe = function(options) { | 
|         var wrapper = document.createElement('div'); | 
|         wrapper.className = 'mui-iframe-wrapper'; | 
|         var styles = options.styles || {}; | 
|         if (typeof styles.top !== 'string') { | 
|             styles.top = '0px'; | 
|         } | 
|         if (typeof styles.bottom !== 'string') { | 
|             styles.bottom = '0px'; | 
|         } | 
|         wrapper.style.top = styles.top; | 
|         wrapper.style.bottom = styles.bottom; | 
|         var iframe = document.createElement('iframe'); | 
|         iframe.src = options.url; | 
|         iframe.id = options.id || options.url; | 
|         iframe.name = iframe.id; | 
|         wrapper.appendChild(iframe); | 
|         document.body.appendChild(wrapper); | 
|         //目前仅处理微信 | 
|         $.os.wechat && handleScroll(wrapper, iframe); | 
|     }; | 
|   | 
|     function handleScroll(wrapper, iframe) { | 
|         var key = 'MUI_SCROLL_POSITION_' + document.location.href + '_' + iframe.src; | 
|         var scrollTop = (parseFloat(localStorage.getItem(key)) || 0); | 
|         if (scrollTop) { | 
|             (function(y) { | 
|                 iframe.onload = function() { | 
|                     window.scrollTo(0, y); | 
|                 }; | 
|             })(scrollTop); | 
|         } | 
|         setInterval(function() { | 
|             var _scrollTop = window.scrollY; | 
|             if (scrollTop !== _scrollTop) { | 
|                 localStorage.setItem(key, _scrollTop + ''); | 
|                 scrollTop = _scrollTop; | 
|             } | 
|         }, 100); | 
|     }; | 
|     $(function() { | 
|         var classList = document.body.classList; | 
|         var os = []; | 
|         if ($.os.ios) { | 
|             os.push({ | 
|                 os: 'ios', | 
|                 version: $.os.version | 
|             }); | 
|             classList.add('mui-ios'); | 
|         } else if ($.os.android) { | 
|             os.push({ | 
|                 os: 'android', | 
|                 version: $.os.version | 
|             }); | 
|             classList.add('mui-android'); | 
|         } | 
|         if ($.os.wechat) { | 
|             os.push({ | 
|                 os: 'wechat', | 
|                 version: $.os.wechat.version | 
|             }); | 
|             classList.add('mui-wechat'); | 
|         } | 
|         if (os.length) { | 
|             $.each(os, function(index, osObj) { | 
|                 var version = ''; | 
|                 var classArray = []; | 
|                 if (osObj.version) { | 
|                     $.each(osObj.version.split('.'), function(i, v) { | 
|                         version = version + (version ? '-' : '') + v; | 
|                         classList.add($.className(osObj.os + '-' + version)); | 
|                     }); | 
|                 } | 
|             }); | 
|         } | 
|     }); | 
| })(mui); | 
| /** | 
|  * mui.init 5+ | 
|  * @param {type} $ | 
|  * @returns {undefined} | 
|  */ | 
| (function($) { | 
|     var defaultOptions = { | 
|         swipeBack: false, | 
|         preloadPages: [], //5+ lazyLoad webview | 
|         preloadLimit: 10, //预加载窗口的数量限制(一旦超出,先进先出) | 
|         keyEventBind: { | 
|             backbutton: true, | 
|             menubutton: true | 
|         }, | 
|         titleConfig: { | 
|             height: "44px", | 
|             backgroundColor: "#f7f7f7", //导航栏背景色 | 
|             bottomBorderColor: "#cccccc", //底部边线颜色 | 
|             title: { //标题配置 | 
|                 text: "", //标题文字 | 
|                 position: { | 
|                     top: 0, | 
|                     left: 0, | 
|                     width: "100%", | 
|                     height: "100%" | 
|                 }, | 
|                 styles: { | 
|                     color: "#000000", | 
|                     align: "center", | 
|                     family: "'Helvetica Neue',Helvetica,sans-serif", | 
|                     size: "17px", | 
|                     style: "normal", | 
|                     weight: "normal", | 
|                     fontSrc: "" | 
|                 } | 
|             }, | 
|             back: { | 
|                 image: { | 
|                     base64Data: '', | 
|                     imgSrc: '', | 
|                     sprite: { | 
|                         top: '0px', | 
|                         left: '0px', | 
|                         width: '100%', | 
|                         height: '100%' | 
|                     }, | 
|                     position: { | 
|                         top: "10px", | 
|                         left: "10px", | 
|                         width: "24px", | 
|                         height: "24px" | 
|                     } | 
|                 } | 
|             } | 
|         } | 
|     }; | 
|   | 
|     //默认页面动画 | 
|     var defaultShow = { | 
|         event:"titleUpdate", | 
|         autoShow: true, | 
|         duration: 300, | 
|         aniShow: 'slide-in-right', | 
|         extras:{} | 
|     }; | 
|     //若执行了显示动画初始化操作,则要覆盖默认配置 | 
|     if($.options.show) { | 
|         defaultShow = $.extend(true, defaultShow, $.options.show); | 
|     } | 
|   | 
|     $.currentWebview = null; | 
|   | 
|     $.extend(true, $.global, defaultOptions); | 
|     $.extend(true, $.options, defaultOptions); | 
|     /** | 
|      * 等待动画配置 | 
|      * @param {type} options | 
|      * @returns {Object} | 
|      */ | 
|     $.waitingOptions = function(options) { | 
|         return $.extend(true, {}, { | 
|             autoShow: true, | 
|             title: '', | 
|             modal: false | 
|         }, options); | 
|     }; | 
|     /** | 
|      * 窗口显示配置 | 
|      * @param {type} options | 
|      * @returns {Object} | 
|      */ | 
|     $.showOptions = function(options) { | 
|         return $.extend(true, {}, defaultShow, options); | 
|     }; | 
|     /** | 
|      * 窗口默认配置 | 
|      * @param {type} options | 
|      * @returns {Object} | 
|      */ | 
|     $.windowOptions = function(options) { | 
|         return $.extend({ | 
|             scalable: false, | 
|             bounce: "" //vertical | 
|         }, options); | 
|     }; | 
|     /** | 
|      * plusReady | 
|      * @param {type} callback | 
|      * @returns {_L6.$} | 
|      */ | 
|     $.plusReady = function(callback) { | 
|         if(window.plus) { | 
|             setTimeout(function() { //解决callback与plusready事件的执行时机问题(典型案例:showWaiting,closeWaiting) | 
|                 callback(); | 
|             }, 0); | 
|         } else { | 
|             document.addEventListener("plusready", function() { | 
|                 callback(); | 
|             }, false); | 
|         } | 
|         return this; | 
|     }; | 
|     /** | 
|      * 5+ event(5+没提供之前我自己实现) | 
|      * @param {type} webview | 
|      * @param {type} eventType | 
|      * @param {type} data | 
|      * @returns {undefined} | 
|      */ | 
|     $.fire = function(webview, eventType, data) { | 
|         if(webview) { | 
|             if(typeof data === 'undefined') { | 
|                 data = ''; | 
|             } else if(typeof data === 'boolean' || typeof data === 'number') { | 
|                 webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "'," + data + ")"); | 
|                 return; | 
|             } else if($.isPlainObject(data) || $.isArray(data)) { | 
|                 data = JSON.stringify(data || {}).replace(/\'/g, "\\u0027").replace(/\\/g, "\\u005c"); | 
|             } | 
|             webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "','" + data + "')"); | 
|         } | 
|     }; | 
|     /** | 
|      * 5+ event(5+没提供之前我自己实现) | 
|      * @param {type} eventType | 
|      * @param {type} data | 
|      * @returns {undefined} | 
|      */ | 
|     $.receive = function(eventType, data) { | 
|         if(eventType) { | 
|             try { | 
|                 if(data && typeof data === 'string') { | 
|                     data = JSON.parse(data); | 
|                 } | 
|             } catch(e) {} | 
|             $.trigger(document, eventType, data); | 
|         } | 
|     }; | 
|     var triggerPreload = function(webview) { | 
|         if(!webview.preloaded) { //保证仅触发一次 | 
|             $.fire(webview, 'preload'); | 
|             var list = webview.children(); | 
|             for(var i = 0; i < list.length; i++) { | 
|                 $.fire(list[i], 'preload'); | 
|             } | 
|             webview.preloaded = true; | 
|         } | 
|     }; | 
|     var trigger = function(webview, eventType, timeChecked) { | 
|         if(timeChecked) { | 
|             if(!webview[eventType + 'ed']) { | 
|                 $.fire(webview, eventType); | 
|                 var list = webview.children(); | 
|                 for(var i = 0; i < list.length; i++) { | 
|                     $.fire(list[i], eventType); | 
|                 } | 
|                 webview[eventType + 'ed'] = true; | 
|             } | 
|         } else { | 
|             $.fire(webview, eventType); | 
|             var list = webview.children(); | 
|             for(var i = 0; i < list.length; i++) { | 
|                 $.fire(list[i], eventType); | 
|             } | 
|         } | 
|   | 
|     }; | 
|     /** | 
|      * 打开新窗口 | 
|      * @param {string} url 要打开的页面地址 | 
|      * @param {string} id 指定页面ID | 
|      * @param {object} options 可选:参数,等待,窗口,显示配置{params:{},waiting:{},styles:{},show:{}} | 
|      */ | 
|     $.openWindow = function(url, id, options) { | 
|         if(typeof url === 'object') { | 
|             options = url; | 
|             url = options.url; | 
|             id = options.id || url; | 
|         } else { | 
|             if(typeof id === 'object') { | 
|                 options = id; | 
|                 id = options.id || url; | 
|             } else { | 
|                 id = id || url; | 
|             } | 
|         } | 
|         if(!$.os.plus) { | 
|             //TODO 先临时这么处理:手机上顶层跳,PC上parent跳 | 
|             if($.os.ios || $.os.android) { | 
|                 window.top.location.href = url; | 
|             } else { | 
|                 window.parent.location.href = url; | 
|             } | 
|             return; | 
|         } | 
|         if(!window.plus) { | 
|             return; | 
|         } | 
|   | 
|         options = options || {}; | 
|         var params = options.params || {}; | 
|         var webview = null, | 
|             webviewCache = null, | 
|             nShow, nWaiting; | 
|   | 
|         if($.webviews[id]) { | 
|             webviewCache = $.webviews[id]; | 
|             //webview真实存在,才能获取 | 
|             if(plus.webview.getWebviewById(id)) { | 
|                 webview = webviewCache.webview; | 
|             } | 
|         } else if(options.createNew !== true) { | 
|             webview = plus.webview.getWebviewById(id); | 
|         } | 
|   | 
|         if(webview) { //已缓存 | 
|             //每次show都需要传递动画参数; | 
|             //预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置; | 
|             nShow = webviewCache ? webviewCache.show : defaultShow; | 
|             nShow = options.show ? $.extend(nShow, options.show) : nShow; | 
|             nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() { | 
|                 triggerPreload(webview); | 
|                 trigger(webview, 'pagebeforeshow', false); | 
|             }); | 
|             if(webviewCache) { | 
|                 webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')'); | 
|             } | 
|             return webview; | 
|         } else { //新窗口 | 
|             if(!url) { | 
|                 throw new Error('webview[' + id + '] does not exist'); | 
|             } | 
|   | 
|             //显示waiting | 
|             var waitingConfig = $.waitingOptions(options.waiting); | 
|             if(waitingConfig.autoShow) { | 
|                 nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options); | 
|             } | 
|   | 
|             //创建页面 | 
|             options = $.extend(options, { | 
|                 id: id, | 
|                 url: url | 
|             }); | 
|   | 
|             webview = $.createWindow(options); | 
|   | 
|             //显示 | 
|             nShow = $.showOptions(options.show); | 
|             if(nShow.autoShow) { | 
|                 var showWebview = function() { | 
|                     //关闭等待框 | 
|                     if(nWaiting) { | 
|                         nWaiting.close(); | 
|                     } | 
|                     //显示页面 | 
|                     webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras); | 
|                     options.afterShowMethodName && webview.evalJS(options.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')'); | 
|                 }; | 
|                 //titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview | 
|                 webview.addEventListener(nShow.event, showWebview, false); | 
|                 //loaded事件发生后,触发预加载和pagebeforeshow事件 | 
|                 webview.addEventListener("loaded", function() { | 
|                     triggerPreload(webview); | 
|                     trigger(webview, 'pagebeforeshow', false); | 
|                 }, false); | 
|             } | 
|         } | 
|         return webview; | 
|     }; | 
|   | 
|     $.openWindowWithTitle = function(options, titleConfig) { | 
|         options = options || {}; | 
|         var url = options.url; | 
|         var id = options.id || url; | 
|   | 
|         if(!$.os.plus) { | 
|             //TODO 先临时这么处理:手机上顶层跳,PC上parent跳 | 
|             if($.os.ios || $.os.android) { | 
|                 window.top.location.href = url; | 
|             } else { | 
|                 window.parent.location.href = url; | 
|             } | 
|             return; | 
|         } | 
|         if(!window.plus) { | 
|             return; | 
|         } | 
|   | 
|         var params = options.params || {}; | 
|         var webview = null, | 
|             webviewCache = null, | 
|             nShow, nWaiting; | 
|   | 
|         if($.webviews[id]) { | 
|             webviewCache = $.webviews[id]; | 
|             //webview真实存在,才能获取 | 
|             if(plus.webview.getWebviewById(id)) { | 
|                 webview = webviewCache.webview; | 
|             } | 
|         } else if(options.createNew !== true) { | 
|             webview = plus.webview.getWebviewById(id); | 
|         } | 
|   | 
|         if(webview) { //已缓存 | 
|             //每次show都需要传递动画参数; | 
|             //预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置; | 
|             nShow = webviewCache ? webviewCache.show : defaultShow; | 
|             nShow = options.show ? $.extend(nShow, options.show) : nShow; | 
|             nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() { | 
|                 triggerPreload(webview); | 
|                 trigger(webview, 'pagebeforeshow', false); | 
|             }); | 
|             if(webviewCache) { | 
|                 webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')'); | 
|             } | 
|             return webview; | 
|         } else { //新窗口 | 
|             if(!url) { | 
|                 throw new Error('webview[' + id + '] does not exist'); | 
|             } | 
|   | 
|             //显示waiting | 
|             var waitingConfig = $.waitingOptions(options.waiting); | 
|             if(waitingConfig.autoShow) { | 
|                 nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options); | 
|             } | 
|   | 
|             //创建页面 | 
|             options = $.extend(options, { | 
|                 id: id, | 
|                 url: url | 
|             }); | 
|   | 
|             webview = $.createWindow(options); | 
|   | 
|             if(titleConfig) { //处理原生头 | 
|                 $.extend(true, $.options.titleConfig, titleConfig); | 
|                 var tid = $.options.titleConfig.id ? $.options.titleConfig.id : id + "_title"; | 
|                 var view = new plus.nativeObj.View(tid, { | 
|                     top: 0, | 
|                     height: $.options.titleConfig.height, | 
|                     width: "100%", | 
|                     dock: "top", | 
|                     position: "dock" | 
|                 }); | 
|                 view.drawRect($.options.titleConfig.backgroundColor); //绘制背景色 | 
|                 var _b = parseInt($.options.titleConfig.height) - 1; | 
|                 view.drawRect($.options.titleConfig.bottomBorderColor, { | 
|                     top: _b + "px", | 
|                     left: "0px" | 
|                 }); //绘制底部边线 | 
|   | 
|                 //绘制文字 | 
|                 if($.options.titleConfig.title.text){ | 
|                     var _title = $.options.titleConfig.title; | 
|                     view.drawText(_title.text,_title.position , _title.styles); | 
|                 } | 
|                  | 
|                 //返回图标绘制 | 
|                 var _back = $.options.titleConfig.back; | 
|                 var backClick = null; | 
|                 //优先字体 | 
|   | 
|                 //其次是图片 | 
|                 var _backImage = _back.image; | 
|                 if(_backImage.base64Data || _backImage.imgSrc) { | 
|                     //TODO 此处需要处理百分比的情况 | 
|                     backClick = { | 
|                         left:parseInt(_backImage.position.left), | 
|                         right:parseInt(_backImage.position.left) + parseInt(_backImage.position.width) | 
|                     }; | 
|                     var bitmap = new plus.nativeObj.Bitmap(id + "_back"); | 
|                     if(_backImage.base64Data) { //优先base64编码字符串 | 
|                         bitmap.loadBase64Data(_backImage.base64Data); | 
|                     } else { //其次加载图片文件 | 
|                         bitmap.load(_backImage.imgSrc); | 
|                     } | 
|                     view.drawBitmap(bitmap,_backImage.sprite , _backImage.position); | 
|                 } | 
|   | 
|                 //处理点击事件 | 
|                 view.setTouchEventRect({ | 
|                     top: "0px", | 
|                     left: "0px", | 
|                     width: "100%", | 
|                     height: "100%" | 
|                 }); | 
|                 view.interceptTouchEvent(true); | 
|                 view.addEventListener("click", function(e) { | 
|                     var x = e.clientX; | 
|                      | 
|                     //返回按钮点击 | 
|                     if(backClick&& x > backClick.left && x < backClick.right){ | 
|                         if( _back.click && $.isFunction(_back.click)){ | 
|                             _back.click(); | 
|                         }else{ | 
|                             webview.evalJS("window.mui&&mui.back();"); | 
|                         } | 
|                     } | 
|                 }, false); | 
|                 webview.append(view); | 
|   | 
|             } | 
|   | 
|             //显示 | 
|             nShow = $.showOptions(options.show); | 
|             if(nShow.autoShow) { | 
|                 //titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview | 
|                 webview.addEventListener(nShow.event, function () { | 
|                     //关闭等待框 | 
|                     if(nWaiting) { | 
|                         nWaiting.close(); | 
|                     } | 
|                     //显示页面 | 
|                     webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras); | 
|                 }, false); | 
|             } | 
|         } | 
|         return webview; | 
|     }; | 
|   | 
|     /** | 
|      * 根据配置信息创建一个webview | 
|      * @param {type} options | 
|      * @param {type} isCreate | 
|      * @returns {webview} | 
|      */ | 
|     $.createWindow = function(options, isCreate) { | 
|         if(!window.plus) { | 
|             return; | 
|         } | 
|         var id = options.id || options.url; | 
|         var webview; | 
|         if(options.preload) { | 
|             if($.webviews[id] && $.webviews[id].webview.getURL()) { //已经cache | 
|                 webview = $.webviews[id].webview; | 
|             } else { //新增预加载窗口 | 
|                 //判断是否携带createNew参数,默认为false | 
|                 if(options.createNew !== true) { | 
|                     webview = plus.webview.getWebviewById(id); | 
|                 } | 
|   | 
|                 //之前没有,那就新创建     | 
|                 if(!webview) { | 
|                     webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), $.extend({ | 
|                         preload: true | 
|                     }, options.extras)); | 
|                     if(options.subpages) { | 
|                         $.each(options.subpages, function(index, subpage) { | 
|                             var subpageId = subpage.id || subpage.url; | 
|                             if(subpageId) { //过滤空对象 | 
|                                 var subWebview = plus.webview.getWebviewById(subpageId); | 
|                                 if(!subWebview) { //如果该webview不存在,则创建 | 
|                                     subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), $.extend({ | 
|                                         preload: true | 
|                                     }, subpage.extras)); | 
|                                 } | 
|                                 webview.append(subWebview); | 
|                             } | 
|                         }); | 
|                     } | 
|                 } | 
|             } | 
|   | 
|             //TODO 理论上,子webview也应该计算到预加载队列中,但这样就麻烦了,要退必须退整体,否则可能出现问题; | 
|             $.webviews[id] = { | 
|                 webview: webview, //目前仅preload的缓存webview | 
|                 preload: true, | 
|                 show: $.showOptions(options.show), | 
|                 afterShowMethodName: options.afterShowMethodName //就不应该用evalJS。应该是通过事件消息通讯 | 
|             }; | 
|             //索引该预加载窗口 | 
|             var preloads = $.data.preloads; | 
|             var index = preloads.indexOf(id); | 
|             if(~index) { //删除已存在的(变相调整插入位置) | 
|                 preloads.splice(index, 1); | 
|             } | 
|             preloads.push(id); | 
|             if(preloads.length > $.options.preloadLimit) { | 
|                 //先进先出 | 
|                 var first = $.data.preloads.shift(); | 
|                 var webviewCache = $.webviews[first]; | 
|                 if(webviewCache && webviewCache.webview) { | 
|                     //需要将自己打开的所有页面,全部close; | 
|                     //关闭该预加载webview     | 
|                     $.closeAll(webviewCache.webview); | 
|                 } | 
|                 //删除缓存 | 
|                 delete $.webviews[first]; | 
|             } | 
|         } else { | 
|             if(isCreate !== false) { //直接创建非预加载窗口 | 
|                 webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), options.extras); | 
|                 if(options.subpages) { | 
|                     $.each(options.subpages, function(index, subpage) { | 
|                         var subpageId = subpage.id || subpage.url; | 
|                         var subWebview = plus.webview.getWebviewById(subpageId); | 
|                         if(!subWebview) { | 
|                             subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), subpage.extras); | 
|                         } | 
|                         webview.append(subWebview); | 
|                     }); | 
|                 } | 
|             } | 
|         } | 
|         return webview; | 
|     }; | 
|   | 
|     /** | 
|      * 预加载 | 
|      */ | 
|     $.preload = function(options) { | 
|         //调用预加载函数,不管是否传递preload参数,强制变为true | 
|         if(!options.preload) { | 
|             options.preload = true; | 
|         } | 
|         return $.createWindow(options); | 
|     }; | 
|   | 
|     /** | 
|      *关闭当前webview打开的所有webview; | 
|      */ | 
|     $.closeOpened = function(webview) { | 
|         var opened = webview.opened(); | 
|         if(opened) { | 
|             for(var i = 0, len = opened.length; i < len; i++) { | 
|                 var openedWebview = opened[i]; | 
|                 var open_open = openedWebview.opened(); | 
|                 if(open_open && open_open.length > 0) { | 
|                     //关闭打开的webview | 
|                     $.closeOpened(openedWebview); | 
|                     //关闭自己 | 
|                     openedWebview.close("none"); | 
|                 } else { | 
|                     //如果直接孩子节点,就不用关闭了,因为父关闭的时候,会自动关闭子; | 
|                     if(openedWebview.parent() !== webview) { | 
|                         openedWebview.close('none'); | 
|                     } | 
|                 } | 
|             } | 
|         } | 
|     }; | 
|     $.closeAll = function(webview, aniShow) { | 
|         $.closeOpened(webview); | 
|         if(aniShow) { | 
|             webview.close(aniShow); | 
|         } else { | 
|             webview.close(); | 
|         } | 
|     }; | 
|   | 
|     /** | 
|      * 批量创建webview | 
|      * @param {type} options | 
|      * @returns {undefined} | 
|      */ | 
|     $.createWindows = function(options) { | 
|         $.each(options, function(index, option) { | 
|             //初始化预加载窗口(创建)和非预加载窗口(仅配置,不创建) | 
|             $.createWindow(option, false); | 
|         }); | 
|     }; | 
|     /** | 
|      * 创建当前页面的子webview | 
|      * @param {type} options | 
|      * @returns {webview} | 
|      */ | 
|     $.appendWebview = function(options) { | 
|         if(!window.plus) { | 
|             return; | 
|         } | 
|         var id = options.id || options.url; | 
|         var webview; | 
|         if(!$.webviews[id]) { //保证执行一遍 | 
|             //TODO 这里也有隐患,比如某个webview不是作为subpage创建的,而是作为target webview的话; | 
|             if(!plus.webview.getWebviewById(id)) { | 
|                 webview = plus.webview.create(options.url, id, options.styles, options.extras); | 
|             } | 
|             //之前的实现方案:子窗口loaded之后再append到父窗口中; | 
|             //问题:部分子窗口loaded事件发生较晚,此时执行父窗口的children方法会返回空,导致父子通讯失败; | 
|             //     比如父页面执行完preload事件后,需触发子页面的preload事件,此时未append的话,就无法触发; | 
|             //修改方式:不再监控loaded事件,直接append | 
|             //by chb@20150521 | 
|             // webview.addEventListener('loaded', function() { | 
|             plus.webview.currentWebview().append(webview); | 
|             // }); | 
|             $.webviews[id] = options; | 
|   | 
|         } | 
|         return webview; | 
|     }; | 
|   | 
|     //全局webviews | 
|     $.webviews = {}; | 
|     //预加载窗口索引 | 
|     $.data.preloads = []; | 
|     //$.currentWebview | 
|     $.plusReady(function() { | 
|         $.currentWebview = plus.webview.currentWebview(); | 
|     }); | 
|     $.addInit({ | 
|         name: '5+', | 
|         index: 100, | 
|         handle: function() { | 
|             var options = $.options; | 
|             var subpages = options.subpages || []; | 
|             if($.os.plus) { | 
|                 $.plusReady(function() { | 
|                     //TODO  这里需要判断一下,最好等子窗口加载完毕后,再调用主窗口的show方法; | 
|                     //或者:在openwindow方法中,监听实现; | 
|                     $.each(subpages, function(index, subpage) { | 
|                         $.appendWebview(subpage); | 
|                     }); | 
|                     //判断是否首页 | 
|                     if(plus.webview.currentWebview() === plus.webview.getWebviewById(plus.runtime.appid)) { | 
|                         //首页需要自己激活预加载; | 
|                         //timeout因为子页面loaded之后才append的,防止子页面尚未append、从而导致其preload未触发的问题; | 
|                         setTimeout(function() { | 
|                             triggerPreload(plus.webview.currentWebview()); | 
|                         }, 300); | 
|                     } | 
|                     //设置ios顶部状态栏颜色; | 
|                     if($.os.ios && $.options.statusBarBackground) { | 
|                         plus.navigator.setStatusBarBackground($.options.statusBarBackground); | 
|                     } | 
|                     if($.os.android && parseFloat($.os.version) < 4.4) { | 
|                         //解决Android平台4.4版本以下,resume后,父窗体标题延迟渲染的问题; | 
|                         if(plus.webview.currentWebview().parent() == null) { | 
|                             document.addEventListener("resume", function() { | 
|                                 var body = document.body; | 
|                                 body.style.display = 'none'; | 
|                                 setTimeout(function() { | 
|                                     body.style.display = ''; | 
|                                 }, 10); | 
|                             }); | 
|                         } | 
|                     } | 
|                 }); | 
|             } else { | 
|                 //已支持iframe嵌入 | 
|                 //                if (subpages.length > 0) { | 
|                 //                    var err = document.createElement('div'); | 
|                 //                    err.className = 'mui-error'; | 
|                 //                    //文字描述 | 
|                 //                    var span = document.createElement('span'); | 
|                 //                    span.innerHTML = '在该浏览器下,不支持创建子页面,具体参考'; | 
|                 //                    err.appendChild(span); | 
|                 //                    var a = document.createElement('a'); | 
|                 //                    a.innerHTML = '"mui框架适用场景"'; | 
|                 //                    a.href = 'http://ask.dcloud.net.cn/article/113'; | 
|                 //                    err.appendChild(a); | 
|                 //                    document.body.appendChild(err); | 
|                 //                    console.log('在该浏览器下,不支持创建子页面'); | 
|                 //                } | 
|   | 
|             } | 
|   | 
|         } | 
|     }); | 
|     window.addEventListener('preload', function() { | 
|         //处理预加载部分 | 
|         var webviews = $.options.preloadPages || []; | 
|         $.plusReady(function() { | 
|             $.each(webviews, function(index, webview) { | 
|                 $.createWindow($.extend(webview, { | 
|                     preload: true | 
|                 })); | 
|             }); | 
|   | 
|         }); | 
|     }); | 
|     $.supportStatusbarOffset = function() { | 
|         return $.os.plus && $.os.ios && parseFloat($.os.version) >= 7; | 
|     }; | 
|     $.ready(function() { | 
|         //标识当前环境支持statusbar | 
|         if($.supportStatusbarOffset()) { | 
|             document.body.classList.add('mui-statusbar'); | 
|         } | 
|     }); | 
| })(mui); | 
|   | 
| /** | 
|  * mui back | 
|  * @param {type} $ | 
|  * @param {type} window | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window) { | 
|     /** | 
|      * register back | 
|      * @param {type} back | 
|      * @returns {$.gestures} | 
|      */ | 
|     $.addBack = function(back) { | 
|         return $.addAction('backs', back); | 
|     }; | 
|     /** | 
|      * default | 
|      */ | 
|     $.addBack({ | 
|         name: 'browser', | 
|         index: 100, | 
|         handle: function() { | 
|             if (window.history.length > 1) { | 
|                 window.history.back(); | 
|                 return true; | 
|             } | 
|             return false; | 
|         } | 
|     }); | 
|     /** | 
|      * 后退 | 
|      */ | 
|     $.back = function() { | 
|         if (typeof $.options.beforeback === 'function') { | 
|             if ($.options.beforeback() === false) { | 
|                 return; | 
|             } | 
|         } | 
|         $.doAction('backs'); | 
|     }; | 
|     window.addEventListener('tap', function(e) { | 
|         var action = $.targets.action; | 
|         if (action && action.classList.contains('mui-action-back')) { | 
|             $.back(); | 
|             $.targets.action = false; | 
|         } | 
|     }); | 
|     window.addEventListener('swiperight', function(e) { | 
|         var detail = e.detail; | 
|         if ($.options.swipeBack === true && Math.abs(detail.angle) < 3) { | 
|             $.back(); | 
|         } | 
|     }); | 
|   | 
| })(mui, window); | 
| /** | 
|  * mui back 5+ | 
|  * @param {type} $ | 
|  * @param {type} window | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window) { | 
|     if ($.os.plus && $.os.android) { | 
|         $.addBack({ | 
|             name: 'mui', | 
|             index: 5, | 
|             handle: function() { | 
|                 //后续重新设计此处,将back放到各个空间内部实现 | 
|                 //popover | 
|                 if ($.targets._popover && $.targets._popover.classList.contains('mui-active')) { | 
|                     $($.targets._popover).popover('hide'); | 
|                     return true; | 
|                 } | 
|                 //offcanvas | 
|                 var offCanvas = document.querySelector('.mui-off-canvas-wrap.mui-active'); | 
|                 if (offCanvas) { | 
|                     $(offCanvas).offCanvas('close'); | 
|                     return true; | 
|                 } | 
|                 var previewImage = $.isFunction($.getPreviewImage) && $.getPreviewImage(); | 
|                 if (previewImage && previewImage.isShown()) { | 
|                     previewImage.close(); | 
|                     return true; | 
|                 } | 
|                 //popup | 
|                 return $.closePopup(); | 
|             } | 
|         }); | 
|     } | 
|     //首次按下back按键的时间 | 
|     $.__back__first = null; | 
|     /** | 
|      * 5+ back | 
|      */ | 
|     $.addBack({ | 
|         name: '5+', | 
|         index: 10, | 
|         handle: function() { | 
|             if (!window.plus) { | 
|                 return false; | 
|             } | 
|             var wobj = plus.webview.currentWebview(); | 
|             var parent = wobj.parent(); | 
|             if (parent) { | 
|                 parent.evalJS('mui&&mui.back();'); | 
|             } else { | 
|                 wobj.canBack(function(e) { | 
|                     //by chb 暂时注释,在碰到类似popover之类的锚点的时候,需多次点击才能返回; | 
|                     if (e.canBack) { //webview history back | 
|                         window.history.back(); | 
|                     } else { //webview close or hide | 
|                         //fixed by fxy 此处不应该用opener判断,因为用户有可能自己close掉当前窗口的opener。这样的话。opener就为空了,导致不能执行close | 
|                         if (wobj.id === plus.runtime.appid) { //首页 | 
|                             //首页不存在opener的情况下,后退实际上应该是退出应用; | 
|                             //首次按键,提示‘再按一次退出应用’ | 
|                             if (!$.__back__first) { | 
|                                 $.__back__first = new Date().getTime(); | 
|                                 mui.toast('再按一次退出应用'); | 
|                                 setTimeout(function() { | 
|                                     $.__back__first = null; | 
|                                 }, 2000); | 
|                             } else { | 
|                                 if (new Date().getTime() - $.__back__first < 2000) { | 
|                                     plus.runtime.quit(); | 
|                                 } | 
|                             } | 
|                         } else { //其他页面, | 
|                             if (wobj.preload) { | 
|                                 wobj.hide("auto"); | 
|                             } else { | 
|                                 //关闭页面时,需要将其打开的所有子页面全部关闭; | 
|                                 $.closeAll(wobj); | 
|                             } | 
|                         } | 
|                     } | 
|                 }); | 
|             } | 
|             return true; | 
|         } | 
|     }); | 
|   | 
|   | 
|     $.menu = function() { | 
|         var menu = document.querySelector('.mui-action-menu'); | 
|         if (menu) { | 
|             $.trigger(menu, $.EVENT_START); //临时处理menu无touchstart的话,找不到当前targets的问题 | 
|             $.trigger(menu, 'tap'); | 
|         } else { //执行父窗口的menu | 
|             if (window.plus) { | 
|                 var wobj = $.currentWebview; | 
|                 var parent = wobj.parent(); | 
|                 if (parent) { //又得evalJS | 
|                     parent.evalJS('mui&&mui.menu();'); | 
|                 } | 
|             } | 
|         } | 
|     }; | 
|     var __back = function() { | 
|         $.back(); | 
|     }; | 
|     var __menu = function() { | 
|         $.menu(); | 
|     }; | 
|     //默认监听 | 
|     $.plusReady(function() { | 
|         if ($.options.keyEventBind.backbutton) { | 
|             plus.key.addEventListener('backbutton', __back, false); | 
|         } | 
|         if ($.options.keyEventBind.menubutton) { | 
|             plus.key.addEventListener('menubutton', __menu, false); | 
|         } | 
|     }); | 
|     //处理按键监听事件 | 
|     $.addInit({ | 
|         name: 'keyEventBind', | 
|         index: 1000, | 
|         handle: function() { | 
|             $.plusReady(function() { | 
|                 //如果不为true,则移除默认监听 | 
|                 if (!$.options.keyEventBind.backbutton) { | 
|                     plus.key.removeEventListener('backbutton', __back); | 
|                 } | 
|                 if (!$.options.keyEventBind.menubutton) { | 
|                     plus.key.removeEventListener('menubutton', __menu); | 
|                 } | 
|             }); | 
|         } | 
|     }); | 
| })(mui, window); | 
| /** | 
|  * mui.init pulldownRefresh | 
|  * @param {type} $ | 
|  * @returns {undefined} | 
|  */ | 
| (function($) { | 
|     $.addInit({ | 
|         name: 'pullrefresh', | 
|         index: 1000, | 
|         handle: function() { | 
|             var options = $.options; | 
|             var pullRefreshOptions = options.pullRefresh || {}; | 
|             var hasPulldown = pullRefreshOptions.down && pullRefreshOptions.down.hasOwnProperty('callback'); | 
|             var hasPullup = pullRefreshOptions.up && pullRefreshOptions.up.hasOwnProperty('callback'); | 
|             if(hasPulldown || hasPullup) { | 
|                 var container = pullRefreshOptions.container; | 
|                 if(container) { | 
|                     var $container = $(container); | 
|                     if($container.length === 1) { | 
|                         if($.os.plus) { //5+环境 | 
|                             if(hasPulldown && pullRefreshOptions.down.style == "circle") { //原生转圈 | 
|                                 $.plusReady(function() { | 
|                                     //这里改写$.fn.pullRefresh | 
|                                     $.fn.pullRefresh = $.fn.pullRefresh_native; | 
|                                     $container.pullRefresh(pullRefreshOptions); | 
|                                 }); | 
|   | 
|                             } else if($.os.android) { //非原生转圈,但是Android环境 | 
|                                 $.plusReady(function() { | 
|                                     //这里改写$.fn.pullRefresh | 
|                                     $.fn.pullRefresh = $.fn.pullRefresh_native | 
|                                     var webview = plus.webview.currentWebview(); | 
|                                     if(window.__NWin_Enable__ === false) { //不支持多webview | 
|                                         $container.pullRefresh(pullRefreshOptions); | 
|                                     } else { | 
|                                         if(hasPullup) { | 
|                                             //当前页面初始化pullup | 
|                                             var upOptions = {}; | 
|                                             upOptions.up = pullRefreshOptions.up; | 
|                                             upOptions.webviewId = webview.id || webview.getURL(); | 
|                                             $container.pullRefresh(upOptions); | 
|                                         } | 
|                                         if(hasPulldown) { | 
|                                             var parent = webview.parent(); | 
|                                             var id = webview.id || webview.getURL(); | 
|                                             if(parent) { | 
|                                                 if(!hasPullup) { //如果没有上拉加载,需要手动初始化一个默认的pullRefresh,以便当前页面容器可以调用endPulldownToRefresh等方法 | 
|                                                     $container.pullRefresh({ | 
|                                                         webviewId: id | 
|                                                     }); | 
|                                                 } | 
|                                                 var downOptions = { | 
|                                                     webviewId: id//子页面id | 
|                                                 }; | 
|                                                 downOptions.down = $.extend({}, pullRefreshOptions.down); | 
|                                                 downOptions.down.callback = '_CALLBACK'; | 
|                                                 //改写父页面的$.fn.pullRefresh | 
|                                                 parent.evalJS("mui.fn.pullRefresh=mui.fn.pullRefresh_native"); | 
|                                                 //父页面初始化pulldown | 
|                                                 parent.evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify(downOptions) + "')"); | 
|                                             } | 
|                                         } | 
|                                     } | 
|                                 }); | 
|                             } else { //非原生转圈,iOS环境 | 
|                                 $container.pullRefresh(pullRefreshOptions); | 
|                             } | 
|                         } else { | 
|                             $container.pullRefresh(pullRefreshOptions); | 
|                         } | 
|                     } | 
|                 } | 
|             } | 
|         } | 
|     }); | 
| })(mui); | 
| /** | 
|  * mui ajax | 
|  * @param {type} $ | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window, undefined) { | 
|   | 
|     var jsonType = 'application/json'; | 
|     var htmlType = 'text/html'; | 
|     var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi; | 
|     var scriptTypeRE = /^(?:text|application)\/javascript/i; | 
|     var xmlTypeRE = /^(?:text|application)\/xml/i; | 
|     var blankRE = /^\s*$/; | 
|   | 
|     $.ajaxSettings = { | 
|         type: 'GET', | 
|         beforeSend: $.noop, | 
|         success: $.noop, | 
|         error: $.noop, | 
|         complete: $.noop, | 
|         context: null, | 
|         xhr: function(protocol) { | 
|             return new window.XMLHttpRequest(); | 
|         }, | 
|         accepts: { | 
|             script: 'text/javascript, application/javascript, application/x-javascript', | 
|             json: jsonType, | 
|             xml: 'application/xml, text/xml', | 
|             html: htmlType, | 
|             text: 'text/plain' | 
|         }, | 
|         timeout: 0, | 
|         processData: true, | 
|         cache: true | 
|     }; | 
|     var ajaxBeforeSend = function(xhr, settings) { | 
|         var context = settings.context | 
|         if(settings.beforeSend.call(context, xhr, settings) === false) { | 
|             return false; | 
|         } | 
|     }; | 
|     var ajaxSuccess = function(data, xhr, settings) { | 
|         settings.success.call(settings.context, data, 'success', xhr); | 
|         ajaxComplete('success', xhr, settings); | 
|     }; | 
|     // type: "timeout", "error", "abort", "parsererror" | 
|     var ajaxError = function(error, type, xhr, settings) { | 
|         settings.error.call(settings.context, xhr, type, error); | 
|         ajaxComplete(type, xhr, settings); | 
|     }; | 
|     // status: "success", "notmodified", "error", "timeout", "abort", "parsererror" | 
|     var ajaxComplete = function(status, xhr, settings) { | 
|         settings.complete.call(settings.context, xhr, status); | 
|     }; | 
|   | 
|     var serialize = function(params, obj, traditional, scope) { | 
|         var type, array = $.isArray(obj), | 
|             hash = $.isPlainObject(obj); | 
|         $.each(obj, function(key, value) { | 
|             type = $.type(value); | 
|             if(scope) { | 
|                 key = traditional ? scope : | 
|                     scope + '[' + (hash || type === 'object' || type === 'array' ? key : '') + ']'; | 
|             } | 
|             // handle data in serializeArray() format | 
|             if(!scope && array) { | 
|                 params.add(value.name, value.value); | 
|             } | 
|             // recurse into nested objects | 
|             else if(type === "array" || (!traditional && type === "object")) { | 
|                 serialize(params, value, traditional, key); | 
|             } else { | 
|                 params.add(key, value); | 
|             } | 
|         }); | 
|     }; | 
|     var serializeData = function(options) { | 
|         if(options.processData && options.data && typeof options.data !== "string") { | 
|             var contentType = options.contentType; | 
|             if(!contentType && options.headers) { | 
|                 contentType = options.headers['Content-Type']; | 
|             } | 
|             if(contentType && ~contentType.indexOf(jsonType)) { //application/json | 
|                 options.data = JSON.stringify(options.data); | 
|             } else { | 
|                 options.data = $.param(options.data, options.traditional); | 
|             } | 
|         } | 
|         if(options.data && (!options.type || options.type.toUpperCase() === 'GET')) { | 
|             options.url = appendQuery(options.url, options.data); | 
|             options.data = undefined; | 
|         } | 
|     }; | 
|     var appendQuery = function(url, query) { | 
|         if(query === '') { | 
|             return url; | 
|         } | 
|         return(url + '&' + query).replace(/[&?]{1,2}/, '?'); | 
|     }; | 
|     var mimeToDataType = function(mime) { | 
|         if(mime) { | 
|             mime = mime.split(';', 2)[0]; | 
|         } | 
|         return mime && (mime === htmlType ? 'html' : | 
|             mime === jsonType ? 'json' : | 
|             scriptTypeRE.test(mime) ? 'script' : | 
|             xmlTypeRE.test(mime) && 'xml') || 'text'; | 
|     }; | 
|     var parseArguments = function(url, data, success, dataType) { | 
|         if($.isFunction(data)) { | 
|             dataType = success, success = data, data = undefined; | 
|         } | 
|         if(!$.isFunction(success)) { | 
|             dataType = success, success = undefined; | 
|         } | 
|         return { | 
|             url: url, | 
|             data: data, | 
|             success: success, | 
|             dataType: dataType | 
|         }; | 
|     }; | 
|     $.ajax = function(url, options) { | 
|         if(typeof url === "object") { | 
|             options = url; | 
|             url = undefined; | 
|         } | 
|         var settings = options || {}; | 
|         settings.url = url || settings.url; | 
|         for(var key in $.ajaxSettings) { | 
|             if(settings[key] === undefined) { | 
|                 settings[key] = $.ajaxSettings[key]; | 
|             } | 
|         } | 
|         serializeData(settings); | 
|         var dataType = settings.dataType; | 
|   | 
|         if(settings.cache === false || ((!options || options.cache !== true) && ('script' === dataType))) { | 
|             settings.url = appendQuery(settings.url, '_=' + $.now()); | 
|         } | 
|         var mime = settings.accepts[dataType && dataType.toLowerCase()]; | 
|         var headers = {}; | 
|         var setHeader = function(name, value) { | 
|             headers[name.toLowerCase()] = [name, value]; | 
|         }; | 
|         var protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol;         | 
|         var xhr = settings.xhr(settings); | 
|          | 
|         if(location.protocol === 'file:' && $.os.ios && window.webkit && window.webkit.messageHandlers && !(xhr instanceof plus.net.XMLHttpRequest)){ | 
|             console.error("当前运行环境为WKWebview,需在plusReady事件触发后再调用mui.ajax,否则可能会执行失败或报Script error的错误") | 
|         } | 
|         var nativeSetHeader = xhr.setRequestHeader; | 
|         var abortTimeout; | 
|   | 
|         setHeader('X-Requested-With', 'XMLHttpRequest'); | 
|         setHeader('Accept', mime || '*/*'); | 
|         if(!!(mime = settings.mimeType || mime)) { | 
|             if(mime.indexOf(',') > -1) { | 
|                 mime = mime.split(',', 2)[0]; | 
|             } | 
|             xhr.overrideMimeType && xhr.overrideMimeType(mime); | 
|         } | 
|         if(settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() !== 'GET')) { | 
|             setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded'); | 
|         } | 
|         if(settings.headers) { | 
|             for(var name in settings.headers) | 
|                 setHeader(name, settings.headers[name]); | 
|         } | 
|         xhr.setRequestHeader = setHeader; | 
|   | 
|         xhr.onreadystatechange = function() { | 
|             if(xhr.readyState === 4) { | 
|                 xhr.onreadystatechange = $.noop; | 
|                 clearTimeout(abortTimeout); | 
|                 var result, error = false; | 
|                 var isLocal = protocol === 'file:'; | 
|                 if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || (xhr.status === 0 && isLocal && xhr.responseText)) { | 
|                     dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type')); | 
|                     result = xhr.responseText; | 
|                     try { | 
|                         // http://perfectionkills.com/global-eval-what-are-the-options/ | 
|                         if(dataType === 'script') { | 
|                             (1, eval)(result); | 
|                         } else if(dataType === 'xml') { | 
|                             result = xhr.responseXML; | 
|                         } else if(dataType === 'json') { | 
|                             result = blankRE.test(result) ? null : $.parseJSON(result); | 
|                         } | 
|                     } catch(e) { | 
|                         error = e; | 
|                     } | 
|   | 
|                     if(error) { | 
|                         ajaxError(error, 'parsererror', xhr, settings); | 
|                     } else { | 
|                         ajaxSuccess(result, xhr, settings); | 
|                     } | 
|                 } else { | 
|                     var status = xhr.status ? 'error' : 'abort'; | 
|                     var statusText = xhr.statusText || null; | 
|                     if(isLocal) { | 
|                         status = 'error'; | 
|                         statusText = '404'; | 
|                     } | 
|                     ajaxError(statusText, status, xhr, settings); | 
|                 } | 
|             } | 
|         }; | 
|         if(ajaxBeforeSend(xhr, settings) === false) { | 
|             xhr.abort(); | 
|             ajaxError(null, 'abort', xhr, settings); | 
|             return xhr; | 
|         } | 
|   | 
|         if(settings.xhrFields) { | 
|             for(var name in settings.xhrFields) { | 
|                 xhr[name] = settings.xhrFields[name]; | 
|             } | 
|         } | 
|   | 
|         var async = 'async' in settings ? settings.async : true; | 
|   | 
|         xhr.open(settings.type.toUpperCase(), settings.url, async, settings.username, settings.password); | 
|   | 
|         for(var name in headers) { | 
|             if(headers.hasOwnProperty(name)) { | 
|                 nativeSetHeader.apply(xhr, headers[name]); | 
|             } | 
|         } | 
|         if(settings.timeout > 0) { | 
|             abortTimeout = setTimeout(function() { | 
|                 xhr.onreadystatechange = $.noop; | 
|                 xhr.abort(); | 
|                 ajaxError(null, 'timeout', xhr, settings); | 
|             }, settings.timeout); | 
|         } | 
|         xhr.send(settings.data ? settings.data : null); | 
|         return xhr; | 
|     }; | 
|   | 
|     $.param = function(obj, traditional) { | 
|         var params = []; | 
|         params.add = function(k, v) { | 
|             this.push(encodeURIComponent(k) + '=' + encodeURIComponent(v)); | 
|         }; | 
|         serialize(params, obj, traditional); | 
|         return params.join('&').replace(/%20/g, '+'); | 
|     }; | 
|     $.get = function( /* url, data, success, dataType */ ) { | 
|         return $.ajax(parseArguments.apply(null, arguments)); | 
|     }; | 
|   | 
|     $.post = function( /* url, data, success, dataType */ ) { | 
|         var options = parseArguments.apply(null, arguments); | 
|         options.type = 'POST'; | 
|         return $.ajax(options); | 
|     }; | 
|   | 
|     $.getJSON = function( /* url, data, success */ ) { | 
|         var options = parseArguments.apply(null, arguments); | 
|         options.dataType = 'json'; | 
|         return $.ajax(options); | 
|     }; | 
|   | 
|     $.fn.load = function(url, data, success) { | 
|         if(!this.length) | 
|             return this; | 
|         var self = this, | 
|             parts = url.split(/\s/), | 
|             selector, | 
|             options = parseArguments(url, data, success), | 
|             callback = options.success; | 
|         if(parts.length > 1) | 
|             options.url = parts[0], selector = parts[1]; | 
|         options.success = function(response) { | 
|             if(selector) { | 
|                 var div = document.createElement('div'); | 
|                 div.innerHTML = response.replace(rscript, ""); | 
|                 var selectorDiv = document.createElement('div'); | 
|                 var childs = div.querySelectorAll(selector); | 
|                 if(childs && childs.length > 0) { | 
|                     for(var i = 0, len = childs.length; i < len; i++) { | 
|                         selectorDiv.appendChild(childs[i]); | 
|                     } | 
|                 } | 
|                 self[0].innerHTML = selectorDiv.innerHTML; | 
|             } else { | 
|                 self[0].innerHTML = response; | 
|             } | 
|             callback && callback.apply(self, arguments); | 
|         }; | 
|         $.ajax(options); | 
|         return this; | 
|     }; | 
|   | 
| })(mui, window); | 
| /** | 
|  * 5+ ajax | 
|  */ | 
| (function($) { | 
|     var originAnchor = document.createElement('a'); | 
|     originAnchor.href = window.location.href; | 
|     $.plusReady(function() { | 
|         $.ajaxSettings = $.extend($.ajaxSettings, { | 
|             xhr: function(settings) { | 
|                 if (settings.crossDomain) { //强制使用plus跨域 | 
|                     return new plus.net.XMLHttpRequest(); | 
|                 } | 
|                 //仅在webview的url为远程文件,且ajax请求的资源不同源下使用plus.net.XMLHttpRequest | 
|                 if (originAnchor.protocol !== 'file:') { | 
|                     var urlAnchor = document.createElement('a'); | 
|                     urlAnchor.href = settings.url; | 
|                     urlAnchor.href = urlAnchor.href; | 
|                     settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host); | 
|                     if (settings.crossDomain) { | 
|                         return new plus.net.XMLHttpRequest(); | 
|                     } | 
|                 } | 
|                 if ($.os.ios && window.webkit && window.webkit.messageHandlers) { //wkwebview下同样使用5+ xhr | 
|                     return new plus.net.XMLHttpRequest(); | 
|                 } | 
|                 return new window.XMLHttpRequest(); | 
|             } | 
|         }); | 
|     }); | 
| })(mui); | 
| /** | 
|  * mui layout(offset[,position,width,height...]) | 
|  * @param {type} $ | 
|  * @param {type} window | 
|  * @param {type} undefined | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window, undefined) { | 
|     $.offset = function(element) { | 
|         var box = { | 
|             top : 0, | 
|             left : 0 | 
|         }; | 
|         if ( typeof element.getBoundingClientRect !== undefined) { | 
|             box = element.getBoundingClientRect(); | 
|         } | 
|         return { | 
|             top : box.top + window.pageYOffset - element.clientTop, | 
|             left : box.left + window.pageXOffset - element.clientLeft | 
|         }; | 
|     }; | 
| })(mui, window);  | 
| /** | 
|  * mui animation | 
|  */ | 
| (function($, window) { | 
|     /** | 
|      * scrollTo | 
|      */ | 
|     $.scrollTo = function(scrollTop, duration, callback) { | 
|         duration = duration || 1000; | 
|         var scroll = function(duration) { | 
|             if (duration <= 0) { | 
|                 window.scrollTo(0, scrollTop); | 
|                 callback && callback(); | 
|                 return; | 
|             } | 
|             var distaince = scrollTop - window.scrollY; | 
|             setTimeout(function() { | 
|                 window.scrollTo(0, window.scrollY + distaince / duration * 10); | 
|                 scroll(duration - 10); | 
|             }, 16.7); | 
|         }; | 
|         scroll(duration); | 
|     }; | 
|     $.animationFrame = function(cb) { | 
|         var args, isQueued, context; | 
|         return function() { | 
|             args = arguments; | 
|             context = this; | 
|             if (!isQueued) { | 
|                 isQueued = true; | 
|                 requestAnimationFrame(function() { | 
|                     cb.apply(context, args); | 
|                     isQueued = false; | 
|                 }); | 
|             } | 
|         }; | 
|     }; | 
|   | 
| })(mui, window); | 
| (function($) { | 
|     var initializing = false, | 
|         fnTest = /xyz/.test(function() { | 
|             xyz; | 
|         }) ? /\b_super\b/ : /.*/; | 
|   | 
|     var Class = function() {}; | 
|     Class.extend = function(prop) { | 
|         var _super = this.prototype; | 
|         initializing = true; | 
|         var prototype = new this(); | 
|         initializing = false; | 
|         for (var name in prop) { | 
|             prototype[name] = typeof prop[name] == "function" && | 
|                 typeof _super[name] == "function" && fnTest.test(prop[name]) ? | 
|                 (function(name, fn) { | 
|                     return function() { | 
|                         var tmp = this._super; | 
|   | 
|                         this._super = _super[name]; | 
|   | 
|                         var ret = fn.apply(this, arguments); | 
|                         this._super = tmp; | 
|   | 
|                         return ret; | 
|                     }; | 
|                 })(name, prop[name]) : | 
|                 prop[name]; | 
|         } | 
|         function Class() { | 
|             if (!initializing && this.init) | 
|                 this.init.apply(this, arguments); | 
|         } | 
|         Class.prototype = prototype; | 
|         Class.prototype.constructor = Class; | 
|         Class.extend = arguments.callee; | 
|         return Class; | 
|     }; | 
|     $.Class = Class; | 
| })(mui); | 
| (function($, document, undefined) { | 
|     var CLASS_PULL_TOP_POCKET = 'mui-pull-top-pocket'; | 
|     var CLASS_PULL_BOTTOM_POCKET = 'mui-pull-bottom-pocket'; | 
|     var CLASS_PULL = 'mui-pull'; | 
|     var CLASS_PULL_LOADING = 'mui-pull-loading'; | 
|     var CLASS_PULL_CAPTION = 'mui-pull-caption'; | 
|     var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down'; | 
|     var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh'; | 
|     var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore'; | 
|   | 
|     var CLASS_ICON = 'mui-icon'; | 
|     var CLASS_SPINNER = 'mui-spinner'; | 
|     var CLASS_ICON_PULLDOWN = 'mui-icon-pulldown'; | 
|   | 
|     var CLASS_BLOCK = 'mui-block'; | 
|     var CLASS_HIDDEN = 'mui-hidden'; | 
|     var CLASS_VISIBILITY = 'mui-visibility'; | 
|   | 
|     var CLASS_LOADING_UP = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN; | 
|     var CLASS_LOADING_DOWN = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN; | 
|     var CLASS_LOADING = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_SPINNER; | 
|   | 
|     var pocketHtml = ['<div class="' + CLASS_PULL + '">', '<div class="{icon}"></div>', '<div class="' + CLASS_PULL_CAPTION + '">{contentrefresh}</div>', '</div>'].join(''); | 
|   | 
|     var PullRefresh = { | 
|         init: function(element, options) { | 
|             this._super(element, $.extend(true, { | 
|                 scrollY: true, | 
|                 scrollX: false, | 
|                 indicators: true, | 
|                 deceleration: 0.003, | 
|                 down: { | 
|                     height: 50, | 
|                     contentinit: '下拉可以刷新', | 
|                     contentdown: '下拉可以刷新', | 
|                     contentover: '释放立即刷新', | 
|                     contentrefresh: '正在刷新...' | 
|                 }, | 
|                 up: { | 
|                     height: 50, | 
|                     auto: false, | 
|                     contentinit: '上拉显示更多', | 
|                     contentdown: '上拉显示更多', | 
|                     contentrefresh: '正在加载...', | 
|                     contentnomore: '没有更多数据了', | 
|                     duration: 300 | 
|                 } | 
|             }, options)); | 
|         }, | 
|         _init: function() { | 
|             this._super(); | 
|             this._initPocket(); | 
|         }, | 
|         _initPulldownRefresh: function() { | 
|             this.pulldown = true; | 
|             if (this.topPocket) { | 
|                 this.pullPocket = this.topPocket; | 
|                 this.pullPocket.classList.add(CLASS_BLOCK); | 
|                 this.pullPocket.classList.add(CLASS_VISIBILITY); | 
|                 this.pullCaption = this.topCaption; | 
|                 this.pullLoading = this.topLoading; | 
|             } | 
|         }, | 
|         _initPullupRefresh: function() { | 
|             this.pulldown = false; | 
|             if (this.bottomPocket) { | 
|                 this.pullPocket = this.bottomPocket; | 
|                 this.pullPocket.classList.add(CLASS_BLOCK); | 
|                 this.pullPocket.classList.add(CLASS_VISIBILITY); | 
|                 this.pullCaption = this.bottomCaption; | 
|                 this.pullLoading = this.bottomLoading; | 
|             } | 
|         }, | 
|         _initPocket: function() { | 
|             var options = this.options; | 
|             if (options.down && options.down.hasOwnProperty('callback')) { | 
|                 this.topPocket = this.scroller.querySelector('.' + CLASS_PULL_TOP_POCKET); | 
|                 if (!this.topPocket) { | 
|                     this.topPocket = this._createPocket(CLASS_PULL_TOP_POCKET, options.down, CLASS_LOADING_DOWN); | 
|                     this.wrapper.insertBefore(this.topPocket, this.wrapper.firstChild); | 
|                 } | 
|                 this.topLoading = this.topPocket.querySelector('.' + CLASS_PULL_LOADING); | 
|                 this.topCaption = this.topPocket.querySelector('.' + CLASS_PULL_CAPTION); | 
|             } | 
|             if (options.up && options.up.hasOwnProperty('callback')) { | 
|                 this.bottomPocket = this.scroller.querySelector('.' + CLASS_PULL_BOTTOM_POCKET); | 
|                 if (!this.bottomPocket) { | 
|                     this.bottomPocket = this._createPocket(CLASS_PULL_BOTTOM_POCKET, options.up, CLASS_LOADING); | 
|                     this.scroller.appendChild(this.bottomPocket); | 
|                 } | 
|                 this.bottomLoading = this.bottomPocket.querySelector('.' + CLASS_PULL_LOADING); | 
|                 this.bottomCaption = this.bottomPocket.querySelector('.' + CLASS_PULL_CAPTION); | 
|                 //TODO only for h5 | 
|                 this.wrapper.addEventListener('scrollbottom', this); | 
|             } | 
|         }, | 
|         _createPocket: function(clazz, options, iconClass) { | 
|             var pocket = document.createElement('div'); | 
|             pocket.className = clazz; | 
|             pocket.innerHTML = pocketHtml.replace('{contentrefresh}', options.contentinit).replace('{icon}', iconClass); | 
|             return pocket; | 
|         }, | 
|         _resetPullDownLoading: function() { | 
|             var loading = this.pullLoading; | 
|             if (loading) { | 
|                 this.pullCaption.innerHTML = this.options.down.contentdown; | 
|                 loading.style.webkitTransition = ""; | 
|                 loading.style.webkitTransform = ""; | 
|                 loading.style.webkitAnimation = ""; | 
|                 loading.className = CLASS_LOADING_DOWN; | 
|             } | 
|         }, | 
|         _setCaptionClass: function(isPulldown, caption, title) { | 
|             if (!isPulldown) { | 
|                 switch (title) { | 
|                     case this.options.up.contentdown: | 
|                         caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN; | 
|                         break; | 
|                     case this.options.up.contentrefresh: | 
|                         caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH | 
|                         break; | 
|                     case this.options.up.contentnomore: | 
|                         caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE; | 
|                         break; | 
|                 } | 
|             } | 
|         }, | 
|         _setCaption: function(title, reset) { | 
|             if (this.loading) { | 
|                 return; | 
|             } | 
|             var options = this.options; | 
|             var pocket = this.pullPocket; | 
|             var caption = this.pullCaption; | 
|             var loading = this.pullLoading; | 
|             var isPulldown = this.pulldown; | 
|             var self = this; | 
|             if (pocket) { | 
|                 if (reset) { | 
|                     setTimeout(function() { | 
|                         caption.innerHTML = self.lastTitle = title; | 
|                         if (isPulldown) { | 
|                             loading.className = CLASS_LOADING_DOWN; | 
|                         } else { | 
|                             self._setCaptionClass(false, caption, title); | 
|                             loading.className = CLASS_LOADING; | 
|                         } | 
|                         loading.style.webkitAnimation = ""; | 
|                         loading.style.webkitTransition = ""; | 
|                         loading.style.webkitTransform = ""; | 
|                     }, 100); | 
|                 } else { | 
|                     if (title !== this.lastTitle) { | 
|                         caption.innerHTML = title; | 
|                         if (isPulldown) { | 
|                             if (title === options.down.contentrefresh) { | 
|                                 loading.className = CLASS_LOADING; | 
|                                 loading.style.webkitAnimation = "spinner-spin 1s step-end infinite"; | 
|                             } else if (title === options.down.contentover) { | 
|                                 loading.className = CLASS_LOADING_UP; | 
|                                 loading.style.webkitTransition = "-webkit-transform 0.3s ease-in"; | 
|                                 loading.style.webkitTransform = "rotate(180deg)"; | 
|                             } else if (title === options.down.contentdown) { | 
|                                 loading.className = CLASS_LOADING_DOWN; | 
|                                 loading.style.webkitTransition = "-webkit-transform 0.3s ease-in"; | 
|                                 loading.style.webkitTransform = "rotate(0deg)"; | 
|                             } | 
|                         } else { | 
|                             if (title === options.up.contentrefresh) { | 
|                                 loading.className = CLASS_LOADING + ' ' + CLASS_VISIBILITY; | 
|                             } else { | 
|                                 loading.className = CLASS_LOADING + ' ' + CLASS_HIDDEN; | 
|                             } | 
|                             self._setCaptionClass(false, caption, title); | 
|                         } | 
|                         this.lastTitle = title; | 
|                     } | 
|                 } | 
|   | 
|             } | 
|         } | 
|     }; | 
|     $.PullRefresh = PullRefresh; | 
| })(mui, document); | 
| (function($, window, document, undefined) { | 
|     var CLASS_SCROLL = 'mui-scroll'; | 
|     var CLASS_SCROLLBAR = 'mui-scrollbar'; | 
|     var CLASS_INDICATOR = 'mui-scrollbar-indicator'; | 
|     var CLASS_SCROLLBAR_VERTICAL = CLASS_SCROLLBAR + '-vertical'; | 
|     var CLASS_SCROLLBAR_HORIZONTAL = CLASS_SCROLLBAR + '-horizontal'; | 
|   | 
|     var CLASS_ACTIVE = 'mui-active'; | 
|   | 
|     var ease = { | 
|         quadratic: { | 
|             style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', | 
|             fn: function(k) { | 
|                 return k * (2 - k); | 
|             } | 
|         }, | 
|         circular: { | 
|             style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', | 
|             fn: function(k) { | 
|                 return Math.sqrt(1 - (--k * k)); | 
|             } | 
|         }, | 
|         outCirc: { | 
|             style: 'cubic-bezier(0.075, 0.82, 0.165, 1)' | 
|         }, | 
|         outCubic: { | 
|             style: 'cubic-bezier(0.165, 0.84, 0.44, 1)' | 
|         } | 
|     } | 
|     var Scroll = $.Class.extend({ | 
|         init: function(element, options) { | 
|             this.wrapper = this.element = element; | 
|             this.scroller = this.wrapper.children[0]; | 
|             this.scrollerStyle = this.scroller && this.scroller.style; | 
|             this.stopped = false; | 
|   | 
|             this.options = $.extend(true, { | 
|                 scrollY: true, //是否竖向滚动 | 
|                 scrollX: false, //是否横向滚动 | 
|                 startX: 0, //初始化时滚动至x | 
|                 startY: 0, //初始化时滚动至y | 
|   | 
|                 indicators: true, //是否显示滚动条 | 
|                 stopPropagation: false, | 
|                 hardwareAccelerated: true, | 
|                 fixedBadAndorid: false, | 
|                 preventDefaultException: { | 
|                     tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/ | 
|                 }, | 
|                 momentum: true, | 
|   | 
|                 snapX: 0.5, //横向切换距离(以当前容器宽度为基准) | 
|                 snap: false, //图片轮播,拖拽式选项卡 | 
|   | 
|                 bounce: true, //是否启用回弹 | 
|                 bounceTime: 500, //回弹动画时间 | 
|                 bounceEasing: ease.outCirc, //回弹动画曲线 | 
|   | 
|                 scrollTime: 500, | 
|                 scrollEasing: ease.outCubic, //轮播动画曲线 | 
|   | 
|                 directionLockThreshold: 5, | 
|   | 
|                 parallaxElement: false, //视差元素 | 
|                 parallaxRatio: 0.5 | 
|             }, options); | 
|   | 
|             this.x = 0; | 
|             this.y = 0; | 
|             this.translateZ = this.options.hardwareAccelerated ? ' translateZ(0)' : ''; | 
|   | 
|             this._init(); | 
|             if (this.scroller) { | 
|                 this.refresh(); | 
|                 //                if (this.options.startX !== 0 || this.options.startY !== 0) { //需要判断吗?后续根据实际情况再看看 | 
|                 this.scrollTo(this.options.startX, this.options.startY); | 
|                 //                } | 
|             } | 
|         }, | 
|         _init: function() { | 
|             this._initParallax(); | 
|             this._initIndicators(); | 
|             this._initEvent(); | 
|         }, | 
|         _initParallax: function() { | 
|             if (this.options.parallaxElement) { | 
|                 this.parallaxElement = document.querySelector(this.options.parallaxElement); | 
|                 this.parallaxStyle = this.parallaxElement.style; | 
|                 this.parallaxHeight = this.parallaxElement.offsetHeight; | 
|                 this.parallaxImgStyle = this.parallaxElement.querySelector('img').style; | 
|             } | 
|         }, | 
|         _initIndicators: function() { | 
|             var self = this; | 
|             self.indicators = []; | 
|             if (!this.options.indicators) { | 
|                 return; | 
|             } | 
|             var indicators = [], | 
|                 indicator; | 
|   | 
|             // Vertical scrollbar | 
|             if (self.options.scrollY) { | 
|                 indicator = { | 
|                     el: this._createScrollBar(CLASS_SCROLLBAR_VERTICAL), | 
|                     listenX: false | 
|                 }; | 
|   | 
|                 this.wrapper.appendChild(indicator.el); | 
|                 indicators.push(indicator); | 
|             } | 
|   | 
|             // Horizontal scrollbar | 
|             if (this.options.scrollX) { | 
|                 indicator = { | 
|                     el: this._createScrollBar(CLASS_SCROLLBAR_HORIZONTAL), | 
|                     listenY: false | 
|                 }; | 
|   | 
|                 this.wrapper.appendChild(indicator.el); | 
|                 indicators.push(indicator); | 
|             } | 
|   | 
|             for (var i = indicators.length; i--;) { | 
|                 this.indicators.push(new Indicator(this, indicators[i])); | 
|             } | 
|   | 
|         }, | 
|         _initSnap: function() { | 
|             this.currentPage = {}; | 
|             this.pages = []; | 
|             var snaps = this.snaps; | 
|             var length = snaps.length; | 
|             var m = 0; | 
|             var n = -1; | 
|             var x = 0; | 
|             var leftX = 0; | 
|             var rightX = 0; | 
|             var snapX = 0; | 
|             for (var i = 0; i < length; i++) { | 
|                 var snap = snaps[i]; | 
|                 var offsetLeft = snap.offsetLeft; | 
|                 var offsetWidth = snap.offsetWidth; | 
|                 if (i === 0 || offsetLeft <= snaps[i - 1].offsetLeft) { | 
|                     m = 0; | 
|                     n++; | 
|                 } | 
|                 if (!this.pages[m]) { | 
|                     this.pages[m] = []; | 
|                 } | 
|                 x = this._getSnapX(offsetLeft); | 
|                 snapX = Math.round((offsetWidth) * this.options.snapX); | 
|                 leftX = x - snapX; | 
|                 rightX = x - offsetWidth + snapX; | 
|                 this.pages[m][n] = { | 
|                     x: x, | 
|                     leftX: leftX, | 
|                     rightX: rightX, | 
|                     pageX: m, | 
|                     element: snap | 
|                 } | 
|                 if (snap.classList.contains(CLASS_ACTIVE)) { | 
|                     this.currentPage = this.pages[m][0]; | 
|                 } | 
|                 if (x >= this.maxScrollX) { | 
|                     m++; | 
|                 } | 
|             } | 
|             this.options.startX = this.currentPage.x || 0; | 
|         }, | 
|         _getSnapX: function(offsetLeft) { | 
|             return Math.max(Math.min(0, -offsetLeft + (this.wrapperWidth / 2)), this.maxScrollX); | 
|         }, | 
|         _gotoPage: function(index) { | 
|             this.currentPage = this.pages[Math.min(index, this.pages.length - 1)][0]; | 
|             for (var i = 0, len = this.snaps.length; i < len; i++) { | 
|                 if (i === index) { | 
|                     this.snaps[i].classList.add(CLASS_ACTIVE); | 
|                 } else { | 
|                     this.snaps[i].classList.remove(CLASS_ACTIVE); | 
|                 } | 
|             } | 
|             this.scrollTo(this.currentPage.x, 0, this.options.scrollTime); | 
|         }, | 
|         _nearestSnap: function(x) { | 
|             if (!this.pages.length) { | 
|                 return { | 
|                     x: 0, | 
|                     pageX: 0 | 
|                 }; | 
|             } | 
|             var i = 0; | 
|             var length = this.pages.length; | 
|             if (x > 0) { | 
|                 x = 0; | 
|             } else if (x < this.maxScrollX) { | 
|                 x = this.maxScrollX; | 
|             } | 
|             for (; i < length; i++) { | 
|                 var nearestX = this.direction === 'left' ? this.pages[i][0].leftX : this.pages[i][0].rightX; | 
|                 if (x >= nearestX) { | 
|                     return this.pages[i][0]; | 
|                 } | 
|             } | 
|             return { | 
|                 x: 0, | 
|                 pageX: 0 | 
|             }; | 
|         }, | 
|         _initEvent: function(detach) { | 
|             var action = detach ? 'removeEventListener' : 'addEventListener'; | 
|             window[action]('orientationchange', this); | 
|             window[action]('resize', this); | 
|   | 
|             this.scroller[action]('webkitTransitionEnd', this); | 
|   | 
|             this.wrapper[action]($.EVENT_START, this); | 
|             this.wrapper[action]($.EVENT_CANCEL, this); | 
|             this.wrapper[action]($.EVENT_END, this); | 
|             this.wrapper[action]('drag', this); | 
|             this.wrapper[action]('dragend', this); | 
|             this.wrapper[action]('flick', this); | 
|             this.wrapper[action]('scrollend', this); | 
|             if (this.options.scrollX) { | 
|                 this.wrapper[action]('swiperight', this); | 
|             } | 
|             var segmentedControl = this.wrapper.querySelector('.mui-segmented-control'); | 
|             if (segmentedControl) { //靠,这个bug排查了一下午,阻止hash跳转,一旦hash跳转会导致可拖拽选项卡的tab不见 | 
|                 mui(segmentedControl)[detach ? 'off' : 'on']('click', 'a', $.preventDefault); | 
|             } | 
|   | 
|             this.wrapper[action]('scrollstart', this); | 
|             this.wrapper[action]('refresh', this); | 
|         }, | 
|         _handleIndicatorScrollend: function() { | 
|             this.indicators.map(function(indicator) { | 
|                 indicator.fade(); | 
|             }); | 
|         }, | 
|         _handleIndicatorScrollstart: function() { | 
|             this.indicators.map(function(indicator) { | 
|                 indicator.fade(1); | 
|             }); | 
|         }, | 
|         _handleIndicatorRefresh: function() { | 
|             this.indicators.map(function(indicator) { | 
|                 indicator.refresh(); | 
|             }); | 
|         }, | 
|         handleEvent: function(e) { | 
|             if (this.stopped) { | 
|                 this.resetPosition(); | 
|                 return; | 
|             } | 
|   | 
|             switch (e.type) { | 
|                 case $.EVENT_START: | 
|                     this._start(e); | 
|                     break; | 
|                 case 'drag': | 
|                     this.options.stopPropagation && e.stopPropagation(); | 
|                     this._drag(e); | 
|                     break; | 
|                 case 'dragend': | 
|                 case 'flick': | 
|                     this.options.stopPropagation && e.stopPropagation(); | 
|                     this._flick(e); | 
|                     break; | 
|                 case $.EVENT_CANCEL: | 
|                 case $.EVENT_END: | 
|                     this._end(e); | 
|                     break; | 
|                 case 'webkitTransitionEnd': | 
|                     this.transitionTimer && this.transitionTimer.cancel(); | 
|                     this._transitionEnd(e); | 
|                     break; | 
|                 case 'scrollstart': | 
|                     this._handleIndicatorScrollstart(e); | 
|                     break; | 
|                 case 'scrollend': | 
|                     this._handleIndicatorScrollend(e); | 
|                     this._scrollend(e); | 
|                     e.stopPropagation(); | 
|                     break; | 
|                 case 'orientationchange': | 
|                 case 'resize': | 
|                     this._resize(); | 
|                     break; | 
|                 case 'swiperight': | 
|                     e.stopPropagation(); | 
|                     break; | 
|                 case 'refresh': | 
|                     this._handleIndicatorRefresh(e); | 
|                     break; | 
|   | 
|             } | 
|         }, | 
|         _start: function(e) { | 
|             this.moved = this.needReset = false; | 
|             this._transitionTime(); | 
|             if (this.isInTransition) { | 
|                 this.needReset = true; | 
|                 this.isInTransition = false; | 
|                 var pos = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform')); | 
|                 this.setTranslate(Math.round(pos.x), Math.round(pos.y)); | 
|                 //                this.resetPosition(); //reset | 
|                 $.trigger(this.scroller, 'scrollend', this); | 
|                 //                e.stopPropagation(); | 
|                 e.preventDefault(); | 
|             } | 
|             this.reLayout(); | 
|             $.trigger(this.scroller, 'beforescrollstart', this); | 
|         }, | 
|         _getDirectionByAngle: function(angle) { | 
|             if (angle < -80 && angle > -100) { | 
|                 return 'up'; | 
|             } else if (angle >= 80 && angle < 100) { | 
|                 return 'down'; | 
|             } else if (angle >= 170 || angle <= -170) { | 
|                 return 'left'; | 
|             } else if (angle >= -35 && angle <= 10) { | 
|                 return 'right'; | 
|             } | 
|             return null; | 
|         }, | 
|         _drag: function(e) { | 
|             //            if (this.needReset) { | 
|             //                e.stopPropagation(); //disable parent drag(nested scroller) | 
|             //                return; | 
|             //            } | 
|             var detail = e.detail; | 
|             if (this.options.scrollY || detail.direction === 'up' || detail.direction === 'down') { //如果是竖向滚动或手势方向是上或下 | 
|                 //ios8 hack | 
|                 if ($.os.ios && parseFloat($.os.version) >= 8) { //多webview时,离开当前webview会导致后续touch事件不触发 | 
|                     var clientY = detail.gesture.touches[0].clientY; | 
|                     //下拉刷新 or 上拉加载 | 
|                     if ((clientY + 10) > window.innerHeight || clientY < 10) { | 
|                         this.resetPosition(this.options.bounceTime); | 
|                         return; | 
|                     } | 
|                 } | 
|             } | 
|             var isPreventDefault = isReturn = false; | 
|             var direction = this._getDirectionByAngle(detail.angle); | 
|             if (detail.direction === 'left' || detail.direction === 'right') { | 
|                 if (this.options.scrollX) { | 
|                     isPreventDefault = true; | 
|                     if (!this.moved) { //识别角度(该角度导致轮播不灵敏) | 
|                         //                        if (direction !== 'left' && direction !== 'right') { | 
|                         //                            isReturn = true; | 
|                         //                        } else { | 
|                         $.gestures.session.lockDirection = true; //锁定方向 | 
|                         $.gestures.session.startDirection = detail.direction; | 
|                         //                        } | 
|                     } | 
|                 } else if (this.options.scrollY && !this.moved) { | 
|                     isReturn = true; | 
|                 } | 
|             } else if (detail.direction === 'up' || detail.direction === 'down') { | 
|                 if (this.options.scrollY) { | 
|                     isPreventDefault = true; | 
|                     //                    if (!this.moved) { //识别角度,竖向滚动似乎没必要进行小角度验证 | 
|                     //                        if (direction !== 'up' && direction !== 'down') { | 
|                     //                            isReturn = true; | 
|                     //                        } | 
|                     //                    } | 
|                     if (!this.moved) { | 
|                         $.gestures.session.lockDirection = true; //锁定方向 | 
|                         $.gestures.session.startDirection = detail.direction; | 
|                     } | 
|                 } else if (this.options.scrollX && !this.moved) { | 
|                     isReturn = true; | 
|                 } | 
|             } else { | 
|                 isReturn = true; | 
|             } | 
|             if (this.moved || isPreventDefault) { | 
|                 e.stopPropagation(); //阻止冒泡(scroll类嵌套) | 
|                 detail.gesture && detail.gesture.preventDefault(); | 
|             } | 
|             if (isReturn) { //禁止非法方向滚动 | 
|                 return; | 
|             } | 
|             if (!this.moved) { | 
|                 $.trigger(this.scroller, 'scrollstart', this); | 
|             } else { | 
|                 e.stopPropagation(); //move期间阻止冒泡(scroll嵌套) | 
|             } | 
|             var deltaX = 0; | 
|             var deltaY = 0; | 
|             if (!this.moved) { //start | 
|                 deltaX = detail.deltaX; | 
|                 deltaY = detail.deltaY; | 
|             } else { //move | 
|                 deltaX = detail.deltaX - $.gestures.session.prevTouch.deltaX; | 
|                 deltaY = detail.deltaY - $.gestures.session.prevTouch.deltaY; | 
|             } | 
|             var absDeltaX = Math.abs(detail.deltaX); | 
|             var absDeltaY = Math.abs(detail.deltaY); | 
|             if (absDeltaX > absDeltaY + this.options.directionLockThreshold) { | 
|                 deltaY = 0; | 
|             } else if (absDeltaY >= absDeltaX + this.options.directionLockThreshold) { | 
|                 deltaX = 0; | 
|             } | 
|   | 
|             deltaX = this.hasHorizontalScroll ? deltaX : 0; | 
|             deltaY = this.hasVerticalScroll ? deltaY : 0; | 
|             var newX = this.x + deltaX; | 
|             var newY = this.y + deltaY; | 
|             // Slow down if outside of the boundaries | 
|             if (newX > 0 || newX < this.maxScrollX) { | 
|                 newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; | 
|             } | 
|             if (newY > 0 || newY < this.maxScrollY) { | 
|                 newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; | 
|             } | 
|   | 
|             if (!this.requestAnimationFrame) { | 
|                 this._updateTranslate(); | 
|             } | 
|             this.direction = detail.deltaX > 0 ? 'right' : 'left'; | 
|             this.moved = true; | 
|             this.x = newX; | 
|             this.y = newY; | 
|             $.trigger(this.scroller, 'scroll', this); | 
|         }, | 
|         _flick: function(e) { | 
|             //            if (!this.moved || this.needReset) { | 
|             //                return; | 
|             //            } | 
|             if (!this.moved) { | 
|                 return; | 
|             } | 
|             e.stopPropagation(); | 
|             var detail = e.detail; | 
|             this._clearRequestAnimationFrame(); | 
|             if (e.type === 'dragend' && detail.flick) { //dragend | 
|                 return; | 
|             } | 
|   | 
|             var newX = Math.round(this.x); | 
|             var newY = Math.round(this.y); | 
|   | 
|             this.isInTransition = false; | 
|             // reset if we are outside of the boundaries | 
|             if (this.resetPosition(this.options.bounceTime)) { | 
|                 return; | 
|             } | 
|   | 
|             this.scrollTo(newX, newY); // ensures that the last position is rounded | 
|   | 
|             if (e.type === 'dragend') { //dragend | 
|                 $.trigger(this.scroller, 'scrollend', this); | 
|                 return; | 
|             } | 
|             var time = 0; | 
|             var easing = ''; | 
|             // start momentum animation if needed | 
|             if (this.options.momentum && detail.flickTime < 300) { | 
|                 momentumX = this.hasHorizontalScroll ? this._momentum(this.x, detail.flickDistanceX, detail.flickTime, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { | 
|                     destination: newX, | 
|                     duration: 0 | 
|                 }; | 
|                 momentumY = this.hasVerticalScroll ? this._momentum(this.y, detail.flickDistanceY, detail.flickTime, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { | 
|                     destination: newY, | 
|                     duration: 0 | 
|                 }; | 
|                 newX = momentumX.destination; | 
|                 newY = momentumY.destination; | 
|                 time = Math.max(momentumX.duration, momentumY.duration); | 
|                 this.isInTransition = true; | 
|             } | 
|   | 
|             if (newX != this.x || newY != this.y) { | 
|                 if (newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY) { | 
|                     easing = ease.quadratic; | 
|                 } | 
|                 this.scrollTo(newX, newY, time, easing); | 
|                 return; | 
|             } | 
|   | 
|             $.trigger(this.scroller, 'scrollend', this); | 
|             //            e.stopPropagation(); | 
|         }, | 
|         _end: function(e) { | 
|             this.needReset = false; | 
|             if ((!this.moved && this.needReset) || e.type === $.EVENT_CANCEL) { | 
|                 this.resetPosition(); | 
|             } | 
|         }, | 
|         _transitionEnd: function(e) { | 
|             if (e.target != this.scroller || !this.isInTransition) { | 
|                 return; | 
|             } | 
|             this._transitionTime(); | 
|             if (!this.resetPosition(this.options.bounceTime)) { | 
|                 this.isInTransition = false; | 
|                 $.trigger(this.scroller, 'scrollend', this); | 
|             } | 
|         }, | 
|         _scrollend: function(e) { | 
|             if ((this.y === 0 && this.maxScrollY === 0) || (Math.abs(this.y) > 0 && this.y <= this.maxScrollY)) { | 
|                 $.trigger(this.scroller, 'scrollbottom', this); | 
|             } | 
|         }, | 
|         _resize: function() { | 
|             var that = this; | 
|             clearTimeout(that.resizeTimeout); | 
|             that.resizeTimeout = setTimeout(function() { | 
|                 that.refresh(); | 
|             }, that.options.resizePolling); | 
|         }, | 
|         _transitionTime: function(time) { | 
|             time = time || 0; | 
|             this.scrollerStyle['webkitTransitionDuration'] = time + 'ms'; | 
|             if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果 | 
|                 this.parallaxStyle['webkitTransitionDuration'] = time + 'ms'; | 
|             } | 
|             if (this.options.fixedBadAndorid && !time && $.os.isBadAndroid) { | 
|                 this.scrollerStyle['webkitTransitionDuration'] = '0.001s'; | 
|                 if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果 | 
|                     this.parallaxStyle['webkitTransitionDuration'] = '0.001s'; | 
|                 } | 
|             } | 
|             if (this.indicators) { | 
|                 for (var i = this.indicators.length; i--;) { | 
|                     this.indicators[i].transitionTime(time); | 
|                 } | 
|             } | 
|             if (time) { //自定义timer,保证webkitTransitionEnd始终触发 | 
|                 this.transitionTimer && this.transitionTimer.cancel(); | 
|                 this.transitionTimer = $.later(function() { | 
|                     $.trigger(this.scroller, 'webkitTransitionEnd'); | 
|                 }, time + 100, this); | 
|             } | 
|         }, | 
|         _transitionTimingFunction: function(easing) { | 
|             this.scrollerStyle['webkitTransitionTimingFunction'] = easing; | 
|             if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果 | 
|                 this.parallaxStyle['webkitTransitionDuration'] = easing; | 
|             } | 
|             if (this.indicators) { | 
|                 for (var i = this.indicators.length; i--;) { | 
|                     this.indicators[i].transitionTimingFunction(easing); | 
|                 } | 
|             } | 
|         }, | 
|         _translate: function(x, y) { | 
|             this.x = x; | 
|             this.y = y; | 
|         }, | 
|         _clearRequestAnimationFrame: function() { | 
|             if (this.requestAnimationFrame) { | 
|                 cancelAnimationFrame(this.requestAnimationFrame); | 
|                 this.requestAnimationFrame = null; | 
|             } | 
|         }, | 
|         _updateTranslate: function() { | 
|             var self = this; | 
|             if (self.x !== self.lastX || self.y !== self.lastY) { | 
|                 self.setTranslate(self.x, self.y); | 
|             } | 
|             self.requestAnimationFrame = requestAnimationFrame(function() { | 
|                 self._updateTranslate(); | 
|             }); | 
|         }, | 
|         _createScrollBar: function(clazz) { | 
|             var scrollbar = document.createElement('div'); | 
|             var indicator = document.createElement('div'); | 
|             scrollbar.className = CLASS_SCROLLBAR + ' ' + clazz; | 
|             indicator.className = CLASS_INDICATOR; | 
|             scrollbar.appendChild(indicator); | 
|             if (clazz === CLASS_SCROLLBAR_VERTICAL) { | 
|                 this.scrollbarY = scrollbar; | 
|                 this.scrollbarIndicatorY = indicator; | 
|             } else if (clazz === CLASS_SCROLLBAR_HORIZONTAL) { | 
|                 this.scrollbarX = scrollbar; | 
|                 this.scrollbarIndicatorX = indicator; | 
|             } | 
|             this.wrapper.appendChild(scrollbar); | 
|             return scrollbar; | 
|         }, | 
|         _preventDefaultException: function(el, exceptions) { | 
|             for (var i in exceptions) { | 
|                 if (exceptions[i].test(el[i])) { | 
|                     return true; | 
|                 } | 
|             } | 
|             return false; | 
|         }, | 
|         _reLayout: function() { | 
|             if (!this.hasHorizontalScroll) { | 
|                 this.maxScrollX = 0; | 
|                 this.scrollerWidth = this.wrapperWidth; | 
|             } | 
|   | 
|             if (!this.hasVerticalScroll) { | 
|                 this.maxScrollY = 0; | 
|                 this.scrollerHeight = this.wrapperHeight; | 
|             } | 
|   | 
|             this.indicators.map(function(indicator) { | 
|                 indicator.refresh(); | 
|             }); | 
|   | 
|             //以防slider类嵌套使用 | 
|             if (this.options.snap && typeof this.options.snap === 'string') { | 
|                 var items = this.scroller.querySelectorAll(this.options.snap); | 
|                 this.itemLength = 0; | 
|                 this.snaps = []; | 
|                 for (var i = 0, len = items.length; i < len; i++) { | 
|                     var item = items[i]; | 
|                     if (item.parentNode === this.scroller) { | 
|                         this.itemLength++; | 
|                         this.snaps.push(item); | 
|                     } | 
|                 } | 
|                 this._initSnap(); //需要每次都_initSnap么。其实init的时候执行一次,后续resize的时候执行一次就行了吧.先这么做吧,如果影响性能,再调整 | 
|             } | 
|         }, | 
|         _momentum: function(current, distance, time, lowerMargin, wrapperSize, deceleration) { | 
|             var speed = parseFloat(Math.abs(distance) / time), | 
|                 destination, | 
|                 duration; | 
|   | 
|             deceleration = deceleration === undefined ? 0.0006 : deceleration; | 
|             destination = current + (speed * speed) / (2 * deceleration) * (distance < 0 ? -1 : 1); | 
|             duration = speed / deceleration; | 
|             if (destination < lowerMargin) { | 
|                 destination = wrapperSize ? lowerMargin - (wrapperSize / 2.5 * (speed / 8)) : lowerMargin; | 
|                 distance = Math.abs(destination - current); | 
|                 duration = distance / speed; | 
|             } else if (destination > 0) { | 
|                 destination = wrapperSize ? wrapperSize / 2.5 * (speed / 8) : 0; | 
|                 distance = Math.abs(current) + destination; | 
|                 duration = distance / speed; | 
|             } | 
|   | 
|             return { | 
|                 destination: Math.round(destination), | 
|                 duration: duration | 
|             }; | 
|         }, | 
|         _getTranslateStr: function(x, y) { | 
|             if (this.options.hardwareAccelerated) { | 
|                 return 'translate3d(' + x + 'px,' + y + 'px,0px) ' + this.translateZ; | 
|             } | 
|             return 'translate(' + x + 'px,' + y + 'px) '; | 
|         }, | 
|         //API | 
|         setStopped: function(stopped) { | 
|             // this.stopped = !!stopped; | 
|   | 
|             // fixed ios双webview模式下拉刷新 | 
|             if(stopped) { | 
|                 this.disablePullupToRefresh(); | 
|                 this.disablePulldownToRefresh(); | 
|             } else { | 
|                 this.enablePullupToRefresh(); | 
|                 this.enablePulldownToRefresh(); | 
|             } | 
|         }, | 
|         setTranslate: function(x, y) { | 
|             this.x = x; | 
|             this.y = y; | 
|             this.scrollerStyle['webkitTransform'] = this._getTranslateStr(x, y); | 
|             if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果 | 
|                 var parallaxY = y * this.options.parallaxRatio; | 
|                 var scale = 1 + parallaxY / ((this.parallaxHeight - parallaxY) / 2); | 
|                 if (scale > 1) { | 
|                     this.parallaxImgStyle['opacity'] = 1 - parallaxY / 100 * this.options.parallaxRatio; | 
|                     this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -parallaxY) + ' scale(' + scale + ',' + scale + ')'; | 
|                 } else { | 
|                     this.parallaxImgStyle['opacity'] = 1; | 
|                     this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -1) + ' scale(1,1)'; | 
|                 } | 
|             } | 
|             if (this.indicators) { | 
|                 for (var i = this.indicators.length; i--;) { | 
|                     this.indicators[i].updatePosition(); | 
|                 } | 
|             } | 
|             this.lastX = this.x; | 
|             this.lastY = this.y; | 
|             $.trigger(this.scroller, 'scroll', this); | 
|         }, | 
|         reLayout: function() { | 
|             this.wrapper.offsetHeight; | 
|   | 
|             var paddingLeft = parseFloat($.getStyles(this.wrapper, 'padding-left')) || 0; | 
|             var paddingRight = parseFloat($.getStyles(this.wrapper, 'padding-right')) || 0; | 
|             var paddingTop = parseFloat($.getStyles(this.wrapper, 'padding-top')) || 0; | 
|             var paddingBottom = parseFloat($.getStyles(this.wrapper, 'padding-bottom')) || 0; | 
|   | 
|             var clientWidth = this.wrapper.clientWidth; | 
|             var clientHeight = this.wrapper.clientHeight; | 
|   | 
|             this.scrollerWidth = this.scroller.offsetWidth; | 
|             this.scrollerHeight = this.scroller.offsetHeight; | 
|   | 
|             this.wrapperWidth = clientWidth - paddingLeft - paddingRight; | 
|             this.wrapperHeight = clientHeight - paddingTop - paddingBottom; | 
|   | 
|             this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0); | 
|             this.maxScrollY = Math.min(this.wrapperHeight - this.scrollerHeight, 0); | 
|             this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; | 
|             this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; | 
|             this._reLayout(); | 
|         }, | 
|         resetPosition: function(time) { | 
|             var x = this.x, | 
|                 y = this.y; | 
|   | 
|             time = time || 0; | 
|             if (!this.hasHorizontalScroll || this.x > 0) { | 
|                 x = 0; | 
|             } else if (this.x < this.maxScrollX) { | 
|                 x = this.maxScrollX; | 
|             } | 
|   | 
|             if (!this.hasVerticalScroll || this.y > 0) { | 
|                 y = 0; | 
|             } else if (this.y < this.maxScrollY) { | 
|                 y = this.maxScrollY; | 
|             } | 
|   | 
|             if (x == this.x && y == this.y) { | 
|                 return false; | 
|             } | 
|             this.scrollTo(x, y, time, this.options.scrollEasing); | 
|   | 
|             return true; | 
|         }, | 
|         _reInit: function() { | 
|             var groups = this.wrapper.querySelectorAll('.' + CLASS_SCROLL); | 
|             for (var i = 0, len = groups.length; i < len; i++) { | 
|                 if (groups[i].parentNode === this.wrapper) { | 
|                     this.scroller = groups[i]; | 
|                     break; | 
|                 } | 
|             } | 
|             this.scrollerStyle = this.scroller && this.scroller.style; | 
|         }, | 
|         refresh: function() { | 
|             this._reInit(); | 
|             this.reLayout(); | 
|             $.trigger(this.scroller, 'refresh', this); | 
|             this.resetPosition(); | 
|         }, | 
|         scrollTo: function(x, y, time, easing) { | 
|             var easing = easing || ease.circular; | 
|             //            this.isInTransition = time > 0 && (this.lastX != x || this.lastY != y); | 
|             //暂不严格判断x,y,否则会导致部分版本上不正常触发轮播 | 
|             this.isInTransition = time > 0; | 
|             if (this.isInTransition) { | 
|                 this._clearRequestAnimationFrame(); | 
|                 this._transitionTimingFunction(easing.style); | 
|                 this._transitionTime(time); | 
|                 this.setTranslate(x, y); | 
|             } else { | 
|                 this.setTranslate(x, y); | 
|             } | 
|   | 
|         }, | 
|         scrollToBottom: function(time, easing) { | 
|             time = time || this.options.scrollTime; | 
|             this.scrollTo(0, this.maxScrollY, time, easing); | 
|         }, | 
|         gotoPage: function(index) { | 
|             this._gotoPage(index); | 
|         }, | 
|         destroy: function() { | 
|             this._initEvent(true); //detach | 
|             delete $.data[this.wrapper.getAttribute('data-scroll')]; | 
|             this.wrapper.setAttribute('data-scroll', ''); | 
|         } | 
|     }); | 
|     //Indicator | 
|     var Indicator = function(scroller, options) { | 
|         this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; | 
|         this.wrapperStyle = this.wrapper.style; | 
|         this.indicator = this.wrapper.children[0]; | 
|         this.indicatorStyle = this.indicator.style; | 
|         this.scroller = scroller; | 
|   | 
|         this.options = $.extend({ | 
|             listenX: true, | 
|             listenY: true, | 
|             fade: false, | 
|             speedRatioX: 0, | 
|             speedRatioY: 0 | 
|         }, options); | 
|   | 
|         this.sizeRatioX = 1; | 
|         this.sizeRatioY = 1; | 
|         this.maxPosX = 0; | 
|         this.maxPosY = 0; | 
|   | 
|         if (this.options.fade) { | 
|             this.wrapperStyle['webkitTransform'] = this.scroller.translateZ; | 
|             this.wrapperStyle['webkitTransitionDuration'] = this.options.fixedBadAndorid && $.os.isBadAndroid ? '0.001s' : '0ms'; | 
|             this.wrapperStyle.opacity = '0'; | 
|         } | 
|     } | 
|     Indicator.prototype = { | 
|         handleEvent: function(e) { | 
|   | 
|         }, | 
|         transitionTime: function(time) { | 
|             time = time || 0; | 
|             this.indicatorStyle['webkitTransitionDuration'] = time + 'ms'; | 
|             if (this.scroller.options.fixedBadAndorid && !time && $.os.isBadAndroid) { | 
|                 this.indicatorStyle['webkitTransitionDuration'] = '0.001s'; | 
|             } | 
|         }, | 
|         transitionTimingFunction: function(easing) { | 
|             this.indicatorStyle['webkitTransitionTimingFunction'] = easing; | 
|         }, | 
|         refresh: function() { | 
|             this.transitionTime(); | 
|   | 
|             if (this.options.listenX && !this.options.listenY) { | 
|                 this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; | 
|             } else if (this.options.listenY && !this.options.listenX) { | 
|                 this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; | 
|             } else { | 
|                 this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; | 
|             } | 
|   | 
|             this.wrapper.offsetHeight; // force refresh | 
|   | 
|             if (this.options.listenX) { | 
|                 this.wrapperWidth = this.wrapper.clientWidth; | 
|                 this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); | 
|                 this.indicatorStyle.width = this.indicatorWidth + 'px'; | 
|   | 
|                 this.maxPosX = this.wrapperWidth - this.indicatorWidth; | 
|   | 
|                 this.minBoundaryX = 0; | 
|                 this.maxBoundaryX = this.maxPosX; | 
|   | 
|                 this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); | 
|             } | 
|   | 
|             if (this.options.listenY) { | 
|                 this.wrapperHeight = this.wrapper.clientHeight; | 
|                 this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); | 
|                 this.indicatorStyle.height = this.indicatorHeight + 'px'; | 
|   | 
|                 this.maxPosY = this.wrapperHeight - this.indicatorHeight; | 
|   | 
|                 this.minBoundaryY = 0; | 
|                 this.maxBoundaryY = this.maxPosY; | 
|   | 
|                 this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); | 
|             } | 
|   | 
|             this.updatePosition(); | 
|         }, | 
|   | 
|         updatePosition: function() { | 
|             var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, | 
|                 y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; | 
|   | 
|             if (x < this.minBoundaryX) { | 
|                 this.width = Math.max(this.indicatorWidth + x, 8); | 
|                 this.indicatorStyle.width = this.width + 'px'; | 
|                 x = this.minBoundaryX; | 
|             } else if (x > this.maxBoundaryX) { | 
|                 this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); | 
|                 this.indicatorStyle.width = this.width + 'px'; | 
|                 x = this.maxPosX + this.indicatorWidth - this.width; | 
|             } else if (this.width != this.indicatorWidth) { | 
|                 this.width = this.indicatorWidth; | 
|                 this.indicatorStyle.width = this.width + 'px'; | 
|             } | 
|   | 
|             if (y < this.minBoundaryY) { | 
|                 this.height = Math.max(this.indicatorHeight + y * 3, 8); | 
|                 this.indicatorStyle.height = this.height + 'px'; | 
|                 y = this.minBoundaryY; | 
|             } else if (y > this.maxBoundaryY) { | 
|                 this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); | 
|                 this.indicatorStyle.height = this.height + 'px'; | 
|                 y = this.maxPosY + this.indicatorHeight - this.height; | 
|             } else if (this.height != this.indicatorHeight) { | 
|                 this.height = this.indicatorHeight; | 
|                 this.indicatorStyle.height = this.height + 'px'; | 
|             } | 
|   | 
|             this.x = x; | 
|             this.y = y; | 
|   | 
|             this.indicatorStyle['webkitTransform'] = this.scroller._getTranslateStr(x, y); | 
|   | 
|         }, | 
|         fade: function(val, hold) { | 
|             if (hold && !this.visible) { | 
|                 return; | 
|             } | 
|   | 
|             clearTimeout(this.fadeTimeout); | 
|             this.fadeTimeout = null; | 
|   | 
|             var time = val ? 250 : 500, | 
|                 delay = val ? 0 : 300; | 
|   | 
|             val = val ? '1' : '0'; | 
|   | 
|             this.wrapperStyle['webkitTransitionDuration'] = time + 'ms'; | 
|   | 
|             this.fadeTimeout = setTimeout((function(val) { | 
|                 this.wrapperStyle.opacity = val; | 
|                 this.visible = +val; | 
|             }).bind(this, val), delay); | 
|         } | 
|     }; | 
|   | 
|     $.Scroll = Scroll; | 
|   | 
|     $.fn.scroll = function(options) { | 
|         var scrollApis = []; | 
|         this.each(function() { | 
|             var scrollApi = null; | 
|             var self = this; | 
|             var id = self.getAttribute('data-scroll'); | 
|             if (!id) { | 
|                 id = ++$.uuid; | 
|                 var _options = $.extend({}, options); | 
|                 if (self.classList.contains('mui-segmented-control')) { | 
|                     _options = $.extend(_options, { | 
|                         scrollY: false, | 
|                         scrollX: true, | 
|                         indicators: false, | 
|                         snap: '.mui-control-item' | 
|                     }); | 
|                 } | 
|                 $.data[id] = scrollApi = new Scroll(self, _options); | 
|                 self.setAttribute('data-scroll', id); | 
|             } else { | 
|                 scrollApi = $.data[id]; | 
|             } | 
|             scrollApis.push(scrollApi); | 
|         }); | 
|         return scrollApis.length === 1 ? scrollApis[0] : scrollApis; | 
|     }; | 
| })(mui, window, document); | 
| (function($, window, document, undefined) { | 
|   | 
|     var CLASS_VISIBILITY = 'mui-visibility'; | 
|     var CLASS_HIDDEN = 'mui-hidden'; | 
|   | 
|     var PullRefresh = $.Scroll.extend($.extend({ | 
|         handleEvent: function(e) { | 
|             this._super(e); | 
|             if (e.type === 'scrollbottom') { | 
|                 if (e.target === this.scroller) { | 
|                     this._scrollbottom(); | 
|                 } | 
|             } | 
|         }, | 
|         _scrollbottom: function() { | 
|             if (!this.pulldown && !this.loading) { | 
|                 this.pulldown = false; | 
|                 this._initPullupRefresh(); | 
|                 this.pullupLoading(); | 
|             } | 
|         }, | 
|         _start: function(e) { | 
|             //仅下拉刷新在start阻止默认事件 | 
|             if (e.touches && e.touches.length && e.touches[0].clientX > 30) { | 
|                 e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault(); | 
|             } | 
|             if (!this.loading) { | 
|                 this.pulldown = this.pullPocket = this.pullCaption = this.pullLoading = false | 
|             } | 
|             this._super(e); | 
|         }, | 
|         _drag: function(e) { | 
|             if (this.y >= 0 && this.disablePulldown && e.detail.direction === 'down') { //禁用下拉刷新 | 
|                 return; | 
|             } | 
|             this._super(e); | 
|             if (!this.pulldown && !this.loading && this.topPocket && e.detail.direction === 'down' && this.y >= 0) { | 
|                 this._initPulldownRefresh(); | 
|             } | 
|             if (this.pulldown) { | 
|                 this._setCaption(this.y > this.options.down.height ? this.options.down.contentover : this.options.down.contentdown); | 
|             } | 
|         }, | 
|   | 
|         _reLayout: function() { | 
|             this.hasVerticalScroll = true; | 
|             this._super(); | 
|         }, | 
|         //API | 
|         resetPosition: function(time) { | 
|             if (this.pulldown && !this.disablePulldown) { | 
|                 if (this.y >= this.options.down.height) { | 
|                     this.pulldownLoading(undefined, time || 0); | 
|                     return true; | 
|                 } else { | 
|                     !this.loading && this.topPocket.classList.remove(CLASS_VISIBILITY); | 
|                 } | 
|             } | 
|             return this._super(time); | 
|         }, | 
|         pulldownLoading: function(y, time) { | 
|             typeof y === 'undefined' && (y = this.options.down.height); //默认高度 | 
|             this.scrollTo(0, y, time, this.options.bounceEasing); | 
|             if (this.loading) { | 
|                 return; | 
|             } | 
|             //            if (!this.pulldown) { | 
|             this._initPulldownRefresh(); | 
|             //            } | 
|             this._setCaption(this.options.down.contentrefresh); | 
|             this.loading = true; | 
|             this.indicators.map(function(indicator) { | 
|                 indicator.fade(0); | 
|             }); | 
|             var callback = this.options.down.callback; | 
|             callback && callback.call(this); | 
|         }, | 
|         endPulldownToRefresh: function() { | 
|             var self = this; | 
|             if (self.topPocket && self.loading && this.pulldown) { | 
|                 self.scrollTo(0, 0, self.options.bounceTime, self.options.bounceEasing); | 
|                 self.loading = false; | 
|                 self._setCaption(self.options.down.contentdown, true); | 
|                 setTimeout(function() { | 
|                     self.loading || self.topPocket.classList.remove(CLASS_VISIBILITY); | 
|                 }, 350); | 
|             } | 
|         }, | 
|         pullupLoading: function(callback, x, time) { | 
|             x = x || 0; | 
|             this.scrollTo(x, this.maxScrollY, time, this.options.bounceEasing); | 
|             if (this.loading) { | 
|                 return; | 
|             } | 
|             this._initPullupRefresh(); | 
|             this._setCaption(this.options.up.contentrefresh); | 
|             this.indicators.map(function(indicator) { | 
|                 indicator.fade(0); | 
|             }); | 
|             this.loading = true; | 
|             callback = callback || this.options.up.callback; | 
|             callback && callback.call(this); | 
|         }, | 
|         endPullupToRefresh: function(finished) { | 
|             var self = this; | 
|             if (self.bottomPocket) { // && self.loading && !this.pulldown | 
|                 self.loading = false; | 
|                 if (finished) { | 
|                     this.finished = true; | 
|                     self._setCaption(self.options.up.contentnomore); | 
|                     //                    self.bottomPocket.classList.remove(CLASS_VISIBILITY); | 
|                     //                    self.bottomPocket.classList.add(CLASS_HIDDEN); | 
|                     self.wrapper.removeEventListener('scrollbottom', self); | 
|                 } else { | 
|                     self._setCaption(self.options.up.contentdown); | 
|                     //                    setTimeout(function() { | 
|                     self.loading || self.bottomPocket.classList.remove(CLASS_VISIBILITY); | 
|                     //                    }, 300); | 
|                 } | 
|             } | 
|         }, | 
|         disablePullupToRefresh: function() { | 
|             this._initPullupRefresh(); | 
|             this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN; | 
|             this.wrapper.removeEventListener('scrollbottom', this); | 
|         }, | 
|         disablePulldownToRefresh: function() { | 
|             this._initPulldownRefresh(); | 
|             this.topPocket.className = 'mui-pull-top-pocket' + ' ' + CLASS_HIDDEN; | 
|             this.disablePulldown = true; | 
|         }, | 
|         enablePulldownToRefresh: function() { | 
|             this._initPulldownRefresh(); | 
|             this.topPocket.classList.remove(CLASS_HIDDEN); | 
|             this._setCaption(this.options.down.contentdown); | 
|             this.disablePulldown = false; | 
|         }, | 
|         enablePullupToRefresh: function() { | 
|             this._initPullupRefresh(); | 
|             this.bottomPocket.classList.remove(CLASS_HIDDEN); | 
|             this._setCaption(this.options.up.contentdown); | 
|             this.wrapper.addEventListener('scrollbottom', this); | 
|         }, | 
|         refresh: function(isReset) { | 
|             if (isReset && this.finished) { | 
|                 this.enablePullupToRefresh(); | 
|                 this.finished = false; | 
|             } | 
|             this._super(); | 
|         }, | 
|     }, $.PullRefresh)); | 
|     $.fn.pullRefresh = function(options) { | 
|         if (this.length === 1) { | 
|             var self = this[0]; | 
|             var pullRefreshApi = null; | 
|             var id = self.getAttribute('data-pullrefresh'); | 
|             if (!id && typeof options === 'undefined') { | 
|                 return false; | 
|             } | 
|             options = options || {}; | 
|             if (!id) { | 
|                 id = ++$.uuid; | 
|                 $.data[id] = pullRefreshApi = new PullRefresh(self, options); | 
|                 self.setAttribute('data-pullrefresh', id); | 
|             } else { | 
|                 pullRefreshApi = $.data[id]; | 
|             } | 
|             if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次 | 
|                 pullRefreshApi.pulldownLoading(options.down.autoY); | 
|             } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次 | 
|                 pullRefreshApi.pullupLoading(); | 
|             } | 
|             //暂不提供这种调用方式吧             | 
|             //            if (typeof options === 'string') { | 
|             //                var methodValue = pullRefreshApi[options].apply(pullRefreshApi, $.slice.call(arguments, 1)); | 
|             //                if (methodValue !== undefined) { | 
|             //                    return methodValue; | 
|             //                } | 
|             //            } | 
|             return pullRefreshApi; | 
|         } | 
|     }; | 
| })(mui, window, document); | 
| /** | 
|  * snap 重构 | 
|  * @param {Object} $ | 
|  * @param {Object} window | 
|  */ | 
| (function($, window) { | 
|     var CLASS_SLIDER = 'mui-slider'; | 
|     var CLASS_SLIDER_GROUP = 'mui-slider-group'; | 
|     var CLASS_SLIDER_LOOP = 'mui-slider-loop'; | 
|     var CLASS_SLIDER_INDICATOR = 'mui-slider-indicator'; | 
|     var CLASS_ACTION_PREVIOUS = 'mui-action-previous'; | 
|     var CLASS_ACTION_NEXT = 'mui-action-next'; | 
|     var CLASS_SLIDER_ITEM = 'mui-slider-item'; | 
|   | 
|     var CLASS_ACTIVE = 'mui-active'; | 
|   | 
|     var SELECTOR_SLIDER_ITEM = '.' + CLASS_SLIDER_ITEM; | 
|     var SELECTOR_SLIDER_INDICATOR = '.' + CLASS_SLIDER_INDICATOR; | 
|     var SELECTOR_SLIDER_PROGRESS_BAR = '.mui-slider-progress-bar'; | 
|   | 
|     var Slider = $.Slider = $.Scroll.extend({ | 
|         init: function(element, options) { | 
|             this._super(element, $.extend(true, { | 
|                 fingers: 1, | 
|                 interval: 0, //设置为0,则不定时轮播 | 
|                 scrollY: false, | 
|                 scrollX: true, | 
|                 indicators: false, | 
|                 scrollTime: 1000, | 
|                 startX: false, | 
|                 slideTime: 0, //滑动动画时间 | 
|                 snap: SELECTOR_SLIDER_ITEM | 
|             }, options)); | 
|             if (this.options.startX) { | 
|                 //                $.trigger(this.wrapper, 'scrollend', this); | 
|             } | 
|         }, | 
|         _init: function() { | 
|             this._reInit(); | 
|             if (this.scroller) { | 
|                 this.scrollerStyle = this.scroller.style; | 
|                 this.progressBar = this.wrapper.querySelector(SELECTOR_SLIDER_PROGRESS_BAR); | 
|                 if (this.progressBar) { | 
|                     this.progressBarWidth = this.progressBar.offsetWidth; | 
|                     this.progressBarStyle = this.progressBar.style; | 
|                 } | 
|                 //忘记这个代码是干什么的了? | 
|                 //                this.x = this._getScroll(); | 
|                 //                if (this.options.startX === false) { | 
|                 //                    this.options.startX = this.x; | 
|                 //                } | 
|                 //根据active修正startX | 
|   | 
|                 this._super(); | 
|                 this._initTimer(); | 
|             } | 
|         }, | 
|         _triggerSlide: function() { | 
|             var self = this; | 
|             self.isInTransition = false; | 
|             var page = self.currentPage; | 
|             self.slideNumber = self._fixedSlideNumber(); | 
|             if (self.loop) { | 
|                 if (self.slideNumber === 0) { | 
|                     self.setTranslate(self.pages[1][0].x, 0); | 
|                 } else if (self.slideNumber === self.itemLength - 3) { | 
|                     self.setTranslate(self.pages[self.itemLength - 2][0].x, 0); | 
|                 } | 
|             } | 
|             if (self.lastSlideNumber != self.slideNumber) { | 
|                 self.lastSlideNumber = self.slideNumber; | 
|                 self.lastPage = self.currentPage; | 
|                 $.trigger(self.wrapper, 'slide', { | 
|                     slideNumber: self.slideNumber | 
|                 }); | 
|             } | 
|             self._initTimer(); | 
|         }, | 
|         _handleSlide: function(e) { | 
|             var self = this; | 
|             if (e.target !== self.wrapper) { | 
|                 return; | 
|             } | 
|             var detail = e.detail; | 
|             detail.slideNumber = detail.slideNumber || 0; | 
|             var temps = self.scroller.querySelectorAll(SELECTOR_SLIDER_ITEM); | 
|             var items = []; | 
|             for (var i = 0, len = temps.length; i < len; i++) { | 
|                 var item = temps[i]; | 
|                 if (item.parentNode === self.scroller) { | 
|                     items.push(item); | 
|                 } | 
|             } | 
|             var _slideNumber = detail.slideNumber; | 
|             if (self.loop) { | 
|                 _slideNumber += 1; | 
|             } | 
|             if (!self.wrapper.classList.contains('mui-segmented-control')) { | 
|                 for (var i = 0, len = items.length; i < len; i++) { | 
|                     var item = items[i]; | 
|                     if (item.parentNode === self.scroller) { | 
|                         if (i === _slideNumber) { | 
|                             item.classList.add(CLASS_ACTIVE); | 
|                         } else { | 
|                             item.classList.remove(CLASS_ACTIVE); | 
|                         } | 
|                     } | 
|                 } | 
|             } | 
|             var indicatorWrap = self.wrapper.querySelector('.mui-slider-indicator'); | 
|             if (indicatorWrap) { | 
|                 if (indicatorWrap.getAttribute('data-scroll')) { //scroll | 
|                     $(indicatorWrap).scroll().gotoPage(detail.slideNumber); | 
|                 } | 
|                 var indicators = indicatorWrap.querySelectorAll('.mui-indicator'); | 
|                 if (indicators.length > 0) { //图片轮播 | 
|                     for (var i = 0, len = indicators.length; i < len; i++) { | 
|                         indicators[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE); | 
|                     } | 
|                 } else { | 
|                     var number = indicatorWrap.querySelector('.mui-number span'); | 
|                     if (number) { //图文表格 | 
|                         number.innerText = (detail.slideNumber + 1); | 
|                     } else { //segmented controls | 
|                         var controlItems = indicatorWrap.querySelectorAll('.mui-control-item'); | 
|                         for (var i = 0, len = controlItems.length; i < len; i++) { | 
|                             controlItems[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE); | 
|                         } | 
|                     } | 
|                 } | 
|             } | 
|             e.stopPropagation(); | 
|         }, | 
|         _handleTabShow: function(e) { | 
|             var self = this; | 
|             self.gotoItem((e.detail.tabNumber || 0), self.options.slideTime); | 
|         }, | 
|         _handleIndicatorTap: function(event) { | 
|             var self = this; | 
|             var target = event.target; | 
|             if (target.classList.contains(CLASS_ACTION_PREVIOUS) || target.classList.contains(CLASS_ACTION_NEXT)) { | 
|                 self[target.classList.contains(CLASS_ACTION_PREVIOUS) ? 'prevItem' : 'nextItem'](); | 
|                 event.stopPropagation(); | 
|             } | 
|         }, | 
|         _initEvent: function(detach) { | 
|             var self = this; | 
|             self._super(detach); | 
|             var action = detach ? 'removeEventListener' : 'addEventListener'; | 
|             self.wrapper[action]('slide', this); | 
|             self.wrapper[action]($.eventName('shown', 'tab'), this); | 
|         }, | 
|         handleEvent: function(e) { | 
|             this._super(e); | 
|             switch (e.type) { | 
|                 case 'slide': | 
|                     this._handleSlide(e); | 
|                     break; | 
|                 case $.eventName('shown', 'tab'): | 
|                     if (~this.snaps.indexOf(e.target)) { //避免嵌套监听错误的tab show | 
|                         this._handleTabShow(e); | 
|                     } | 
|                     break; | 
|             } | 
|         }, | 
|         _scrollend: function(e) { | 
|             this._super(e); | 
|             this._triggerSlide(e); | 
|         }, | 
|         _drag: function(e) { | 
|             this._super(e); | 
|             var direction = e.detail.direction; | 
|             if (direction === 'left' || direction === 'right') { | 
|                 //拖拽期间取消定时 | 
|                 var slidershowTimer = this.wrapper.getAttribute('data-slidershowTimer'); | 
|                 slidershowTimer && window.clearTimeout(slidershowTimer); | 
|   | 
|                 e.stopPropagation(); | 
|             } | 
|         }, | 
|         _initTimer: function() { | 
|             var self = this; | 
|             var slider = self.wrapper; | 
|             var interval = self.options.interval; | 
|             var slidershowTimer = slider.getAttribute('data-slidershowTimer'); | 
|             slidershowTimer && window.clearTimeout(slidershowTimer); | 
|             if (interval) { | 
|                 slidershowTimer = window.setTimeout(function() { | 
|                     if (!slider) { | 
|                         return; | 
|                     } | 
|                     //仅slider显示状态进行自动轮播 | 
|                     if (!!(slider.offsetWidth || slider.offsetHeight)) { | 
|                         self.nextItem(true); | 
|                         //下一个 | 
|                     } | 
|                     self._initTimer(); | 
|                 }, interval); | 
|                 slider.setAttribute('data-slidershowTimer', slidershowTimer); | 
|             } | 
|         }, | 
|   | 
|         _fixedSlideNumber: function(page) { | 
|             page = page || this.currentPage; | 
|             var slideNumber = page.pageX; | 
|             if (this.loop) { | 
|                 if (page.pageX === 0) { | 
|                     slideNumber = this.itemLength - 3; | 
|                 } else if (page.pageX === (this.itemLength - 1)) { | 
|                     slideNumber = 0; | 
|                 } else { | 
|                     slideNumber = page.pageX - 1; | 
|                 } | 
|             } | 
|             return slideNumber; | 
|         }, | 
|         _reLayout: function() { | 
|             this.hasHorizontalScroll = true; | 
|             this.loop = this.scroller.classList.contains(CLASS_SLIDER_LOOP); | 
|             this._super(); | 
|         }, | 
|         _getScroll: function() { | 
|             var result = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform')); | 
|             return result ? result.x : 0; | 
|         }, | 
|         _transitionEnd: function(e) { | 
|             if (e.target !== this.scroller || !this.isInTransition) { | 
|                 return; | 
|             } | 
|             this._transitionTime(); | 
|             this.isInTransition = false; | 
|             $.trigger(this.wrapper, 'scrollend', this); | 
|         }, | 
|         _flick: function(e) { | 
|             if (!this.moved) { //无moved | 
|                 return; | 
|             } | 
|             var detail = e.detail; | 
|             var direction = detail.direction; | 
|             this._clearRequestAnimationFrame(); | 
|             this.isInTransition = true; | 
|             //            if (direction === 'up' || direction === 'down') { | 
|             //                this.resetPosition(this.options.bounceTime); | 
|             //                return; | 
|             //            } | 
|             if (e.type === 'flick') { | 
|                 if (detail.deltaTime < 200) { //flick,太容易触发,额外校验一下deltaTime | 
|                     this.x = this._getPage((this.slideNumber + (direction === 'right' ? -1 : 1)), true).x; | 
|                 } | 
|                 this.resetPosition(this.options.bounceTime); | 
|             } else if (e.type === 'dragend' && !detail.flick) { | 
|                 this.resetPosition(this.options.bounceTime); | 
|             } | 
|             e.stopPropagation(); | 
|         }, | 
|         _initSnap: function() { | 
|             this.scrollerWidth = this.itemLength * this.scrollerWidth; | 
|             this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0); | 
|             this._super(); | 
|             if (!this.currentPage.x) { | 
|                 //当slider处于隐藏状态时,导致snap计算是错误的,临时先这么判断一下,后续要考虑解决所有scroll在隐藏状态下初始化属性不正确的问题 | 
|                 var currentPage = this.pages[this.loop ? 1 : 0]; | 
|                 currentPage = currentPage || this.pages[0]; | 
|                 if (!currentPage) { | 
|                     return; | 
|                 } | 
|                 this.currentPage = currentPage[0]; | 
|                 this.slideNumber = 0; | 
|                 this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? 0 : this.lastSlideNumber; | 
|             } else { | 
|                 this.slideNumber = this._fixedSlideNumber(); | 
|                 this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? this.slideNumber : this.lastSlideNumber; | 
|             } | 
|             this.options.startX = this.currentPage.x || 0; | 
|         }, | 
|         _getSnapX: function(offsetLeft) { | 
|             return Math.max(-offsetLeft, this.maxScrollX); | 
|         }, | 
|         _getPage: function(slideNumber, isFlick) { | 
|             if (this.loop) { | 
|                 if (slideNumber > (this.itemLength - (isFlick ? 2 : 3))) { | 
|                     slideNumber = 1; | 
|                     time = 0; | 
|                 } else if (slideNumber < (isFlick ? -1 : 0)) { | 
|                     slideNumber = this.itemLength - 2; | 
|                     time = 0; | 
|                 } else { | 
|                     slideNumber += 1; | 
|                 } | 
|             } else { | 
|                 if (!isFlick) { | 
|                     if (slideNumber > (this.itemLength - 1)) { | 
|                         slideNumber = 0; | 
|                         time = 0; | 
|                     } else if (slideNumber < 0) { | 
|                         slideNumber = this.itemLength - 1; | 
|                         time = 0; | 
|                     } | 
|                 } | 
|                 slideNumber = Math.min(Math.max(0, slideNumber), this.itemLength - 1); | 
|             } | 
|             return this.pages[slideNumber][0]; | 
|         }, | 
|         _gotoItem: function(slideNumber, time) { | 
|             this.currentPage = this._getPage(slideNumber, true); //此处传true。可保证程序切换时,动画与人手操作一致(第一张,最后一张的切换动画) | 
|             this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing); | 
|             if (time === 0) { | 
|                 $.trigger(this.wrapper, 'scrollend', this); | 
|             } | 
|         }, | 
|         //API | 
|         setTranslate: function(x, y) { | 
|             this._super(x, y); | 
|             var progressBar = this.progressBar; | 
|             if (progressBar) { | 
|                 this.progressBarStyle.webkitTransform = this._getTranslateStr((-x * (this.progressBarWidth / this.wrapperWidth)), 0); | 
|             } | 
|         }, | 
|         resetPosition: function(time) { | 
|             time = time || 0; | 
|             if (this.x > 0) { | 
|                 this.x = 0; | 
|             } else if (this.x < this.maxScrollX) { | 
|                 this.x = this.maxScrollX; | 
|             } | 
|             this.currentPage = this._nearestSnap(this.x); | 
|             this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing); | 
|             return true; | 
|         }, | 
|         gotoItem: function(slideNumber, time) { | 
|             this._gotoItem(slideNumber, typeof time === 'undefined' ? this.options.scrollTime : time); | 
|         }, | 
|         nextItem: function() { | 
|             this._gotoItem(this.slideNumber + 1, this.options.scrollTime); | 
|         }, | 
|         prevItem: function() { | 
|             this._gotoItem(this.slideNumber - 1, this.options.scrollTime); | 
|         }, | 
|         getSlideNumber: function() { | 
|             return this.slideNumber || 0; | 
|         }, | 
|         _reInit: function() { | 
|             var groups = this.wrapper.querySelectorAll('.' + CLASS_SLIDER_GROUP); | 
|             for (var i = 0, len = groups.length; i < len; i++) { | 
|                 if (groups[i].parentNode === this.wrapper) { | 
|                     this.scroller = groups[i]; | 
|                     break; | 
|                 } | 
|             } | 
|             this.scrollerStyle = this.scroller && this.scroller.style; | 
|             if (this.progressBar) { | 
|                 this.progressBarWidth = this.progressBar.offsetWidth; | 
|                 this.progressBarStyle = this.progressBar.style; | 
|             } | 
|         }, | 
|         refresh: function(options) { | 
|             if (options) { | 
|                 $.extend(this.options, options); | 
|                 this._super(); | 
|                 this._initTimer(); | 
|             } else { | 
|                 this._super(); | 
|             } | 
|         }, | 
|         destroy: function() { | 
|             this._initEvent(true); //detach | 
|             delete $.data[this.wrapper.getAttribute('data-slider')]; | 
|             this.wrapper.setAttribute('data-slider', ''); | 
|         } | 
|     }); | 
|     $.fn.slider = function(options) { | 
|         var slider = null; | 
|         this.each(function() { | 
|             var sliderElement = this; | 
|             if (!this.classList.contains(CLASS_SLIDER)) { | 
|                 sliderElement = this.querySelector('.' + CLASS_SLIDER); | 
|             } | 
|             if (sliderElement && sliderElement.querySelector(SELECTOR_SLIDER_ITEM)) { | 
|                 var id = sliderElement.getAttribute('data-slider'); | 
|                 if (!id) { | 
|                     id = ++$.uuid; | 
|                     $.data[id] = slider = new Slider(sliderElement, options); | 
|                     sliderElement.setAttribute('data-slider', id); | 
|                 } else { | 
|                     slider = $.data[id]; | 
|                     if (slider && options) { | 
|                         slider.refresh(options); | 
|                     } | 
|                 } | 
|             } | 
|         }); | 
|         return slider; | 
|     }; | 
|     $.ready(function() { | 
|         //        setTimeout(function() { | 
|         $('.mui-slider').slider(); | 
|         $('.mui-scroll-wrapper.mui-slider-indicator.mui-segmented-control').scroll({ | 
|             scrollY: false, | 
|             scrollX: true, | 
|             indicators: false, | 
|             snap: '.mui-control-item' | 
|         }); | 
|         //        }, 500); //临时处理slider宽度计算不正确的问题(初步确认是scrollbar导致的) | 
|   | 
|     }); | 
| })(mui, window); | 
| /** | 
|  * pullRefresh 5+ | 
|  * @param {type} $ | 
|  * @returns {undefined} | 
|  */ | 
| (function($, document) { | 
|     if (!($.os.plus)) { //仅在5+android支持多webview的使用 | 
|         return; | 
|     } | 
|     $.plusReady(function() { | 
|         if (window.__NWin_Enable__ === false) { //不支持多webview,则不用5+下拉刷新 | 
|             return; | 
|         } | 
|         var CLASS_PLUS_PULLREFRESH = 'mui-plus-pullrefresh'; | 
|         var CLASS_VISIBILITY = 'mui-visibility'; | 
|         var CLASS_HIDDEN = 'mui-hidden'; | 
|         var CLASS_BLOCK = 'mui-block'; | 
|   | 
|         var CLASS_PULL_CAPTION = 'mui-pull-caption'; | 
|         var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down'; | 
|         var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh'; | 
|         var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore'; | 
|   | 
|         var PlusPullRefresh = $.Class.extend({ | 
|             init: function(element, options) { | 
|                 this.element = element; | 
|                 this.options = options; | 
|                 this.wrapper = this.scroller = element; | 
|                 this._init(); | 
|                 this._initPulldownRefreshEvent(); | 
|             }, | 
|             _init: function() { | 
|                 var self = this; | 
|                 //document.addEventListener('plusscrollbottom', this); | 
|                 window.addEventListener('dragup', self); | 
|                 document.addEventListener("plusscrollbottom", self); | 
|                 self.scrollInterval = window.setInterval(function() { | 
|                     if (self.isScroll && !self.loading) { | 
|                         if (window.pageYOffset + window.innerHeight + 10 >= document.documentElement.scrollHeight) { | 
|                             self.isScroll = false; //放在这里是因为快速滚动的话,有可能检测时,还没到底,所以只要有滚动,没到底之前一直检测高度变化 | 
|                             if (self.bottomPocket) { | 
|                                 self.pullupLoading(); | 
|                             } | 
|                         } | 
|                     } | 
|                 }, 100); | 
|             }, | 
|             _initPulldownRefreshEvent: function() { | 
|                 var self = this; | 
|                 $.plusReady(function() { | 
|                     if (self.options.down.style == "circle") { | 
|                         //单webview、原生转圈 | 
|                         self.options.webview = plus.webview.currentWebview(); | 
|                         self.options.webview.setPullToRefresh({ | 
|                             support: true, | 
|                             color: self.options.down.color || '#2BD009', | 
|                             height: self.options.down.height || '50px', | 
|                             range: self.options.down.range || '100px', | 
|                             style: 'circle', | 
|                             offset: self.options.down.offset || '0px' | 
|                         }, function() { | 
|                             self.options.down.callback(); | 
|                         }); | 
|                     } else if (self.topPocket && self.options.webviewId) { | 
|                         var webview = plus.webview.getWebviewById(self.options.webviewId); //子窗口 | 
|                         if (!webview) { | 
|                             return; | 
|                         } | 
|                         self.options.webview = webview; | 
|                         var downOptions = self.options.down; | 
|                         var height = downOptions.height; | 
|                         webview.addEventListener('close', function() { | 
|                             var attrWebviewId = self.options.webviewId && self.options.webviewId.replace(/\//g, "_"); //替换所有"/"  | 
|                             self.element.removeAttribute('data-pullrefresh-plus-' + attrWebviewId); | 
|                         }); | 
|                         webview.addEventListener("dragBounce", function(e) { | 
|                             if (!self.pulldown) { | 
|                                 self._initPulldownRefresh(); | 
|                             } else { | 
|                                 self.pullPocket.classList.add(CLASS_BLOCK); | 
|                             } | 
|                             switch (e.status) { | 
|                                 case "beforeChangeOffset": //下拉可刷新状态 | 
|                                     self._setCaption(downOptions.contentdown); | 
|                                     break; | 
|                                 case "afterChangeOffset": //松开可刷新状态 | 
|                                     self._setCaption(downOptions.contentover); | 
|                                     break; | 
|                                 case "dragEndAfterChangeOffset": //正在刷新状态 | 
|                                     //执行下拉刷新所在webview的回调函数 | 
|                                     webview.evalJS("window.mui&&mui.options.pullRefresh.down.callback()"); | 
|                                     self._setCaption(downOptions.contentrefresh); | 
|                                     break; | 
|                                 default: | 
|                                     break; | 
|                             } | 
|                         }, false); | 
|   | 
|                         webview.setBounce({ | 
|                             position: { | 
|                                 top: height * 2 + 'px' | 
|                             }, | 
|                             changeoffset: { | 
|                                 top: height + 'px' | 
|                             } | 
|                         }); | 
|   | 
|                     } | 
|                 }); | 
|             }, | 
|             handleEvent: function(e) { | 
|                 var self = this; | 
|                 if (self.stopped) { | 
|                     return; | 
|                 } | 
|                 self.isScroll = false; | 
|                 if (e.type === 'dragup' || e.type === 'plusscrollbottom') { | 
|                     self.isScroll = true; | 
|                     setTimeout(function() { | 
|                         self.isScroll = false; | 
|                     }, 1000); | 
|                 } | 
|             } | 
|         }).extend($.extend({ | 
|             setStopped: function(stopped) { //该方法是子页面调用的 | 
|                 this.stopped = !!stopped; | 
|                 // TODO 此处需要设置当前webview的bounce为none,目前5+有BUG | 
|                 if (this.stopped) { | 
|                     this.disablePullupToRefresh(); | 
|                     this.disablePulldownToRefresh(); | 
|                 } else { | 
|                     this.enablePullupToRefresh(); | 
|                     this.enablePulldownToRefresh(); | 
|                 } | 
|             }, | 
|             beginPulldown: function() { | 
|                 var self = this; | 
|                 $.plusReady(function() { | 
|                     //这里延时的目的是为了保证下拉刷新组件初始化完成,后续应该做成有状态的 | 
|                     setTimeout(function() { | 
|                         if (self.options.down.style == "circle") { //单webview下拉刷新 | 
|                             plus.webview.currentWebview().beginPullToRefresh(); | 
|                         } else { //双webview模式 | 
|                             var webview = self.options.webview; | 
|                             if (webview) { | 
|                                 webview.setBounce({ | 
|                                     offset: { | 
|                                         top: self.options.down.height + "px" | 
|                                     } | 
|                                 }); | 
|                             } | 
|                         } | 
|                     }, 15); | 
|                 }.bind(this)); | 
|             }, | 
|             pulldownLoading: function() { //该方法是子页面调用的,兼容老的历史API | 
|                 this.beginPulldown(); | 
|             }, | 
|             _pulldownLoading: function() { //该方法是父页面调用的 | 
|                 var self = this; | 
|                 $.plusReady(function() { | 
|                     var childWebview = plus.webview.getWebviewById(self.options.webviewId); | 
|                     childWebview && childWebview.setBounce({ | 
|                         offset: { | 
|                             top: self.options.down.height + "px" | 
|                         } | 
|                     }); | 
|                 }); | 
|             }, | 
|             endPulldown: function() { | 
|                 var _wv = plus.webview.currentWebview(); | 
|                 //双webview的下拉刷新,需要修改父窗口提示信息 | 
|                 if (_wv.parent() && this.options.down.style !== "circle") { | 
|                     _wv.parent().evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify({ | 
|                         webviewId: _wv.id | 
|                     }) + "')._endPulldownToRefresh()"); | 
|                 } else { | 
|                     _wv.endPullToRefresh(); | 
|                 } | 
|             }, | 
|             endPulldownToRefresh: function() { //该方法是子页面调用的,兼容老的历史API | 
|                 this.endPulldown(); | 
|             }, | 
|             _endPulldownToRefresh: function() { //该方法是父页面调用的 | 
|                 var self = this; | 
|                 if (self.topPocket && self.options.webview) { | 
|                     self.options.webview.endPullToRefresh(); //下拉刷新所在webview回弹 | 
|                     self.loading = false; | 
|                     self._setCaption(self.options.down.contentdown, true); | 
|                     setTimeout(function() { | 
|                         self.loading || self.topPocket.classList.remove(CLASS_BLOCK); | 
|                     }, 350); | 
|                 } | 
|             }, | 
|             beginPullup: function(callback) { //开始上拉加载 | 
|                 var self = this; | 
|                 if (self.isLoading) return; | 
|                 self.isLoading = true; | 
|                 if (self.pulldown !== false) { | 
|                     self._initPullupRefresh(); | 
|                 } else { | 
|                     this.pullPocket.classList.add(CLASS_BLOCK); | 
|                 } | 
|                 setTimeout(function() { | 
|                     self.pullLoading.classList.add(CLASS_VISIBILITY); | 
|                     self.pullLoading.classList.remove(CLASS_HIDDEN); | 
|                     self.pullCaption.innerHTML = ''; //修正5+里边第一次加载时,文字显示的bug(还会显示出来个“多”,猜测应该是渲染问题导致的) | 
|                     self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH; | 
|                     self.pullCaption.innerHTML = self.options.up.contentrefresh; | 
|                     callback = callback || self.options.up.callback; | 
|                     callback && callback.call(self); | 
|                 }, 300); | 
|             }, | 
|             pullupLoading: function(callback) { //兼容老的API | 
|                 this.beginPullup(callback); | 
|             }, | 
|             endPullup: function(finished) { //上拉加载结束 | 
|                 var self = this; | 
|                 if (self.pullLoading) { | 
|                     self.pullLoading.classList.remove(CLASS_VISIBILITY); | 
|                     self.pullLoading.classList.add(CLASS_HIDDEN); | 
|                     self.isLoading = false; | 
|                     if (finished) { | 
|                         self.finished = true; | 
|                         self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE; | 
|                         self.pullCaption.innerHTML = self.options.up.contentnomore; | 
|                         //取消5+的plusscrollbottom事件 | 
|                         document.removeEventListener('plusscrollbottom', self); | 
|                         window.removeEventListener('dragup', self); | 
|                     } else { //初始化时隐藏,后续不再隐藏 | 
|                         self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN; | 
|                         self.pullCaption.innerHTML = self.options.up.contentdown; | 
|                     } | 
|                 } | 
|             }, | 
|             endPullupToRefresh: function(finished) { //上拉加载结束,兼容老的API | 
|                 this.endPullup(finished); | 
|             }, | 
|             disablePulldownToRefresh: function() { | 
|                 var webview = plus.webview.currentWebview(); | 
|                 if (this.options.down.style && this.options.down.style == 'circle') { // 单webview模式禁止原生下拉刷新 | 
|                     this.options.webview.setPullToRefresh({ | 
|                         support: false, | 
|                         style: 'circle' | 
|                     }); | 
|                 } else { // 双webview模式禁止下拉刷新 | 
|                     webview.setStyle({ | 
|                         bounce: 'none' | 
|                     }); | 
|                     webview.setBounce({ | 
|                         position: { | 
|                             top: 'none' | 
|                         } | 
|                     }); | 
|                 } | 
|             }, | 
|             enablePulldownToRefresh: function() { | 
|                 var self = this, | 
|                     webview = plus.webview.currentWebview(), | 
|                     height = this.options.down.height; | 
|                 // 单webview模式禁止原生下拉刷新 | 
|                 if (this.options.down.style && this.options.down.style == 'circle') { | 
|                     webview.setPullToRefresh({ | 
|                         support: true, | 
|                         height: height || '50px', | 
|                         range: self.options.down.range || '100px', | 
|                         style: 'circle', | 
|                         offset: self.options.down.offset || '0px' | 
|                     }); | 
|                 } else { // 重新初始化双webview模式下拉刷新 | 
|                     webview.setStyle({ | 
|                         bounce: 'vertical' | 
|                     }); | 
|                     webview.setBounce({ | 
|                         position: { | 
|                             top: height * 2 + 'px' | 
|                         }, | 
|                         changeoffset: { | 
|                             top: height + 'px' | 
|                         } | 
|                     }); | 
|                 } | 
|             }, | 
|             disablePullupToRefresh: function() { | 
|                 this._initPullupRefresh(); | 
|                 this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN; | 
|                 window.removeEventListener('dragup', this); | 
|             }, | 
|             enablePullupToRefresh: function() { | 
|                 this._initPullupRefresh(); | 
|                 this.bottomPocket.classList.remove(CLASS_HIDDEN); | 
|                 this.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN; | 
|                 this.pullCaption.innerHTML = this.options.up.contentdown; | 
|                 document.addEventListener("plusscrollbottom", this); | 
|                 window.addEventListener('dragup', this); | 
|             }, | 
|             scrollTo: function(x, y, time) { | 
|                 $.scrollTo(y, time); | 
|             }, | 
|             scrollToBottom: function(time) { | 
|                 $.scrollTo(document.documentElement.scrollHeight, time); | 
|             }, | 
|             refresh: function(isReset) { | 
|                 if (isReset && this.finished) { | 
|                     this.enablePullupToRefresh(); | 
|                     this.finished = false; | 
|                 } | 
|             } | 
|         }, $.PullRefresh)); | 
|   | 
|         //override h5 pullRefresh | 
|         $.fn.pullRefresh_native = function(options) { | 
|             var self; | 
|             if (this.length === 0) { | 
|                 self = document.createElement('div'); | 
|                 self.className = 'mui-content'; | 
|                 document.body.appendChild(self); | 
|             } else { | 
|                 self = this[0]; | 
|             } | 
|             var args = options; | 
|             //一个父需要支持多个子下拉刷新 | 
|             options = options || {} | 
|             if (typeof options === 'string') { | 
|                 options = $.parseJSON(options); | 
|             }; | 
|             !options.webviewId && (options.webviewId = (plus.webview.currentWebview().id || plus.webview.currentWebview().getURL())); | 
|             var pullRefreshApi = null; | 
|             var attrWebviewId = options.webviewId && options.webviewId.replace(/\//g, "_"); //替换所有"/" | 
|             var id = self.getAttribute('data-pullrefresh-plus-' + attrWebviewId); | 
|             if (!id && typeof args === 'undefined') { | 
|                 return false; | 
|             } | 
|             if (!id) { //避免重复初始化5+ pullrefresh | 
|                 id = ++$.uuid; | 
|                 self.setAttribute('data-pullrefresh-plus-' + attrWebviewId, id); | 
|                 document.body.classList.add(CLASS_PLUS_PULLREFRESH); | 
|                 $.data[id] = pullRefreshApi = new PlusPullRefresh(self, options); | 
|             } else { | 
|                 pullRefreshApi = $.data[id]; | 
|             } | 
|             if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次 | 
|                 //pullRefreshApi._pulldownLoading(); //parent webview | 
|                 pullRefreshApi.beginPulldown(); | 
|             } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次 | 
|                 pullRefreshApi.beginPullup(); | 
|             } | 
|             return pullRefreshApi; | 
|         }; | 
|     }); | 
|   | 
| })(mui, document); | 
| /** | 
|  * off-canvas | 
|  * @param {type} $ | 
|  * @param {type} window | 
|  * @param {type} document | 
|  * @param {type} action | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window, document, name) { | 
|     var CLASS_OFF_CANVAS_LEFT = 'mui-off-canvas-left'; | 
|     var CLASS_OFF_CANVAS_RIGHT = 'mui-off-canvas-right'; | 
|     var CLASS_ACTION_BACKDROP = 'mui-off-canvas-backdrop'; | 
|     var CLASS_OFF_CANVAS_WRAP = 'mui-off-canvas-wrap'; | 
|   | 
|     var CLASS_SLIDE_IN = 'mui-slide-in'; | 
|     var CLASS_ACTIVE = 'mui-active'; | 
|   | 
|   | 
|     var CLASS_TRANSITIONING = 'mui-transitioning'; | 
|   | 
|     var SELECTOR_INNER_WRAP = '.mui-inner-wrap'; | 
|   | 
|   | 
|     var OffCanvas = $.Class.extend({ | 
|         init: function(element, options) { | 
|             this.wrapper = this.element = element; | 
|             this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP); | 
|             this.classList = this.wrapper.classList; | 
|             if (this.scroller) { | 
|                 this.options = $.extend(true, { | 
|                     dragThresholdX: 10, | 
|                     scale: 0.8, | 
|                     opacity: 0.1, | 
|                     preventDefaultException: { | 
|                         tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/ | 
|                     }, | 
|                 }, options); | 
|                 document.body.classList.add('mui-fullscreen'); //fullscreen | 
|                 this.refresh(); | 
|                 this.initEvent(); | 
|             } | 
|         }, | 
|         _preventDefaultException: function(el, exceptions) { | 
|             for (var i in exceptions) { | 
|                 if (exceptions[i].test(el[i])) { | 
|                     return true; | 
|                 } | 
|             } | 
|             return false; | 
|         }, | 
|         refresh: function(offCanvas) { | 
|             //            offCanvas && !offCanvas.classList.contains(CLASS_ACTIVE) && this.classList.remove(CLASS_ACTIVE); | 
|             this.slideIn = this.classList.contains(CLASS_SLIDE_IN); | 
|             this.scalable = this.classList.contains('mui-scalable') && !this.slideIn; | 
|             this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP); | 
|             //            !offCanvas && this.scroller.classList.remove(CLASS_TRANSITIONING); | 
|             //            !offCanvas && this.scroller.setAttribute('style', ''); | 
|             this.offCanvasLefts = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_LEFT); | 
|             this.offCanvasRights = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_RIGHT); | 
|             if (offCanvas) { | 
|                 if (offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) { | 
|                     this.offCanvasLeft = offCanvas; | 
|                 } else if (offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) { | 
|                     this.offCanvasRight = offCanvas; | 
|                 } | 
|             } else { | 
|                 this.offCanvasRight = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT); | 
|                 this.offCanvasLeft = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT); | 
|             } | 
|             this.offCanvasRightWidth = this.offCanvasLeftWidth = 0; | 
|             this.offCanvasLeftSlideIn = this.offCanvasRightSlideIn = false; | 
|             if (this.offCanvasRight) { | 
|                 this.offCanvasRightWidth = this.offCanvasRight.offsetWidth; | 
|                 this.offCanvasRightSlideIn = this.slideIn && (this.offCanvasRight.parentNode === this.wrapper); | 
|                 //                this.offCanvasRight.classList.remove(CLASS_TRANSITIONING); | 
|                 //                this.offCanvasRight.classList.remove(CLASS_ACTIVE); | 
|                 //                this.offCanvasRight.setAttribute('style', ''); | 
|             } | 
|             if (this.offCanvasLeft) { | 
|                 this.offCanvasLeftWidth = this.offCanvasLeft.offsetWidth; | 
|                 this.offCanvasLeftSlideIn = this.slideIn && (this.offCanvasLeft.parentNode === this.wrapper); | 
|                 //                this.offCanvasLeft.classList.remove(CLASS_TRANSITIONING); | 
|                 //                this.offCanvasLeft.classList.remove(CLASS_ACTIVE); | 
|                 //                this.offCanvasLeft.setAttribute('style', ''); | 
|             } | 
|             this.backdrop = this.scroller.querySelector('.' + CLASS_ACTION_BACKDROP); | 
|   | 
|             this.options.dragThresholdX = this.options.dragThresholdX || 10; | 
|   | 
|             this.visible = false; | 
|             this.startX = null; | 
|             this.lastX = null; | 
|             this.offsetX = null; | 
|             this.lastTranslateX = null; | 
|         }, | 
|         handleEvent: function(e) { | 
|             switch (e.type) { | 
|                 case $.EVENT_START: | 
|                     e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault(); | 
|                     break; | 
|                 case 'webkitTransitionEnd': //有个bug需要处理,需要考虑假设没有触发webkitTransitionEnd的情况 | 
|                     if (e.target === this.scroller) { | 
|                         this._dispatchEvent(); | 
|                     } | 
|                     break; | 
|                 case 'drag': | 
|                     var detail = e.detail; | 
|                     if (!this.startX) { | 
|                         this.startX = detail.center.x; | 
|                         this.lastX = this.startX; | 
|                     } else { | 
|                         this.lastX = detail.center.x; | 
|                     } | 
|                     if (!this.isDragging && Math.abs(this.lastX - this.startX) > this.options.dragThresholdX && (detail.direction === 'left' || (detail.direction === 'right'))) { | 
|                         if (this.slideIn) { | 
|                             this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP); | 
|                             if (this.classList.contains(CLASS_ACTIVE)) { | 
|                                 if (this.offCanvasRight && this.offCanvasRight.classList.contains(CLASS_ACTIVE)) { | 
|                                     this.offCanvas = this.offCanvasRight; | 
|                                     this.offCanvasWidth = this.offCanvasRightWidth; | 
|                                 } else { | 
|                                     this.offCanvas = this.offCanvasLeft; | 
|                                     this.offCanvasWidth = this.offCanvasLeftWidth; | 
|                                 } | 
|                             } else { | 
|                                 if (detail.direction === 'left' && this.offCanvasRight) { | 
|                                     this.offCanvas = this.offCanvasRight; | 
|                                     this.offCanvasWidth = this.offCanvasRightWidth; | 
|                                 } else if (detail.direction === 'right' && this.offCanvasLeft) { | 
|                                     this.offCanvas = this.offCanvasLeft; | 
|                                     this.offCanvasWidth = this.offCanvasLeftWidth; | 
|                                 } else { | 
|                                     this.scroller = null; | 
|                                 } | 
|                             } | 
|                         } else { | 
|                             if (this.classList.contains(CLASS_ACTIVE)) { | 
|                                 if (detail.direction === 'left') { | 
|                                     this.offCanvas = this.offCanvasLeft; | 
|                                     this.offCanvasWidth = this.offCanvasLeftWidth; | 
|                                 } else { | 
|                                     this.offCanvas = this.offCanvasRight; | 
|                                     this.offCanvasWidth = this.offCanvasRightWidth; | 
|                                 } | 
|                             } else { | 
|                                 if (detail.direction === 'right') { | 
|                                     this.offCanvas = this.offCanvasLeft; | 
|                                     this.offCanvasWidth = this.offCanvasLeftWidth; | 
|                                 } else { | 
|                                     this.offCanvas = this.offCanvasRight; | 
|                                     this.offCanvasWidth = this.offCanvasRightWidth; | 
|                                 } | 
|                             } | 
|                         } | 
|                         if (this.offCanvas && this.scroller) { | 
|                             this.startX = this.lastX; | 
|                             this.isDragging = true; | 
|   | 
|                             $.gestures.session.lockDirection = true; //锁定方向 | 
|                             $.gestures.session.startDirection = detail.direction; | 
|   | 
|                             this.offCanvas.classList.remove(CLASS_TRANSITIONING); | 
|                             this.scroller.classList.remove(CLASS_TRANSITIONING); | 
|                             this.offsetX = this.getTranslateX(); | 
|                             this._initOffCanvasVisible(); | 
|                         } | 
|                     } | 
|                     if (this.isDragging) { | 
|                         this.updateTranslate(this.offsetX + (this.lastX - this.startX)); | 
|                         detail.gesture.preventDefault(); | 
|                         e.stopPropagation(); | 
|                     } | 
|                     break; | 
|                 case 'dragend': | 
|                     if (this.isDragging) { | 
|                         var detail = e.detail; | 
|                         var direction = detail.direction; | 
|                         this.isDragging = false; | 
|                         this.offCanvas.classList.add(CLASS_TRANSITIONING); | 
|                         this.scroller.classList.add(CLASS_TRANSITIONING); | 
|                         var ratio = 0; | 
|                         var x = this.getTranslateX(); | 
|                         if (!this.slideIn) { | 
|                             if (x >= 0) { | 
|                                 ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0; | 
|                             } else { | 
|                                 ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0; | 
|                             } | 
|                             if (ratio === 0) { | 
|                                 this.openPercentage(0); | 
|                                 this._dispatchEvent(); //此处不触发webkitTransitionEnd,所以手动dispatch | 
|                                 return; | 
|                             } | 
|                             if (direction === 'right' && ratio >= 0 && (ratio >= 0.5 || detail.swipe)) { //右滑打开 | 
|                                 this.openPercentage(100); | 
|                             } else if (direction === 'right' && ratio < 0 && (ratio > -0.5 || detail.swipe)) { //右滑关闭 | 
|                                 this.openPercentage(0); | 
|                             } else if (direction === 'right' && ratio > 0 && ratio < 0.5) { //右滑还原关闭 | 
|                                 this.openPercentage(0); | 
|                             } else if (direction === 'right' && ratio < 0.5) { //右滑还原打开 | 
|                                 this.openPercentage(-100); | 
|                             } else if (direction === 'left' && ratio <= 0 && (ratio <= -0.5 || detail.swipe)) { //左滑打开 | 
|                                 this.openPercentage(-100); | 
|                             } else if (direction === 'left' && ratio > 0 && (ratio <= 0.5 || detail.swipe)) { //左滑关闭 | 
|                                 this.openPercentage(0); | 
|                             } else if (direction === 'left' && ratio < 0 && ratio >= -0.5) { //左滑还原关闭 | 
|                                 this.openPercentage(0); | 
|                             } else if (direction === 'left' && ratio > 0.5) { //左滑还原打开 | 
|                                 this.openPercentage(100); | 
|                             } else { //默认关闭 | 
|                                 this.openPercentage(0); | 
|                             } | 
|                             if (ratio === 1 || ratio === -1) { //此处不触发webkitTransitionEnd,所以手动dispatch | 
|                                 this._dispatchEvent(); | 
|                             } | 
|                         } else { | 
|                             if (x >= 0) { | 
|                                 ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0; | 
|                             } else { | 
|                                 ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0; | 
|                             } | 
|                             if (direction === 'right' && ratio <= 0 && (ratio >= -0.5 || detail.swipe)) { //右滑打开 | 
|                                 this.openPercentage(100); | 
|                             } else if (direction === 'right' && ratio > 0 && (ratio >= 0.5 || detail.swipe)) { //右滑关闭 | 
|                                 this.openPercentage(0); | 
|                             } else if (direction === 'right' && ratio <= -0.5) { //右滑还原关闭 | 
|                                 this.openPercentage(0); | 
|                             } else if (direction === 'right' && ratio > 0 && ratio <= 0.5) { //右滑还原打开 | 
|                                 this.openPercentage(-100); | 
|                             } else if (direction === 'left' && ratio >= 0 && (ratio <= 0.5 || detail.swipe)) { //左滑打开 | 
|                                 this.openPercentage(-100); | 
|                             } else if (direction === 'left' && ratio < 0 && (ratio <= -0.5 || detail.swipe)) { //左滑关闭 | 
|                                 this.openPercentage(0); | 
|                             } else if (direction === 'left' && ratio >= 0.5) { //左滑还原关闭 | 
|                                 this.openPercentage(0); | 
|                             } else if (direction === 'left' && ratio >= -0.5 && ratio < 0) { //左滑还原打开 | 
|                                 this.openPercentage(100); | 
|                             } else { | 
|                                 this.openPercentage(0); | 
|                             } | 
|                             if (ratio === 1 || ratio === -1 || ratio === 0) { | 
|                                 this._dispatchEvent(); | 
|                                 return; | 
|                             } | 
|   | 
|                         } | 
|                     } | 
|                     break; | 
|             } | 
|         }, | 
|         _dispatchEvent: function() { | 
|             if (this.classList.contains(CLASS_ACTIVE)) { | 
|                 $.trigger(this.wrapper, 'shown', this); | 
|             } else { | 
|                 $.trigger(this.wrapper, 'hidden', this); | 
|             } | 
|         }, | 
|         _initOffCanvasVisible: function() { | 
|             if (!this.visible) { | 
|                 this.visible = true; | 
|                 if (this.offCanvasLeft) { | 
|                     this.offCanvasLeft.style.visibility = 'visible'; | 
|                 } | 
|                 if (this.offCanvasRight) { | 
|                     this.offCanvasRight.style.visibility = 'visible'; | 
|                 } | 
|             } | 
|         }, | 
|         initEvent: function() { | 
|             var self = this; | 
|             if (self.backdrop) { | 
|                 self.backdrop.addEventListener('tap', function(e) { | 
|                     self.close(); | 
|                     e.detail.gesture.preventDefault(); | 
|                 }); | 
|             } | 
|             if (this.classList.contains('mui-draggable')) { | 
|                 this.wrapper.addEventListener($.EVENT_START, this); //临时处理 | 
|                 this.wrapper.addEventListener('drag', this); | 
|                 this.wrapper.addEventListener('dragend', this); | 
|             } | 
|             this.wrapper.addEventListener('webkitTransitionEnd', this); | 
|         }, | 
|         openPercentage: function(percentage) { | 
|             var p = percentage / 100; | 
|             if (!this.slideIn) { | 
|                 if (this.offCanvasLeft && percentage >= 0) { | 
|                     this.updateTranslate(this.offCanvasLeftWidth * p); | 
|                     this.offCanvasLeft.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); | 
|                 } else if (this.offCanvasRight && percentage <= 0) { | 
|                     this.updateTranslate(this.offCanvasRightWidth * p); | 
|                     this.offCanvasRight.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); | 
|                 } | 
|                 this.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); | 
|             } else { | 
|                 if (this.offCanvasLeft && percentage >= 0) { | 
|                     p = p === 0 ? -1 : 0; | 
|                     this.updateTranslate(this.offCanvasLeftWidth * p); | 
|                     this.offCanvasLeft.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); | 
|                 } else if (this.offCanvasRight && percentage <= 0) { | 
|                     p = p === 0 ? 1 : 0; | 
|                     this.updateTranslate(this.offCanvasRightWidth * p); | 
|                     this.offCanvasRight.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); | 
|                 } | 
|                 this.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); | 
|             } | 
|         }, | 
|         updateTranslate: function(x) { | 
|             if (x !== this.lastTranslateX) { | 
|                 if (!this.slideIn) { | 
|                     if ((!this.offCanvasLeft && x > 0) || (!this.offCanvasRight && x < 0)) { | 
|                         this.setTranslateX(0); | 
|                         return; | 
|                     } | 
|                     if (this.leftShowing && x > this.offCanvasLeftWidth) { | 
|                         this.setTranslateX(this.offCanvasLeftWidth); | 
|                         return; | 
|                     } | 
|                     if (this.rightShowing && x < -this.offCanvasRightWidth) { | 
|                         this.setTranslateX(-this.offCanvasRightWidth); | 
|                         return; | 
|                     } | 
|                     this.setTranslateX(x); | 
|                     if (x >= 0) { | 
|                         this.leftShowing = true; | 
|                         this.rightShowing = false; | 
|                         if (x > 0) { | 
|                             if (this.offCanvasLeft) { | 
|                                 $.each(this.offCanvasLefts, function(index, offCanvas) { | 
|                                     if (offCanvas === this.offCanvasLeft) { | 
|                                         this.offCanvasLeft.style.zIndex = 0; | 
|                                     } else { | 
|                                         offCanvas.style.zIndex = -1; | 
|                                     } | 
|                                 }.bind(this)); | 
|                             } | 
|                             if (this.offCanvasRight) { | 
|                                 this.offCanvasRight.style.zIndex = -1; | 
|                             } | 
|                         } | 
|                     } else { | 
|                         this.rightShowing = true; | 
|                         this.leftShowing = false; | 
|                         if (this.offCanvasRight) { | 
|                             $.each(this.offCanvasRights, function(index, offCanvas) { | 
|                                 if (offCanvas === this.offCanvasRight) { | 
|                                     offCanvas.style.zIndex = 0; | 
|                                 } else { | 
|                                     offCanvas.style.zIndex = -1; | 
|                                 } | 
|                             }.bind(this)); | 
|                         } | 
|                         if (this.offCanvasLeft) { | 
|                             this.offCanvasLeft.style.zIndex = -1; | 
|                         } | 
|                     } | 
|                 } else { | 
|                     if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) { | 
|                         if (x < 0) { | 
|                             this.setTranslateX(0); | 
|                             return; | 
|                         } | 
|                         if (x > this.offCanvasRightWidth) { | 
|                             this.setTranslateX(this.offCanvasRightWidth); | 
|                             return; | 
|                         } | 
|                     } else { | 
|                         if (x > 0) { | 
|                             this.setTranslateX(0); | 
|                             return; | 
|                         } | 
|                         if (x < -this.offCanvasLeftWidth) { | 
|                             this.setTranslateX(-this.offCanvasLeftWidth); | 
|                             return; | 
|                         } | 
|                     } | 
|                     this.setTranslateX(x); | 
|                 } | 
|                 this.lastTranslateX = x; | 
|             } | 
|         }, | 
|         setTranslateX: $.animationFrame(function(x) { | 
|             if (this.scroller) { | 
|                 if (this.scalable && this.offCanvas.parentNode === this.wrapper) { | 
|                     var percent = Math.abs(x) / this.offCanvasWidth; | 
|                     var zoomOutScale = 1 - (1 - this.options.scale) * percent; | 
|                     var zoomInScale = this.options.scale + (1 - this.options.scale) * percent; | 
|                     var zoomOutOpacity = 1 - (1 - this.options.opacity) * percent; | 
|                     var zoomInOpacity = this.options.opacity + (1 - this.options.opacity) * percent; | 
|                     if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) { | 
|                         this.offCanvas.style.webkitTransformOrigin = '-100%'; | 
|                         this.scroller.style.webkitTransformOrigin = 'left'; | 
|                     } else { | 
|                         this.offCanvas.style.webkitTransformOrigin = '200%'; | 
|                         this.scroller.style.webkitTransformOrigin = 'right'; | 
|                     } | 
|                     this.offCanvas.style.opacity = zoomInOpacity; | 
|                     this.offCanvas.style.webkitTransform = 'translate3d(0,0,0) scale(' + zoomInScale + ')'; | 
|                     this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0) scale(' + zoomOutScale + ')'; | 
|                 } else { | 
|                     if (this.slideIn) { | 
|                         this.offCanvas.style.webkitTransform = 'translate3d(' + x + 'px,0,0)'; | 
|                     } else { | 
|                         this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0)'; | 
|                     } | 
|                 } | 
|             } | 
|         }), | 
|         getTranslateX: function() { | 
|             if (this.offCanvas) { | 
|                 var scroller = this.slideIn ? this.offCanvas : this.scroller; | 
|                 var result = $.parseTranslateMatrix($.getStyles(scroller, 'webkitTransform')); | 
|                 return (result && result.x) || 0; | 
|             } | 
|             return 0; | 
|         }, | 
|         isShown: function(direction) { | 
|             var shown = false; | 
|             if (!this.slideIn) { | 
|                 var x = this.getTranslateX(); | 
|                 if (direction === 'right') { | 
|                     shown = this.classList.contains(CLASS_ACTIVE) && x < 0; | 
|                 } else if (direction === 'left') { | 
|                     shown = this.classList.contains(CLASS_ACTIVE) && x > 0; | 
|                 } else { | 
|                     shown = this.classList.contains(CLASS_ACTIVE) && x !== 0; | 
|                 } | 
|             } else { | 
|                 if (direction === 'left') { | 
|                     shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE); | 
|                 } else if (direction === 'right') { | 
|                     shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE); | 
|                 } else { | 
|                     shown = this.classList.contains(CLASS_ACTIVE) && (this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE)); | 
|                 } | 
|             } | 
|             return shown; | 
|         }, | 
|         close: function() { | 
|             this._initOffCanvasVisible(); | 
|             this.offCanvas = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE); | 
|             this.offCanvasWidth = this.offCanvas.offsetWidth; | 
|             if (this.scroller) { | 
|                 this.offCanvas.offsetHeight; | 
|                 this.offCanvas.classList.add(CLASS_TRANSITIONING); | 
|                 this.scroller.classList.add(CLASS_TRANSITIONING); | 
|                 this.openPercentage(0); | 
|             } | 
|         }, | 
|         show: function(direction) { | 
|             this._initOffCanvasVisible(); | 
|             if (this.isShown(direction)) { | 
|                 return false; | 
|             } | 
|             if (!direction) { | 
|                 direction = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT) ? 'right' : 'left'; | 
|             } | 
|             if (direction === 'right') { | 
|                 this.offCanvas = this.offCanvasRight; | 
|                 this.offCanvasWidth = this.offCanvasRightWidth; | 
|             } else { | 
|                 this.offCanvas = this.offCanvasLeft; | 
|                 this.offCanvasWidth = this.offCanvasLeftWidth; | 
|             } | 
|             if (this.scroller) { | 
|                 this.offCanvas.offsetHeight; | 
|                 this.offCanvas.classList.add(CLASS_TRANSITIONING); | 
|                 this.scroller.classList.add(CLASS_TRANSITIONING); | 
|                 this.openPercentage(direction === 'left' ? 100 : -100); | 
|             } | 
|             return true; | 
|         }, | 
|         toggle: function(directionOrOffCanvas) { | 
|             var direction = directionOrOffCanvas; | 
|             if (directionOrOffCanvas && directionOrOffCanvas.classList) { | 
|                 direction = directionOrOffCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT) ? 'left' : 'right'; | 
|                 this.refresh(directionOrOffCanvas); | 
|             } | 
|             if (!this.show(direction)) { | 
|                 this.close(); | 
|             } | 
|         } | 
|     }); | 
|   | 
|     //hash to offcanvas | 
|     var findOffCanvasContainer = function(target) { | 
|         parentNode = target.parentNode; | 
|         if (parentNode) { | 
|             if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) { | 
|                 return parentNode; | 
|             } else { | 
|                 parentNode = parentNode.parentNode; | 
|                 if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) { | 
|                     return parentNode; | 
|                 } | 
|             } | 
|         } | 
|     }; | 
|     var handle = function(event, target) { | 
|         if (target.tagName === 'A' && target.hash) { | 
|             var offcanvas = document.getElementById(target.hash.replace('#', '')); | 
|             if (offcanvas) { | 
|                 var container = findOffCanvasContainer(offcanvas); | 
|                 if (container) { | 
|                     $.targets._container = container; | 
|                     return offcanvas; | 
|                 } | 
|             } | 
|         } | 
|         return false; | 
|     }; | 
|   | 
|     $.registerTarget({ | 
|         name: name, | 
|         index: 60, | 
|         handle: handle, | 
|         target: false, | 
|         isReset: false, | 
|         isContinue: true | 
|     }); | 
|   | 
|     window.addEventListener('tap', function(e) { | 
|         if (!$.targets.offcanvas) { | 
|             return; | 
|         } | 
|         //TODO 此处类型的代码后续考虑统一优化(target机制),现在的实现费力不讨好 | 
|         var target = e.target; | 
|         for (; target && target !== document; target = target.parentNode) { | 
|             if (target.tagName === 'A' && target.hash && target.hash === ('#' + $.targets.offcanvas.id)) { | 
|                 e.detail && e.detail.gesture && e.detail.gesture.preventDefault(); //fixed hashchange | 
|                 $($.targets._container).offCanvas().toggle($.targets.offcanvas); | 
|                 $.targets.offcanvas = $.targets._container = null; | 
|                 break; | 
|             } | 
|         } | 
|     }); | 
|   | 
|     $.fn.offCanvas = function(options) { | 
|         var offCanvasApis = []; | 
|         this.each(function() { | 
|             var offCanvasApi = null; | 
|             var self = this; | 
|             //hack old version | 
|             if (!self.classList.contains(CLASS_OFF_CANVAS_WRAP)) { | 
|                 self = findOffCanvasContainer(self); | 
|             } | 
|             var id = self.getAttribute('data-offCanvas'); | 
|             if (!id) { | 
|                 id = ++$.uuid; | 
|                 $.data[id] = offCanvasApi = new OffCanvas(self, options); | 
|                 self.setAttribute('data-offCanvas', id); | 
|             } else { | 
|                 offCanvasApi = $.data[id]; | 
|             } | 
|             if (options === 'show' || options === 'close' || options === 'toggle') { | 
|                 offCanvasApi.toggle(); | 
|             } | 
|             offCanvasApis.push(offCanvasApi); | 
|         }); | 
|         return offCanvasApis.length === 1 ? offCanvasApis[0] : offCanvasApis; | 
|     }; | 
|     $.ready(function() { | 
|         $('.mui-off-canvas-wrap').offCanvas(); | 
|     }); | 
| })(mui, window, document, 'offcanvas'); | 
| /** | 
|  * actions | 
|  * @param {type} $ | 
|  * @param {type} name | 
|  * @returns {undefined} | 
|  */ | 
| (function($, name) { | 
|     var CLASS_ACTION = 'mui-action'; | 
|   | 
|     var handle = function(event, target) { | 
|         var className = target.className || ''; | 
|         if (typeof className !== 'string') { //svg className(SVGAnimatedString) | 
|             className = ''; | 
|         } | 
|         if (className && ~className.indexOf(CLASS_ACTION)) { | 
|             if (target.classList.contains('mui-action-back')) { | 
|                 event.preventDefault(); | 
|             } | 
|             return target; | 
|         } | 
|         return false; | 
|     }; | 
|   | 
|     $.registerTarget({ | 
|         name: name, | 
|         index: 50, | 
|         handle: handle, | 
|         target: false, | 
|         isContinue: true | 
|     }); | 
|   | 
| })(mui, 'action'); | 
| /** | 
|  * Modals | 
|  * @param {type} $ | 
|  * @param {type} window | 
|  * @param {type} document | 
|  * @param {type} name | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window, document, name) { | 
|     var CLASS_MODAL = 'mui-modal'; | 
|   | 
|     var handle = function(event, target) { | 
|         if (target.tagName === 'A' && target.hash) { | 
|             var modal = document.getElementById(target.hash.replace('#', '')); | 
|             if (modal && modal.classList.contains(CLASS_MODAL)) { | 
|                 return modal; | 
|             } | 
|         } | 
|         return false; | 
|     }; | 
|   | 
|     $.registerTarget({ | 
|         name: name, | 
|         index: 50, | 
|         handle: handle, | 
|         target: false, | 
|         isReset: false, | 
|         isContinue: true | 
|     }); | 
|   | 
|     window.addEventListener('tap', function(event) { | 
|         if ($.targets.modal) { | 
|             event.detail.gesture.preventDefault(); //fixed hashchange | 
|             $.targets.modal.classList.toggle('mui-active'); | 
|         } | 
|     }); | 
| })(mui, window, document, 'modal'); | 
| /** | 
|  * Popovers | 
|  * @param {type} $ | 
|  * @param {type} window | 
|  * @param {type} document | 
|  * @param {type} name | 
|  * @param {type} undefined | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window, document, name) { | 
|   | 
|     var CLASS_POPOVER = 'mui-popover'; | 
|     var CLASS_POPOVER_ARROW = 'mui-popover-arrow'; | 
|     var CLASS_ACTION_POPOVER = 'mui-popover-action'; | 
|     var CLASS_BACKDROP = 'mui-backdrop'; | 
|     var CLASS_BAR_POPOVER = 'mui-bar-popover'; | 
|     var CLASS_BAR_BACKDROP = 'mui-bar-backdrop'; | 
|     var CLASS_ACTION_BACKDROP = 'mui-backdrop-action'; | 
|     var CLASS_ACTIVE = 'mui-active'; | 
|     var CLASS_BOTTOM = 'mui-bottom'; | 
|   | 
|   | 
|   | 
|     var handle = function(event, target) { | 
|         if (target.tagName === 'A' && target.hash) { | 
|             $.targets._popover = document.getElementById(target.hash.replace('#', '')); | 
|             if ($.targets._popover && $.targets._popover.classList.contains(CLASS_POPOVER)) { | 
|                 return target; | 
|             } else { | 
|                 $.targets._popover = null; | 
|             } | 
|         } | 
|         return false; | 
|     }; | 
|   | 
|     $.registerTarget({ | 
|         name: name, | 
|         index: 60, | 
|         handle: handle, | 
|         target: false, | 
|         isReset: false, | 
|         isContinue: true | 
|     }); | 
|   | 
|     var onPopoverShown = function(e) { | 
|         this.removeEventListener('webkitTransitionEnd', onPopoverShown); | 
|         this.addEventListener($.EVENT_MOVE, $.preventDefault); | 
|         $.trigger(this, 'shown', this); | 
|     } | 
|     var onPopoverHidden = function(e) { | 
|         setStyle(this, 'none'); | 
|         this.removeEventListener('webkitTransitionEnd', onPopoverHidden); | 
|         this.removeEventListener($.EVENT_MOVE, $.preventDefault); | 
|         $.trigger(this, 'hidden', this); | 
|     }; | 
|   | 
|     var backdrop = (function() { | 
|         var element = document.createElement('div'); | 
|         element.classList.add(CLASS_BACKDROP); | 
|         element.addEventListener($.EVENT_MOVE, $.preventDefault); | 
|         element.addEventListener('tap', function(e) { | 
|             var popover = $.targets._popover; | 
|             if (popover) { | 
|                 popover.addEventListener('webkitTransitionEnd', onPopoverHidden); | 
|                 popover.classList.remove(CLASS_ACTIVE); | 
|                 removeBackdrop(popover); | 
|             } | 
|         }); | 
|   | 
|         return element; | 
|     }()); | 
|     var removeBackdropTimer; | 
|     var removeBackdrop = function(popover) { | 
|         backdrop.setAttribute('style', 'opacity:0'); | 
|         $.targets.popover = $.targets._popover = null; //reset | 
|         removeBackdropTimer = $.later(function() { | 
|             if (!popover.classList.contains(CLASS_ACTIVE) && backdrop.parentNode && backdrop.parentNode === document.body) { | 
|                 document.body.removeChild(backdrop); | 
|             } | 
|         }, 350); | 
|     }; | 
|     window.addEventListener('tap', function(e) { | 
|         if (!$.targets.popover) { | 
|             return; | 
|         } | 
|         var toggle = false; | 
|         var target = e.target; | 
|         for (; target && target !== document; target = target.parentNode) { | 
|             if (target === $.targets.popover) { | 
|                 toggle = true; | 
|             } | 
|         } | 
|         if (toggle) { | 
|             e.detail.gesture.preventDefault(); //fixed hashchange | 
|             togglePopover($.targets._popover, $.targets.popover); | 
|         } | 
|   | 
|     }); | 
|   | 
|     var togglePopover = function(popover, anchor, state) { | 
|         if ((state === 'show' && popover.classList.contains(CLASS_ACTIVE)) || (state === 'hide' && !popover.classList.contains(CLASS_ACTIVE))) { | 
|             return; | 
|         } | 
|         removeBackdropTimer && removeBackdropTimer.cancel(); //取消remove的timer | 
|         //remove一遍,以免来回快速切换,导致webkitTransitionEnd不触发,无法remove | 
|         popover.removeEventListener('webkitTransitionEnd', onPopoverShown); | 
|         popover.removeEventListener('webkitTransitionEnd', onPopoverHidden); | 
|         backdrop.classList.remove(CLASS_BAR_BACKDROP); | 
|         backdrop.classList.remove(CLASS_ACTION_BACKDROP); | 
|         var _popover = document.querySelector('.mui-popover.mui-active'); | 
|         if (_popover) { | 
|             //            _popover.setAttribute('style', ''); | 
|             _popover.addEventListener('webkitTransitionEnd', onPopoverHidden); | 
|             _popover.classList.remove(CLASS_ACTIVE); | 
|             //            _popover.removeEventListener('webkitTransitionEnd', onPopoverHidden); | 
|             //同一个弹出则直接返回,解决同一个popover的toggle | 
|             if (popover === _popover) { | 
|                 removeBackdrop(_popover); | 
|                 return; | 
|             } | 
|         } | 
|         var isActionSheet = false; | 
|         if (popover.classList.contains(CLASS_BAR_POPOVER) || popover.classList.contains(CLASS_ACTION_POPOVER)) { //navBar | 
|             if (popover.classList.contains(CLASS_ACTION_POPOVER)) { //action sheet popover | 
|                 isActionSheet = true; | 
|                 backdrop.classList.add(CLASS_ACTION_BACKDROP); | 
|             } else { //bar popover | 
|                 backdrop.classList.add(CLASS_BAR_BACKDROP); | 
|                 //                if (anchor) { | 
|                 //                    if (anchor.parentNode) { | 
|                 //                        var offsetWidth = anchor.offsetWidth; | 
|                 //                        var offsetLeft = anchor.offsetLeft; | 
|                 //                        var innerWidth = window.innerWidth; | 
|                 //                        popover.style.left = (Math.min(Math.max(offsetLeft, defaultPadding), innerWidth - offsetWidth - defaultPadding)) + "px"; | 
|                 //                    } else { | 
|                 //                        //TODO anchor is position:{left,top,bottom,right} | 
|                 //                    } | 
|                 //                } | 
|             } | 
|         } | 
|         setStyle(popover, 'block'); //actionsheet transform | 
|         popover.offsetHeight; | 
|         popover.classList.add(CLASS_ACTIVE); | 
|         backdrop.setAttribute('style', ''); | 
|         document.body.appendChild(backdrop); | 
|         calPosition(popover, anchor, isActionSheet); //position | 
|         backdrop.classList.add(CLASS_ACTIVE); | 
|         popover.addEventListener('webkitTransitionEnd', onPopoverShown); | 
|     }; | 
|     var setStyle = function(popover, display, top, left) { | 
|         var style = popover.style; | 
|         if (typeof display !== 'undefined') | 
|             style.display = display; | 
|         if (typeof top !== 'undefined') | 
|             style.top = top + 'px'; | 
|         if (typeof left !== 'undefined') | 
|             style.left = left + 'px'; | 
|     }; | 
|     var calPosition = function(popover, anchor, isActionSheet) { | 
|         if (!popover || !anchor) { | 
|             return; | 
|         } | 
|   | 
|         if (isActionSheet) { //actionsheet | 
|             setStyle(popover, 'block') | 
|             return; | 
|         } | 
|   | 
|         var wWidth = window.innerWidth; | 
|         var wHeight = window.innerHeight; | 
|   | 
|         var pWidth = popover.offsetWidth; | 
|         var pHeight = popover.offsetHeight; | 
|   | 
|         var aWidth = anchor.offsetWidth; | 
|         var aHeight = anchor.offsetHeight; | 
|         var offset = $.offset(anchor); | 
|   | 
|         var arrow = popover.querySelector('.' + CLASS_POPOVER_ARROW); | 
|         if (!arrow) { | 
|             arrow = document.createElement('div'); | 
|             arrow.className = CLASS_POPOVER_ARROW; | 
|             popover.appendChild(arrow); | 
|         } | 
|         var arrowSize = arrow && arrow.offsetWidth / 2 || 0; | 
|   | 
|   | 
|   | 
|         var pTop = 0; | 
|         var pLeft = 0; | 
|         var diff = 0; | 
|         var arrowLeft = 0; | 
|         var defaultPadding = popover.classList.contains(CLASS_ACTION_POPOVER) ? 0 : 5; | 
|   | 
|         var position = 'top'; | 
|         if ((pHeight + arrowSize) < (offset.top - window.pageYOffset)) { //top | 
|             pTop = offset.top - pHeight - arrowSize; | 
|         } else if ((pHeight + arrowSize) < (wHeight - (offset.top - window.pageYOffset) - aHeight)) { //bottom | 
|             position = 'bottom'; | 
|             pTop = offset.top + aHeight + arrowSize; | 
|         } else { //middle | 
|             position = 'middle'; | 
|             pTop = Math.max((wHeight - pHeight) / 2 + window.pageYOffset, 0); | 
|             pLeft = Math.max((wWidth - pWidth) / 2 + window.pageXOffset, 0); | 
|         } | 
|         if (position === 'top' || position === 'bottom') { | 
|             pLeft = aWidth / 2 + offset.left - pWidth / 2; | 
|             diff = pLeft; | 
|             if (pLeft < defaultPadding) pLeft = defaultPadding; | 
|             if (pLeft + pWidth > wWidth) pLeft = wWidth - pWidth - defaultPadding; | 
|   | 
|             if (arrow) { | 
|                 if (position === 'top') { | 
|                     arrow.classList.add(CLASS_BOTTOM); | 
|                 } else { | 
|                     arrow.classList.remove(CLASS_BOTTOM); | 
|                 } | 
|                 diff = diff - pLeft; | 
|                 arrowLeft = (pWidth / 2 - arrowSize / 2 + diff); | 
|                 arrowLeft = Math.max(Math.min(arrowLeft, pWidth - arrowSize * 2 - 6), 6); | 
|                 arrow.setAttribute('style', 'left:' + arrowLeft + 'px'); | 
|             } | 
|         } else if (position === 'middle') { | 
|             arrow.setAttribute('style', 'display:none'); | 
|         } | 
|         setStyle(popover, 'block', pTop, pLeft); | 
|     }; | 
|   | 
|     $.createMask = function(callback) { | 
|         var element = document.createElement('div'); | 
|         element.classList.add(CLASS_BACKDROP); | 
|         element.addEventListener($.EVENT_MOVE, $.preventDefault); | 
|         element.addEventListener('tap', function() { | 
|             mask.close(); | 
|         }); | 
|         var mask = [element]; | 
|         mask._show = false; | 
|         mask.show = function() { | 
|             mask._show = true; | 
|             element.setAttribute('style', 'opacity:1'); | 
|             document.body.appendChild(element); | 
|             return mask; | 
|         }; | 
|         mask._remove = function() { | 
|             if (mask._show) { | 
|                 mask._show = false; | 
|                 element.setAttribute('style', 'opacity:0'); | 
|                 $.later(function() { | 
|                     var body = document.body; | 
|                     element.parentNode === body && body.removeChild(element); | 
|                 }, 350); | 
|             } | 
|             return mask; | 
|         }; | 
|         mask.close = function() { | 
|             if (callback) { | 
|                 if (callback() !== false) { | 
|                     mask._remove(); | 
|                 } | 
|             } else { | 
|                 mask._remove(); | 
|             } | 
|         }; | 
|         return mask; | 
|     }; | 
|     $.fn.popover = function() { | 
|         var args = arguments; | 
|         this.each(function() { | 
|             $.targets._popover = this; | 
|             if (args[0] === 'show' || args[0] === 'hide' || args[0] === 'toggle') { | 
|                 togglePopover(this, args[1], args[0]); | 
|             } | 
|         }); | 
|     }; | 
|   | 
| })(mui, window, document, 'popover'); | 
| /** | 
|  * segmented-controllers | 
|  * @param {type} $ | 
|  * @param {type} window | 
|  * @param {type} document | 
|  * @param {type} undefined | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window, document, name, undefined) { | 
|   | 
|     var CLASS_CONTROL_ITEM = 'mui-control-item'; | 
|     var CLASS_SEGMENTED_CONTROL = 'mui-segmented-control'; | 
|     var CLASS_SEGMENTED_CONTROL_VERTICAL = 'mui-segmented-control-vertical'; | 
|     var CLASS_CONTROL_CONTENT = 'mui-control-content'; | 
|     var CLASS_TAB_BAR = 'mui-bar-tab'; | 
|     var CLASS_TAB_ITEM = 'mui-tab-item'; | 
|     var CLASS_SLIDER_ITEM = 'mui-slider-item'; | 
|   | 
|    var handle = function(event, target) { | 
|         if (target.classList && (target.classList.contains(CLASS_CONTROL_ITEM) || target.classList.contains(CLASS_TAB_ITEM))) { | 
|             if (target.parentNode && target.parentNode.classList && target.parentNode.classList.contains(CLASS_SEGMENTED_CONTROL_VERTICAL)) { | 
|                 //vertical 如果preventDefault会导致无法滚动 | 
|             } else { | 
|   | 
|                     event.preventDefault();       | 
|                     // if(target.tagName == 'A') { | 
|                     //     // fixed 底部选项卡href 无法跳转 && stop hash change | 
|                     //     var curr_href = location.hostname + location.pathname, | 
|                     //         target_href = target.hostname + target.pathname; | 
|                     | 
|                     //     if (curr_href == target_href && target.hash !== "") { | 
|                     //         event.preventDefault(); | 
|                     //         return target; | 
|                     //     }else{ | 
|                     //             return false | 
|                     //     } | 
|                     // } | 
|             } | 
|             //          if (target.hash) { | 
|             return target; | 
|             //          } | 
|         } | 
|         return false; | 
|     }; | 
|   | 
|     $.registerTarget({ | 
|         name: name, | 
|         index: 80, | 
|         handle: handle, | 
|         target: false | 
|     }); | 
|   | 
|     window.addEventListener('tap', function(e) { | 
|   | 
|         var targetTab = $.targets.tab; | 
|         if (!targetTab) { | 
|             return; | 
|         } | 
|         var activeTab; | 
|         var activeBodies; | 
|         var targetBody; | 
|         var className = 'mui-active'; | 
|         var classSelector = '.' + className; | 
|         var segmentedControl = targetTab.parentNode; | 
|   | 
|         for (; segmentedControl && segmentedControl !== document; segmentedControl = segmentedControl.parentNode) { | 
|             if (segmentedControl.classList.contains(CLASS_SEGMENTED_CONTROL)) { | 
|                 activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_CONTROL_ITEM); | 
|                 break; | 
|             } else if (segmentedControl.classList.contains(CLASS_TAB_BAR)) { | 
|                 activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_TAB_ITEM); | 
|             } | 
|         } | 
|   | 
|         if (activeTab) { | 
|             activeTab.classList.remove(className); | 
|         } | 
|   | 
|         var isLastActive = targetTab === activeTab; | 
|         if (targetTab) { | 
|             targetTab.classList.add(className); | 
|         } | 
|   | 
|         if (!targetTab.hash) { | 
|             return; | 
|         } | 
|         targetBody = document.getElementById(targetTab.hash.replace('#', '')); | 
|   | 
|         if (!targetBody) { | 
|             return; | 
|         } | 
|         if (!targetBody.classList.contains(CLASS_CONTROL_CONTENT)) { //tab bar popover | 
|             targetTab.classList[isLastActive ? 'remove' : 'add'](className); | 
|             return; | 
|         } | 
|         if (isLastActive) { //same | 
|             return; | 
|         } | 
|         var parentNode = targetBody.parentNode; | 
|         activeBodies = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT + classSelector); | 
|         for (var i = 0; i < activeBodies.length; i++) { | 
|             var activeBody = activeBodies[i]; | 
|             activeBody.parentNode === parentNode && activeBody.classList.remove(className); | 
|         } | 
|   | 
|         targetBody.classList.add(className); | 
|   | 
|         var contents = []; | 
|         var _contents = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT); | 
|         for (var i = 0; i < _contents.length; i++) { //查找直属子节点 | 
|             _contents[i].parentNode === parentNode && (contents.push(_contents[i])); | 
|         } | 
|         $.trigger(targetBody, $.eventName('shown', name), { | 
|             tabNumber: Array.prototype.indexOf.call(contents, targetBody) | 
|         }); | 
|         e.detail && e.detail.gesture.preventDefault(); //fixed hashchange | 
|     }); | 
|   | 
| })(mui, window, document, 'tab'); | 
| /** | 
|  * Toggles switch | 
|  * @param {type} $ | 
|  * @param {type} window | 
|  * @param {type} name | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window, name) { | 
|   | 
|     var CLASS_SWITCH = 'mui-switch'; | 
|     var CLASS_SWITCH_HANDLE = 'mui-switch-handle'; | 
|     var CLASS_ACTIVE = 'mui-active'; | 
|     var CLASS_DRAGGING = 'mui-dragging'; | 
|   | 
|     var CLASS_DISABLED = 'mui-disabled'; | 
|   | 
|     var SELECTOR_SWITCH_HANDLE = '.' + CLASS_SWITCH_HANDLE; | 
|   | 
|     var handle = function(event, target) { | 
|         if (target.classList && target.classList.contains(CLASS_SWITCH)) { | 
|             return target; | 
|         } | 
|         return false; | 
|     }; | 
|   | 
|     $.registerTarget({ | 
|         name: name, | 
|         index: 100, | 
|         handle: handle, | 
|         target: false | 
|     }); | 
|   | 
|   | 
|     var Toggle = function(element) { | 
|         this.element = element; | 
|         this.classList = this.element.classList; | 
|         this.handle = this.element.querySelector(SELECTOR_SWITCH_HANDLE); | 
|         this.init(); | 
|         this.initEvent(); | 
|     }; | 
|     Toggle.prototype.init = function() { | 
|         this.toggleWidth = this.element.offsetWidth; | 
|         this.handleWidth = this.handle.offsetWidth; | 
|         this.handleX = this.toggleWidth - this.handleWidth - 3; | 
|     }; | 
|     Toggle.prototype.initEvent = function() { | 
|         this.element.addEventListener($.EVENT_START, this); | 
|         this.element.addEventListener('drag', this); | 
|         this.element.addEventListener('swiperight', this); | 
|         this.element.addEventListener($.EVENT_END, this); | 
|         this.element.addEventListener($.EVENT_CANCEL, this); | 
|   | 
|     }; | 
|     Toggle.prototype.handleEvent = function(e) { | 
|         if (this.classList.contains(CLASS_DISABLED)) { | 
|             return; | 
|         } | 
|         switch (e.type) { | 
|             case $.EVENT_START: | 
|                 this.start(e); | 
|                 break; | 
|             case 'drag': | 
|                 this.drag(e); | 
|                 break; | 
|             case 'swiperight': | 
|                 this.swiperight(); | 
|                 break; | 
|             case $.EVENT_END: | 
|             case $.EVENT_CANCEL: | 
|                 this.end(e); | 
|                 break; | 
|         } | 
|     }; | 
|     Toggle.prototype.start = function(e) { | 
|         this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s'; | 
|         this.classList.add(CLASS_DRAGGING); | 
|         if (this.toggleWidth === 0 || this.handleWidth === 0) { //当switch处于隐藏状态时,width为0,需要重新初始化 | 
|             this.init(); | 
|         } | 
|     }; | 
|     Toggle.prototype.drag = function(e) { | 
|         var detail = e.detail; | 
|         if (!this.isDragging) { | 
|             if (detail.direction === 'left' || detail.direction === 'right') { | 
|                 this.isDragging = true; | 
|                 this.lastChanged = undefined; | 
|                 this.initialState = this.classList.contains(CLASS_ACTIVE); | 
|             } | 
|         } | 
|         if (this.isDragging) { | 
|             this.setTranslateX(detail.deltaX); | 
|             e.stopPropagation(); | 
|             detail.gesture.preventDefault(); | 
|         } | 
|     }; | 
|     Toggle.prototype.swiperight = function(e) { | 
|         if (this.isDragging) { | 
|             e.stopPropagation(); | 
|         } | 
|     }; | 
|     Toggle.prototype.end = function(e) { | 
|         this.classList.remove(CLASS_DRAGGING); | 
|         if (this.isDragging) { | 
|             this.isDragging = false; | 
|             e.stopPropagation(); | 
|             $.trigger(this.element, 'toggle', { | 
|                 isActive: this.classList.contains(CLASS_ACTIVE) | 
|             }); | 
|         } else { | 
|             this.toggle(); | 
|         } | 
|     }; | 
|     Toggle.prototype.toggle = function(animate) { | 
|         var classList = this.classList; | 
|         if (animate === false) { | 
|             this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '0s'; | 
|         } else { | 
|             this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s'; | 
|         } | 
|         if (classList.contains(CLASS_ACTIVE)) { | 
|             classList.remove(CLASS_ACTIVE); | 
|             this.handle.style.webkitTransform = 'translate(0,0)'; | 
|         } else { | 
|             classList.add(CLASS_ACTIVE); | 
|             this.handle.style.webkitTransform = 'translate(' + this.handleX + 'px,0)'; | 
|         } | 
|         $.trigger(this.element, 'toggle', { | 
|             isActive: this.classList.contains(CLASS_ACTIVE) | 
|         }); | 
|     }; | 
|     Toggle.prototype.setTranslateX = $.animationFrame(function(x) { | 
|         if (!this.isDragging) { | 
|             return; | 
|         } | 
|         var isChanged = false; | 
|         if ((this.initialState && -x > (this.handleX / 2)) || (!this.initialState && x > (this.handleX / 2))) { | 
|             isChanged = true; | 
|         } | 
|         if (this.lastChanged !== isChanged) { | 
|             if (isChanged) { | 
|                 this.handle.style.webkitTransform = 'translate(' + (this.initialState ? 0 : this.handleX) + 'px,0)'; | 
|                 this.classList[this.initialState ? 'remove' : 'add'](CLASS_ACTIVE); | 
|             } else { | 
|                 this.handle.style.webkitTransform = 'translate(' + (this.initialState ? this.handleX : 0) + 'px,0)'; | 
|                 this.classList[this.initialState ? 'add' : 'remove'](CLASS_ACTIVE); | 
|             } | 
|             this.lastChanged = isChanged; | 
|         } | 
|   | 
|     }); | 
|   | 
|     $.fn['switch'] = function(options) { | 
|         var switchApis = []; | 
|         this.each(function() { | 
|             var switchApi = null; | 
|             var id = this.getAttribute('data-switch'); | 
|             if (!id) { | 
|                 id = ++$.uuid; | 
|                 $.data[id] = new Toggle(this); | 
|                 this.setAttribute('data-switch', id); | 
|             } else { | 
|                 switchApi = $.data[id]; | 
|             } | 
|             switchApis.push(switchApi); | 
|         }); | 
|         return switchApis.length > 1 ? switchApis : switchApis[0]; | 
|     }; | 
|     $.ready(function() { | 
|         $('.' + CLASS_SWITCH)['switch'](); | 
|     }); | 
| })(mui, window, 'toggle'); | 
| /** | 
|  * Tableviews | 
|  * @param {type} $ | 
|  * @param {type} window | 
|  * @param {type} document | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window, document) { | 
|   | 
|     var CLASS_ACTIVE = 'mui-active'; | 
|     var CLASS_SELECTED = 'mui-selected'; | 
|     var CLASS_GRID_VIEW = 'mui-grid-view'; | 
|     var CLASS_RADIO_VIEW = 'mui-table-view-radio'; | 
|     var CLASS_TABLE_VIEW_CELL = 'mui-table-view-cell'; | 
|     var CLASS_COLLAPSE_CONTENT = 'mui-collapse-content'; | 
|     var CLASS_DISABLED = 'mui-disabled'; | 
|     var CLASS_TOGGLE = 'mui-switch'; | 
|     var CLASS_BTN = 'mui-btn'; | 
|   | 
|     var CLASS_SLIDER_HANDLE = 'mui-slider-handle'; | 
|     var CLASS_SLIDER_LEFT = 'mui-slider-left'; | 
|     var CLASS_SLIDER_RIGHT = 'mui-slider-right'; | 
|     var CLASS_TRANSITIONING = 'mui-transitioning'; | 
|   | 
|   | 
|     var SELECTOR_SLIDER_HANDLE = '.' + CLASS_SLIDER_HANDLE; | 
|     var SELECTOR_SLIDER_LEFT = '.' + CLASS_SLIDER_LEFT; | 
|     var SELECTOR_SLIDER_RIGHT = '.' + CLASS_SLIDER_RIGHT; | 
|     var SELECTOR_SELECTED = '.' + CLASS_SELECTED; | 
|     var SELECTOR_BUTTON = '.' + CLASS_BTN; | 
|     var overFactor = 0.8; | 
|     var cell, a; | 
|   | 
|     var isMoved = isOpened = openedActions = progress = false; | 
|     var sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false; | 
|     var timer = translateX = lastTranslateX = sliderActionLeftWidth = sliderActionRightWidth = 0; | 
|   | 
|   | 
|   | 
|     var toggleActive = function(isActive) { | 
|         if (isActive) { | 
|             if (a) { | 
|                 a.classList.add(CLASS_ACTIVE); | 
|             } else if (cell) { | 
|                 cell.classList.add(CLASS_ACTIVE); | 
|             } | 
|         } else { | 
|             timer && timer.cancel(); | 
|             if (a) { | 
|                 a.classList.remove(CLASS_ACTIVE); | 
|             } else if (cell) { | 
|                 cell.classList.remove(CLASS_ACTIVE); | 
|             } | 
|         } | 
|     }; | 
|   | 
|     var updateTranslate = function() { | 
|         if (translateX !== lastTranslateX) { | 
|             if (buttonsRight && buttonsRight.length > 0) { | 
|                 progress = translateX / sliderActionRightWidth; | 
|                 if (translateX < -sliderActionRightWidth) { | 
|                     translateX = -sliderActionRightWidth - Math.pow(-translateX - sliderActionRightWidth, overFactor); | 
|                 } | 
|                 for (var i = 0, len = buttonsRight.length; i < len; i++) { | 
|                     var buttonRight = buttonsRight[i]; | 
|                     if (typeof buttonRight._buttonOffset === 'undefined') { | 
|                         buttonRight._buttonOffset = buttonRight.offsetLeft; | 
|                     } | 
|                     buttonOffset = buttonRight._buttonOffset; | 
|                     setTranslate(buttonRight, (translateX - buttonOffset * (1 + Math.max(progress, -1)))); | 
|                 } | 
|             } | 
|             if (buttonsLeft && buttonsLeft.length > 0) { | 
|                 progress = translateX / sliderActionLeftWidth; | 
|                 if (translateX > sliderActionLeftWidth) { | 
|                     translateX = sliderActionLeftWidth + Math.pow(translateX - sliderActionLeftWidth, overFactor); | 
|                 } | 
|                 for (var i = 0, len = buttonsLeft.length; i < len; i++) { | 
|                     var buttonLeft = buttonsLeft[i]; | 
|                     if (typeof buttonLeft._buttonOffset === 'undefined') { | 
|                         buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth; | 
|                     } | 
|                     buttonOffset = buttonLeft._buttonOffset; | 
|                     if (buttonsLeft.length > 1) { | 
|                         buttonLeft.style.zIndex = buttonsLeft.length - i; | 
|                     } | 
|                     setTranslate(buttonLeft, (translateX + buttonOffset * (1 - Math.min(progress, 1)))); | 
|                 } | 
|             } | 
|             setTranslate(sliderHandle, translateX); | 
|             lastTranslateX = translateX; | 
|         } | 
|         sliderRequestAnimationFrame = requestAnimationFrame(function() { | 
|             updateTranslate(); | 
|         }); | 
|     }; | 
|     var setTranslate = function(element, x) { | 
|         if (element) { | 
|             element.style.webkitTransform = 'translate(' + x + 'px,0)'; | 
|         } | 
|     }; | 
|   | 
|     window.addEventListener($.EVENT_START, function(event) { | 
|         if (cell) { | 
|             toggleActive(false); | 
|         } | 
|         cell = a = false; | 
|         isMoved = isOpened = openedActions = false; | 
|         var target = event.target; | 
|         var isDisabled = false; | 
|         for (; target && target !== document; target = target.parentNode) { | 
|             if (target.classList) { | 
|                 var classList = target.classList; | 
|                 if ((target.tagName === 'INPUT' && target.type !== 'radio' && target.type !== 'checkbox') || target.tagName === 'BUTTON' || classList.contains(CLASS_TOGGLE) || classList.contains(CLASS_BTN) || classList.contains(CLASS_DISABLED)) { | 
|                     isDisabled = true; | 
|                 } | 
|                 if (classList.contains(CLASS_COLLAPSE_CONTENT)) { //collapse content | 
|                     break; | 
|                 } | 
|                 if (classList.contains(CLASS_TABLE_VIEW_CELL)) { | 
|                     cell = target; | 
|                     //TODO swipe to delete close | 
|                     var selected = cell.parentNode.querySelector(SELECTOR_SELECTED); | 
|                     if (!cell.parentNode.classList.contains(CLASS_RADIO_VIEW) && selected && selected !== cell) { | 
|                         $.swipeoutClose(selected); | 
|                         cell = isDisabled = false; | 
|                         return; | 
|                     } | 
|                     if (!cell.parentNode.classList.contains(CLASS_GRID_VIEW)) { | 
|                         var link = cell.querySelector('a'); | 
|                         if (link && link.parentNode === cell) { //li>a | 
|                             a = link; | 
|                         } | 
|                     } | 
|                     var handle = cell.querySelector(SELECTOR_SLIDER_HANDLE); | 
|                     if (handle) { | 
|                         toggleEvents(cell); | 
|                         event.stopPropagation(); | 
|                     } | 
|                     if (!isDisabled) { | 
|                         if (handle) { | 
|                             if (timer) { | 
|                                 timer.cancel(); | 
|                             } | 
|                             timer = $.later(function() { | 
|                                 toggleActive(true); | 
|                             }, 100); | 
|                         } else { | 
|                             toggleActive(true); | 
|                         } | 
|                     } | 
|                     break; | 
|                 } | 
|             } | 
|         } | 
|     }); | 
|     window.addEventListener($.EVENT_MOVE, function(event) { | 
|         toggleActive(false); | 
|     }); | 
|   | 
|     var handleEvent = { | 
|         handleEvent: function(event) { | 
|             switch (event.type) { | 
|                 case 'drag': | 
|                     this.drag(event); | 
|                     break; | 
|                 case 'dragend': | 
|                     this.dragend(event); | 
|                     break; | 
|                 case 'flick': | 
|                     this.flick(event); | 
|                     break; | 
|                 case 'swiperight': | 
|                     this.swiperight(event); | 
|                     break; | 
|                 case 'swipeleft': | 
|                     this.swipeleft(event); | 
|                     break; | 
|             } | 
|         }, | 
|         drag: function(event) { | 
|             if (!cell) { | 
|                 return; | 
|             } | 
|             if (!isMoved) { //init | 
|                 sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false; | 
|                 sliderHandle = cell.querySelector(SELECTOR_SLIDER_HANDLE); | 
|                 if (sliderHandle) { | 
|                     sliderActionLeft = cell.querySelector(SELECTOR_SLIDER_LEFT); | 
|                     sliderActionRight = cell.querySelector(SELECTOR_SLIDER_RIGHT); | 
|                     if (sliderActionLeft) { | 
|                         sliderActionLeftWidth = sliderActionLeft.offsetWidth; | 
|                         buttonsLeft = sliderActionLeft.querySelectorAll(SELECTOR_BUTTON); | 
|                     } | 
|                     if (sliderActionRight) { | 
|                         sliderActionRightWidth = sliderActionRight.offsetWidth; | 
|                         buttonsRight = sliderActionRight.querySelectorAll(SELECTOR_BUTTON); | 
|                     } | 
|                     cell.classList.remove(CLASS_TRANSITIONING); | 
|                     isOpened = cell.classList.contains(CLASS_SELECTED); | 
|                     if (isOpened) { | 
|                         openedActions = cell.querySelector(SELECTOR_SLIDER_LEFT + SELECTOR_SELECTED) ? 'left' : 'right'; | 
|                     } | 
|                 } | 
|             } | 
|             var detail = event.detail; | 
|             var direction = detail.direction; | 
|             var angle = detail.angle; | 
|             if (direction === 'left' && (angle > 150 || angle < -150)) { | 
|                 if (buttonsRight || (buttonsLeft && isOpened)) { //存在右侧按钮或存在左侧按钮且是已打开状态 | 
|                     isMoved = true; | 
|                 } | 
|             } else if (direction === 'right' && (angle > -30 && angle < 30)) { | 
|                 if (buttonsLeft || (buttonsRight && isOpened)) { //存在左侧按钮或存在右侧按钮且是已打开状态 | 
|                     isMoved = true; | 
|                 } | 
|             } | 
|             if (isMoved) { | 
|                 event.stopPropagation(); | 
|                 event.detail.gesture.preventDefault(); | 
|                 var translate = event.detail.deltaX; | 
|                 if (isOpened) { | 
|                     if (openedActions === 'right') { | 
|                         translate = translate - sliderActionRightWidth; | 
|                     } else { | 
|                         translate = translate + sliderActionLeftWidth; | 
|                     } | 
|                 } | 
|                 if ((translate > 0 && !buttonsLeft) || (translate < 0 && !buttonsRight)) { | 
|                     if (!isOpened) { | 
|                         return; | 
|                     } | 
|                     translate = 0; | 
|                 } | 
|                 if (translate < 0) { | 
|                     sliderDirection = 'toLeft'; | 
|                 } else if (translate > 0) { | 
|                     sliderDirection = 'toRight'; | 
|                 } else { | 
|                     if (!sliderDirection) { | 
|                         sliderDirection = 'toLeft'; | 
|                     } | 
|                 } | 
|                 if (!sliderRequestAnimationFrame) { | 
|                     updateTranslate(); | 
|                 } | 
|                 translateX = translate; | 
|             } | 
|         }, | 
|         flick: function(event) { | 
|             if (isMoved) { | 
|                 event.stopPropagation(); | 
|             } | 
|         }, | 
|         swipeleft: function(event) { | 
|             if (isMoved) { | 
|                 event.stopPropagation(); | 
|             } | 
|         }, | 
|         swiperight: function(event) { | 
|             if (isMoved) { | 
|                 event.stopPropagation(); | 
|             } | 
|         }, | 
|         dragend: function(event) { | 
|             if (!isMoved) { | 
|                 return; | 
|             } | 
|             event.stopPropagation(); | 
|             if (sliderRequestAnimationFrame) { | 
|                 cancelAnimationFrame(sliderRequestAnimationFrame); | 
|                 sliderRequestAnimationFrame = null; | 
|             } | 
|             var detail = event.detail; | 
|             isMoved = false; | 
|             var action = 'close'; | 
|             var actionsWidth = sliderDirection === 'toLeft' ? sliderActionRightWidth : sliderActionLeftWidth; | 
|             var isToggle = detail.swipe || (Math.abs(translateX) > actionsWidth / 2); | 
|             if (isToggle) { | 
|                 if (!isOpened) { | 
|                     action = 'open'; | 
|                 } else if (detail.direction === 'left' && openedActions === 'right') { | 
|                     action = 'open'; | 
|                 } else if (detail.direction === 'right' && openedActions === 'left') { | 
|                     action = 'open'; | 
|                 } | 
|   | 
|             } | 
|             cell.classList.add(CLASS_TRANSITIONING); | 
|             var buttons; | 
|             if (action === 'open') { | 
|                 var newTranslate = sliderDirection === 'toLeft' ? -actionsWidth : actionsWidth; | 
|                 setTranslate(sliderHandle, newTranslate); | 
|                 buttons = sliderDirection === 'toLeft' ? buttonsRight : buttonsLeft; | 
|                 if (typeof buttons !== 'undefined') { | 
|                     var button = null; | 
|                     for (var i = 0; i < buttons.length; i++) { | 
|                         button = buttons[i]; | 
|                         setTranslate(button, newTranslate); | 
|                     } | 
|                     button.parentNode.classList.add(CLASS_SELECTED); | 
|                     cell.classList.add(CLASS_SELECTED); | 
|                     if (!isOpened) { | 
|                         $.trigger(cell, sliderDirection === 'toLeft' ? 'slideleft' : 'slideright'); | 
|                     } | 
|                 } | 
|             } else { | 
|                 setTranslate(sliderHandle, 0); | 
|                 sliderActionLeft && sliderActionLeft.classList.remove(CLASS_SELECTED); | 
|                 sliderActionRight && sliderActionRight.classList.remove(CLASS_SELECTED); | 
|                 cell.classList.remove(CLASS_SELECTED); | 
|             } | 
|             var buttonOffset; | 
|             if (buttonsLeft && buttonsLeft.length > 0 && buttonsLeft !== buttons) { | 
|                 for (var i = 0, len = buttonsLeft.length; i < len; i++) { | 
|                     var buttonLeft = buttonsLeft[i]; | 
|                     buttonOffset = buttonLeft._buttonOffset; | 
|                     if (typeof buttonOffset === 'undefined') { | 
|                         buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth; | 
|                     } | 
|                     setTranslate(buttonLeft, buttonOffset); | 
|                 } | 
|             } | 
|             if (buttonsRight && buttonsRight.length > 0 && buttonsRight !== buttons) { | 
|                 for (var i = 0, len = buttonsRight.length; i < len; i++) { | 
|                     var buttonRight = buttonsRight[i]; | 
|                     buttonOffset = buttonRight._buttonOffset; | 
|                     if (typeof buttonOffset === 'undefined') { | 
|                         buttonRight._buttonOffset = buttonRight.offsetLeft; | 
|                     } | 
|                     setTranslate(buttonRight, -buttonOffset); | 
|                 } | 
|             } | 
|         } | 
|     }; | 
|   | 
|     function toggleEvents(element, isRemove) { | 
|         var method = !!isRemove ? 'removeEventListener' : 'addEventListener'; | 
|         element[method]('drag', handleEvent); | 
|         element[method]('dragend', handleEvent); | 
|         element[method]('swiperight', handleEvent); | 
|         element[method]('swipeleft', handleEvent); | 
|         element[method]('flick', handleEvent); | 
|     }; | 
|     /** | 
|      * 打开滑动菜单 | 
|      * @param {Object} el | 
|      * @param {Object} direction | 
|      */ | 
|     $.swipeoutOpen = function(el, direction) { | 
|         if (!el) return; | 
|         var classList = el.classList; | 
|         if (classList.contains(CLASS_SELECTED)) return; | 
|         if (!direction) { | 
|             if (el.querySelector(SELECTOR_SLIDER_RIGHT)) { | 
|                 direction = 'right'; | 
|             } else { | 
|                 direction = 'left'; | 
|             } | 
|         } | 
|         var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction)); | 
|         if (!swipeoutAction) return; | 
|         swipeoutAction.classList.add(CLASS_SELECTED); | 
|         classList.add(CLASS_SELECTED); | 
|         classList.remove(CLASS_TRANSITIONING); | 
|         var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON); | 
|         var swipeoutWidth = swipeoutAction.offsetWidth; | 
|         var translate = (direction === 'right') ? -swipeoutWidth : swipeoutWidth; | 
|         var length = buttons.length; | 
|         var button; | 
|         for (var i = 0; i < length; i++) { | 
|             button = buttons[i]; | 
|             if (direction === 'right') { | 
|                 setTranslate(button, -button.offsetLeft); | 
|             } else { | 
|                 setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft)); | 
|             } | 
|         } | 
|         classList.add(CLASS_TRANSITIONING); | 
|         for (var i = 0; i < length; i++) { | 
|             setTranslate(buttons[i], translate); | 
|         } | 
|         setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), translate); | 
|     }; | 
|     /** | 
|      * 关闭滑动菜单 | 
|      * @param {Object} el | 
|      */ | 
|     $.swipeoutClose = function(el) { | 
|         if (!el) return; | 
|         var classList = el.classList; | 
|         if (!classList.contains(CLASS_SELECTED)) return; | 
|         var direction = el.querySelector(SELECTOR_SLIDER_RIGHT + SELECTOR_SELECTED) ? 'right' : 'left'; | 
|         var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction)); | 
|         if (!swipeoutAction) return; | 
|         swipeoutAction.classList.remove(CLASS_SELECTED); | 
|         classList.remove(CLASS_SELECTED); | 
|         classList.add(CLASS_TRANSITIONING); | 
|         var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON); | 
|         var swipeoutWidth = swipeoutAction.offsetWidth; | 
|         var length = buttons.length; | 
|         var button; | 
|         setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), 0); | 
|         for (var i = 0; i < length; i++) { | 
|             button = buttons[i]; | 
|             if (direction === 'right') { | 
|                 setTranslate(button, (-button.offsetLeft)); | 
|             } else { | 
|                 setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft)); | 
|             } | 
|         } | 
|     }; | 
|   | 
|     window.addEventListener($.EVENT_END, function(event) { //使用touchend来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件 | 
|         if (!cell) { | 
|             return; | 
|         } | 
|         toggleActive(false); | 
|         sliderHandle && toggleEvents(cell, true); | 
|     }); | 
|     window.addEventListener($.EVENT_CANCEL, function(event) { //使用touchcancel来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件 | 
|         if (!cell) { | 
|             return; | 
|         } | 
|         toggleActive(false); | 
|         sliderHandle && toggleEvents(cell, true); | 
|     }); | 
|     var radioOrCheckboxClick = function(event) { | 
|         var type = event.target && event.target.type || ''; | 
|         if (type === 'radio' || type === 'checkbox') { | 
|             return; | 
|         } | 
|         var classList = cell.classList; | 
|         if (classList.contains('mui-radio')) { | 
|             var input = cell.querySelector('input[type=radio]'); | 
|             if (input) { | 
|                 //                input.click(); | 
|                 if (!input.disabled && !input.readOnly) { | 
|                     input.checked = !input.checked; | 
|                     $.trigger(input, 'change'); | 
|                 } | 
|             } | 
|         } else if (classList.contains('mui-checkbox')) { | 
|             var input = cell.querySelector('input[type=checkbox]'); | 
|             if (input) { | 
|                 //                input.click(); | 
|                 if (!input.disabled && !input.readOnly) { | 
|                     input.checked = !input.checked; | 
|                     $.trigger(input, 'change'); | 
|                 } | 
|             } | 
|         } | 
|     }; | 
|     //fixed hashchange(android) | 
|     window.addEventListener($.EVENT_CLICK, function(e) { | 
|         if (cell && cell.classList.contains('mui-collapse')) { | 
|             e.preventDefault(); | 
|         } | 
|     }); | 
|     window.addEventListener('doubletap', function(event) { | 
|         if (cell) { | 
|             radioOrCheckboxClick(event); | 
|         } | 
|     }); | 
|     var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/; | 
|     window.addEventListener('tap', function(event) { | 
|         if (!cell) { | 
|             return; | 
|         } | 
|         var isExpand = false; | 
|         var classList = cell.classList; | 
|         var ul = cell.parentNode; | 
|         if (ul && ul.classList.contains(CLASS_RADIO_VIEW)) { | 
|             if (classList.contains(CLASS_SELECTED)) { | 
|                 return; | 
|             } | 
|             var selected = ul.querySelector('li' + SELECTOR_SELECTED); | 
|             if (selected) { | 
|                 selected.classList.remove(CLASS_SELECTED); | 
|             } | 
|             classList.add(CLASS_SELECTED); | 
|             $.trigger(cell, 'selected', { | 
|                 el: cell | 
|             }); | 
|             return; | 
|         } | 
|         if (classList.contains('mui-collapse') && !cell.parentNode.classList.contains('mui-unfold')) { | 
|             if (!preventDefaultException.test(event.target.tagName)) { | 
|                 event.detail.gesture.preventDefault(); | 
|             } | 
|   | 
|             if (!classList.contains(CLASS_ACTIVE)) { //展开时,需要收缩其他同类 | 
|                 var collapse = cell.parentNode.querySelector('.mui-collapse.mui-active'); | 
|                 if (collapse) { | 
|                     collapse.classList.remove(CLASS_ACTIVE); | 
|                 } | 
|                 isExpand = true; | 
|             } | 
|             classList.toggle(CLASS_ACTIVE); | 
|             if (isExpand) { | 
|                 //触发展开事件 | 
|                 $.trigger(cell, 'expand'); | 
|   | 
|                 //scroll | 
|                 //暂不滚动 | 
|                 // var offsetTop = $.offset(cell).top; | 
|                 // var scrollTop = document.body.scrollTop; | 
|                 // var height = window.innerHeight; | 
|                 // var offsetHeight = cell.offsetHeight; | 
|                 // var cellHeight = (offsetTop - scrollTop + offsetHeight); | 
|                 // if (offsetHeight > height) { | 
|                 //     $.scrollTo(offsetTop, 300); | 
|                 // } else if (cellHeight > height) { | 
|                 //     $.scrollTo(cellHeight - height + scrollTop, 300); | 
|                 // } | 
|             } | 
|         } else { | 
|             radioOrCheckboxClick(event); | 
|         } | 
|     }); | 
| })(mui, window, document); | 
| (function($, window) { | 
|     /** | 
|      * 警告消息框 | 
|      */ | 
|     $.alert = function(message, title, btnValue, callback) { | 
|         if ($.os.plus) { | 
|             if (typeof message === 'undefined') { | 
|                 return; | 
|             } else { | 
|                 if (typeof title === 'function') { | 
|                     callback = title; | 
|                     title = null; | 
|                     btnValue = '确定'; | 
|                 } else if (typeof btnValue === 'function') { | 
|                     callback = btnValue; | 
|                     btnValue = null; | 
|                 } | 
|                 $.plusReady(function() { | 
|                     plus.nativeUI.alert(message, callback, title, btnValue); | 
|                 }); | 
|             } | 
|   | 
|         } else { | 
|             //TODO H5版本 | 
|             window.alert(message); | 
|         } | 
|     }; | 
|   | 
| })(mui, window); | 
| (function($, window) { | 
|     /** | 
|      * 确认消息框 | 
|      */ | 
|     $.confirm = function(message, title, btnArray, callback) { | 
|         if ($.os.plus) { | 
|             if (typeof message === 'undefined') { | 
|                 return; | 
|             } else { | 
|                 if (typeof title === 'function') { | 
|                     callback = title; | 
|                     title = null; | 
|                     btnArray = null; | 
|                 } else if (typeof btnArray === 'function') { | 
|                     callback = btnArray; | 
|                     btnArray = null; | 
|                 } | 
|                 $.plusReady(function() { | 
|                     plus.nativeUI.confirm(message, callback, title, btnArray); | 
|                 }); | 
|             } | 
|   | 
|         } else { | 
|             //H5版本,0为确认,1为取消 | 
|             if (window.confirm(message)) { | 
|                 callback({ | 
|                     index: 0 | 
|                 }); | 
|             } else { | 
|                 callback({ | 
|                     index: 1 | 
|                 }); | 
|             } | 
|         } | 
|     }; | 
|   | 
| })(mui, window); | 
| (function($, window) { | 
|     /** | 
|      * 输入对话框 | 
|      */ | 
|     $.prompt = function(text, defaultText, title, btnArray, callback) { | 
|         if ($.os.plus) { | 
|             if (typeof message === 'undefined') { | 
|                 return; | 
|             } else { | 
|   | 
|                 if (typeof defaultText === 'function') { | 
|                     callback = defaultText; | 
|                     defaultText = null; | 
|                     title = null; | 
|                     btnArray = null; | 
|                 } else if (typeof title === 'function') { | 
|                     callback = title; | 
|                     title = null; | 
|                     btnArray = null; | 
|                 } else if (typeof btnArray === 'function') { | 
|                     callback = btnArray; | 
|                     btnArray = null; | 
|                 } | 
|                 $.plusReady(function() { | 
|                     plus.nativeUI.prompt(text, callback, title, defaultText, btnArray); | 
|                 }); | 
|             } | 
|   | 
|         } else { | 
|             //H5版本(确认index为0,取消index为1) | 
|             var result = window.prompt(text); | 
|             if (result) { | 
|                 callback({ | 
|                     index: 0, | 
|                     value: result | 
|                 }); | 
|             } else { | 
|                 callback({ | 
|                     index: 1, | 
|                     value: '' | 
|                 }); | 
|             } | 
|         } | 
|     }; | 
|   | 
| })(mui, window); | 
| (function($, window) { | 
|     var CLASS_ACTIVE = 'mui-active'; | 
|     /** | 
|      * 自动消失提示框 | 
|      */ | 
|     $.toast = function(message,options) { | 
|         var durations = { | 
|             'long': 3500, | 
|             'short': 2000 | 
|         }; | 
|   | 
|         //计算显示时间 | 
|          options = $.extend({ | 
|             duration: 'short' | 
|         }, options || {}); | 
|   | 
|   | 
|         if ($.os.plus && options.type !== 'div') { | 
|             //默认显示在底部; | 
|             $.plusReady(function() { | 
|                 plus.nativeUI.toast(message, { | 
|                     verticalAlign: 'bottom', | 
|                     duration:options.duration | 
|                 }); | 
|             }); | 
|         } else { | 
|             if (typeof options.duration === 'number') { | 
|                 duration = options.duration>0 ? options.duration:durations['short']; | 
|             } else { | 
|                 duration = durations[options.duration]; | 
|             } | 
|             if (!duration) { | 
|                 duration = durations['short']; | 
|             } | 
|             var toast = document.createElement('div'); | 
|             toast.classList.add('mui-toast-container'); | 
|             toast.innerHTML = '<div class="' + 'mui-toast-message' + '">' + message + '</div>'; | 
|             toast.addEventListener('webkitTransitionEnd', function() { | 
|                 if (!toast.classList.contains(CLASS_ACTIVE)) { | 
|                     toast.parentNode.removeChild(toast); | 
|                     toast = null; | 
|                 } | 
|             }); | 
|             //点击则自动消失 | 
|             toast.addEventListener('click', function() { | 
|                 toast.parentNode.removeChild(toast); | 
|                 toast = null; | 
|             }); | 
|             document.body.appendChild(toast); | 
|             toast.offsetHeight; | 
|             toast.classList.add(CLASS_ACTIVE); | 
|             setTimeout(function() { | 
|                 toast && toast.classList.remove(CLASS_ACTIVE); | 
|             }, duration); | 
|              | 
|             return { | 
|                 isVisible: function() {return !!toast;} | 
|             } | 
|         }    | 
|     }; | 
|   | 
| })(mui, window); | 
| /** | 
|  * Popup(alert,confirm,prompt)   | 
|  * @param {Object} $ | 
|  * @param {Object} window | 
|  * @param {Object} document | 
|  */ | 
| (function($, window, document) { | 
|     var CLASS_POPUP = 'mui-popup'; | 
|     var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop'; | 
|     var CLASS_POPUP_IN = 'mui-popup-in'; | 
|     var CLASS_POPUP_OUT = 'mui-popup-out'; | 
|     var CLASS_POPUP_INNER = 'mui-popup-inner'; | 
|     var CLASS_POPUP_TITLE = 'mui-popup-title'; | 
|     var CLASS_POPUP_TEXT = 'mui-popup-text'; | 
|     var CLASS_POPUP_INPUT = 'mui-popup-input'; | 
|     var CLASS_POPUP_BUTTONS = 'mui-popup-buttons'; | 
|     var CLASS_POPUP_BUTTON = 'mui-popup-button'; | 
|     var CLASS_POPUP_BUTTON_BOLD = 'mui-popup-button-bold'; | 
|     var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop'; | 
|     var CLASS_ACTIVE = 'mui-active'; | 
|   | 
|     var popupStack = []; | 
|     var backdrop = (function() { | 
|         var element = document.createElement('div'); | 
|         element.classList.add(CLASS_POPUP_BACKDROP); | 
|         element.addEventListener($.EVENT_MOVE, $.preventDefault); | 
|         element.addEventListener('webkitTransitionEnd', function() { | 
|             if (!this.classList.contains(CLASS_ACTIVE)) { | 
|                 element.parentNode && element.parentNode.removeChild(element); | 
|             } | 
|         }); | 
|         return element; | 
|     }()); | 
|   | 
|     var createInput = function(placeholder) { | 
|         return '<div class="' + CLASS_POPUP_INPUT + '"><input type="text" autofocus placeholder="' + (placeholder || '') + '"/></div>'; | 
|     }; | 
|     var createInner = function(message, title, extra) { | 
|         return '<div class="' + CLASS_POPUP_INNER + '"><div class="' + CLASS_POPUP_TITLE + '">' + title + '</div><div class="' + CLASS_POPUP_TEXT + '">' + message.replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>") + '</div>' + (extra || '') + '</div>'; | 
|     }; | 
|     var createButtons = function(btnArray) { | 
|         var length = btnArray.length; | 
|         var btns = []; | 
|         for (var i = 0; i < length; i++) { | 
|             btns.push('<span class="' + CLASS_POPUP_BUTTON + (i === length - 1 ? (' ' + CLASS_POPUP_BUTTON_BOLD) : '') + '">' + btnArray[i] + '</span>'); | 
|         } | 
|         return '<div class="' + CLASS_POPUP_BUTTONS + '">' + btns.join('') + '</div>'; | 
|     }; | 
|   | 
|     var createPopup = function(html, callback) { | 
|         var popupElement = document.createElement('div'); | 
|         popupElement.className = CLASS_POPUP; | 
|         popupElement.innerHTML = html; | 
|         var removePopupElement = function() { | 
|             popupElement.parentNode && popupElement.parentNode.removeChild(popupElement); | 
|             popupElement = null; | 
|         }; | 
|         popupElement.addEventListener($.EVENT_MOVE, $.preventDefault); | 
|         popupElement.addEventListener('webkitTransitionEnd', function(e) { | 
|             if (popupElement && e.target === popupElement && popupElement.classList.contains(CLASS_POPUP_OUT)) { | 
|                 removePopupElement(); | 
|             } | 
|         }); | 
|         popupElement.style.display = 'block'; | 
|         document.body.appendChild(popupElement); | 
|         popupElement.offsetHeight; | 
|         popupElement.classList.add(CLASS_POPUP_IN); | 
|   | 
|         if (!backdrop.classList.contains(CLASS_ACTIVE)) { | 
|             backdrop.style.display = 'block'; | 
|             document.body.appendChild(backdrop); | 
|             backdrop.offsetHeight; | 
|             backdrop.classList.add(CLASS_ACTIVE); | 
|         } | 
|         var btns = $.qsa('.' + CLASS_POPUP_BUTTON, popupElement); | 
|         var input = popupElement.querySelector('.' + CLASS_POPUP_INPUT + ' input'); | 
|         var popup = { | 
|             element: popupElement, | 
|             close: function(index, animate) { | 
|                 if (popupElement) { | 
|                     var result = callback && callback({ | 
|                         index: index || 0, | 
|                         value: input && input.value || '' | 
|                     }); | 
|                     if (result === false) { //返回false则不关闭当前popup | 
|                         return; | 
|                     } | 
|                     if (animate !== false) { | 
|                         popupElement.classList.remove(CLASS_POPUP_IN); | 
|                         popupElement.classList.add(CLASS_POPUP_OUT); | 
|                     } else { | 
|                         removePopupElement(); | 
|                     } | 
|                     popupStack.pop(); | 
|                     //如果还有其他popup,则不remove backdrop | 
|                     if (popupStack.length) { | 
|                         popupStack[popupStack.length - 1]['show'](animate); | 
|                     } else { | 
|                         backdrop.classList.remove(CLASS_ACTIVE); | 
|                     } | 
|                 } | 
|             } | 
|         }; | 
|         var handleEvent = function(e) { | 
|             popup.close(btns.indexOf(e.target)); | 
|         }; | 
|         $(popupElement).on('tap', '.' + CLASS_POPUP_BUTTON, handleEvent); | 
|         if (popupStack.length) { | 
|             popupStack[popupStack.length - 1]['hide'](); | 
|         } | 
|         popupStack.push({ | 
|             close: popup.close, | 
|             show: function(animate) { | 
|                 popupElement.style.display = 'block'; | 
|                 popupElement.offsetHeight; | 
|                 popupElement.classList.add(CLASS_POPUP_IN); | 
|             }, | 
|             hide: function() { | 
|                 popupElement.style.display = 'none'; | 
|                 popupElement.classList.remove(CLASS_POPUP_IN); | 
|             } | 
|         }); | 
|         return popup; | 
|     }; | 
|     var createAlert = function(message, title, btnValue, callback, type) { | 
|         if (typeof message === 'undefined') { | 
|             return; | 
|         } else { | 
|             if (typeof title === 'function') { | 
|                 callback = title; | 
|                 type = btnValue; | 
|                 title = null; | 
|                 btnValue = null; | 
|             } else if (typeof btnValue === 'function') { | 
|                 type = callback; | 
|                 callback = btnValue; | 
|                 btnValue = null; | 
|             } | 
|         } | 
|         if (!$.os.plus || type === 'div') { | 
|             return createPopup(createInner(message, title || '提示') + createButtons([btnValue || '确定']), callback); | 
|         } | 
|         return plus.nativeUI.alert(message, callback, title || '提示', btnValue || '确定'); | 
|     }; | 
|     var createConfirm = function(message, title, btnArray, callback, type) { | 
|         if (typeof message === 'undefined') { | 
|             return; | 
|         } else { | 
|             if (typeof title === 'function') { | 
|                 callback = title; | 
|                 type = btnArray; | 
|                 title = null; | 
|                 btnArray = null; | 
|             } else if (typeof btnArray === 'function') { | 
|                 type = callback; | 
|                 callback = btnArray; | 
|                 btnArray = null; | 
|             } | 
|         } | 
|         if (!$.os.plus || type === 'div') { | 
|             return createPopup(createInner(message, title || '提示') + createButtons(btnArray || ['取消', '确认']), callback); | 
|         } | 
|         return plus.nativeUI.confirm(message, callback, title, btnArray || ['取消', '确认']); | 
|     }; | 
|     var createPrompt = function(message, placeholder, title, btnArray, callback, type) { | 
|         if (typeof message === 'undefined') { | 
|             return; | 
|         } else { | 
|             if (typeof placeholder === 'function') { | 
|                 callback = placeholder; | 
|                 type = title; | 
|                 placeholder = null; | 
|                 title = null; | 
|                 btnArray = null; | 
|             } else if (typeof title === 'function') { | 
|                 callback = title; | 
|                 type = btnArray; | 
|                 title = null; | 
|                 btnArray = null; | 
|             } else if (typeof btnArray === 'function') { | 
|                 type = callback; | 
|                 callback = btnArray; | 
|                 btnArray = null; | 
|             } | 
|         } | 
|         if (!$.os.plus || type === 'div') { | 
|             return createPopup(createInner(message, title || '提示', createInput(placeholder)) + createButtons(btnArray || ['取消', '确认']), callback); | 
|         } | 
|         return plus.nativeUI.prompt(message, callback, title || '提示', placeholder, btnArray || ['取消', '确认']); | 
|     }; | 
|     var closePopup = function() { | 
|         if (popupStack.length) { | 
|             popupStack[popupStack.length - 1]['close'](); | 
|             return true; | 
|         } else { | 
|             return false; | 
|         } | 
|     }; | 
|     var closePopups = function() { | 
|         while (popupStack.length) { | 
|             popupStack[popupStack.length - 1]['close'](); | 
|         } | 
|     }; | 
|   | 
|     $.closePopup = closePopup; | 
|     $.closePopups = closePopups; | 
|     $.alert = createAlert; | 
|     $.confirm = createConfirm; | 
|     $.prompt = createPrompt; | 
| })(mui, window, document); | 
| (function($, document) { | 
|     var CLASS_PROGRESSBAR = 'mui-progressbar'; | 
|     var CLASS_PROGRESSBAR_IN = 'mui-progressbar-in'; | 
|     var CLASS_PROGRESSBAR_OUT = 'mui-progressbar-out'; | 
|     var CLASS_PROGRESSBAR_INFINITE = 'mui-progressbar-infinite'; | 
|   | 
|     var SELECTOR_PROGRESSBAR = '.mui-progressbar'; | 
|   | 
|     var _findProgressbar = function(container) { | 
|         container = $(container || 'body'); | 
|         if (container.length === 0) return; | 
|         container = container[0]; | 
|         if (container.classList.contains(CLASS_PROGRESSBAR)) { | 
|             return container; | 
|         } | 
|         var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR); | 
|         if (progressbars) { | 
|             for (var i = 0, len = progressbars.length; i < len; i++) { | 
|                 var progressbar = progressbars[i]; | 
|                 if (progressbar.parentNode === container) { | 
|                     return progressbar; | 
|                 } | 
|             } | 
|         } | 
|     }; | 
|     /** | 
|      * 创建并显示进度条  | 
|      * @param {Object} container  可选,默认body,支持selector,DOM Node,mui wrapper | 
|      * @param {Object} progress 可选,undefined表示循环,数字表示具体进度 | 
|      * @param {Object} color 可选,指定颜色样式(目前暂未提供实际样式,可暂时不暴露此参数) | 
|      */ | 
|     var showProgressbar = function(container, progress, color) { | 
|         if (typeof container === 'number') { | 
|             color = progress; | 
|             progress = container; | 
|             container = 'body'; | 
|         } | 
|         container = $(container || 'body'); | 
|         if (container.length === 0) return; | 
|         container = container[0]; | 
|         var progressbar; | 
|         if (container.classList.contains(CLASS_PROGRESSBAR)) { | 
|             progressbar = container; | 
|         } else { | 
|             var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR + ':not(.' + CLASS_PROGRESSBAR_OUT + ')'); | 
|             if (progressbars) { | 
|                 for (var i = 0, len = progressbars.length; i < len; i++) { | 
|                     var _progressbar = progressbars[i]; | 
|                     if (_progressbar.parentNode === container) { | 
|                         progressbar = _progressbar; | 
|                         break; | 
|                     } | 
|                 } | 
|             } | 
|             if (!progressbar) { | 
|                 progressbar = document.createElement('span'); | 
|                 progressbar.className = CLASS_PROGRESSBAR + ' ' + CLASS_PROGRESSBAR_IN + (typeof progress !== 'undefined' ? '' : (' ' + CLASS_PROGRESSBAR_INFINITE)) + (color ? (' ' + CLASS_PROGRESSBAR + '-' + color) : ''); | 
|                 if (typeof progress !== 'undefined') { | 
|                     progressbar.innerHTML = '<span></span>'; | 
|                 } | 
|                 container.appendChild(progressbar); | 
|             } else { | 
|                 progressbar.classList.add(CLASS_PROGRESSBAR_IN); | 
|             } | 
|         } | 
|         if (progress) setProgressbar(container, progress); | 
|         return progressbar; | 
|     }; | 
|     /** | 
|      * 关闭进度条  | 
|      * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper | 
|      */ | 
|     var hideProgressbar = function(container) { | 
|         var progressbar = _findProgressbar(container); | 
|         if (!progressbar) { | 
|             return; | 
|         } | 
|         var classList = progressbar.classList; | 
|         if (!classList.contains(CLASS_PROGRESSBAR_IN) || classList.contains(CLASS_PROGRESSBAR_OUT)) { | 
|             return; | 
|         } | 
|         classList.remove(CLASS_PROGRESSBAR_IN); | 
|         classList.add(CLASS_PROGRESSBAR_OUT); | 
|         progressbar.addEventListener('webkitAnimationEnd', function() { | 
|             progressbar.parentNode && progressbar.parentNode.removeChild(progressbar); | 
|             progressbar = null; | 
|         }); | 
|         return; | 
|     }; | 
|     /** | 
|      * 设置指定进度条进度  | 
|      * @param {Object} container  可选,默认body,支持selector,DOM Node,mui wrapper | 
|      * @param {Object} progress 可选,默认0 取值范围[0-100] | 
|      * @param {Object} speed 进度条动画时间 | 
|      */ | 
|     var setProgressbar = function(container, progress, speed) { | 
|         if (typeof container === 'number') { | 
|             speed = progress; | 
|             progress = container; | 
|             container = false; | 
|         } | 
|         var progressbar = _findProgressbar(container); | 
|         if (!progressbar || progressbar.classList.contains(CLASS_PROGRESSBAR_INFINITE)) { | 
|             return; | 
|         } | 
|         if (progress) progress = Math.min(Math.max(progress, 0), 100); | 
|         progressbar.offsetHeight; | 
|         var span = progressbar.querySelector('span'); | 
|         if (span) { | 
|             var style = span.style; | 
|             style.webkitTransform = 'translate3d(' + (-100 + progress) + '%,0,0)'; | 
|             if (typeof speed !== 'undefined') { | 
|                 style.webkitTransitionDuration = speed + 'ms'; | 
|             } else { | 
|                 style.webkitTransitionDuration = ''; | 
|             } | 
|         } | 
|         return progressbar; | 
|     }; | 
|     $.fn.progressbar = function(options) { | 
|         var progressbarApis = []; | 
|         options = options || {}; | 
|         this.each(function() { | 
|             var self = this; | 
|             var progressbarApi = self.mui_plugin_progressbar; | 
|             if (!progressbarApi) { | 
|                 self.mui_plugin_progressbar = progressbarApi = { | 
|                     options: options, | 
|                     setOptions: function(options) { | 
|                         this.options = options; | 
|                     }, | 
|                     show: function() { | 
|                         return showProgressbar(self, this.options.progress, this.options.color); | 
|                     }, | 
|                     setProgress: function(progress) { | 
|                         return setProgressbar(self, progress); | 
|                     }, | 
|                     hide: function() { | 
|                         return hideProgressbar(self); | 
|                     } | 
|                 }; | 
|             } else if (options) { | 
|                 progressbarApi.setOptions(options); | 
|             } | 
|             progressbarApis.push(progressbarApi); | 
|         }); | 
|         return progressbarApis.length === 1 ? progressbarApis[0] : progressbarApis; | 
|     }; | 
|     //    $.setProgressbar = setProgressbar; | 
|     //    $.showProgressbar = showProgressbar; | 
|     //    $.hideProgressbar = hideProgressbar; | 
| })(mui, document); | 
| /** | 
|  * Input(TODO resize) | 
|  * @param {type} $ | 
|  * @param {type} window | 
|  * @param {type} document | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window, document) { | 
|     var CLASS_ICON = 'mui-icon'; | 
|     var CLASS_ICON_CLEAR = 'mui-icon-clear'; | 
|     var CLASS_ICON_SPEECH = 'mui-icon-speech'; | 
|     var CLASS_ICON_SEARCH = 'mui-icon-search'; | 
|     var CLASS_ICON_PASSWORD = 'mui-icon-eye'; | 
|     var CLASS_INPUT_ROW = 'mui-input-row'; | 
|     var CLASS_PLACEHOLDER = 'mui-placeholder'; | 
|     var CLASS_TOOLTIP = 'mui-tooltip'; | 
|     var CLASS_HIDDEN = 'mui-hidden'; | 
|     var CLASS_FOCUSIN = 'mui-focusin'; | 
|     var SELECTOR_ICON_CLOSE = '.' + CLASS_ICON_CLEAR; | 
|     var SELECTOR_ICON_SPEECH = '.' + CLASS_ICON_SPEECH; | 
|     var SELECTOR_ICON_PASSWORD = '.' + CLASS_ICON_PASSWORD; | 
|     var SELECTOR_PLACEHOLDER = '.' + CLASS_PLACEHOLDER; | 
|     var SELECTOR_TOOLTIP = '.' + CLASS_TOOLTIP; | 
|   | 
|     var findRow = function(target) { | 
|         for (; target && target !== document; target = target.parentNode) { | 
|             if (target.classList && target.classList.contains(CLASS_INPUT_ROW)) { | 
|                 return target; | 
|             } | 
|         } | 
|         return null; | 
|     }; | 
|     var Input = function(element, options) { | 
|         this.element = element; | 
|         this.options = options || { | 
|             actions: 'clear' | 
|         }; | 
|         if (~this.options.actions.indexOf('slider')) { //slider | 
|             this.sliderActionClass = CLASS_TOOLTIP + ' ' + CLASS_HIDDEN; | 
|             this.sliderActionSelector = SELECTOR_TOOLTIP; | 
|         } else { //clear,speech,search | 
|             if (~this.options.actions.indexOf('clear')) { | 
|                 this.clearActionClass = CLASS_ICON + ' ' + CLASS_ICON_CLEAR + ' ' + CLASS_HIDDEN; | 
|                 this.clearActionSelector = SELECTOR_ICON_CLOSE; | 
|             } | 
|             if (~this.options.actions.indexOf('speech')) { //only for 5+ | 
|                 this.speechActionClass = CLASS_ICON + ' ' + CLASS_ICON_SPEECH; | 
|                 this.speechActionSelector = SELECTOR_ICON_SPEECH; | 
|             } | 
|             if (~this.options.actions.indexOf('search')) { | 
|                 this.searchActionClass = CLASS_PLACEHOLDER; | 
|                 this.searchActionSelector = SELECTOR_PLACEHOLDER; | 
|             } | 
|             if (~this.options.actions.indexOf('password')) { | 
|                 this.passwordActionClass = CLASS_ICON + ' ' + CLASS_ICON_PASSWORD; | 
|                 this.passwordActionSelector = SELECTOR_ICON_PASSWORD; | 
|             } | 
|         } | 
|         this.init(); | 
|     }; | 
|     Input.prototype.init = function() { | 
|         this.initAction(); | 
|         this.initElementEvent(); | 
|     }; | 
|     Input.prototype.initAction = function() { | 
|         var self = this; | 
|   | 
|         var row = self.element.parentNode; | 
|         if (row) { | 
|             if (self.sliderActionClass) { | 
|                 self.sliderAction = self.createAction(row, self.sliderActionClass, self.sliderActionSelector); | 
|             } else { | 
|                 if (self.searchActionClass) { | 
|                     self.searchAction = self.createAction(row, self.searchActionClass, self.searchActionSelector); | 
|                     self.searchAction.addEventListener('tap', function(e) { | 
|                         $.focus(self.element); | 
|                         e.stopPropagation(); | 
|                     }); | 
|                 } | 
|                 if (self.speechActionClass) { | 
|                     self.speechAction = self.createAction(row, self.speechActionClass, self.speechActionSelector); | 
|                     self.speechAction.addEventListener('click', $.stopPropagation); | 
|                     self.speechAction.addEventListener('tap', function(event) { | 
|                         self.speechActionClick(event); | 
|                     }); | 
|                 } | 
|                 if (self.clearActionClass) { | 
|                     self.clearAction = self.createAction(row, self.clearActionClass, self.clearActionSelector); | 
|                     self.clearAction.addEventListener('tap', function(event) { | 
|                         self.clearActionClick(event); | 
|                     }); | 
|                 } | 
|                 if (self.passwordActionClass) { | 
|                     self.passwordAction = self.createAction(row, self.passwordActionClass, self.passwordActionSelector); | 
|                     self.passwordAction.addEventListener('tap', function(event) { | 
|                         self.passwordActionClick(event); | 
|                     }); | 
|                 } | 
|             } | 
|         } | 
|     }; | 
|     Input.prototype.createAction = function(row, actionClass, actionSelector) { | 
|         var action = row.querySelector(actionSelector); | 
|         if (!action) { | 
|             var action = document.createElement('span'); | 
|             action.className = actionClass; | 
|             if (actionClass === this.searchActionClass) { | 
|                 action.innerHTML = '<span class="' + CLASS_ICON + ' ' + CLASS_ICON_SEARCH + '"></span><span>' + this.element.getAttribute('placeholder') + '</span>'; | 
|                 this.element.setAttribute('placeholder', ''); | 
|                 if (this.element.value.trim()) { | 
|                     row.classList.add('mui-active'); | 
|                 } | 
|             } | 
|             row.insertBefore(action, this.element.nextSibling); | 
|         } | 
|         return action; | 
|     }; | 
|     Input.prototype.initElementEvent = function() { | 
|         var element = this.element; | 
|   | 
|         if (this.sliderActionClass) { | 
|             var tooltip = this.sliderAction; | 
|             var timer = null; | 
|             var showTip = function() { //每次重新计算是因为控件可能被隐藏,初始化时计算是不正确的 | 
|                 tooltip.classList.remove(CLASS_HIDDEN); | 
|                 var offsetLeft = element.offsetLeft; | 
|                 var width = element.offsetWidth - 28; | 
|                 var tooltipWidth = tooltip.offsetWidth; | 
|                 var distince = Math.abs(element.max - element.min); | 
|                 var scaleWidth = (width / distince) * Math.abs(element.value - element.min); | 
|                 tooltip.style.left = (14 + offsetLeft + scaleWidth - tooltipWidth / 2) + 'px'; | 
|                 tooltip.innerText = element.value; | 
|                 if (timer) { | 
|                     clearTimeout(timer); | 
|                 } | 
|                 timer = setTimeout(function() { | 
|                     tooltip.classList.add(CLASS_HIDDEN); | 
|                 }, 1000); | 
|             }; | 
|             element.addEventListener('input', showTip); | 
|             element.addEventListener('tap', showTip); | 
|             element.addEventListener($.EVENT_MOVE, function(e) { | 
|                 e.stopPropagation(); | 
|             }); | 
|         } else { | 
|             if (this.clearActionClass) { | 
|                 var action = this.clearAction; | 
|                 if (!action) { | 
|                     return; | 
|                 } | 
|                 $.each(['keyup', 'change', 'input', 'focus', 'cut', 'paste'], function(index, type) { | 
|                     (function(type) { | 
|                         element.addEventListener(type, function() { | 
|                             action.classList[element.value.trim() ? 'remove' : 'add'](CLASS_HIDDEN); | 
|                         }); | 
|                     })(type); | 
|                 }); | 
|                 element.addEventListener('blur', function() { | 
|                     action.classList.add(CLASS_HIDDEN); | 
|                 }); | 
|             } | 
|             if (this.searchActionClass) { | 
|                 element.addEventListener('focus', function() { | 
|                     element.parentNode.classList.add('mui-active'); | 
|                 }); | 
|                 element.addEventListener('blur', function() { | 
|                     if (!element.value.trim()) { | 
|                         element.parentNode.classList.remove('mui-active'); | 
|                     } | 
|                 }); | 
|             } | 
|         } | 
|     }; | 
|     Input.prototype.setPlaceholder = function(text) { | 
|         if (this.searchActionClass) { | 
|             var placeholder = this.element.parentNode.querySelector(SELECTOR_PLACEHOLDER); | 
|             placeholder && (placeholder.getElementsByTagName('span')[1].innerText = text); | 
|         } else { | 
|             this.element.setAttribute('placeholder', text); | 
|         } | 
|     }; | 
|     Input.prototype.passwordActionClick = function(event) { | 
|         if (this.element.type === 'text') { | 
|             this.element.type = 'password'; | 
|         } else { | 
|             this.element.type = 'text'; | 
|         } | 
|         this.passwordAction.classList.toggle('mui-active'); | 
|         event.preventDefault(); | 
|     }; | 
|     Input.prototype.clearActionClick = function(event) { | 
|         var self = this; | 
|         self.element.value = ''; | 
|         $.focus(self.element); | 
|         self.clearAction.classList.add(CLASS_HIDDEN); | 
|         event.preventDefault(); | 
|     }; | 
|     Input.prototype.speechActionClick = function(event) { | 
|         if (window.plus) { | 
|             var self = this; | 
|             var oldValue = self.element.value; | 
|             self.element.value = ''; | 
|             document.body.classList.add(CLASS_FOCUSIN); | 
|             plus.speech.startRecognize({ | 
|                 engine: 'iFly' | 
|             }, function(s) { | 
|                 self.element.value += s; | 
|                 $.focus(self.element); | 
|                 plus.speech.stopRecognize(); | 
|                 $.trigger(self.element, 'recognized', { | 
|                     value: self.element.value | 
|                 }); | 
|                 if (oldValue !== self.element.value) { | 
|                     $.trigger(self.element, 'change'); | 
|                     $.trigger(self.element, 'input'); | 
|                 } | 
|                 // document.body.classList.remove(CLASS_FOCUSIN); | 
|             }, function(e) { | 
|                 document.body.classList.remove(CLASS_FOCUSIN); | 
|             }); | 
|         } else { | 
|             alert('only for 5+'); | 
|         } | 
|         event.preventDefault(); | 
|     }; | 
|     $.fn.input = function(options) { | 
|         var inputApis = []; | 
|         this.each(function() { | 
|             var inputApi = null; | 
|             var actions = []; | 
|             var row = findRow(this.parentNode); | 
|             if (this.type === 'range' && row.classList.contains('mui-input-range')) { | 
|                 actions.push('slider'); | 
|             } else { | 
|                 var classList = this.classList; | 
|                 if (classList.contains('mui-input-clear')) { | 
|                     actions.push('clear'); | 
|                 } | 
|                 if (!($.os.android && $.os.stream) && classList.contains('mui-input-speech')) { | 
|                     actions.push('speech'); | 
|                 } | 
|                 if (classList.contains('mui-input-password')) { | 
|                     actions.push('password'); | 
|                 } | 
|                 if (this.type === 'search' && row.classList.contains('mui-search')) { | 
|                     actions.push('search'); | 
|                 } | 
|             } | 
|             var id = this.getAttribute('data-input-' + actions[0]); | 
|             if (!id) { | 
|                 id = ++$.uuid; | 
|                 inputApi = $.data[id] = new Input(this, { | 
|                     actions: actions.join(',') | 
|                 }); | 
|                 for (var i = 0, len = actions.length; i < len; i++) { | 
|                     this.setAttribute('data-input-' + actions[i], id); | 
|                 } | 
|             } else { | 
|                 inputApi = $.data[id]; | 
|             } | 
|             inputApis.push(inputApi); | 
|         }); | 
|         return inputApis.length === 1 ? inputApis[0] : inputApis; | 
|     }; | 
|     $.ready(function() { | 
|         $('.mui-input-row input').input(); | 
|     }); | 
| })(mui, window, document); | 
| (function($, window) { | 
|     var CLASS_ACTIVE = 'mui-active'; | 
|     var rgbaRegex = /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/; | 
|     var getColor = function(colorStr) { | 
|         var matches = colorStr.match(rgbaRegex); | 
|         if (matches && matches.length === 5) { | 
|             return [ | 
|                 matches[1], | 
|                 matches[2], | 
|                 matches[3], | 
|                 matches[4] | 
|             ]; | 
|         } | 
|         return []; | 
|     }; | 
|     var Transparent = function(element, options) { | 
|         this.element = element; | 
|         this.options = $.extend({ | 
|             top: 0, //距离顶部高度(到达该高度即触发) | 
|             offset: 150, //滚动透明距离 | 
|             duration: 16, //过渡时间 | 
|             scrollby: window//监听滚动距离容器 | 
|         }, options || {}); | 
|   | 
|         this.scrollByElem = this.options.scrollby || window; | 
|         if (!this.scrollByElem) { | 
|             throw new Error("监听滚动的元素不存在"); | 
|         } | 
|         this.isNativeScroll = false; | 
|         if (this.scrollByElem === window) { | 
|             this.isNativeScroll = true; | 
|         } else if (!~this.scrollByElem.className.indexOf('mui-scroll-wrapper')) { | 
|             this.isNativeScroll = true; | 
|         } | 
|   | 
|         this._style = this.element.style; | 
|         this._bgColor = this._style.backgroundColor; | 
|         var color = getColor(mui.getStyles(this.element, 'backgroundColor')); | 
|         if (color.length) { | 
|             this._R = color[0]; | 
|             this._G = color[1]; | 
|             this._B = color[2]; | 
|             this._A = parseFloat(color[3]); | 
|             this.lastOpacity = this._A; | 
|             this._bufferFn = $.buffer(this.handleScroll, this.options.duration, this); | 
|             this.initEvent(); | 
|         } else { | 
|             throw new Error("元素背景颜色必须为RGBA"); | 
|         } | 
|     }; | 
|   | 
|     Transparent.prototype.initEvent = function() { | 
|         this.scrollByElem.addEventListener('scroll', this._bufferFn); | 
|         if (this.isNativeScroll) { //原生scroll | 
|             this.scrollByElem.addEventListener($.EVENT_MOVE, this._bufferFn); | 
|         } | 
|     } | 
|     Transparent.prototype.handleScroll = function(e) { | 
|         var y = window.scrollY; | 
|         if (!this.isNativeScroll && e && e.detail) { | 
|             y = -e.detail.y; | 
|         } | 
|         var opacity = (y - this.options.top) / this.options.offset + this._A; | 
|         opacity = Math.min(Math.max(this._A, opacity), 1); | 
|         this._style.backgroundColor = 'rgba(' + this._R + ',' + this._G + ',' + this._B + ',' + opacity + ')'; | 
|         if (opacity > this._A) { | 
|             this.element.classList.add(CLASS_ACTIVE); | 
|         } else { | 
|             this.element.classList.remove(CLASS_ACTIVE); | 
|         } | 
|         if (this.lastOpacity !== opacity) { | 
|             $.trigger(this.element, 'alpha', { | 
|                 alpha: opacity | 
|             }); | 
|             this.lastOpacity = opacity; | 
|         } | 
|     }; | 
|     Transparent.prototype.destory = function() { | 
|         this.scrollByElem.removeEventListener('scroll', this._bufferFn); | 
|         this.scrollByElem.removeEventListener($.EVENT_MOVE, this._bufferFn); | 
|         this.element.style.backgroundColor = this._bgColor; | 
|         this.element.mui_plugin_transparent = null; | 
|     }; | 
|     $.fn.transparent = function(options) { | 
|         options = options || {}; | 
|         var transparentApis = []; | 
|         this.each(function() { | 
|             var transparentApi = this.mui_plugin_transparent; | 
|             if (!transparentApi) { | 
|                 var top = this.getAttribute('data-top'); | 
|                 var offset = this.getAttribute('data-offset'); | 
|                 var duration = this.getAttribute('data-duration'); | 
|                 var scrollby = this.getAttribute('data-scrollby'); | 
|                 if (top !== null && typeof options.top === 'undefined') { | 
|                     options.top = top; | 
|                 } | 
|                 if (offset !== null && typeof options.offset === 'undefined') { | 
|                     options.offset = offset; | 
|                 } | 
|                 if (duration !== null && typeof options.duration === 'undefined') { | 
|                     options.duration = duration; | 
|                 } | 
|                 if (scrollby !== null && typeof options.scrollby === 'undefined') { | 
|                     options.scrollby = document.querySelector(scrollby) || window; | 
|                 } | 
|                 transparentApi = this.mui_plugin_transparent = new Transparent(this, options); | 
|             } | 
|             transparentApis.push(transparentApi); | 
|         }); | 
|         return transparentApis.length === 1 ? transparentApis[0] : transparentApis; | 
|     }; | 
|     $.ready(function() { | 
|         $('.mui-bar-transparent').transparent(); | 
|     }); | 
| })(mui, window); | 
| /** | 
|  * 数字输入框 | 
|  * varstion 1.0.1 | 
|  * by Houfeng | 
|  * Houfeng@DCloud.io | 
|  */ | 
|   | 
| (function($) { | 
|   | 
|     var touchSupport = ('ontouchstart' in document); | 
|     var tapEventName = touchSupport ? 'tap' : 'click'; | 
|     var changeEventName = 'change'; | 
|     var holderClassName = 'mui-numbox'; | 
|     var plusClassSelector = '.mui-btn-numbox-plus,.mui-numbox-btn-plus'; | 
|     var minusClassSelector = '.mui-btn-numbox-minus,.mui-numbox-btn-minus'; | 
|     var inputClassSelector = '.mui-input-numbox,.mui-numbox-input'; | 
|   | 
|     var Numbox = $.Numbox = $.Class.extend({ | 
|         /** | 
|          * 构造函数 | 
|          **/ | 
|         init: function(holder, options) { | 
|             var self = this; | 
|             if (!holder) { | 
|                 throw "构造 numbox 时缺少容器元素"; | 
|             } | 
|             self.holder = holder; | 
|             options = options || {}; | 
|             options.step = parseInt(options.step || 1); | 
|             self.options = options; | 
|             self.input = $.qsa(inputClassSelector, self.holder)[0]; | 
|             self.plus = $.qsa(plusClassSelector, self.holder)[0]; | 
|             self.minus = $.qsa(minusClassSelector, self.holder)[0]; | 
|             self.checkValue(); | 
|             self.initEvent(); | 
|         }, | 
|         /** | 
|          * 初始化事件绑定 | 
|          **/ | 
|         initEvent: function() { | 
|             var self = this; | 
|             self.plus.addEventListener(tapEventName, function(event) { | 
|                 var val = parseInt(self.input.value) + self.options.step; | 
|                 self.input.value = val.toString(); | 
|                 $.trigger(self.input, changeEventName, null); | 
|             }); | 
|             self.minus.addEventListener(tapEventName, function(event) { | 
|                 var val = parseInt(self.input.value) - self.options.step; | 
|                 self.input.value = val.toString(); | 
|                 $.trigger(self.input, changeEventName, null); | 
|             }); | 
|             self.input.addEventListener(changeEventName, function(event) { | 
|                 self.checkValue(); | 
|                 var val = parseInt(self.input.value); | 
|                 //触发顶层容器 | 
|                 $.trigger(self.holder, changeEventName, { | 
|                     value: val | 
|                 }); | 
|             }); | 
|         }, | 
|         /** | 
|          * 获取当前值 | 
|          **/ | 
|         getValue: function() { | 
|             var self = this; | 
|             return parseInt(self.input.value); | 
|         }, | 
|         /** | 
|          * 验证当前值是法合法 | 
|          **/ | 
|         checkValue: function() { | 
|             var self = this; | 
|             var val = self.input.value; | 
|             if (val == null || val == '' || isNaN(val)) { | 
|                 self.input.value = self.options.min || 0; | 
|                 self.minus.disabled = self.options.min != null; | 
|             } else { | 
|                 var val = parseInt(val); | 
|                 if (self.options.max != null && !isNaN(self.options.max) && val >= parseInt(self.options.max)) { | 
|                     val = self.options.max; | 
|                     self.plus.disabled = true; | 
|                 } else { | 
|                     self.plus.disabled = false; | 
|                 } | 
|                 if (self.options.min != null && !isNaN(self.options.min) && val <= parseInt(self.options.min)) { | 
|                     val = self.options.min; | 
|                     self.minus.disabled = true; | 
|                 } else { | 
|                     self.minus.disabled = false; | 
|                 } | 
|                 self.input.value = val; | 
|             } | 
|         }, | 
|         /** | 
|          * 更新选项 | 
|          **/ | 
|         setOption: function(name, value) { | 
|             var self = this; | 
|             self.options[name] = value; | 
|         }, | 
|         /** | 
|          * 动态设置新值 | 
|          **/ | 
|         setValue: function(value) { | 
|             this.input.value = value; | 
|             this.checkValue(); | 
|         } | 
|     }); | 
|   | 
|     $.fn.numbox = function(options) { | 
|         var instanceArray = []; | 
|         //遍历选择的元素 | 
|         this.each(function(i, element) { | 
|             if (element.numbox) { | 
|                 return; | 
|             } | 
|             if (options) { | 
|                 element.numbox = new Numbox(element, options); | 
|             } else { | 
|                 var optionsText = element.getAttribute('data-numbox-options'); | 
|                 var options = optionsText ? JSON.parse(optionsText) : {}; | 
|                 options.step = element.getAttribute('data-numbox-step') || options.step; | 
|                 options.min = element.getAttribute('data-numbox-min') || options.min; | 
|                 options.max = element.getAttribute('data-numbox-max') || options.max; | 
|                 element.numbox = new Numbox(element, options); | 
|             } | 
|         }); | 
|         return this[0] ? this[0].numbox : null; | 
|     } | 
|   | 
|     //自动处理 class='mui-locker' 的 dom | 
|     $.ready(function() { | 
|         $('.' + holderClassName).numbox(); | 
|     }); | 
|   | 
| }(mui)); | 
| /** | 
|  * Button | 
|  * @param {type} $ | 
|  * @param {type} window | 
|  * @param {type} document | 
|  * @returns {undefined} | 
|  */ | 
| (function($, window, document) { | 
|     var CLASS_ICON = 'mui-icon'; | 
|     var CLASS_DISABLED = 'mui-disabled'; | 
|   | 
|     var STATE_RESET = 'reset'; | 
|     var STATE_LOADING = 'loading'; | 
|   | 
|     var defaultOptions = { | 
|         loadingText: 'Loading...', //文案 | 
|         loadingIcon: 'mui-spinner' + ' ' + 'mui-spinner-white', //图标,可为空 | 
|         loadingIconPosition: 'left' //图标所处位置,仅支持left|right | 
|     }; | 
|   | 
|     var Button = function(element, options) { | 
|         this.element = element; | 
|         this.options = $.extend({}, defaultOptions, options); | 
|         if (!this.options.loadingText) { | 
|             this.options.loadingText = defaultOptions.loadingText; | 
|         } | 
|         if (this.options.loadingIcon === null) { | 
|             this.options.loadingIcon = 'mui-spinner'; | 
|             if ($.getStyles(this.element, 'color') === 'rgb(255, 255, 255)') { | 
|                 this.options.loadingIcon += ' ' + 'mui-spinner-white'; | 
|             } | 
|         } | 
|         this.isInput = this.element.tagName === 'INPUT'; | 
|         this.resetHTML = this.isInput ? this.element.value : this.element.innerHTML; | 
|         this.state = ''; | 
|     }; | 
|     Button.prototype.loading = function() { | 
|         this.setState(STATE_LOADING); | 
|     }; | 
|     Button.prototype.reset = function() { | 
|         this.setState(STATE_RESET); | 
|     }; | 
|     Button.prototype.setState = function(state) { | 
|         if (this.state === state) { | 
|             return false; | 
|         } | 
|         this.state = state; | 
|         if (state === STATE_RESET) { | 
|             this.element.disabled = false; | 
|             this.element.classList.remove(CLASS_DISABLED); | 
|             this.setHtml(this.resetHTML); | 
|         } else if (state === STATE_LOADING) { | 
|             this.element.disabled = true; | 
|             this.element.classList.add(CLASS_DISABLED); | 
|             var html = this.isInput ? this.options.loadingText : ('<span>' + this.options.loadingText + '</span>'); | 
|             if (this.options.loadingIcon && !this.isInput) { | 
|                 if (this.options.loadingIconPosition === 'right') { | 
|                     html += ' <span class="' + this.options.loadingIcon + '"></span>'; | 
|                 } else { | 
|                     html = '<span class="' + this.options.loadingIcon + '"></span> ' + html; | 
|                 } | 
|             } | 
|             this.setHtml(html); | 
|         } | 
|     }; | 
|     Button.prototype.setHtml = function(html) { | 
|         if (this.isInput) { | 
|             this.element.value = html; | 
|         } else { | 
|             this.element.innerHTML = html; | 
|         } | 
|     } | 
|     $.fn.button = function(state) { | 
|         var buttonApis = []; | 
|         this.each(function() { | 
|             var buttonApi = this.mui_plugin_button; | 
|             if (!buttonApi) { | 
|                 var loadingText = this.getAttribute('data-loading-text'); | 
|                 var loadingIcon = this.getAttribute('data-loading-icon'); | 
|                 var loadingIconPosition = this.getAttribute('data-loading-icon-position'); | 
|                 this.mui_plugin_button = buttonApi = new Button(this, { | 
|                     loadingText: loadingText, | 
|                     loadingIcon: loadingIcon, | 
|                     loadingIconPosition: loadingIconPosition | 
|                 }); | 
|             } | 
|             if (state === STATE_LOADING || state === STATE_RESET) { | 
|                 buttonApi.setState(state); | 
|             } | 
|             buttonApis.push(buttonApi); | 
|         }); | 
|         return buttonApis.length === 1 ? buttonApis[0] : buttonApis; | 
|     }; | 
| })(mui, window, document); |