text: var avalon = require("avalon"),
  template = "<div class=\"oni-carousel\"\n     ms-css-width=\"pictureWidth\"\n     ms-css-height=\"pictureHeight\"\n     ms-mouseenter=\"stopPlay\"\n     ms-mouseleave=\"restartPlay('carousel')\"\n        >\n    <div class=\"oni-carousel-panel\"\n         ms-css-width=\"pictureWidth* picNum\"\n         ms-css-left=\"panelOffsetX\"\n         ms-css-position=\"panelPosition\"\n            >\n        <div class=\"oni-carousel-item\"\n             ms-repeat=\"pictures\"\n             ms-css-width=\"pictureWidth\"\n             ms-css-position=\"itemPosition\"\n             ms-css-opacity=\"getOpacity($index)\"\n                >\n            <img class=\"oni-img-placeholder\" ms-if=\"lazyloading\" ms-src=\"placeholderImg\" />\n            <img class=\"oni-img-origin\" ms-src=\"{{el.src}}\" ms-on-load=\"imgOnload($event, $index)\" ms-attr-alt=\"{{el.alt}}\"/>\n            <a class=\"oni-carousel-link\"\n               target=\"_blank\"\n               ms-if=\"typeof links[$index] !== 'undefined' && links[$index] !== ''\"\n               ms-attr-title=\"{{links[$index].title}}\"\n               ms-href=\"{{links[$index].href}}\"\n               ms-css-width=\"pictureWidth\"\n               ms-css-height=\"pictureHeight\">\n            </a>\n        </div>\n    </div>\n    <div class=\"oni-carousel-selection-wrap\"\n         ms-visible=\"alwaysShowSelection\"\n         ms-css-margin-left=\"selectionWrapOffset\"\n            >\n        <a ms-class=\"selected:el==currentIndex\"\n           ms-mouseenter=\"selectPic($index,$event)\"\n           ms-click=\"selectPic($index,$event)\"\n           ms-mouseleave=\"restartPlay('tab')\"\n           ms-repeat=\"selections\"\n                ></a>\n    </div>\n    <a ms-class=\"{{arrowLeftClass}}\" class=\"arrow prev png24\"\n       ms-click=\"animate(-1)\"\n       ms-mouseenter=\"arrowHover('left')\"\n       ms-mouseleave=\"arrowBlur('left')\"\n       ms-visible=\"arrowVisible\"\n       ms-css-background-image=\"arrowLeftBg\"\n            >\n    </a>\n    <a ms-class=\"{{arrowRightClass}}\" class=\"arrow after png24\"\n       ms-click=\"animate(1)\"\n       ms-mouseenter=\"arrowHover('right')\"\n       ms-mouseleave=\"arrowBlur('right')\"\n       ms-visible=\"arrowVisible\"\n       ms-css-background-image=\"arrowRightBg\"\n            >\n    </a>\n</div>\n";
  
  module.exports = (
  function () {
      //获取当前JS绝对路径
      var path, t = document.getElementsByTagName('SCRIPT');
      for (var i in t) {
          if (t[i].outerHTML && t[i].outerHTML.indexOf('avalon.carousel.js') !== -1) {
              var wholePath = t[i].src;
              path = wholePath.substring(0, wholePath.lastIndexOf('/'));
          }
      }
      var requestAnimationFrame = function () {
              //requestAnimationFrame 兼容
              return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
                  window.setTimeout(callback, 10);
              };
          }();
      var Tween = {
              //线性以及二次方的缓动
              linear: function (t, b, c, d) {
                  return c * t / d + b;
              },
              easeIn: function (t, b, c, d) {
                  return c * (t /= d) * t + b;
              },
              easeOut: function (t, b, c, d) {
                  return -c * (t /= d) * (t - 2) + b;
              },
              easeInOut: function (t, b, c, d) {
                  if ((t /= d / 2) < 1)
                      return c / 2 * t * t + b;
                  return -c / 2 * (--t * (t - 2) - 1) + b;
              }
          };
      var widget = avalon.ui.carousel = function (element, data, vmodels) {
              var options = data.carouselOptions;
              options.template = options.getTemplate(template, options);
              var vmodel = avalon.define(data.carouselId, function (vm) {
                      avalon.mix(vm, options);
                      vm.widgetElement = element;
                      vm.picNum = vm.pictures.length + 1;
                      //图片数量（包括复制到末尾的第一个元素）
                      vm.pictureOpacity = {};
                      vm.itemPosition = 'relative';
                      //默认slide effect下结构
                      vm.panelPosition = 'absolute';
                      //默认slide effect下结构
                      vm.selections = avalon.range(vm.pictures.length);
                      //圆形选择的数据数组（不包括复制到末尾的第一个元素）
                      vm.currentIndex = 0;
                      // 圆形选择的index
                      vm.selectionWrapOffset = -vm.pictures.length * 20 / 2;
                      //圆形选择CSS位置修正
                      vm.panelOffsetX = 0;
                      //长panel的X方向偏移，正向移动（右）时减小，反向移动（左）时增大
                      vm.arrowVisible = false;
                      //箭头是否可见
                      vm.arrowLeftBg = vm.arrowLeftNormalSrc !== '' ? 'url(' + vm.arrowLeftNormalSrc + ')' : '';
                      vm.arrowRightBg = vm.arrowRightNormalSrc !== '' ? 'url(' + vm.arrowRightNormalSrc + ')' : '';
                      vm.imgNodeArr = new Array(vm.picNum);
                      vm.lazyloading = options.lazyload;
                      vm.placeholderImg = path + '/images/loading.gif';
                      vm.$skipArray = [
                          'widgetElement',
                          'template',
                          'selectionWrapOffset'
                      ];
                      var inited;
                      vm.$init = function (continueScan) {
                          if (inited)
                              return;
                          inited = true;
                          var pageHTML = options.template;
                          element.style.display = 'none';
                          element.innerHTML = pageHTML;
                          element.style.display = 'block';
                          if (vm.adaptiveWidth || vm.pictureWidth === '100%') {
                              //自动填充外围容器宽度
                              vm.pictureWidth = element.offsetWidth;
                          }
                          if (vm.adaptiveHeight || vm.pictureHeight === '100%') {
                              //自动填充外围容器高度
                              element.style.height = '100%';
                              var children = element.children;
                              for (var i = 0, len = children.length; i < len; i++) {
                                  if (children[i].getAttribute('class') === 'oni-carousel') {
                                      children[i].style.height = '100%';
                                  }
                              }
                          }
                          // 预加载图片
                          var originPictures = vm.pictures.slice(), placeholderPics = [];
                          for (var i = 0; i < vm.picNum; i++) {
                              var imgPreload = new Image();
                              if (vm.lazyload) {
                                  for (var j = 0; j < vm.picNum; j++) {
                                      placeholderPics.push(path + '/images/placeholder.png');
                                  }
                                  vm.pictures = placeholderPics;
                                  (function (i) {
                                      imgPreload.onload = function (e) {
                                          setTimeout(function () {
                                              vm.imgNodeArr[i].setAttribute('src', originPictures[i]);
                                          }, 200);
                                      };
                                  }(i));
                              }
                              imgPreload.src = vm.pictures[i].src;
                          }
                          // 预加载icons
                          var icons = [];
                          icons.push('http://source.qunarzz.com/general/oniui/carousel/arrows-left-hover-icon.png', 'http://source.qunarzz.com/general/oniui/carousel/arrows-right-hover-icon.png');
                          for (var i = 0; i < icons.length; i++) {
                              icons[i] = (icons[i].match(/^http/g) ? '' : path) + icons[i];
                              var image_preload = new Image();
                              image_preload.src = icons[i];
                          }
                          if (continueScan) {
                              continueScan();
                          } else {
                              avalon.log('\u8BF7\u5C3D\u5FEB\u5347\u5230avalon1.3.7+');
                              avalon.scan(element, _vmodels);
                              if (typeof options.onInit === 'function') {
                                  options.onInit.call(element, vmodel, options, vmodels);
                              }
                          }
                      };
                      vm.$remove = function () {
                          element.innerHTML = element.textContent = '';
                      };
                      vm.stopPlay = function () {
                          //hover在组件上时使Arrow显示，停止轮播
                          vm.arrowVisible = vm.alwaysShowArrow ? true : false;
                          if (vm.hoverStop && vm.autoSlide) {
                              clearTimeout(timer);
                              timer = null;
                          }
                      };
                      vm.restartPlay = function (type) {
                          //hover离开时使Arrow隐藏，重新开始轮播
                          if (type === 'carousel') {
                              vm.arrowVisible = false;
                          }
                          vm.autoPlay();
                      };
                      vm.imgOnload = function (e, i) {
                          vm.imgNodeArr[i] = e.target;
                      };
                      //动画参数
                      vm.fadein = 1;
                      //effect为fade时，渐入的图片透明度
                      vm.fadeout = 0;
                      //effect为fade时，渐出的图片透明度
                      var animated = false;
                      //动画正在进行
                      var duringTime = vm.during / 10;
                      //补间动画的时间长度
                      var lastIndex;
                      //上一张图片index
                      vm.animate = function (direct, distance) {
                          //@method animate(direct, distance) 图片滚动，direct为方向（1/-1），distance为距离（>0整数）
                          if (animated) {
                              //防止动画队列堆积
                              return;
                          }
                          distance = distance || 1;
                          if (vm.effect === 'slide') {
                              //移动准备
                              if (direct === 1 && vm.panelOffsetX === -vm.pictureWidth * (vm.picNum - 1)) {
                                  //点击为正方向且panel处于队列末尾，队列先回到0
                                  vm.panelOffsetX = 0;
                              } else if (direct === -1 && vm.panelOffsetX === 0) {
                                  //点击为负方向且panel处于队列开始，队列先回到末尾
                                  vm.panelOffsetX = -vm.pictureWidth * (vm.picNum - 1);
                              }
                              var offset = vm.panelOffsetX - vm.pictureWidth * direct * distance;
                              //设置移动终点位置
                              //进行移动
                              var currentTime = 0;
                              //当前时间
                              var startpos = vm.panelOffsetX;
                              //位置初始值
                              var duringDistance = vm.pictureWidth * -direct * distance;
                              //位置变化量
                              var go = function () {
                                  animated = false;
                                  if (vm.panelOffsetX <= -vm.pictureWidth * (vm.pictures.length - 1) && direct > 0) {
                                      //队列已到末尾位置，且将要往正方向移动，队列回到0
                                      vm.panelOffsetX = 0;
                                  } else if (vm.panelOffsetX >= 0 && direct < 0) {
                                      //队列已到开始位置，且将要往反方向移动，队列回到末尾
                                      vm.panelOffsetX = -vm.pictureWidth * (vm.picNum - 1);
                                  } else {
                                      //队列还未到终点，在移动过程中
                                      vm.panelOffsetX = Tween[vm.easing](currentTime, startpos, duringDistance, duringTime);
                                      //移动
                                      if (currentTime < duringTime) {
                                          currentTime += 1;
                                          requestAnimationFrame(go);
                                          animated = true;
                                      }
                                  }
                              };
                          } else if (vm.effect === 'fade') {
                              //effect为fade
                              var currentTime = 0;
                              //当前时间
                              var go = function () {
                                  animated = false;
                                  vm.fadein = Tween[vm.easing](currentTime, 0, 1, duringTime);
                                  //移动
                                  vm.fadeout = Tween[vm.easing](currentTime, 1, -1, duringTime);
                                  //移动
                                  if (currentTime < duringTime) {
                                      currentTime += 1;
                                      requestAnimationFrame(go);
                                      animated = true;
                                  }
                              };
                          } else {
                              //effect为none
                              var go = function () {
                                  vm.fadein = 1;
                                  vm.fadeout = 0;
                              };
                          }
                          go();
                          //更新图片index
                          lastIndex = vm.currentIndex;
                          //当前图片变为上一张
                          vm.currentIndex += 1 * direct * distance;
                          if (vm.currentIndex > vm.selections.length - 1) {
                              //最右端继续+1时回0
                              vm.currentIndex = 0;
                          } else if (vm.currentIndex < 0) {
                              //最左端继续-1时回末尾
                              vm.currentIndex = vm.selections.length - 1;
                          }
                      };
                      vm.getOpacity = function (index) {
                          //@method getOpacity(index) fade effect 下改变前后图片透明度
                          if (vm.effect !== 'slide') {
                              var num = vm.fadein + vm.fadeout;
                              if (index === vm.currentIndex) {
                                  return vm.fadein;
                              } else if (index === lastIndex) {
                                  return vm.fadeout;
                              } else {
                                  return 0;
                              }
                          } else {
                              return 1;
                          }
                      };
                      var hoverIndex = 0;
                      vm.selectPic = function (index, e) {
                          //@method selectPic(index) 通过底部圆形选择图片
                          hoverIndex = index;
                          if (e.type === vm.eventType || vm.eventType === 'both') {
                              var distance = vm.currentIndex - index;
                              var direct = distance > 0 ? -1 : 1;
                              if (e.type === 'mouseenter') {
                                  setTimeout(function () {
                                      vm.animate(direct, Math.abs(distance));
                                  }, 300)    //mouseenter事件设置延时以防止切换时间间隔太小
  ;
                              } else {
                                  vm.animate(direct, Math.abs(distance));
                              }
                              if (vm.autoSlide) {
                                  clearTimeout(timer);
                                  timer = null;
                              }
                              //修复hover的TAB和select的TAB不一致
                              var fixIndex = setInterval(function () {
                                      if (vm.currentIndex !== hoverIndex) {
                                          var distance = vm.currentIndex - hoverIndex;
                                          var direct = distance > 0 ? -1 : 1;
                                          vm.animate(direct, Math.abs(distance));
                                      } else {
                                          clearInterval(fixIndex);
                                      }
                                  }, 800);
                          }
                      };
                      vm.arrowHover = function (direction) {
                          //@method arrowHover(direction) 左右箭头hover事件
                          if (direction === 'left') {
                              vm.arrowLeftBg = vm.arrowLeftHoverSrc !== '' ? 'url(' + vm.arrowLeftHoverSrc + ')' : '';
                          } else {
                              vm.arrowRightBg = vm.arrowRightHoverSrc !== '' ? 'url(' + vm.arrowRightHoverSrc + ')' : '';
                          }
                      };
                      vm.arrowBlur = function (direction) {
                          //@method arrowBlur(direction) 左右箭头blur事件
                          if (direction === 'left') {
                              vm.arrowLeftBg = vm.arrowLeftNormalSrc !== '' ? 'url(' + vm.arrowLeftNormalSrc + ')' : '';
                          } else {
                              vm.arrowRightBg = vm.arrowRightNormalSrc !== '' ? 'url(' + vm.arrowRightNormalSrc + ')' : '';
                          }
                      };
                      var timer = null;
                      //轮播计时器
                      vm.autoPlay = function () {
                          //@method autoPlay(vmodel) 自动开始轮播
                          if (timer === null && vm.autoSlide) {
                              function play() {
                                  timer = setTimeout(function () {
                                      vm.animate(1);
                                      //正方向移动
                                      play();
                                  }, vm.timeout);
                              }
                              play();
                          }
                      };
                  });
              if (vmodel.effect !== 'slide') {
                  //fade 或者 none 模式下的布局
                  vmodel.itemPosition = 'absolute';
                  vmodel.panelPosition = 'relative';
              }
              vmodel.pictures.push(vmodel.pictures[0]);
              if (typeof vmodel.links[0] !== 'undefined') {
                  vmodel.links.push(vmodel.links[0]);
              }
              vmodel.autoPlay();
              //自动开始轮播
              return vmodel;
          };
      widget.vertion = '1.0.1';
      widget.defaults = {
          pictures: [],
          //@config  轮播图片素材
          links: [],
          //@config  图片链接
          pictureWidth: 500,
          //@config  图片显示宽度
          pictureHeight: 200,
          //@config  图片显示高度
          effect: 'slide',
          //@config  图片切换类型，取值：none:无特效 / fade:渐隐 / slide:滑动
          easing: 'easeInOut',
          //@config  缓动类型，取值 linear:无缓动效果 / easeIn:在过渡的开始提供缓动效果 / easeOut:在过渡的结尾提供缓动效果 / easeInOut 在过渡的开始和结尾提供缓动效果
          timeout: 2500,
          //@config  切换时间间隔
          during: 300,
          //@config  切换速度，越小越快，单位为毫秒
          alwaysShowArrow: true,
          //@config  显示左右切换箭头
          alwaysShowSelection: true,
          //@config  显示底部圆形切换部件
          autoSlide: true,
          //@config  自动播放
          hoverStop: true,
          //@config  鼠标经过停止播放
          adaptiveWidth: false,
          //@config  适应外围宽度，为true时指定pictureWidth不起作用
          adaptiveHeight: false,
          //@config  适应外围高度，为true时指定pictureHeight不起作用
          eventType: 'click',
          //@config  触发tab切换的nav上的事件类型，取值click\mouseenter\both
          arrowLeftNormalSrc: '',
          //@config  左箭头正常状态图标，可不传
          arrowRightNormalSrc: '',
          //@config  右箭头正常状态图标，可不传
          arrowLeftHoverSrc: '',
          //@config  左箭头hover状态图标，可不传
          arrowRightHoverSrc: '',
          //@config  右箭头hover状态图标，可不传
          arrowLeftClass: '',
          //@config  左右箭头的className，可不传
          arrowRightClass: '',
          //@config  左右箭头的className，可不传
          lazyload: false,
          //@config  图片进行懒加载
          onInit: avalon.noop,
          //@optMethod onInit(vmodel, options, vmodels) 完成初始化之后的回调,call as element's method
          getTemplate: function (tmpl, opts, tplName) {
              return tmpl;
          },
          //@optMethod getTemplate(tpl, opts, tplName) 定制修改模板接口
          $author: 'heiwu805@hotmail.com'
      };
  }
  )();