text: /*!
   * =====================================================
   * Mui v3.7.2 (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);
          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 += '&nbsp;<span class="' + this.options.loadingIcon + '"></span>';
                  } else {
                      html = '<span class="' + this.options.loadingIcon + '"></span>&nbsp;' + 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);