scroller

sh做的js控件。

scroller

另外内部被scroller包裹的div不可以定位成absolute,会撑不出高度。

上面只是使用的注意事项。

很佩服人家能封装出这样的控件。

如果我也能写得出来就能毕业了,也不用担心现在公司有个万一,以后的营生问题。

全部源码:

(function($) {

    "use strict";

    

    var cache = {};

    var objId = function(obj) {

        if(!obj.afscrollerID) obj.afscrollerID = $.uuid();

        return obj.afscrollerID;

    };

    $.fn.scroller=function(opts){

        opts=opts||{};

        if(this.length===0) return;

        var tmp, id;

        for(var i = 0; i < this.length; i++) {

            //cache system

            id = objId(this[i]);

            if(!cache[id]) {

                if(!opts) opts = {};

                tmp = new Scroller(this[i], opts);

                cache[id] = tmp;

            } else {

                tmp = cache[id];

            }

        }

        return this.length == 1 ? tmp : this;

    };

    

    if(!$.mixin) {

        $.mixin = {};

    }

    

    if(!$.scroller) {

        $.scroller = {};

    }

    

    var mixin = $.mixin,

        scroller = $.scroller;

    

    mixin.scrollerMixin = {

        scrollerElement: null,

        scrollerContainerElement: null,

        direction: 'both',

        isAxisEnabledFlags: null,

        translatable: null,

        autoResize: true,

        isDragging: false,

        minPostion: null,

        outOfBoundRestrictFactor: 0.5,

        startMomentumResetTime: 300,

        maxAbsoluteVelocity: 6,

        containerSize: 'auto',

        size: 'auto',

        

        showIndicator: true,

        

        wrapper: '<div class="c-scroller">' + 

            '<div class="c-scroller__bar-wrapper">' + 

                '<div class="c-scroller__bar__table">' +

                    '<div class="c-scroller__bar__row">' +

                        '<div></div>' + 

                        '<div>' +

                            '<div class="c-scroller__bar--y">' + 

                                '<div class="c-scroller__bar--y__indicator"></div>' +

                            '</div>' +

                        '</div>' +

                    '</div>' +

                    '<div class="c-scroller__bar__row">' +

                        '<div>' + 

                            '<div class="c-scroller__bar--x">' +

                                '<div class="c-scroller__bar--x__indicator"></div>' +

                            '</div>' +

                        '</div>' + 

                        '<div></div>' +

                    '</div>' +

                '</div>' +

            '</div>' +

            '<div class="c-scroller__scroller-container">' +

                '<div class="c-scroller__scroller-content"></div>' +

            '</div>' +

        '</div>',



        initScroller: function() {

            this.initData();

            

            this.addWrapper();

            

            this.initAxisEnabledFlag();

            

            this.addSizeChangedListener();

            

            this.addResizeListener();

            

            this.initTranslatable();

            

            this.addDragListener();

            

            this.addAirGestureListener();

        },

        

        initData: function() {

            this.dragStartPosition = {

                x: 0,

                y: 0

            };

            this.startPosition = {

                x: 0,

                y: 0

            };

            this.position = {

                x: 0,

                y: 0

            };

            this.dragDirection = {

                x: 0,

                y: 0

            };



            this.flickStartPosition = {

                x: 0,

                y: 0

            };

            this.flickStartTime = {

                x: 0,

                y: 0

            };



            this.lastDragPosition = {

                x: 0,

                y: 0

            };

        },

        

        getPosition: function() {

            return this.position;

        },

        

        addDragListener: function() {

            var $el = $(this.scrollerContainerElement);

            itu.event.on($el, "dragstart", this.dragStart, this);

            itu.event.on($el, "drag", this.drag, this);

            itu.event.on($el, "dragend", this.dragEnd, this);

            itu.event.on($el, "touch", this.touch, this);            

        },

        

        addAirGestureListener: function() {

            this.airGestureHandler = this.airGestureHandler.bind(this);

            window.addEventListener("keydown", this.airGestureHandler);

        },

        

        airGestureHandler: function(ev) {

            this.airGestureEvent(ev.keyCode);

        },

        

        airGestureEvent: function(keyCode) {

            console.warn("scroller :: receive the air gesture event start");

            

            console.warn("scroller :: ifInVRMode: " + ifInVRMode);

            if (ifInVRMode) {

                console.warn("scroller :: return directly because of in VR mode");

                return;

            }

            

            var event = new Object();

            event.data = new Object();

            event.data.gesture = new Object();

            event.data.gesture.srcEvent = new Object();

            event.data.gesture.srcEvent.changedTouches = new Array();

            event.data.gesture.srcEvent.changedTouches[0] = new Object();

            if ((keyCode === 0x102) || (keyCode === 0x103)) { //0x102,0x103

                event.data.gesture.srcEvent.changedTouches[0].pageX = this.lastDragPosition.x;

                event.data.gesture.srcEvent.changedTouches[0].pageY = this.dragStartPosition.y;

            }    

            else {

                return;

            }

                

            this.dragStart(event);

            var me = this;

            setTimeout(function() {

                me.modifyEvent(event, keyCode);

                me.drag(event);

            }, 50);

            

            setTimeout(function() {

                me.modifyEvent(event, keyCode);

                me.drag(event);

            }, 50);



            setTimeout(function() {

                me.modifyEvent(event, keyCode);

                me.dragEnd(event);

            }, 50);

            console.warn("scroller :: receive the air gesture event end");

        },

        

        modifyEvent: function(event, keyCode) {

            if (keyCode === 0x103) { //Up 0x103 -->38(keyboard)

                if (this.position.y == 0) {

                    event.data.gesture.srcEvent.changedTouches[0].pageY += 55;

                }

                else {

                    event.data.gesture.srcEvent.changedTouches[0].pageY += 30;

                }

            }

            else if (keyCode === 0x102) { //Down 0x102 -->40(keyboard)

                if (this.position.y == 0) {

                    event.data.gesture.srcEvent.changedTouches[0].pageY -= 55;

                }

                else {

                    event.data.gesture.srcEvent.changedTouches[0].pageY -= 30;

                }

            }



            return event;

        },

        

        addWrapper: function() {

            var wrapper = this.wrapper,

                element = this.element;

            this.$wrapper = $(wrapper).insertBefore($(element));

            

            this.scrollerElement = this.$wrapper.find('.c-scroller__scroller-content');

            this.scrollerContainerElement = this.$wrapper.find('.c-scroller__scroller-container');

            

            $(element).appendTo(this.scrollerElement);

        },

        

        deleteWrapper: function() {

            var $wrapper, element, $element;

            $wrapper = this.$wrapper;

            element = this.element;

            $element = $(element);

            

            //delete the list

            $element.remove();

            

            //make become siblings

            $element.insertBefore($wrapper);

            

            //delete the wrapper

            $wrapper.remove();

        },

        

        addResizeListener: function() {

            var autoResize = this.autoResize;

//            var scrollerElement = this.scrollerElement;

//            var scrollerContainerElement = this.scrollerContainerElement;



            if (autoResize) {

//                this.onScrollerResize = iAuto.Util.bind(this, this.onScrollerResize);

                this.setSize(this.size);

//                scrollerElement.resize(this.onScrollerResize);

            }



//            this.onScrollerContainerResize = iAuto.Util.bind(this, this.onScrollerContainerResize);

            this.setContainerSize(this.containerSize);

//            scrollerContainerElement.resize(this.onScrollerContainerResize);



            var autoResize = this.autoResize;



            if (autoResize) {



                this.setSize(this.size);



                this.lastSize = this.getSize();



            }



            this.setContainerSize(this.containerSize);



            this.lastContainerSize = this.getContainerSize();



            this.runLoopy();

        },

    

        loopyDelay: 250,



        loopyTimer: null,



        runLoopy: function() {



            var scrollerElement = this.scrollerElement;



            var scrollerContainerElement = this.scrollerContainerElement;



            var me = this;



            this.loopyTimer = setTimeout(function() {



                var scrollerElementHeight = parseInt(scrollerElement.height());



                var scrollerElementWidth = parseInt(scrollerElement.width());



                



                var scrollerElementLastHeight = me.lastSize.y;



                var scrollerElementLastWidth = me.lastSize.x;



                



                if(scrollerElementLastHeight !== scrollerElementHeight || scrollerElementLastWidth !== scrollerElementWidth) {



                    me.onScrollerResize();



                    me.lastSize = me.getSize();



                }



                var scrollerContainerElementHeight = parseInt(scrollerContainerElement.height());



                var scrollerContainerElementWidth = parseInt(scrollerContainerElement.width());



                



                var scrollerContainerElementLastHeight = me.lastContainerSize.y;



                var scrollerContainerElementLastWidth = me.lastContainerSize.x;



                



                if(scrollerContainerElementLastHeight !== scrollerContainerElementHeight || scrollerContainerElementLastWidth !== scrollerContainerElementWidth) {



                    me.onScrollerContainerResize();



                    me.lastContainerSize = me.getContainerSize();



                }



                me.runLoopy();



            }, me.loopyDelay);



        },

        

        onScrollerResize: function() {

            var scrollerElement = this.scrollerElement;

            this.setSize({

                x: scrollerElement.width(),

                y: scrollerElement.height()

            });

        },



        onScrollerContainerResize: function() {

            var scrollerContainerElement = this.scrollerContainerElement;

            this.setContainerSize({

                x: scrollerContainerElement.width(),

                y: scrollerContainerElement.height()

            });

        },



        initAxisEnabledFlag: function() {

            var direction, isAxisEnabledFlags;



            direction = this.direction;

            isAxisEnabledFlags = this.isAxisEnabledFlags;

            if (!isAxisEnabledFlags) {

                this.isAxisEnabledFlags = isAxisEnabledFlags = {};

            }

            if (direction === 'both') {

                isAxisEnabledFlags.x = true;

                isAxisEnabledFlags.y = true;

            } else if (direction === 'vertical') {

                isAxisEnabledFlags.y = true;

                this.$wrapper.addClass('c-vertical');

            } else if (direction === 'horizontal') {

                isAxisEnabledFlags.x = true;

                this.$wrapper.addClass('c-horizontal');

            }

        },



        addSizeChangedListener: function() {

            this.sizeChanged = iAuto.Util.bind(this, this.sizeChanged);

            $.bind(this, 'sizeChanged', this.sizeChanged);

            

            this.containerSizeChanged = iAuto.Util.bind(this, this.containerSizeChanged);

            $.bind(this, 'containerSizeChanged', this.containerSizeChanged);

            

            this.maxPositionChanged = iAuto.Util.bind(this, this.maxPositionChanged);

            $.bind(this, 'maxPositionChanged', this.maxPositionChanged);

        },



        containerSizeChanged: function() {

            this.refreshMaxPostion();

        },



        sizeChanged: function() {

            this.refreshMaxPostion();

        },



        refreshMaxPostion: function() {

            this.maxPosition = null;

            this.getMaxPosition();

        },



        maxPositionChanged: function() {

            this.snapToBoundary();

        },



        initTranslatable: function() {

            var translatable = this.translatable;

            var transformElement = this.scrollerElement[0];

            if (translatable) {

                var xclass = translatable.xclass;

                if (xclass) {

                    xclass = iAuto.resolveNamespace(xclass);

                }

                if (xclass) {

                    this.translatable = xclass.create({

                        transformElement: transformElement

                    });

                } else {

                    iAuto.Logger.error('translatable must be a valid class');

                }

            } else {

                this.translatable = new scroller.CssTranslate();

                this.translatable.init();

                this.translatable.transformElement = transformElement;

            }

            this.onAnimationFrame = iAuto.Util.bind(this, this.onAnimationFrame);

            $.bind(this.translatable, 'animationframe', this.onAnimationFrame);

            

            this.onAnimationEnd = iAuto.Util.bind(this, this.onAnimationEnd);

            $.bind(this.translatable, 'animationend', this.onAnimationEnd);

        },



        isAxisEnabled: function(axis) {

            return this.isAxisEnabledFlags[axis];

        },



        getMinPosition: function() {

            var minPosition = this.minPosition;

            if (!minPosition) {

                this.minPosition = minPosition = {

                    x: 0,

                    y: 0

                };

            }

            return minPosition;

        },



        getMaxPosition: function() {

            var maxPosition = this.maxPosition;

            if (!maxPosition) {

                var containerSize, size;

                containerSize = this.getContainerSize();

                size = this.getSize();

                

                if(typeof(containerSize.x) !== 'number') {

                    this.setContainerSize('auto');

                    containerSize = this.getContainerSize();

                }

                

                if(typeof(size.x) !== 'number') {

                    this.setSize('auto');

                    size = this.getSize();

                }

                

                maxPosition = this.maxPosition = {

                    x: Math.max(0, size.x - containerSize.x),

                    y: Math.max(0, size.y - containerSize.y)

                };

                

                $.trigger(this, 'maxPositionChanged', [maxPosition]);

            }

            return maxPosition;

        },



        touch: function() {

            this.translatable.stopAnimation();

        },



        dragStart: function(event) {

            var browserEvent, touch, dragDirection, dragStartPosition, startPosition;

            var flickStartPosition, flickStartTime, lastDragPosition, currentPosition, x, y, now;

            browserEvent = event.data.gesture.srcEvent;

            touch = browserEvent.changedTouches[0];

            dragDirection = this.dragDirection;

            dragStartPosition = this.dragStartPosition;

            startPosition = this.startPosition;

            flickStartPosition = this.flickStartPosition;

            flickStartTime = this.flickStartTime;

            lastDragPosition = this.lastDragPosition;

            currentPosition = this.position;

            x = currentPosition.x;

            y = currentPosition.y;

            now = Date.now();



            lastDragPosition.x = x;

            lastDragPosition.y = y;



            flickStartPosition.x = x;

            flickStartPosition.y = y;



            flickStartTime.x = now;

            flickStartTime.y = now;



            dragStartPosition.x = touch.pageX;

            dragStartPosition.y = touch.pageY;

            

            dragDirection.x = 0;

            dragDirection.y = 0;



            startPosition.x = x;

            startPosition.y = y;



            this.dragStartTime = now;



            this.isDragging = true;

            

            $.trigger(this, 'scrollstart', [x, y]);

        },



        onAxisDrag: function(axis, delta) {

            if (!this.isAxisEnabled(axis)) {

                return;

            }



            var flickStartPosition, flickStartTime, lastDragPosition, dragDirection, old;

            var min, max, start, last, current, lastDirection, restrictFactor, startMomentumResetTime;

            var now, distance;

            flickStartPosition = this.flickStartPosition;

            flickStartTime = this.flickStartTime;

            lastDragPosition = this.lastDragPosition;

            dragDirection = this.dragDirection;

            old = this.position[axis];

            min = this.getMinPosition()[axis];

            max = this.getMaxPosition()[axis];

            start = this.startPosition[axis];

            last = lastDragPosition[axis];

            current = start - delta;

            lastDirection = dragDirection[axis];

            restrictFactor = this.outOfBoundRestrictFactor;

            startMomentumResetTime = this.startMomentumResetTime;

            now = Date.now();



            if (current < min) {

                current *= restrictFactor;

            } else if (current > max) {

                distance = current - max;

                current = max + distance * restrictFactor;

            }

            if (current > last) {

                dragDirection[axis] = 1;

            } else if (current < last) {

                dragDirection[axis] = -1;

            }



            if ((lastDirection !== 0 && (dragDirection[axis] !== lastDirection)) || (now - flickStartTime[axis]) > startMomentumResetTime) {

                flickStartPosition[axis] = old;

                flickStartTime[axis] = now;

            }



            lastDragPosition[axis] = current;

        },



        scrollTo: function(x, y) {

            var translatable, position, positionChanged, translationX, translationY;

            translatable = this.translatable;

            position = this.position;

            positionChanged = false;

            

            if (this.isAxisEnabled('x')) {

                if (typeof x !== 'number') {

                    x = position.x;

                } else {

                    if (position.x !== x) {

                        position.x = x;

                        positionChanged = true;

                    }

                }



                translationX = -x;

            } else {

                translationX = -position.x;

            }



            if (this.isAxisEnabled('y')) {

                if (typeof y !== 'number') {

                    y = position.y;

                } else {

                    if (position.y !== y) {

                        position.y = y;

                        positionChanged = true;

                    }

                }



                translationY = -y;

            } else {

                translationY = -position.y;

            }



            if (positionChanged) {

                $.trigger(this, 'scroll', [position.x, position.y]);

                translatable.translate(translationX, translationY);

            }



            return this;

        },



        drag: function(event) {

            if (!this.isDragging) {

                return;

            }



            var lastDragPosition, browserEvent, touch, dragStartPosition;

            lastDragPosition = this.lastDragPosition;

            browserEvent = event.data.gesture.srcEvent;

            touch = browserEvent.changedTouches[0];

            dragStartPosition = this.dragStartPosition;



            this.onAxisDrag('x', touch.pageX - dragStartPosition.x);

            this.onAxisDrag('y', touch.pageY - dragStartPosition.y);



            this.scrollTo(lastDragPosition.x, lastDragPosition.y);

        },



        dragEnd: function(event) {

            var easingX, easingY;



            if (!this.isDragging) {

                return;

            }



            this.dragEndTime = new Date().getTime();



            this.drag(event);



            this.isDragging = false;



            easingX = this.getAnimationEasing('x');

            easingY = this.getAnimationEasing('y');



            if (easingX || easingY) {

                this.translatable.animate(easingX, easingY);

            } else {

                this.onScrollEnd();

            }

        },



        getAnimationEasing: function(axis) {

            if (!this.isAxisEnabled(axis)) {

                return null;

            }



            var currentPosition, flickStartPosition, flickStartTime, minPosition, maxPosition;

            var maxAbsVelocity, boundValue, dragEndTime, easing, velocity, duration;

            currentPosition = this.position[axis];

            flickStartPosition = this.flickStartPosition[axis];

            flickStartTime = this.flickStartTime[axis];

            minPosition = this.getMinPosition()[axis];

            maxPosition = this.getMaxPosition()[axis];

            maxAbsVelocity = this.maxAbsoluteVelocity;

            boundValue = null;

            dragEndTime = this.dragEndTime;



            if (currentPosition < minPosition) {

                boundValue = minPosition;

            } else if (currentPosition > maxPosition) {

                boundValue = maxPosition;

            }



            // Out of bound, to be pulled back

            if (boundValue !== null) {

                easing = this.getBounceEasing()[axis];

                easing.setStartTime(dragEndTime);

                easing.setStartValue(-currentPosition);

                easing.setEndValue(-boundValue);



                return easing;

            }



            // Still within boundary, start deceleration

            duration = dragEndTime - flickStartTime;



            if (duration === 0) {

                return null;

            }



            velocity = (currentPosition - flickStartPosition) / (dragEndTime - flickStartTime);



            if (velocity === 0) {

                return null;

            }



            if (velocity < -maxAbsVelocity) {

                velocity = -maxAbsVelocity;

            } else if (velocity > maxAbsVelocity) {

                velocity = maxAbsVelocity;

            }



            easing = this.getMomentumEasing()[axis];

            easing.setStartTime(dragEndTime);

            easing.setStartValue(-currentPosition);

            easing.setStartVelocity(-velocity);

            easing.setMinMomentumValue(-maxPosition);

            easing.setMaxMomentumValue(0);



            return easing;

        },



        getBounceEasing: function() {

            var easing = this.bounceEasing,

                defaultClass, easingX, easingY;

            if (!easing) {

                defaultClass = scroller.EaseOut;

                easingX = new defaultClass();

                easingY = new defaultClass();

                this.bounceEasing = {

                    x: easingX,

                    y: easingY

                };

                easingX.init();

                easingY.init();

                return this.bounceEasing;

            } else {

                return easing;

            }

        },



        getMomentumEasing: function() {

            var boundMomentum = this.momentumEasing,

                defaultClass, easingX, easingY;

            if (!boundMomentum) {

                defaultClass = scroller.BoundMomentum;

                easingX = new defaultClass();

                easingY = new defaultClass();

                this.momentumEasing = {

                    x: easingX,

                    y: easingY

                };

                easingX.init();

                easingY.init();

                return this.momentumEasing;

            } else {

                return boundMomentum;

            }

        },



        onAnimationFrame: function(x, y) {

            var position = this.position;



            position.x = -x;

            position.y = -y;

            

            $.trigger(this, 'scroll', [position.x, position.y]);

        },



        onAnimationEnd: function() {

            this.snapToBoundary();

            this.onScrollEnd();

        },



        snapToBoundary: function() {

            var position, minPosition, maxPosition, minX, minY, maxX, maxY, x, y;



            position = this.position;

            minPosition = this.getMinPosition();

            maxPosition = this.getMaxPosition();

            minX = minPosition.x;

            minY = minPosition.y;

            maxX = maxPosition.x;

            maxY = maxPosition.y;

            x = Math.round(position.x);

            y = Math.round(position.y);



            if (x < minX) {

                x = minX;

            } else if (x > maxX) {

                x = maxX;

            }



            if (y < minY) {

                y = minY;

            } else if (y > maxY) {

                y = maxY;

            }



            this.scrollTo(x, y);

        },



        onScrollEnd: function() {

            var position = this.position;

            $.trigger(this, 'scrollend', [position.x, position.y]);

        },



        setSize: function(size) {

            var scrollElement;



            if (size === 'auto') {

                scrollElement = this.scrollerElement[0];

                this.size = {

                    x: scrollElement.offsetWidth,

                    y: scrollElement.offsetHeight

                };

                $.trigger(this, 'sizeChanged', [this.size]);

            } else if (typeof size === 'number') {

                this.size = {

                    x: size,

                    y: size

                };

                $.trigger(this, 'sizeChanged', [this.size]);

            } else {

                this.size = size;

                $.trigger(this, 'sizeChanged', [this.size]);

            }

        },



        getSize: function() {

            return this.size;

        },



        setContainerSize: function(containerSize) {

            var containerElement;



            if (containerSize === 'auto') {

                containerElement = this.scrollerContainerElement[0];

                this.containerSize = containerSize = {

                    x: containerElement.offsetWidth,

                    y: containerElement.offsetHeight

                };

                $.trigger(this, 'containerSizeChanged', [this.containerSize]);

            } else if (typeof containerSize === 'number') {

                this.containerSize = {

                    x: containerSize,

                    y: containerSize

                };

                $.trigger(this, 'containerSizeChanged', [this.containerSize]);

            } else {

                this.containerSize = containerSize;

                $.trigger(this, 'containerSizeChanged', [this.containerSize]);

            }

        },



        getContainerSize: function() {

            return this.containerSize;

        },



        destroy: function() {

            var translatable = this.translatable;

            if (translatable) {

                translatable.destroy();

            }

            

            var el = this.el;

            if(el) {

                var id = el.afscrollerID;

                if(cache[id]) delete cache[id];

                this.deleteWrapper();

//                window.removeEventListener('keydown', this.airGestureHandler);

            }else {

                console.warn('error can not find sroller el');

            }

        }

    };

    

    mixin.IndicatorMixin = {

        axis: null,

        indicatorElement: null,



        malengthX: 0,



        ratioX: 1,



        ratioY: 1,



        //delay time when hidden indicator

        delayOnHidden: 100,



        indicatorX: null,



        indicatorXOffset: 0,



        indicatorXMinLength: 6,



        indicatorXBaseLength: 0,



        indicatorY: null,



        indicatorYOffset: 0,



        indicatorYMinLength: 6,



        indicatorYBaseLength: 0,



        initIndicator: function() {

            this.setIndicatorOnScrollStart = iAuto.Util.bind(this, this.setIndicatorOnScrollStart);

            $.bind(this, 'scrollstart', this.setIndicatorOnScrollStart);

            

            this.setIndicatorOnScroll = iAuto.Util.bind(this, this.setIndicatorOnScroll);

            $.bind(this, 'scroll', this.setIndicatorOnScroll);

            

            this.setIndicatorOnScrollEnd = iAuto.Util.bind(this, this.setIndicatorOnScrollEnd);

            $.bind(this, 'scrollend', this.setIndicatorOnScrollEnd);

            

            this.initIndicatorElement();

        },



        initIndicatorElement: function() {

            this.indicatorX = this.$wrapper.find('.c-scroller__bar--x__indicator');

            this.indicatorY = this.$wrapper.find('.c-scroller__bar--y__indicator');

        },



        setIndicatorOnScrollStart: function(x, y) {

            var containerSize = this.getContainerSize(),

                size = this.getSize();

            if (this.isAxisEnabled('x')) {

                var ratioX = this.ratioX = containerSize.x / size.x,

                    lengthX = this.indicatorXBaseLength = Math.round(ratioX * containerSize.x),

                    translateX = 'translate3d(' + Math.round(ratioX * x) + 'px, 0, 0)';

                if (this.hideTimerX) {

                    clearTimeout(this.hideTimerX);

                }

                this.indicatorX.css('opacity', 1);

                this.indicatorX.css('width', lengthX);

                this.indicatorX.css('webkitTransform', translateX);

            }

            if (this.isAxisEnabled('y')) {

                var ratioY = this.ratioY = containerSize.y / size.y,

                    lengthY = this.indicatorYBaseLength = Math.round(ratioY * containerSize.y),

                    translateY = 'translate3d(0, ' + Math.round(ratioY * y) + 'px, 0)';

                if (this.hideTimerY) {

                    clearTimeout(this.hideTimerY);

                }

                this.indicatorY.css('opacity', 1);

                this.indicatorY.css('height', lengthY);

                this.indicatorY.css('webkitTransform', translateY);

            }

        },



        setIndicatorOnScroll: function(x, y) {

            var maxPosition = this.getMaxPosition(),

                minPosition = this.getMinPosition(),

                minPositionX = minPosition.x,

                minPositionY = minPosition.y,

                maxPositionX = maxPosition.x,

                maxPositionY = maxPosition.y,

                newLength, translateX, translateY, extra;

            if (this.isAxisEnabled('x')) {

                if (x < minPositionX) {

                    newLength = this.indicatorXBaseLength + (x - minPositionX);

                    this.indicatorX.css('width', newLength);

                } else if (x > maxPositionX) {

                    extra = maxPositionX - x;

                    newLength = this.indicatorXBaseLength + extra;

                    newLength = Math.max(newLength, this.indicatorXMinLength);

                    extra = newLength - this.indicatorXBaseLength;

                    translateX = 'translate3d(' + (this.indicatorXOffset - extra) + 'px, 0, 0)';

                    this.indicatorX.css('webkitTransform', translateX);

                    this.indicatorX.css('width', newLength);

                } else {

                    this.indicatorXOffset = Math.round(x * this.ratioX);

                    translateX = 'translate3d(' + Math.round(x * this.ratioX) + 'px, 0, 0)';

                    this.indicatorX.css('webkitTransform', translateX);

                }

            }

            if (this.isAxisEnabled('y')) {

                if (y < minPositionY) {

                    newLength = this.indicatorYBaseLength + (y - minPositionY);

                    this.indicatorY.css('height', newLength);

                } else if (y > maxPositionY) {

                    extra = maxPositionY - y;

                    newLength = this.indicatorYBaseLength + extra;

                    newLength = Math.max(newLength, this.indicatorYMinLength);

                    extra = newLength - this.indicatorYBaseLength;

                    translateY = 'translate3d(0, ' + (this.indicatorYOffset - extra) + 'px, 0)';

                    this.indicatorY.css('webkitTransform', translateY);

                    this.indicatorY.css('height', newLength);

                } else {

                    this.indicatorYOffset = Math.round(y * this.ratioY);

                    translateY = 'translate3d(0, ' + this.indicatorYOffset + 'px, 0)';

                    this.indicatorY.css('webkitTransform', translateY);

                }

            }

        },



        setIndicatorOnScrollEnd: function() {

            var me = this;

            if (this.delayOnHidden) {

                if (this.isAxisEnabled('x')) {

                    this.hideTimerX = setTimeout(function() {

                        me.hideTimerX = null;

                        me.indicatorX.css('opacity', 0);

                    }, this.delayOnHidden);

                }

                if (this.isAxisEnabled('y')) {

                    this.hideTimerY = setTimeout(function() {

                        me.hideTimerY = null;

                        me.indicatorY.css('opacity', 0);

                    }, this.delayOnHidden);

                }

            } else {

                if (this.isAxisEnabled('x')) {

                    this.indicatorX.css('opacity', 0);

                }

                if (this.isAxisEnabled('y')) {

                    this.indicatorY.css('opacity', 0);

                }

            }

        }

    };

    

    var Scroller = function(el, opts) {

        this.el = el;

        this.$el = $(el);

        

        iAuto.copy(this, mixin.scrollerMixin);

        

        opts = opts || {};

        iAuto.copy(this, opts);

        

        this.initScroller();

        

        //閺勵垰鎯侀弰鍓с仛濠婃艾濮╅弶锟�

        if(this.showIndicator) {

            iAuto.copy(this, mixin.IndicatorMixin);

            this.initIndicator();

        }

        

        var me = this;

        this.$el.one('destroy', function(e) {

            var id = el.afscrollerID;

            if(cache[id]) delete cache[id];

            

            e.stopPropagation();

        });

    };

    

    Scroller.prototype = {

        element: null

    };

    

    var cssTranslate = scroller.CssTranslate = function() {}; 

    cssTranslate.prototype = {

        transformElement: null,

        activeEasingX: null,

        activeEasingY: null,

        lastX: null,

        lastY: null,

        isAnimating: false,

        x: 0,

        y: 0,

        animationFrameId: null,



        init: function() {

            this.doAnimationFrame = iAuto.Util.bind(this,

                this.doAnimationFrame);

        },



        setTransformElement: function(transformElement) {

            this.transformElement = transformElement;

        },



        translate: function(x, y) {

            if (this.isAnimating) {

                this.stopAnimation();

            }



            if (!isNaN(x) && typeof x === 'number') {

                this.x = x;

            }



            if (!isNaN(y) && typeof y === 'number') {

                this.y = y;

            }

            this.doTranslate();

        },



        doTranslate: function() {

            var element = this.transformElement;

            element.style.webkitTransform = 'translate3d(' + this.x + 'px, ' + this.y + 'px, 0px)';

        },



        animate: function(easingX, easingY) {

            this.activeEasingX = easingX;

            this.activeEasingY = easingY;



            this.isAnimating = true;

            this.lastX = null;

            this.lastY = null;



            this.animationFrameId = window.requestAnimationFrame(this.doAnimationFrame);

            

            $.trigger(this, 'animationstart', [this.x, this.y]);



            return this;

        },



        doAnimationFrame: function() {

            var me = this,

                easingX = me.activeEasingX,

                easingY = me.activeEasingY,

                now = Date

                    .now(),

                x, y;



            this.animationFrameId = window.requestAnimationFrame(this.doAnimationFrame);



            if (!me.isAnimating) {

                return;

            }

            me.lastRun = now;

            if (easingX === null && easingY === null) {

                me.stopAnimation();

                return;

            }

            if (easingX !== null) {

                me.x = x = Math.round(easingX.getValue());



                if (easingX.isEnded) {

                    me.activeEasingX = null;

                }

            } else {

                x = me.x;

            }

            if (easingY !== null) {

                me.y = y = Math.round(easingY.getValue());



                if (easingY.isEnded) {

                    me.activeEasingY = null;

                }

            } else {

                y = me.y;

            }

            if (me.lastX !== x || me.lastY !== y) {

                me.doTranslate(x, y);



                me.lastX = x;

                me.lastY = y;

            }

            $.trigger(me, 'animationframe', [x, y]);

        },



        stopAnimation: function() {

            if (!this.isAnimating) {

                return;

            }



            this.activeEasingX = null;

            this.activeEasingY = null;



            this.isAnimating = false;



            window.cancelAnimationFrame(this.animationFrameId);

            $.trigger(this, 'animationend', [this.x, this.y]);

        },



        destroy: function() {

            this.stopAnimation();

        }

    };

    

    var EaseOut = scroller.EaseOut = function() {};

    EaseOut.prototype = {

        startTime: 0,

        startValue: 0,

        isEasing: true,

        isEnded: false,



        endValue: 0,

        exponent: 4,

        duration: 400,



        init: function() {



        },



        setStartTime: function(startTime) {

            this.startTime = startTime;

            this.reset();

        },



        setStartValue: function(startValue) {

            this.distance = this.endValue - startValue;

            this.startValue = startValue;

        },



        reset: function() {

            this.isEnded = false;

        },



        setEndValue: function(endValue) {

            this.distance = endValue - this.startValue;

            this.endValue = endValue;

        },



        setDuration: function(duration) {

            this.duration = duration;

        },



        setExponent: function(exponent) {

            this.exponent = exponent;

        },



        getValue: function() {

            var deltaTime = new Date().getTime() - this.startTime,

                duration = this.duration,

                startValue = this.startValue,

                endValue = this.endValue,

                distance = this.distance,

                theta = deltaTime / duration,

                thetaC = 1 - theta,

                thetaEnd = 1 - Math.pow(thetaC, this.exponent),

                currentValue = startValue + (thetaEnd * distance);



            if (deltaTime >= duration) {

                this.isEnded = true;

                return endValue;

            }

            return currentValue;

        }

    };



    var Momentum = scroller.Momentum = function() {};

    Momentum.prototype = {

        acceleration: 30,

        friction: 0.5,

        startVelocity: 0,



        alpha: 0,



        startTime: 0,

        startValue: 0,

        isEasing: true,

        isEnded: false,



        init: function() {

            this.setFriction(this.friction);

            this.setStartVelocity(this.startVelocity);

            this.setAcceleration(this.acceleration);

        },



        setStartTime: function(startTime) {

            this.startTime = startTime;

            this.reset();

        },



        setStartValue: function(startValue) {

            this.startValue = startValue;

        },



        reset: function() {

            this.isEnded = false;

        },



        setFriction: function(friction) {

            var theta = Math.log(1 - (friction / 10));



            this.theta = theta;



            this.alpha = theta / this.acceleration;

            this.friction = friction;

        },



        setStartVelocity: function(startVelocity) {

            this.velocity = startVelocity * this.acceleration;

            this.startVelocity = startVelocity;

        },



        setAcceleration: function(acceleration) {

            this.velocity = this.startVelocity * acceleration;

            this.alpha = this.theta / acceleration;

            this.acceleration = acceleration;

        },



        getValue: function() {

            return this.startValue - this.velocity * (1 - this.getFrictionFactor()) / this.theta;

        },



        getFrictionFactor: function() {

            var deltaTime = new Date().getTime() - this.startTime;



            return Math.exp(deltaTime * this.alpha);

        },



        getVelocity: function() {

            return this.getFrictionFactor() * this.velocity;

        }

    };



    var Bounce = scroller.Bounce = function() {};

    Bounce.prototype = {

        startTime: 0,

        startValue: 0,

        isEasing: true,

        isEnded: false,



        springTension: 0.3,

        acceleration: 30,

        startVelocity: 0,



        init: function() {



        },



        setStartTime: function(startTime) {

            this.startTime = startTime;

            this.reset();

        },



        setStartValue: function(startValue) {

            this.startValue = startValue;

        },



        reset: function() {

            this.isEnded = false;

        },



        setSpringTension: function(springTension) {

            this.springTension = springTension;

        },



        setAcceleration: function(acceleration) {

            this.acceleration = acceleration;

        },



        setStartVelocity: function(startVelocity) {

            this.startVelocity = startVelocity;

        },



        getValue: function() {

            var deltaTime = new Date().getTime() - this.startTime,

                theta = (deltaTime / this.acceleration),

                powTime = theta * Math.pow(Math.E, -this.springTension * theta);



            return this.startValue + (this.startVelocity * powTime);

        }

    };



    var BoundMomentum = scroller.BoundMomentum = function() {};

    BoundMomentum.prototype = {

        startTime: 0,

        startValue: 0,

        isEasing: true,

        isEnded: false,

        /**

         * @cfg {Object} momentum

         * A valid config object for {@link Ext.fx.easing.Momentum}

         * @accessor

         */

        momentum: null,



        /**

         * @cfg {Object} bounce

         * A valid config object for {@link Ext.fx.easing.Bounce}

         * @accessor

         */

        bounce: null,



        minMomentumValue: 0,



        maxMomentumValue: 0,



        /**

         * @cfg {Number} minVelocity

         * The minimum velocity to end this easing

         * @accessor

         */

        minVelocity: 0.01,



        /**

         * @cfg {Number} startVelocity

         * The start velocity

         * @accessor

         */

        startVelocity: 0,



        init: function() {

            this.initMomentum();

            this.initBounce();

        },



        initMomentum: function() {

            this.momentum = new Momentum();

            this.momentum.init();

        },



        setMinMomentumValue: function(minMomentumValue) {

            this.minMomentumValue = minMomentumValue;

        },



        setMaxMomentumValue: function(maxMomentumValue) {

            this.maxMomentumValue = maxMomentumValue;

        },



        setMinVelocity: function(minVelocity) {

            this.minVelocity = minVelocity;

        },



        setMomentum: function(momentum) {

            this.momentum = momentum;

        },



        initBounce: function() {

            this.bounce = new Bounce();

            this.bounce.init();

        },



        setBounce: function(bounce) {

            this.bounce = new Bounce();

        },



        setStartTime: function(startTime) {

            this.startTime = startTime;

            this.reset();

            this.momentum.setStartTime(startTime);

        },



        setStartVelocity: function(startVelocity) {

            this.momentum.setStartVelocity(startVelocity);

        },



        setStartValue: function(startValue) {

            this.momentum.setStartValue(startValue);

            this.startValue = startValue;

        },



        reset: function() {

            this.lastValue = null;



            this.isBouncingBack = false;



            this.isOutOfBound = false;



            this.isEnded = false;

        },



        getValue: function() {

            var momentum = this.momentum,

                bounce = this.bounce,

                startVelocity = momentum.startVelocity,

                direction = startVelocity > 0 ? 1 : -1,

                minValue = this.minMomentumValue,

                maxValue = this.maxMomentumValue,

                boundedValue = (direction == 1) ? maxValue : minValue,

                lastValue = this.lastValue,

                value, velocity;



            if (startVelocity === 0) {

                return this.startValue;

            }



            if (!this.isOutOfBound) {

                value = momentum.getValue();

                velocity = momentum.getVelocity();

                if (Math.abs(velocity) < this.minVelocity) {

                    this.isEnded = true;

                }



                if (value >= minValue && value <= maxValue) {

                    return value;

                }



                this.isOutOfBound = true;



                bounce.setStartTime(new Date().getTime());

                bounce.setStartVelocity(velocity);

                bounce.setStartValue(boundedValue);

            }



            value = bounce.getValue();

            if (!this.isEnded) {

                if (!this.isBouncingBack) {

                    if (lastValue !== null) {

                        if ((direction == 1 && value < lastValue) || (direction == -1 && value > lastValue)) {

                            this.isBouncingBack = true;

                        }

                    }

                } else {

                    if (Math.round(value) == boundedValue) {

                        this.isEnded = true;

                    }

                }

            }



            this.lastValue = value;



            return value;

        }

    };

    

})(af);
Scroller.js

当然首先要领会人家的思路,模仿人家的结构,再自己独立去写。

顺便更深的去掌握appframework

;

if (!window.af || typeof(af) !== "function") {

    var af = (function(M) {

        var j, h = M.document, O = [], s = O.slice, P = {}, o = [], k = 1, m = [], c = 1, y = /<(\w+)[^>]*>/, J = /^\.([\w-]+)$/, K = /^[\w-]+$/, p = {}, x = {}, W = {

            columncount : true,

            fontweight : true,

            lineheight : true,

            "column-count" : true,

            "font-weight" : true,

            "line-height" : true,

            opacity : true,

            orphans : true,

            widows : true,

            zIndex : true,

            "z-index" : true,

            zoom : true

        }, N = (typeof(MSApp) === "object");

        function E(Z, Y) {

            return (typeof(Y) === "number") && !W[Z.toLowerCase()]

                    ? Y + "px"

                    : Y

        }

        function G(ab, Y, ac) {

            var ad = h.createDocumentFragment();

            if (ac) {

                for (var aa = ab.length - 1; aa >= 0; aa--) {

                    ad.insertBefore(ab[aa], ad.firstChild)

                }

                Y.insertBefore(ad, Y.firstChild)

            } else {

                for (var Z = 0; Z < ab.length; Z++) {

                    ad.appendChild(ab[Z])

                }

                Y.appendChild(ad)

            }

            ad = null

        }

        function T(Y) {

            return Y in P

                    ? P[Y]

                    : (P[Y] = new RegExp("(^|\\s)" + Y + "(\\s|$)"))

        }

        function e(Y) {

            for (var Z = 0; Z < Y.length; Z++) {

                if (Y.indexOf(Y[Z]) != Z) {

                    Y.splice(Z, 1);

                    Z--

                }

            }

            return Y

        }

        function R(Z, aa) {

            var Y = [];

            if (Z == j) {

                return Y

            }

            for (; Z; Z = Z.nextSibling) {

                if (Z.nodeType == 1 && Z !== aa) {

                    Y.push(Z)

                }

            }

            return Y

        }

        var i = function(aa, ab) {

            this.length = 0;

            if (!aa) {

                return this

            } else {

                if (aa instanceof i && ab == j) {

                    return aa

                } else {

                    if (af.isFunction(aa)) {

                        return af(h).ready(aa)

                    } else {

                        if (af.isArray(aa) && aa.length != j) {

                            for (var Z = 0; Z < aa.length; Z++) {

                                this[this.length++] = aa[Z]

                            }

                            return this

                        } else {

                            if (af.isObject(aa) && af.isObject(ab)) {

                                if (aa.length == j) {

                                    if (aa.parentNode == ab) {

                                        this[this.length++] = aa

                                    }

                                } else {

                                    for (var Y = 0; Y < aa.length; Y++) {

                                        if (aa[Y].parentNode == ab) {

                                            this[this.length++] = aa[Y]

                                        }

                                    }

                                }

                                return this

                            } else {

                                if (af.isObject(aa) && ab == j) {

                                    this[this.length++] = aa;

                                    return this

                                } else {

                                    if (ab !== j) {

                                        if (ab instanceof i) {

                                            return ab.find(aa)

                                        }

                                    } else {

                                        ab = h

                                    }

                                }

                            }

                        }

                    }

                }

            }

            return this.selector(aa, ab)

        };

        var H = function(Y, Z) {

            return new i(Y, Z)

        };

        function U(Y, aa) {

            try {

                return aa.querySelectorAll(Y)

            } catch (Z) {

                return []

            }

        }

        function F(Y, aa) {

            Y = Y.trim();

            if (Y[0] === "#" && Y.indexOf(".") == -1 && Y.indexOf(",") == -1

                    && Y.indexOf(" ") === -1 && Y.indexOf(">") === -1) {

                if (aa == h) {

                    S(aa.getElementById(Y.replace("#", "")), this)

                } else {

                    S(U(Y, aa), this)

                }

            } else {

                if ((Y[0] === "<" && Y[Y.length - 1] === ">")

                        || (Y.indexOf("<") !== -1 && Y.indexOf(">") !== -1)) {

                    var Z = h.createElement("div");

                    if (N) {

                        MSApp.execUnsafeLocalFunction(function() {

                            Z.innerHTML = Y.trim()

                        })

                    } else {

                        Z.innerHTML = Y.trim()

                    }

                    S(Z.childNodes, this)

                } else {

                    S((U(Y, aa)), this)

                }

            }

            return this

        }

        function S(Y, aa) {

            if (!Y) {

                return

            }

            if (Y.nodeType) {

                aa[aa.length++] = Y;

                return

            }

            for (var Z = 0, ab = Y.length; Z < ab; Z++) {

                aa[aa.length++] = Y[Z]

            }

        }

        H.is$ = function(Y) {

            return Y instanceof i

        };

        H.map = function(ac, ad) {

            var ab, Y = [], aa, Z;

            if (H.isArray(ac)) {

                for (aa = 0; aa < ac.length; aa++) {

                    ab = ad.apply(ac[aa], [aa, ac[aa]]);

                    if (ab !== j) {

                        Y.push(ab)

                    }

                }

            } else {

                if (H.isObject(ac)) {

                    for (Z in ac) {

                        if (!ac.hasOwnProperty(Z) || Z == "length") {

                            continue

                        }

                        ab = ad(ac[Z], [Z, ac[Z]]);

                        if (ab !== j) {

                            Y.push(ab)

                        }

                    }

                }

            }

            return af(Y)

        };

        H.each = function(aa, ab) {

            var Z, Y;

            if (H.isArray(aa)) {

                for (Z = 0; Z < aa.length; Z++) {

                    if (ab(Z, aa[Z]) === false) {

                        return aa

                    }

                }

            } else {

                if (H.isObject(aa)) {

                    for (Y in aa) {

                        if (!aa.hasOwnProperty(Y) || Y == "length") {

                            continue

                        }

                        if (ab(Y, aa[Y]) === false) {

                            return aa

                        }

                    }

                }

            }

            return aa

        };

        H.extend = function(Z) {

            if (Z == j) {

                Z = this

            }

            if (arguments.length === 1) {

                for (var Y in Z) {

                    this[Y] = Z[Y]

                }

                return this

            } else {

                s.call(arguments, 1).forEach(function(ab) {

                    for (var aa in ab) {

                        Z[aa] = ab[aa]

                    }

                })

            }

            return Z

        };

        H.isArray = function(Y) {

            return Y instanceof Array && Y.push != j

        };

        H.isFunction = function(Y) {

            return typeof Y === "function" && !(Y instanceof RegExp)

        };

        H.isObject = function(Y) {

            return typeof Y === "object" && Y !== null

        };

        H.fn = i.prototype = {

            namepsace : "appframework",

            constructor : i,

            forEach : O.forEach,

            reduce : O.reduce,

            push : O.push,

            indexOf : O.indexOf,

            concat : O.concat,

            selector : F,

            oldElement : undefined,

            slice : O.slice,

            length : 0,

            setupOld : function(Y) {

                if (Y == j) {

                    return H()

                }

                Y.oldElement = this;

                return Y

            },

            map : function(aa) {

                var ab, Y = [], Z;

                for (Z = 0; Z < this.length; Z++) {

                    ab = aa.apply(this[Z], [Z, this[Z]]);

                    if (ab !== j) {

                        Y.push(ab)

                    }

                }

                return H(Y)

            },

            each : function(Y) {

                this.forEach(function(aa, Z) {

                    Y.call(aa, Z, aa)

                });

                return this

            },

            ready : function(Y) {

                if (h.readyState === "complete" || h.readyState === "loaded"

                        || (!H.os.ie && h.readyState === "interactive")) {

                    Y()

                } else {

                    h.addEventListener("DOMContentLoaded", Y, false)

                }

                return this

            },

            find : function(ab) {

                if (this.length === 0) {

                    return this

                }

                var Y = [];

                var ac;

                for (var aa = 0; aa < this.length; aa++) {

                    ac = (H(ab, this[aa]));

                    for (var Z = 0; Z < ac.length; Z++) {

                        Y.push(ac[Z])

                    }

                }

                return H(e(Y))

            },

            html : function(Z, aa) {

                if (this.length === 0) {

                    return this

                }

                if (Z === j) {

                    return this[0].innerHTML

                }

                for (var Y = 0; Y < this.length; Y++) {

                    if (aa !== false) {

                        H.cleanUpContent(this[Y], false, true)

                    }

                    if (N) {

                        var ab = this[Y];

                        MSApp.execUnsafeLocalFunction(function() {

                            ab.innerHTML = Z

                        })

                    } else {

                        this[Y].innerHTML = Z

                    }

                }

                return this

            },

            text : function(Z) {

                if (this.length === 0) {

                    return this

                }

                if (Z === j) {

                    return this[0].textContent

                }

                for (var Y = 0; Y < this.length; Y++) {

                    this[Y].textContent = Z

                }

                return this

            },

            css : function(ab, ac, ae) {

                var ad = ae != j ? ae : this[0];

                if (this.length === 0) {

                    return this

                }

                if (ac == j && typeof(ab) === "string") {

                    var aa = M.getComputedStyle(ad);

                    return ad.style[ab]

                            ? ad.style[ab]

                            : M.getComputedStyle(ad)[ab]

                }

                for (var Z = 0; Z < this.length; Z++) {

                    if (H.isObject(ab)) {

                        for (var Y in ab) {

                            this[Z].style[Y] = E(Y, ab[Y])

                        }

                    } else {

                        this[Z].style[ab] = E(ab, ac)

                    }

                }

                return this

            },

            vendorCss : function(Y, Z, aa) {

                return this.css(H.feat.cssPrefix + Y, Z, aa)

            },

            cssTranslate : function(Y) {

                return this

                        .vendorCss("Transform", "translate"

                                + H.feat.cssTransformStart + Y

                                + H.feat.cssTransformEnd)

            },

            computedStyle : function(Y) {

                if (this.length === 0 || Y == j) {

                    return

                }

                return M.getComputedStyle(this[0], "")[Y]

            },

            empty : function() {

                for (var Y = 0; Y < this.length; Y++) {

                    H.cleanUpContent(this[Y], false, true);

                    this[Y].textContent = ""

                }

                return this

            },

            hide : function() {

                if (this.length === 0) {

                    return this

                }

                for (var Y = 0; Y < this.length; Y++) {

                    if (this.css("display", null, this[Y]) != "none") {

                        this[Y].setAttribute("afmOldStyle", this.css("display",

                                null, this[Y]));

                        this[Y].style.display = "none"

                    }

                }

                return this

            },

            show : function() {

                if (this.length === 0) {

                    return this

                }

                for (var Y = 0; Y < this.length; Y++) {

                    if (this.css("display", null, this[Y]) == "none") {

                        this[Y].style.display = this[Y]

                                .getAttribute("afmOldStyle") ? this[Y]

                                .getAttribute("afmOldStyle") : "block";

                        this[Y].removeAttribute("afmOldStyle")

                    }

                }

                return this

            },

            toggle : function(Z) {

                if (this.length === 0) {

                    return this

                }

                var Y = !!(Z === true);

                for (var aa = 0; aa < this.length; aa++) {

                    if (this.css("display", null, this[aa]) != "none"

                            && (Z == j || Y === false)) {

                        this[aa].setAttribute("afmOldStyle", this.css(

                                "display", null, this[aa]));

                        this[aa].style.display = "none"

                    } else {

                        if (this.css("display", null, this[aa]) == "none"

                                && (Z == j || Y === true)) {

                            this[aa].style.display = this[aa]

                                    .getAttribute("afmOldStyle") ? this[aa]

                                    .getAttribute("afmOldStyle") : "block";

                            this[aa].removeAttribute("afmOldStyle")

                        }

                    }

                }

                return this

            },

            val : function(Z) {

                if (this.length === 0) {

                    return (Z === j) ? undefined : this

                }

                if (Z == j) {

                    return this[0].value

                }

                for (var Y = 0; Y < this.length; Y++) {

                    this[Y].value = Z

                }

                return this

            },

            attr : function(Y, ab) {

                if (this.length === 0) {

                    return (ab === j) ? undefined : this

                }

                if (ab === j && !H.isObject(Y)) {

                    var ac = (this[0].afmCacheId && p[this[0].afmCacheId][Y])

                            ? (this[0].afmCacheId && p[this[0].afmCacheId][Y])

                            : this[0].getAttribute(Y);

                    return ac

                }

                for (var aa = 0; aa < this.length; aa++) {

                    if (H.isObject(Y)) {

                        for (var Z in Y) {

                            H(this[aa]).attr(Z, Y[Z])

                        }

                    } else {

                        if (H.isArray(ab) || H.isObject(ab) || H.isFunction(ab)) {

                            if (!this[aa].afmCacheId) {

                                this[aa].afmCacheId = H.uuid()

                            }

                            if (!p[this[aa].afmCacheId]) {

                                p[this[aa].afmCacheId] = {}

                            }

                            p[this[aa].afmCacheId][Y] = ab

                        } else {

                            if (ab === null) {

                                this[aa].removeAttribute(Y);

                                if (this[aa].afmCacheId

                                        && p[this[aa].afmCacheId][Y]) {

                                    delete p[this[aa].afmCacheId][Y]

                                }

                            } else {

                                this[aa].setAttribute(Y, ab)

                            }

                        }

                    }

                }

                return this

            },

            removeAttr : function(Y) {

                var aa = this;

                for (var Z = 0; Z < this.length; Z++) {

                    Y.split(/\s+/g).forEach(function(ab) {

                        aa[Z].removeAttribute(ab);

                        if (aa[Z].afmCacheId && p[aa[Z].afmCacheId][Y]) {

                            delete p[aa[Z].afmCacheId][Y]

                        }

                    })

                }

                return this

            },

            prop : function(ad, ab) {

                if (this.length === 0) {

                    return (ab === j) ? undefined : this

                }

                if (ab === j && !H.isObject(ad)) {

                    var aa;

                    var ac = (this[0].afmCacheId && x[this[0].afmCacheId][ad])

                            ? (this[0].afmCacheId && x[this[0].afmCacheId][ad])

                            : !(aa = this[0][ad]) && ad in this[0]

                                    ? this[0][ad]

                                    : aa;

                    return ac

                }

                for (var Z = 0; Z < this.length; Z++) {

                    if (H.isObject(ad)) {

                        for (var Y in ad) {

                            H(this[Z]).prop(Y, ad[Y])

                        }

                    } else {

                        if (H.isArray(ab) || H.isObject(ab) || H.isFunction(ab)) {

                            if (!this[Z].afmCacheId) {

                                this[Z].afmCacheId = H.uuid()

                            }

                            if (!x[this[Z].afmCacheId]) {

                                x[this[Z].afmCacheId] = {}

                            }

                            x[this[Z].afmCacheId][ad] = ab

                        } else {

                            if (ab === null && ab !== undefined) {

                                H(this[Z]).removeProp(ad)

                            } else {

                                this[Z][ad] = ab

                            }

                        }

                    }

                }

                return this

            },

            removeProp : function(aa) {

                var Z = this;

                for (var Y = 0; Y < this.length; Y++) {

                    aa.split(/\s+/g).forEach(function(ab) {

                        if (Z[Y][ab]) {

                            Z[Y][ab] = undefined

                        }

                        if (Z[Y].afmCacheId && x[Z[Y].afmCacheId][aa]) {

                            delete x[Z[Y].afmCacheId][aa]

                        }

                    })

                }

                return this

            },

            remove : function(Y) {

                var Z = H(this).filter(Y);

                if (Z == j) {

                    return this

                }

                for (var aa = 0; aa < Z.length; aa++) {

                    H.cleanUpContent(Z[aa], true, true);

                    if (Z[aa] && Z[aa].parentNode) {

                        Z[aa].parentNode.removeChild(Z[aa])

                    }

                }

                return this

            },

            addClass : function(Z) {

                if (Z == j) {

                    return this

                }

                for (var aa = 0; aa < this.length; aa++) {

                    var Y = this[aa].className;

                    var ac = [];

                    var ab = this;

                    Z.split(/\s+/g).forEach(function(ad) {

                        if (!ab.hasClass(ad, ab[aa])) {

                            ac.push(ad)

                        }

                    });

                    this[aa].className += (Y ? " " : "") + ac.join(" ");

                    this[aa].className = this[aa].className.trim()

                }

                return this

            },

            removeClass : function(Y) {

                if (Y == j) {

                    return this

                }

                for (var Z = 0; Z < this.length; Z++) {

                    if (Y == j) {

                        this[Z].className = "";

                        return this

                    }

                    var aa = this[Z].className;

                    if (typeof this[Z].className == "object") {

                        aa = " "

                    }

                    Y.split(/\s+/g).forEach(function(ab) {

                        aa = aa.replace(T(ab), " ")

                    });

                    if (aa.length > 0) {

                        this[Z].className = aa.trim()

                    } else {

                        this[Z].className = ""

                    }

                }

                return this

            },

            toggleClass : function(Y, aa) {

                if (Y == j) {

                    return this

                }

                for (var Z = 0; Z < this.length; Z++) {

                    if (typeof aa != "boolean") {

                        aa = this.hasClass(Y, this[Z])

                    }

                    H(this[Z])[aa ? "removeClass" : "addClass"](Y)

                }

                return this

            },

            replaceClass : function(Z, Y) {

                if (Z == j || Y == j) {

                    return this

                }

                for (var aa = 0; aa < this.length; aa++) {

                    if (Z == j) {

                        this[aa].className = Y;

                        continue

                    }

                    var ab = this[aa].className;

                    Z.split(/\s+/g).concat(Y.split(/\s+/g))

                            .forEach(function(ac) {

                                ab = ab.replace(T(ac), " ")

                            });

                    ab = ab.trim();

                    if (ab.length > 0) {

                        this[aa].className = (ab + " " + Y).trim()

                    } else {

                        this[aa].className = Y

                    }

                }

                return this

            },

            hasClass : function(Y, Z) {

                if (this.length === 0) {

                    return false

                }

                if (!Z) {

                    Z = this[0]

                }

                return T(Y).test(Z.className)

            },

            append : function(Z, aa) {

                if (Z && Z.length != j && Z.length === 0) {

                    return this

                }

                if (H.isArray(Z) || H.isObject(Z)) {

                    Z = H(Z)

                }

                var Y;

                for (Y = 0; Y < this.length; Y++) {

                    if (Z.length && typeof Z != "string") {

                        Z = H(Z);

                        G(Z, this[Y], aa)

                    } else {

                        var ab = y.test(Z) ? H(Z) : undefined;

                        if (ab == j || ab.length === 0) {

                            ab = h.createTextNode(Z)

                        }

                        if (ab.nodeName != j

                                && ab.nodeName.toLowerCase() == "script"

                                && (!ab.type || ab.type.toLowerCase() === "text/javascript")) {

                            M["eval"](ab.innerHTML)

                        } else {

                            if (ab instanceof i) {

                                G(ab, this[Y], aa)

                            } else {

                                aa != j ? this[Y].insertBefore(ab,

                                        this[Y].firstChild) : this[Y]

                                        .appendChild(ab)

                            }

                        }

                    }

                }

                return this

            },

            appendTo : function(Y, aa) {

                var Z = H(Y);

                Z.append(this);

                return this

            },

            prependTo : function(Y) {

                var Z = H(Y);

                Z.append(this, true);

                return this

            },

            prepend : function(Y) {

                return this.append(Y, 1)

            },

            insertBefore : function(Z, aa) {

                if (this.length === 0) {

                    return this

                }

                Z = H(Z).get(0);

                if (!Z) {

                    return this

                }

                for (var Y = 0; Y < this.length; Y++) {

                    aa

                            ? Z.parentNode.insertBefore(this[Y], Z.nextSibling)

                            : Z.parentNode.insertBefore(this[Y], Z)

                }

                return this

            },

            insertAfter : function(Y) {

                this.insertBefore(Y, true)

            },

            get : function(Y) {

                Y = Y == j ? 0 : Y;

                if (Y < 0) {

                    Y += this.length

                }

                return (this[Y]) ? this[Y] : undefined

            },

            offset : function() {

                var Y;

                if (this.length === 0) {

                    return this

                }

                if (this[0] == M) {

                    return {

                        left : 0,

                        top : 0,

                        right : 0,

                        bottom : 0,

                        width : M.innerWidth,

                        height : M.innerHeight

                    }

                } else {

                    Y = this[0].getBoundingClientRect()

                }

                return {

                    left : Y.left + M.pageXOffset,

                    top : Y.top + M.pageYOffset,

                    right : Y.right + M.pageXOffset,

                    bottom : Y.bottom + M.pageYOffset,

                    width : Y.right - Y.left,

                    height : Y.bottom - Y.top

                }

            },

            height : function(Z) {

                if (this.length === 0) {

                    return this

                }

                if (Z != j) {

                    return this.css("height", Z)

                }

                if (this[0] == this[0].window) {

                    return M.innerHeight

                }

                if (this[0].nodeType == this[0].DOCUMENT_NODE) {

                    return this[0].documentElement.offsetheight

                } else {

                    var Y = this.css("height").replace("px", "");

                    if (Y) {

                        return Y

                    } else {

                        return this.offset().height

                    }

                }

            },

            width : function(Z) {

                if (this.length === 0) {

                    return this

                }

                if (Z != j) {

                    return this.css("width", Z)

                }

                if (this[0] == this[0].window) {

                    return M.innerWidth

                }

                if (this[0].nodeType == this[0].DOCUMENT_NODE) {

                    return this[0].documentElement.offsetwidth

                } else {

                    var Y = this.css("width").replace("px", "");

                    if (Y) {

                        return Y

                    } else {

                        return this.offset().width

                    }

                }

            },

            parent : function(Y, aa) {

                if (this.length === 0) {

                    return this

                }

                var Z = [];

                for (var ac = 0; ac < this.length; ac++) {

                    var ab = this[ac];

                    while (ab.parentNode && ab.parentNode != h) {

                        Z.push(ab.parentNode);

                        if (ab.parentNode) {

                            ab = ab.parentNode

                        }

                        if (!aa) {

                            break

                        }

                    }

                }

                return this.setupOld(H(e(Z)).filter(Y))

            },

            parents : function(Y) {

                return this.parent(Y, true)

            },

            children : function(Y) {

                if (this.length === 0) {

                    return this

                }

                var Z = [];

                for (var aa = 0; aa < this.length; aa++) {

                    Z = Z.concat(R(this[aa].firstChild))

                }

                return this.setupOld(H((Z)).filter(Y))

            },

            siblings : function(Y) {

                if (this.length === 0) {

                    return this

                }

                var Z = [];

                for (var aa = 0; aa < this.length; aa++) {

                    if (this[aa].parentNode) {

                        Z = Z

                                .concat(R(this[aa].parentNode.firstChild,

                                        this[aa]))

                    }

                }

                return this.setupOld(H(Z).filter(Y))

            },

            closest : function(Y, aa) {

                if (this.length === 0) {

                    return this

                }

                var Z = [], ab = this[0];

                var ac = H(Y, aa);

                if (ac.length === 0) {

                    return H()

                }

                while (ab && ac.indexOf(ab) == -1) {

                    ab = ab !== aa && ab !== h && ab.parentNode

                }

                return H(ab)

            },

            filter : function(Y) {

                if (this.length === 0) {

                    return this

                }

                if (Y == j) {

                    return this

                }

                var Z = [];

                for (var aa = 0; aa < this.length; aa++) {

                    var ab = this[aa];

                    if (ab.parentNode && H(Y, ab.parentNode).indexOf(ab) >= 0) {

                        Z.push(ab)

                    }

                }

                return this.setupOld(H(e(Z)))

            },

            not : function(Y) {

                if (this.length === 0) {

                    return this

                }

                var Z = [];

                for (var aa = 0; aa < this.length; aa++) {

                    var ab = this[aa];

                    if (ab.parentNode && H(Y, ab.parentNode).indexOf(ab) == -1) {

                        Z.push(ab)

                    }

                }

                return this.setupOld(H(e(Z)))

            },

            data : function(Y, Z) {

                return this.attr("data-" + Y, Z)

            },

            end : function() {

                return this.oldElement != j ? this.oldElement : H()

            },

            clone : function(Y) {

                Y = Y === false ? false : true;

                if (this.length === 0) {

                    return this

                }

                var Z = [];

                for (var aa = 0; aa < this.length; aa++) {

                    Z.push(this[aa].cloneNode(Y))

                }

                return H(Z)

            },

            size : function() {

                return this.length

            },

            serialize : function() {

                if (this.length === 0) {

                    return ""

                }

                var Z = [];

                for (var Y = 0; Y < this.length; Y++) {

                    this.slice.call(this[Y].elements).forEach(function(ac) {

                        var ab = ac.getAttribute("type");

                        if (ac.nodeName.toLowerCase() != "fieldset"

                                && !ac.disabled

                                && ab != "submit"

                                && ab != "reset"

                                && ab != "button"

                                && ((ab != "radio" && ab != "checkbox") || ac.checked)) {

                            if (ac.getAttribute("name")) {

                                if (ac.type == "select-multiple") {

                                    for (var aa = 0; aa < ac.options.length; aa++) {

                                        if (ac.options[aa].selected) {

                                            Z

                                                    .push(ac

                                                            .getAttribute("name")

                                                            + "="

                                                            + encodeURIComponent(ac.options[aa].value))

                                        }

                                    }

                                } else {

                                    Z.push(ac.getAttribute("name") + "="

                                            + encodeURIComponent(ac.value))

                                }

                            }

                        }

                    })

                }

                return Z.join("&")

            },

            eq : function(Y) {

                return H(this.get(Y))

            },

            index : function(Y) {

                return Y ? this.indexOf(H(Y)[0]) : this.parent().children()

                        .indexOf(this[0])

            },

            is : function(Y) {

                return !!Y && this.filter(Y).length > 0

            }

        };

        function a() {

        }

        H.ajaxSettings = {

            type : "GET",

            beforeSend : a,

            success : a,

            error : a,

            complete : a,

            context : undefined,

            timeout : 0,

            crossDomain : null

        };

        H.jsonP = function(Z) {

            if (N) {

                Z.type = "get";

                Z.dataType = null;

                return H.get(Z)

            }

            var ac = "jsonp_callback" + (++c);

            var ab = "", aa;

            var Y = h.createElement("script");

            var ad = function() {

                H(Y).remove();

                if (M[ac]) {

                    M[ac] = a

                }

            };

            M[ac] = function(ae) {

                clearTimeout(ab);

                H(Y).remove();

                delete M[ac];

                Z.success.call(aa, ae)

            };

            Y.src = Z.url.replace(/=\?/, "=" + ac);

            if (Z.error) {

                Y.onerror = function() {

                    clearTimeout(ab);

                    Z.error.call(aa, "", "error")

                }

            }

            H("head").append(Y);

            if (Z.timeout > 0) {

                ab = setTimeout(function() {

                    Z.error.call(aa, "", "timeout")

                }, Z.timeout)

            }

            return {}

        };

        H.ajax = function(Y) {

            var ag;

            try {

                var ab = Y || {};

                for (var ae in H.ajaxSettings) {

                    if (typeof(ab[ae]) == "undefined") {

                        ab[ae] = H.ajaxSettings[ae]

                    }

                }

                if (!ab.url) {

                    ab.url = M.location

                }

                if (!ab.contentType) {

                    ab.contentType = "application/x-www-form-urlencoded"

                }

                if (!ab.headers) {

                    ab.headers = {}

                }

                if (!("async" in ab) || ab.async !== false) {

                    ab.async = true

                }

                if (!ab.dataType) {

                    ab.dataType = "text/html"

                } else {

                    switch (ab.dataType) {

                        case "script" :

                            ab.dataType = "text/javascript, application/javascript";

                            break;

                        case "json" :

                            ab.dataType = "application/json";

                            break;

                        case "xml" :

                            ab.dataType = "application/xml, text/xml";

                            break;

                        case "html" :

                            ab.dataType = "text/html";

                            break;

                        case "text" :

                            ab.dataType = "text/plain";

                            break;

                        default :

                            ab.dataType = "text/html";

                            break;

                        case "jsonp" :

                            return H.jsonP(Y)

                    }

                }

                if (H.isObject(ab.data)) {

                    ab.data = H.param(ab.data)

                }

                if (ab.type.toLowerCase() === "get" && ab.data) {

                    if (ab.url.indexOf("?") === -1) {

                        ab.url += "?" + ab.data

                    } else {

                        ab.url += "&" + ab.data

                    }

                }

                if (/=\?/.test(ab.url)) {

                    return H.jsonP(ab)

                }

                if (ab.crossDomain === null) {

                    ab.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(ab.url)

                            && RegExp.$2 != M.location.host

                }

                if (!ab.crossDomain) {

                    ab.headers = H.extend({

                        "X-Requested-With" : "XMLHttpRequest"

                    }, ab.headers)

                }

                var ad;

                var aa = ab.context;

                var ah = /^([\w-]+:)\/\//.test(ab.url)

                        ? RegExp.$1

                        : M.location.protocol;

                ag = new M.XMLHttpRequest();

                ag.onreadystatechange = function() {

                    var ak = ab.dataType;

                    if (ag.readyState === 4) {

                        clearTimeout(ad);

                        var ai, aj = false;

                        if ((ag.status >= 200 && ag.status < 300)

                                || ag.status === 0) {

                            if (ak === "application/json"

                                    && !(/^\s*$/.test(ag.responseText))) {

                                try {

                                    ai = JSON.parse(ag.responseText)

                                } catch (al) {

                                    aj = al

                                }

                            } else {

                                if (ak === "application/xml, text/xml") {

                                    ai = ag.responseXML

                                } else {

                                    if (ak == "text/html") {

                                        ai = ag.responseText;

                                        H.parseJS(ai)

                                    } else {

                                        ai = ag.responseText

                                    }

                                }

                            }

                            if (ag.status === 0 && ai.length === 0) {

                                aj = true

                            }

                            if (aj) {

                                ab.error.call(aa, ag, "parsererror", aj)

                            } else {

                                ab.success.call(aa, ai, "success", ag)

                            }

                        } else {

                            aj = true;

                            ab.error.call(aa, ag, "error")

                        }

                        ab.complete.call(aa, ag, aj ? "error" : "success")

                    }

                };

                ag.open(ab.type, ab.url, ab.async);

                if (ab.withCredentials) {

                    ag.withCredentials = true

                }

                if (ab.contentType) {

                    ab.headers["Content-Type"] = ab.contentType

                }

                for (var Z in ab.headers) {

                    if (typeof ab.headers[Z] === "string") {

                        ag.setRequestHeader(Z, ab.headers[Z])

                    }

                }

                if (ab.beforeSend.call(aa, ag, ab) === false) {

                    ag.abort();

                    return false

                }

                if (ab.timeout > 0) {

                    ad = setTimeout(function() {

                        ag.onreadystatechange = a;

                        ag.abort();

                        ab.error.call(aa, ag, "timeout")

                    }, ab.timeout)

                }

                ag.send(ab.data)

            } catch (ac) {

                console.log(ac);

                ab.error.call(aa, ag, "error", ac)

            }

            return ag

        };

        H.get = function(Y, Z) {

            return this.ajax({

                url : Y,

                success : Z

            })

        };

        H.post = function(Z, aa, ab, Y) {

            if (typeof(aa) === "function") {

                ab = aa;

                aa = {}

            }

            if (Y === j) {

                Y = "html"

            }

            return this.ajax({

                url : Z,

                type : "POST",

                data : aa,

                dataType : Y,

                success : ab

            })

        };

        H.getJSON = function(Y, Z, aa) {

            if (typeof(Z) === "function") {

                aa = Z;

                Z = {}

            }

            return this.ajax({

                url : Y,

                data : Z,

                success : aa,

                dataType : "json"

            })

        };

        H.param = function(ac, aa) {

            var ad = [];

            if (ac instanceof i) {

                ac.each(function() {

                    var ag = aa ? aa + "[" + this.id + "]" : this.id, ae = this.value;

                    ad.push((ag) + "=" + encodeURIComponent(ae))

                })

            } else {

                for (var ab in ac) {

                    if (H.isFunction(ac[ab])) {

                        continue

                    }

                    var Z = aa ? aa + "[" + ab + "]" : ab, Y = ac[ab];

                    ad.push(H.isObject(Y) ? H.param(Y, Z) : (Z) + "="

                            + encodeURIComponent(Y))

                }

            }

            return ad.join("&")

        };

        H.parseJSON = function(Y) {

            return JSON.parse(Y)

        };

        H.parseXML = function(Y) {

            if (N) {

                MSApp.execUnsafeLocalFunction(function() {

                    return (new DOMParser()).parseFromString(Y, "text/xml")

                })

            } else {

                return (new DOMParser()).parseFromString(Y, "text/xml")

            }

        };

        function g(aa, Z) {

            aa.os = {};

            aa.os.webkit = Z.match(/WebKit\/([\d.]+)/) ? true : false;

            aa.os.android = Z.match(/(Android)\s+([\d.]+)/)

                    || Z.match(/Silk-Accelerated/) ? true : false;

            aa.os.androidICS = aa.os.android && Z.match(/(Android)\s4/)

                    ? true

                    : false;

            aa.os.ipad = Z.match(/(iPad).*OS\s([\d_]+)/) ? true : false;

            aa.os.iphone = !aa.os.ipad && Z.match(/(iPhone\sOS)\s([\d_]+)/)

                    ? true

                    : false;

            aa.os.ios7 = Z.match(/(iPhone\sOS)\s([7_]+)/) ? true : false;

            aa.os.webos = Z.match(/(webOS|hpwOS)[\s\/]([\d.]+)/) ? true : false;

            aa.os.touchpad = aa.os.webos && Z.match(/TouchPad/) ? true : false;

            aa.os.ios = aa.os.ipad || aa.os.iphone;

            aa.os.playbook = Z.match(/PlayBook/) ? true : false;

            aa.os.blackberry10 = Z.match(/BB10/) ? true : false;

            aa.os.blackberry = aa.os.playbook || aa.os.blackberry10

                    || Z.match(/BlackBerry/) ? true : false;

            aa.os.chrome = Z.match(/Chrome/) ? true : false;

            aa.os.opera = Z.match(/Opera/) ? true : false;

            aa.os.fennec = Z.match(/fennec/i) ? true : Z.match(/Firefox/)

                    ? true

                    : false;

            aa.os.ie = Z.match(/MSIE 10.0/i) ? true : false;

            aa.os.ieTouch = aa.os.ie && Z.toLowerCase().match(/touch/i)

                    ? true

                    : false;

            aa.os.supportsTouch = ((M.DocumentTouch && h instanceof M.DocumentTouch) || "ontouchstart" in M);

            aa.feat = {};

            var Y = h.documentElement.getElementsByTagName("head")[0];

            aa.feat.nativeTouchScroll = typeof(Y.style["-webkit-overflow-scrolling"]) !== "undefined"

                    && (aa.os.ios || aa.os.blackberry10);

            aa.feat.cssPrefix = aa.os.webkit ? "Webkit" : aa.os.fennec

                    ? "Moz"

                    : aa.os.ie ? "ms" : aa.os.opera ? "O" : "";

            aa.feat.cssTransformStart = !aa.os.opera ? "3d(" : "(";

            aa.feat.cssTransformEnd = !aa.os.opera ? ",0)" : ")";

            if (aa.os.android && !aa.os.webkit) {

                aa.os.android = false

            }

        }

        g(H, navigator.userAgent);

        H.__detectUA = g;

        H.uuid = function() {

            var Y = function() {

                return (((1 + Math.random()) * 65536) | 0).toString(16)

                        .substring(1)

            };

            return (Y() + Y() + "-" + Y() + "-" + Y() + "-" + Y() + "-" + Y()

                    + Y() + Y())

        };

        H.getCssMatrix = function(ac) {

            if (H.is$(ac)) {

                ac = ac.get(0)

            }

            var ab = M.WebKitCSSMatrix || M.MSCSSMatrix;

            if (ac === j) {

                if (ab) {

                    return new ab()

                } else {

                    return {

                        a : 0,

                        b : 0,

                        c : 0,

                        d : 0,

                        e : 0,

                        f : 0

                    }

                }

            }

            var Y = M.getComputedStyle(ac);

            var Z = Y.webkitTransform || Y.transform

                    || Y[H.feat.cssPrefix + "Transform"];

            if (ab) {

                return new ab(Z)

            } else {

                if (Z) {

                    var aa = Z.replace(/[^0-9\-.,]/g, "").split(",");

                    return {

                        a : +aa[0],

                        b : +aa[1],

                        c : +aa[2],

                        d : +aa[3],

                        e : +aa[4],

                        f : +aa[5]

                    }

                } else {

                    return {

                        a : 0,

                        b : 0,

                        c : 0,

                        d : 0,

                        e : 0,

                        f : 0

                    }

                }

            }

        };

        H.create = function(aa, Z) {

            var ab;

            var ac = new i();

            if (Z || aa[0] !== "<") {

                if (Z.html) {

                    Z.innerHTML = Z.html, delete Z.html

                }

                ab = h.createElement(aa);

                for (var Y in Z) {

                    ab[Y] = Z[Y]

                }

                ac[ac.length++] = ab

            } else {

                ab = h.createElement("div");

                if (N) {

                    MSApp.execUnsafeLocalFunction(function() {

                        ab.innerHTML = selector.trim()

                    })

                } else {

                    ab.innerHTML = aa

                }

                S(ab.childNodes, ac)

            }

            return ac

        };

        H.query = function(Z, aa) {

            if (!Z) {

                return new i()

            }

            aa = aa || h;

            var Y = new i();

            return Y.selector(Z, aa)

        };

        var b = {}, w = 1;

        function u(Y) {

            return Y._afmid || (Y._afmid = w++)

        }

        function L(Z, ab, aa, Y) {

            ab = t(ab);

            if (ab.ns) {

                var ac = D(ab.ns)

            }

            return (b[u(Z)] || []).filter(function(ad) {

                return ad

                        && (!ab.e || ad.e == ab.e)

                        && (!ab.ns || ac.test(ad.ns))

                        && (!aa || ad.fn == aa || (typeof ad.fn === "function"

                                && typeof aa === "function" && ad.fn === aa))

                        && (!Y || ad.sel == Y)

            })

        }

        function t(Y) {

            var Z = ("" + Y).split(".");

            return {

                e : Z[0],

                ns : Z.slice(1).sort().join(" ")

            }

        }

        function D(Y) {

            return new RegExp("(?:^| )" + Y.replace(" ", " .* ?") + "(?: |$)")

        }

        function r(Y, aa, Z) {

            if (H.isObject(Y)) {

                H.each(Y, Z)

            } else {

                Y.split(/\s/).forEach(function(ab) {

                    Z(ab, aa)

                })

            }

        }

        function f(ab, aa, ac, Z, Y) {

            var ae = u(ab), ad = (b[ae] || (b[ae] = []));

            r(aa, ac, function(aj, ai) {

                var ah = Y && Y(ai, aj), al = ah || ai;

                var ak = function(an) {

                    var am = al.apply(ab, [an].concat(an.data));

                    if (am === false) {

                        an.preventDefault()

                    }

                    return am

                };

                var ag = H.extend(t(aj), {

                    fn : ai,

                    proxy : ak,

                    sel : Z,

                    del : ah,

                    i : ad.length

                });

                ad.push(ag);

                ab.addEventListener(ag.e, ak, false)

            })

        }

        function z(aa, Z, ab, Y) {

            var ac = u(aa);

            r(Z || "", ab, function(ae, ad) {

                L(aa, ae, ad, Y).forEach(function(ag) {

                    delete b[ac][ag.i];

                    aa.removeEventListener(ag.e, ag.proxy, false)

                })

            })

        }

        H.event = {

            add : f,

            remove : z

        };

        H.fn.bind = function(Z, aa) {

            for (var Y = 0; Y < this.length; Y++) {

                f(this[Y], Z, aa)

            }

            return this

        };

        H.fn.unbind = function(Z, aa) {

            for (var Y = 0; Y < this.length; Y++) {

                z(this[Y], Z, aa)

            }

            return this

        };

        H.fn.one = function(Y, Z) {

            return this.each(function(ab, aa) {

                f(this, Y, Z, null, function(ad, ac) {

                    return function() {

                        z(aa, ac, ad);

                        var ae = ad.apply(aa, arguments);

                        return ae

                    }

                })

            })

        };

        var Q = function() {

            return true

        };

        var X = function() {

            return false

        };

        var v = {

            preventDefault : "isDefaultPrevented",

            stopImmediatePropagation : "isImmediatePropagationStopped",

            stopPropagation : "isPropagationStopped"

        };

        function C(Z) {

            var Y = H.extend({

                originalEvent : Z

            }, Z);

            H.each(v, function(ab, aa) {

                Y[ab] = function() {

                    this[aa] = Q;

                    if (ab == "stopImmediatePropagation"

                            || ab == "stopPropagation") {

                        Z.cancelBubble = true;

                        if (!Z[ab]) {

                            return

                        }

                    }

                    return Z[ab].apply(Z, arguments)

                };

                Y[aa] = X

            });

            return Y

        }

        function A(Z, aa, ab, Y) {

            f(Z, aa, ab, Y, function(ac) {

                return function(ag) {

                    var ad, ae = H(ag.target).closest(Y, Z).get(0);

                    if (ae) {

                        ad = H.extend(C(ag), {

                            currentTarget : ae,

                            liveFired : Z

                        });

                        return ac.apply(ae, [ad].concat([].slice.call(

                                arguments, 1)))

                    }

                }

            })

        }

        H.fn.delegate = function(Y, aa, ab) {

            for (var Z = 0; Z < this.length; Z++) {

                A(this[Z], aa, ab, Y)

            }

            return this

        };

        H.fn.undelegate = function(Y, aa, ab) {

            for (var Z = 0; Z < this.length; Z++) {

                z(this[Z], aa, ab, Y)

            }

            return this

        };

        H.fn.on = function(Z, Y, aa) {

            return Y === j || H.isFunction(Y) ? this.bind(Z, Y) : this

                    .delegate(Y, Z, aa)

        };

        H.fn.off = function(Z, Y, aa) {

            return Y === j || H.isFunction(Y) ? this.unbind(Z, Y) : this

                    .undelegate(Y, Z, aa)

        };

        H.fn.trigger = function(aa, ab, Z) {

            if (typeof aa == "string") {

                aa = H.Event(aa, Z)

            }

            aa.data = ab;

            for (var Y = 0; Y < this.length; Y++) {

                this[Y].dispatchEvent(aa)

            }

            return this

        };

        H.Event = function(ab, aa) {

            var ac = h.createEvent("Events"), Y = true;

            if (aa) {

                for (var Z in aa) {

                    (Z == "bubbles") ? (Y = !!aa[Z]) : (ac[Z] = aa[Z])

                }

            }

            ac.initEvent(ab, Y, true, null, null, null, null, null, null, null,

                    null, null, null, null, null);

            return ac

        };

        H.bind = function(ab, Z, aa) {

            if (!ab) {

                return

            }

            if (!ab.__events) {

                ab.__events = {}

            }

            if (!H.isArray(Z)) {

                Z = [Z]

            }

            for (var Y = 0; Y < Z.length; Y++) {

                if (!ab.__events[Z[Y]]) {

                    ab.__events[Z[Y]] = []

                }

                ab.__events[Z[Y]].push(aa)

            }

        };

        H.trigger = function(ae, ad, ab) {

            if (!ae) {

                return

            }

            var aa = true;

            if (!ae.__events) {

                return aa

            }

            if (!H.isArray(ad)) {

                ad = [ad]

            }

            if (!H.isArray(ab)) {

                ab = []

            }

            for (var ac = 0; ac < ad.length; ac++) {

                if (ae.__events[ad[ac]]) {

                    var Y = ae.__events[ad[ac]].slice(0);

                    for (var Z = 0; Z < Y.length; Z++) {

                        if (H.isFunction(Y[Z]) && Y[Z].apply(ae, ab) === false) {

                            aa = false

                        }

                    }

                }

            }

            return aa

        };

        H.unbind = function(ad, ab, ac) {

            if (!ad.__events) {

                return

            }

            if (!H.isArray(ab)) {

                ab = [ab]

            }

            for (var aa = 0; aa < ab.length; aa++) {

                if (ad.__events[ab[aa]]) {

                    var Y = ad.__events[ab[aa]];

                    for (var Z = 0; Z < Y.length; Z++) {

                        if (ac == j) {

                            delete Y[Z]

                        }

                        if (Y[Z] == ac) {

                            Y.splice(Z, 1);

                            break

                        }

                    }

                }

            }

        };

        H.proxy = function(Z, aa, Y) {

            return function() {

                if (Y) {

                    return Z.apply(aa, Y)

                }

                return Z.apply(aa, arguments)

            }

        };

        function n(aa, Z) {

            if (Z && aa.dispatchEvent) {

                var ab = H.Event("destroy", {

                    bubbles : false

                });

                aa.dispatchEvent(ab)

            }

            var ac = u(aa);

            if (ac && b[ac]) {

                for (var Y in b[ac]) {

                    aa.removeEventListener(b[ac][Y].e, b[ac][Y].proxy, false)

                }

                delete b[ac]

            }

        }

        function I(ab, aa) {

            if (!ab) {

                return

            }

            var Z = ab.childNodes;

            if (Z && Z.length > 0) {

                for (var Y; Y < Z.length; Y++) {

                    I(Z[Y], aa)

                }

            }

            n(ab, aa)

        }

        var q = function(aa, Z) {

            for (var Y = 0; Y < aa.length; Y++) {

                I(aa[Y], Z)

            }

        };

        H.cleanUpContent = function(aa, Y, Z) {

            if (!aa) {

                return

            }

            var ab = aa.childNodes;

            if (ab && ab.length > 0) {

                H.asap(q, {}, [s.apply(ab, [0]), Z])

            }

            if (Y) {

                n(aa, Z)

            }

        };

        var V = [];

        var B = [];

        var d = [];

        H.asap = function(aa, Z, Y) {

            if (!H.isFunction(aa)) {

                throw "$.asap - argument is not a valid function"

            }

            V.push(aa);

            B.push(Z ? Z : {});

            d.push(Y ? Y : []);

            M.postMessage("afm-asap", "*")

        };

        M.addEventListener("message", function(Y) {

            if (Y.source == M && Y.data == "afm-asap") {

                Y.stopPropagation();

                if (V.length > 0) {

                    (V.shift()).apply(B.shift(), d.shift())

                }

            }

        }, true);

        var l = {};

        H.parseJS = function(ac) {

            if (!ac) {

                return

            }

            if (typeof(ac) == "string") {

                var aa = h.createElement("div");

                if (N) {

                    MSApp.execUnsafeLocalFunction(function() {

                        aa.innerHTML = ac

                    })

                } else {

                    aa.innerHTML = ac

                }

                ac = aa

            }

            var Y = ac.getElementsByTagName("script");

            ac = null;

            for (var Z = 0; Z < Y.length; Z++) {

                if (Y[Z].src.length > 0 && !l[Y[Z].src] && !N) {

                    var ab = h.createElement("script");

                    ab.type = Y[Z].type;

                    ab.src = Y[Z].src;

                    h.getElementsByTagName("head")[0].appendChild(ab);

                    l[Y[Z].src] = 1;

                    ab = null

                } else {

                    M["eval"](Y[Z].innerHTML)

                }

            }

        };

        ["click", "keydown", "keyup", "keypress", "submit", "load", "resize",

                "change", "select", "error"].forEach(function(Y) {

            H.fn[Y] = function(Z) {

                return Z ? this.bind(Y, Z) : this.trigger(Y)

            }

        });

        ["focus", "blur"].forEach(function(Y) {

            H.fn[Y] = function(ab) {

                if (this.length === 0) {

                    return

                }

                if (ab) {

                    this.bind(Y, ab)

                } else {

                    for (var Z = 0; Z < this.length; Z++) {

                        try {

                            this[Z][Y]()

                        } catch (aa) {

                        }

                    }

                }

                return this

            }

        });

        return H

    })(window);

    window.jq = af;

    "$" in window || (window.$ = af);

    if (typeof define === "function" && define.amd) {

        define("appframework", [], function() {

            return af

        })

    } else {

        if (typeof module !== "undefined" && module.exports) {

            module.exports.af = af;

            module.exports.$ = af

        }

    }

    if (!window.numOnly) {

        window.numOnly = function numOnly(a) {

            if (a === undefined || a === "") {

                return 0

            }

            if (isNaN(parseFloat(a))) {

                if (a.replace) {

                    a = a.replace(/[^0-9.-]/g, "")

                } else {

                    return 0

                }

            }

            return parseFloat(a)

        }

    }

}

/*! Hammer.JS - v1.0.6dev - 2013-11-18

 * http://eightmedia.github.com/hammer.js

 *

 * Copyright (c) 2013 Jorik Tangelder <[email protected]>;

 * Licensed under the MIT license */

(function(B, j) {

    var w = function(M, L) {

        return new w.Instance(M, L || {})

    };

    w.defaults = {

        stop_browser_behavior : {

            userSelect : "none",

            touchAction : "none",

            touchCallout : "none",

            contentZooming : "none",

            userDrag : "none",

            tapHighlightColor : "rgba(0,0,0,0)"

        }

    };

    w.HAS_POINTEREVENTS = B.navigator.pointerEnabled

            || B.navigator.msPointerEnabled;

    w.HAS_TOUCHEVENTS = ("ontouchstart" in B);

    w.MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android|silk/i;

    w.NO_MOUSEEVENTS = w.HAS_TOUCHEVENTS

            && B.navigator.userAgent.match(w.MOBILE_REGEX);

    w.EVENT_TYPES = {};

    w.DIRECTION_DOWN = "down";

    w.DIRECTION_LEFT = "left";

    w.DIRECTION_UP = "up";

    w.DIRECTION_RIGHT = "right";

    w.POINTER_MOUSE = "mouse";

    w.POINTER_TOUCH = "touch";

    w.POINTER_PEN = "pen";

    w.EVENT_START = "start";

    w.EVENT_MOVE = "move";

    w.EVENT_END = "end";

    w.DOCUMENT = B.document;

    w.plugins = w.plugins || {};

    w.gestures = w.gestures || {};

    w.READY = false;

    function e() {

        if (w.READY) {

            return

        }

        w.event.determineEventTypes();

        w.utils.each(w.gestures, function(L) {

            w.detection.register(L)

        });

        w.event.onTouch(w.DOCUMENT, w.EVENT_MOVE, w.detection.detect);

        w.event.onTouch(w.DOCUMENT, w.EVENT_END, w.detection.detect);

        w.READY = true

    }

    w.utils = {

        extend : function i(L, N, O) {

            for (var M in N) {

                if (L[M] !== j && O) {

                    continue

                }

                L[M] = N[M]

            }

            return L

        },

        each : function(P, N, M) {

            if ("forEach" in P) {

                P.forEach(N, M)

            } else {

                if (P.length != j) {

                    for (var L = 0, O = P.length; L < O; L++) {

                        if (N.call(M, P[L], L, P) === false) {

                            return

                        }

                    }

                } else {

                    for (var L in P) {

                        if (P.hasOwnProperty(L)

                                && N.call(M, P[L], L, P) === false) {

                            return

                        }

                    }

                }

            }

        },

        hasParent : function(M, L) {

            while (M) {

                if (M == L) {

                    return true

                }

                M = M.parentNode

            }

            return false

        },

        getCenter : function x(M) {

            var N = [], L = [];

            w.utils.each(M, function(O) {

                N.push(typeof O.clientX !== "undefined" ? O.clientX : O.pageX);

                L.push(typeof O.clientY !== "undefined" ? O.clientY : O.pageY)

            });

            return {

                pageX : ((Math.min.apply(Math, N) + Math.max.apply(Math, N)) / 2),

                pageY : ((Math.min.apply(Math, L) + Math.max.apply(Math, L)) / 2)

            }

        },

        getVelocity : function a(L, N, M) {

            return {

                x : Math.abs(N / L) || 0,

                y : Math.abs(M / L) || 0

            }

        },

        getAngle : function n(N, M) {

            var O = M.pageY - N.pageY, L = M.pageX - N.pageX;

            return Math.atan2(O, L) * 180 / Math.PI

        },

        getDirection : function k(N, M) {

            var L = Math.abs(N.pageX - M.pageX), O = Math

                    .abs(N.pageY - M.pageY);

            if (L >= O) {

                return N.pageX - M.pageX > 0

                        ? w.DIRECTION_LEFT

                        : w.DIRECTION_RIGHT

            } else {

                return N.pageY - M.pageY > 0

                        ? w.DIRECTION_UP

                        : w.DIRECTION_DOWN

            }

        },

        getDistance : function m(N, M) {

            var L = M.pageX - N.pageX, O = M.pageY - N.pageY;

            return Math.sqrt((L * L) + (O * O))

        },

        getScale : function v(M, L) {

            if (M.length >= 2 && L.length >= 2) {

                return this.getDistance(L[0], L[1])

                        / this.getDistance(M[0], M[1])

            }

            return 1

        },

        getRotation : function t(M, L) {

            if (M.length >= 2 && L.length >= 2) {

                return this.getAngle(L[1], L[0]) - this.getAngle(M[1], M[0])

            }

            return 0

        },

        isVertical : function A(L) {

            return (L == w.DIRECTION_UP || L == w.DIRECTION_DOWN)

        },

        stopDefaultBrowserBehavior : function c(M, L) {

            var O, N = ["webkit", "khtml", "moz", "Moz", "ms", "o", ""];

            if (!L || !M || !M.style) {

                return

            }

            w.utils.each(N, function(P) {

                w.utils.each(L, function(Q) {

                    if (P) {

                        Q = N + Q.substring(0, 1).toUpperCase()

                                + Q.substring(1)

                    }

                    if (Q in M.style) {

                        M.style[Q] = Q

                    }

                })

            });

            if (L.userSelect == "none") {

                M.onselectstart = function() {

                    return false

                }

            }

            if (L.userDrag == "none") {

                M.ondragstart = function() {

                    return false

                }

            }

        }

    };

    w.Instance = function(N, M) {

        var L = this;

        e();

        this.element = N;

        this.enabled = true;

        this.options = w.utils.extend(w.utils.extend({}, w.defaults), M || {});

        if (this.options.stop_browser_behavior) {

            w.utils.stopDefaultBrowserBehavior(this.element,

                    this.options.stop_browser_behavior)

        }

        w.event.onTouch(N, w.EVENT_START, function(O) {

            if (L.enabled) {

                w.detection.startDetect(L, O)

            }

        });

        return this

    };

    w.Instance.prototype = {

        on : function C(L, M) {

            var N = L.split(" ");

            w.utils.each(N, function(O) {

                this.element.addEventListener(O, M, false)

            }, this);

            return this

        },

        off : function o(L, M) {

            var N = L.split(" ");

            w.utils.each(N, function(O) {

                this.element.removeEventListener(O, M, false)

            }, this);

            return this

        },

        trigger : function G(M, O) {

            if (!O) {

                O = {}

            }

            var N = w.DOCUMENT.createEvent("Event");

            N.initEvent(M, true, true);

            N.gesture = O;

            var L = this.element;

            if (w.utils.hasParent(O.target, L)) {

                L = O.target

            }

            L.dispatchEvent(N);

            return this

        },

        enable : function d(L) {

            this.enabled = L;

            return this

        }

    };

    var F = null;

    var l = false;

    var h = false;

    w.event = {

        bindDom : function(M, O, N) {

            var L = O.split(" ");

            w.utils.each(L, function(P) {

                M.addEventListener(P, N, false)

            })

        },

        onTouch : function z(N, M, O) {

            var L = this;

            this.bindDom(N, w.EVENT_TYPES[M], function P(R) {

                var S = R.type.toLowerCase();

                if (S.match(/mouse/) && h) {

                    return

                } else {

                    if (S.match(/touch/) || S.match(/pointerdown/)

                            || (S.match(/mouse/) && R.which === 1)) {

                        l = true

                    } else {

                        if (S.match(/mouse/) && !R.which) {

                            l = false

                        }

                    }

                }

                if (S.match(/touch|pointer/)) {

                    h = true

                }

                var Q = 0;

                if (l) {

                    if (w.HAS_POINTEREVENTS && M != w.EVENT_END) {

                        Q = w.PointerEvent.updatePointer(M, R)

                    } else {

                        if (S.match(/touch/)) {

                            Q = R.touches.length

                        } else {

                            if (!h) {

                                Q = S.match(/up/) ? 0 : 1

                            }

                        }

                    }

                    if (Q > 0 && M == w.EVENT_END) {

                        M = w.EVENT_MOVE

                    } else {

                        if (!Q) {

                            M = w.EVENT_END

                        }

                    }

                    if (Q || F === null) {

                        F = R

                    }

                    O.call(w.detection, L.collectEventData(N, M, L

                            .getTouchList(F, M), R));

                    if (w.HAS_POINTEREVENTS && M == w.EVENT_END) {

                        Q = w.PointerEvent.updatePointer(M, R)

                    }

                }

                if (!Q) {

                    F = null;

                    l = false;

                    h = false;

                    w.PointerEvent.reset()

                }

            })

        },

        determineEventTypes : function E() {

            var L;

            if (w.HAS_POINTEREVENTS) {

                L = w.PointerEvent.getEvents()

            } else {

                if (w.NO_MOUSEEVENTS) {

                    L = ["touchstart", "touchmove", "touchend touchcancel"]

                } else {

                    L = ["touchstart mousedown", "touchmove mousemove",

                            "touchend touchcancel mouseup"]

                }

            }

            w.EVENT_TYPES[w.EVENT_START] = L[0];

            w.EVENT_TYPES[w.EVENT_MOVE] = L[1];

            w.EVENT_TYPES[w.EVENT_END] = L[2]

        },

        getTouchList : function s(L) {

            if (w.HAS_POINTEREVENTS) {

                return w.PointerEvent.getTouchList()

            } else {

                if (L.touches) {

                    return L.touches

                } else {

                    L.indentifier = 1;

                    return [L]

                }

            }

        },

        collectEventData : function J(N, M, P, O) {

            var L = w.POINTER_TOUCH;

            if (O.type.match(/mouse/)

                    || w.PointerEvent.matchType(w.POINTER_MOUSE, O)) {

                L = w.POINTER_MOUSE

            }

            return {

                center : w.utils.getCenter(P),

                timeStamp : new Date().getTime(),

                target : O.target,

                touches : P,

                eventType : M,

                pointerType : L,

                srcEvent : O,

                preventDefault : function() {

                    if (this.srcEvent.preventManipulation) {

                        this.srcEvent.preventManipulation()

                    }

                    if (this.srcEvent.preventDefault) {

                        this.srcEvent.preventDefault()

                    }

                },

                stopPropagation : function() {

                    this.srcEvent.stopPropagation()

                },

                stopDetect : function() {

                    return w.detection.stopDetect()

                }

            }

        }

    };

    w.PointerEvent = {

        pointers : {},

        getTouchList : function() {

            var L = this;

            var M = [];

            w.utils.each(L.pointers, function(N) {

                M.push(N)

            });

            return M

        },

        updatePointer : function(M, L) {

            if (M == w.EVENT_END) {

                this.pointers = {}

            } else {

                L.identifier = L.pointerId;

                this.pointers[L.pointerId] = L

            }

            return Object.keys(this.pointers).length

        },

        matchType : function(L, N) {

            if (!N.pointerType) {

                return false

            }

            var O = N.pointerType, M = {};

            M[w.POINTER_MOUSE] = (O === N.MSPOINTER_TYPE_MOUSE || O === w.POINTER_MOUSE);

            M[w.POINTER_TOUCH] = (O === N.MSPOINTER_TYPE_TOUCH || O === w.POINTER_TOUCH);

            M[w.POINTER_PEN] = (O === N.MSPOINTER_TYPE_PEN || O === w.POINTER_PEN);

            return M[L]

        },

        getEvents : function() {

            return ["pointerdown MSPointerDown", "pointermove MSPointerMove",

                    "pointerup pointercancel MSPointerUp MSPointerCancel"]

        },

        reset : function() {

            this.pointers = {}

        }

    };

    w.detection = {

        gestures : [],

        current : null,

        previous : null,

        stopped : false,

        startDetect : function y(M, L) {

            if (this.current) {

                return

            }

            this.stopped = false;

            this.current = {

                inst : M,

                startEvent : w.utils.extend({}, L),

                lastEvent : false,

                name : ""

            };

            this.detect(L)

        },

        detect : function q(L) {

            if (!this.current || this.stopped) {

                return

            }

            L = this.extendEventData(L);

            var M = this.current.inst.options;

            w.utils.each(this.gestures, function(N) {

                if (!this.stopped && M[N.name] !== false) {

                    if (N.handler.call(N, L, this.current.inst) === false) {

                        this.stopDetect();

                        return false

                    }

                }

            }, this);

            if (this.current) {

                this.current.lastEvent = L

            }

            if (L.eventType == w.EVENT_END && !L.touches.length - 1) {

                this.stopDetect()

            }

            return L

        },

        stopDetect : function b() {

            this.previous = w.utils.extend({}, this.current);

            this.current = null;

            this.stopped = true

        },

        extendEventData : function u(O) {

            var P = this.current.startEvent;

            if (P

                    && (O.touches.length != P.touches.length || O.touches === P.touches)) {

                P.touches = [];

                w.utils.each(O.touches, function(T) {

                    P.touches.push(w.utils.extend({}, T))

                })

            }

            var M = O.timeStamp - P.timeStamp, S = O.center.pageX

                    - P.center.pageX, R = O.center.pageY - P.center.pageY, N = w.utils

                    .getVelocity(M, S, R), Q, L;

            if (O.eventType === "end") {

                Q = this.current.lastEvent

                        && this.current.lastEvent.interimAngle;

                L = this.current.lastEvent

                        && this.current.lastEvent.interimDirection

            } else {

                Q = this.current.lastEvent

                        && w.utils.getAngle(this.current.lastEvent.center,

                                O.center);

                L = this.current.lastEvent

                        && w.utils.getDirection(this.current.lastEvent.center,

                                O.center)

            }

            w.utils.extend(O, {

                deltaTime : M,

                deltaX : S,

                deltaY : R,

                velocityX : N.x,

                velocityY : N.y,

                distance : w.utils.getDistance(P.center, O.center),

                angle : w.utils.getAngle(P.center, O.center),

                interimAngle : Q,

                direction : w.utils.getDirection(P.center, O.center),

                interimDirection : L,

                scale : w.utils.getScale(P.touches, O.touches),

                rotation : w.utils.getRotation(P.touches, O.touches),

                startEvent : P

            });

            return O

        },

        register : function f(M) {

            var L = M.defaults || {};

            if (L[M.name] === j) {

                L[M.name] = true

            }

            w.utils.extend(w.defaults, L, true);

            M.index = M.index || 1000;

            this.gestures.push(M);

            this.gestures.sort(function(O, N) {

                if (O.index < N.index) {

                    return -1

                }

                if (O.index > N.index) {

                    return 1

                }

                return 0

            });

            return this.gestures

        }

    };

    w.gestures.Drag = {

        name : "drag",

        index : 50,

        defaults : {

            drag_min_distance : 10,

            correct_for_drag_min_distance : true,

            drag_max_touches : 1,

            drag_block_horizontal : false,

            drag_block_vertical : false,

            drag_lock_to_axis : false,

            drag_lock_min_distance : 25

        },

        triggered : false,

        handler : function r(M, N) {

            if (w.detection.current.name != this.name && this.triggered) {

                N.trigger(this.name + "end", M);

                this.triggered = false;

                return

            }

            if (N.options.drag_max_touches > 0

                    && M.touches.length > N.options.drag_max_touches) {

                return

            }

            switch (M.eventType) {

                case w.EVENT_START :

                    this.triggered = false;

                    break;

                case w.EVENT_MOVE :

                    if (M.distance < N.options.drag_min_distance

                            && w.detection.current.name != this.name) {

                        return

                    }

                    if (w.detection.current.name != this.name) {

                        w.detection.current.name = this.name;

                        if (N.options.correct_for_drag_min_distance

                                && M.distance > 0) {

                            var L = Math.abs(N.options.drag_min_distance

                                    / M.distance);

                            w.detection.current.startEvent.center.pageX += M.deltaX

                                    * L;

                            w.detection.current.startEvent.center.pageY += M.deltaY

                                    * L;

                            M = w.detection.extendEventData(M)

                        }

                    }

                    if (w.detection.current.lastEvent.drag_locked_to_axis

                            || (N.options.drag_lock_to_axis && N.options.drag_lock_min_distance <= M.distance)) {

                        M.drag_locked_to_axis = true

                    }

                    var O = w.detection.current.lastEvent.direction;

                    if (M.drag_locked_to_axis && O !== M.direction) {

                        if (w.utils.isVertical(O)) {

                            M.direction = (M.deltaY < 0)

                                    ? w.DIRECTION_UP

                                    : w.DIRECTION_DOWN

                        } else {

                            M.direction = (M.deltaX < 0)

                                    ? w.DIRECTION_LEFT

                                    : w.DIRECTION_RIGHT

                        }

                    }

                    if (!this.triggered) {

                        N.trigger(this.name + "start", M);

                        this.triggered = true

                    }

                    N.trigger(this.name, M);

                    N.trigger(this.name + M.direction, M);

                    if ((N.options.drag_block_vertical && w.utils

                            .isVertical(M.direction))

                            || (N.options.drag_block_horizontal && !w.utils

                                    .isVertical(M.direction))) {

                        M.preventDefault()

                    }

                    break;

                case w.EVENT_END :

                    if (this.triggered) {

                        N.trigger(this.name + "end", M)

                    }

                    this.triggered = false;

                    break

            }

        }

    };

    w.gestures.Hold = {

        name : "hold",

        index : 10,

        defaults : {

            hold_timeout : 500,

            hold_threshold : 1

        },

        timer : null,

        handler : function I(L, M) {

            switch (L.eventType) {

                case w.EVENT_START :

                    clearTimeout(this.timer);

                    w.detection.current.name = this.name;

                    this.timer = setTimeout(function() {

                        if (w.detection.current.name == "hold") {

                            M.trigger("hold", L)

                        }

                    }, M.options.hold_timeout);

                    break;

                case w.EVENT_MOVE :

                    if (L.distance > M.options.hold_threshold) {

                        clearTimeout(this.timer)

                    }

                    break;

                case w.EVENT_END :

                    clearTimeout(this.timer);

                    break

            }

        }

    };

    w.gestures.Release = {

        name : "release",

        index : Infinity,

        handler : function H(L, M) {

            if (L.eventType == w.EVENT_END) {

                M.trigger(this.name, L)

            }

        }

    };

    w.gestures.Swipe = {

        name : "swipe",

        index : 40,

        defaults : {

            swipe_min_touches : 1,

            swipe_max_touches : 1,

            swipe_velocity : 0.7

        },

        handler : function K(L, M) {

            if (L.eventType == w.EVENT_END) {

                if (M.options.swipe_max_touches > 0

                        && L.touches.length < M.options.swipe_min_touches

                        && L.touches.length > M.options.swipe_max_touches) {

                    return

                }

                if (L.velocityX > M.options.swipe_velocity

                        || L.velocityY > M.options.swipe_velocity) {

                    M.trigger(this.name, L);

                    M.trigger(this.name + L.direction, L)

                }

            }

        }

    };

    w.gestures.Tap = {

        name : "tap",

        index : 100,

        defaults : {

            tap_max_touchtime : 250,

            tap_max_distance : 10,

            tap_always : true,

            doubletap_distance : 20,

            doubletap_interval : 300

        },

        handler : function D(N, O) {

            if (N.eventType == w.EVENT_END && N.srcEvent.type != "touchcancel") {

                var M = w.detection.previous, L = false;

                if (N.deltaTime > O.options.tap_max_touchtime

                        || N.distance > O.options.tap_max_distance) {

                    return

                }

                if (M

                        && M.name == "tap"

                        && (N.timeStamp - M.lastEvent.timeStamp) < O.options.doubletap_interval

                        && N.distance < O.options.doubletap_distance) {

                    O.trigger("doubletap", N);

                    L = true

                }

                if (!L || O.options.tap_always) {

                    w.detection.current.name = "tap";

                    O.trigger(w.detection.current.name, N)

                }

            }

        }

    };

    w.gestures.Touch = {

        name : "touch",

        index : -Infinity,

        defaults : {

            prevent_default : false,

            prevent_mouseevents : false

        },

        handler : function g(L, M) {

            if (M.options.prevent_mouseevents

                    && L.pointerType == w.POINTER_MOUSE) {

                L.stopDetect();

                return

            }

            if (M.options.prevent_default) {

                L.preventDefault()

            }

            if (L.eventType == w.EVENT_START) {

                M.trigger(this.name, L)

            }

        }

    };

    w.gestures.Transform = {

        name : "transform",

        index : 45,

        defaults : {

            transform_min_scale : 0.01,

            transform_min_rotation : 1,

            transform_always_block : false

        },

        triggered : false,

        handler : function p(N, O) {

            if (w.detection.current.name != this.name && this.triggered) {

                O.trigger(this.name + "end", N);

                this.triggered = false;

                return

            }

            if (N.touches.length < 2) {

                return

            }

            if (O.options.transform_always_block) {

                N.preventDefault()

            }

            switch (N.eventType) {

                case w.EVENT_START :

                    this.triggered = false;

                    break;

                case w.EVENT_MOVE :

                    var M = Math.abs(1 - N.scale);

                    var L = Math.abs(N.rotation);

                    if (M < O.options.transform_min_scale

                            && L < O.options.transform_min_rotation) {

                        return

                    }

                    w.detection.current.name = this.name;

                    if (!this.triggered) {

                        O.trigger(this.name + "start", N);

                        this.triggered = true

                    }

                    O.trigger(this.name, N);

                    if (L > O.options.transform_min_rotation) {

                        O.trigger("rotate", N)

                    }

                    if (M > O.options.transform_min_scale) {

                        O.trigger("pinch", N);

                        O.trigger("pinch" + ((N.scale < 1) ? "in" : "out"), N)

                    }

                    break;

                case w.EVENT_END :

                    if (this.triggered) {

                        O.trigger(this.name + "end", N)

                    }

                    this.triggered = false;

                    break

            }

        }

    };

    if (typeof define == "function" && typeof define.amd == "object"

            && define.amd) {

        define(function() {

            return w

        })

    } else {

        if (typeof module === "object" && typeof module.exports === "object") {

            module.exports = w

        } else {

            B.Hammer = w

        }

    }

})(this);

iAuto.define("iAuto.ui.core.AMD", {

    singleton : true,

    _loadScript : function(c, d, a) {

        var b = document.createElement("script");

        b.type = "text/javascript";

        b.src = c;

        if (d) {

            b.onload = d

        }

        if (a) {

            b.onerror = a

        } else {

            b.onerror = function(f) {

                iAuto.Logger.error(f)

            }

        }

        document.body.appendChild(b)

    },

    linkCss : function(a) {

        var d = document.head.getElementsByTagName("link");

        for (var b = 0; b < d.length; ++b) {

            if (d[b].href.indexOf(a) >= 0) {

                return

            }

        }

        var c = document.createElement("link");

        c.rel = "stylesheet";

        c.type = "text/css";

        c.href = a;

        document.head.appendChild(c)

    },

    require : function(b, d, a) {

        try {

            this._loadScript(b, d, a)

        } catch (c) {

            iAuto.Logger.error(c)

        }

    }

});

iAuto.define("iAuto.ui.core.ClassManager", {

    singleton : true,

    _classes : {

        controller : {},

        xcontrol : {},

        fcontrol : {},

        model : {},

        glayer : {}

    },

    _package : {

        controller : "iAuto.ui.controller",

        xcontrol : "iAuto.ui.xcontrol",

        fcontrol : "iAuto.ui.fcontrol",

        model : "iAuto.ui.model",

        glayer : "iAuto.ui.glayer"

    },

    _directory : {},

    _baseCls : {

        controller : "iAuto.ui.base.Controller",

        xcontrol : "iAuto.ui.base.XControl",

        fcontrol : "iAuto.ui.base.FControl",

        model : "iAuto.ui.base.Model",

        glayer : "iAuto.ui.base.Glayer"

    },

    status : {},

    _state : {

        UNLOAD : 0,

        LOADING : 1,

        LOADERR : 2,

        LOADED : 3

    },

    _loadingQueue : {},

    get : function(b, a) {

        return this._classes[b][a]

    },

    isDefined : function(b) {

        var a = iAuto.ClassManager.get(b);

        return (a && b === a.$classname) ? true : false

    },

    getClassname : function(b, a) {

        return this._package[b] + "." + a

    },

    define : function(g, a, c, j, h) {

        var f = this, d = f._baseCls[g], k = c.requires, e = c.mixins, i = [], b = function(

                p, n, q) {

            var o = f.getClassname(p, n), m, l = f._loadingQueue[o];

            q.name = n;

            m = iAuto.define(o, q);

            if (Array.isArray(l)) {

                l.forEach(function(r) {

                    r.call(m, m)

                })

            }

            if (f._loadingQueue[m]) {

                delete f._loadingQueue[m]

            }

            if (j && j.call) {

                j.call(m, m)

            }

        };

        if (c.extend && c.extend !== d) {

            i.push({

                type : g,

                name : c.extend

            });

            c.extend = f._package[g] + "." + c.extend

        } else {

            c.extend = d

        }

        if (Array.isArray(e) && e.length > 0) {

            i = i.concat(e)

        }

        if (Array.isArray(k) && k.length > 0) {

            i = i.concat(k)

        }

        if (i.length > 0) {

            f.resolveDependences(i, function() {

                b(g, a, c)

            }, function() {

                iAuto.Logger.error("Define " + g + " [" + a + "] error!");

                if (h && h.call) {

                    h.call()

                }

                return false

            })

        } else {

            b(g, a, c)

        }

    },

    resolveDependences : function(e, b, a) {

        var d = this, f = e.length, c = 0, g = function(h) {

            if (++c >= f) {

                if (b && b.call) {

                    b.call(h, h)

                }

            }

        };

        e.forEach(function(h) {

            var k = h.type, j = h.name, i = d._package[k] + "." + j;

            if (d.isDefined(i)) {

                g()

            } else {

                d.loadClass(k, j, g, function() {

                    iAuto.Logger.error("[" + j + "] Load class error!");

                    if (a && a.call) {

                        a.call()

                    }

                })

            }

        })

    },

    loadClass : function(i, b, e, j) {

        var h = this, g = this.getClassname(i, b), c = h._classes[i], f = this.status[g]

                || this._state.UNLOAD, d = this._loadingQueue;

        if (f === this._state.UNLOAD) {

            d[g] = d[g] || [];

            d[g].push(function(m) {

                h.status[g] = h._state.LOADED;

                c[g] = m;

                if ($.isFunction(e)) {

                    e.call(m, m)

                }

            })

        } else {

            if (f === this._state.LOADERR) {

                if ($.isFunction(j)) {

                    j.call()

                }

                return this

            } else {

                if ($.isFunction(e)) {

                    if (f === this._state.LOADED) {

                        var l = iAuto.ClassManager.get(g);

                        if (l) {

                            e.call(null, l)

                        }

                    } else {

                        if (f === this._state.LOADING) {

                            d[g] = d[g] || [];

                            d[g].push(e)

                        }

                    }

                }

                return this

            }

        }

        var a = this.getUrl(i, b), k = iAuto.ui.core.AMD;

        h.status[g] = this._state.LOADING;

        k.require(a, null, function() {

            h.status[g] = h._state.LOADERR;

            if (h._loadingQueue[g]) {

                delete h._loadingQueue[g]

            }

        });

        return this

    },

    getUrl : function(b, c) {

        var a = this._directory;

        switch (b) {

            case "controller" :

                a.controller = a.controller

                        || iAuto.ui.framework.App.getControllersDir();

                return a.controller + c + ".js";

            case "xcontrol" :

                a.xcontrol = a.xcontrol

                        || iAuto.ui.framework.App.getXcontrolsDir();

                return a.xcontrol + c + "/" + c + ".js";

            case "fcontrol" :

                a.fcontrol = a.fcontrol

                        || iAuto.ui.framework.App.getFcontrolsDir();

                return a.fcontrol + c + "/" + c + ".js";

            case "model" :

                a.model = a.model || iAuto.ui.framework.App.getModelsDir();

                return a.model + c + "/" + c + ".js";

            case "glayer" :

                a.glayer = a.glayer || iAuto.ui.framework.App.getGlayersDir();

                return a.glayer + c + ".js"

        }

    }

});

iAuto.define("iAuto.ui.framework.App", {

    singleton : true,

    config : {

        controllersDir : "controllers/",

        modelsDir : "models/",

        viewsDir : "views/",

        xcontrolsDir : "resources/cc/",

        fcontrolsDir : "resources/fc/",

        glayersDir : "resources/gl/",

        cssDir : "resources/css/",

        currController : null,

        preActiveWin : null

    },

    _loadTimer : null,

    _loading : false,

    _modelsReady : true,

    _fcontrolsReady : true,

    _stmReady : true,

    _glayerReady : true,

    ready : function(a) {

        if (this._loading) {

            $(document).one("itumvc:loaded", a)

        } else {

            a()

        }

    },

    route : function(b, f, e) {

        var d = this, a = iAuto.ui.framework.Controller, c;

        if (!b || b.length < 1) {

            throw new Error("This is an empty winscape")

        }

        if ((c = d.getCurrController())) {

            a.leave(c);

            d.setPreActiveWin(c)

        }

        d.setCurrController(b);

        a.entry(b, f, null, e);

        return true

    },

    getCurrentController : function() {

        var a = iAuto.ui.framework.Controller;

        return a.get(this.getCurrController())

    },

    _startLoading : function() {

        if (!this._loading) {

            var b = this;

            b._loading = true;

            var c = $(document);

            var a = function() {

                if (b._modelsReady && b._fcontrolsReady && b._stmReady

                        && b._glayerReady) {

                    b._loading = false;

                    c.trigger("itumvc:loaded")

                }

            };

            c.one("model:loaded", a);

            c.one("fcontrol:loaded", a);

            c.one("stm:ready", a);

            c.one("glayer:ready", a);

            b._loadTimer = setTimeout(function() {

                c.trigger("itumvc:loaded");

                clearTimeout(b._loadTimer);

                c.off("model:loaded", a);

                c.off("fcontrol:loaded", a);

                c.off("stm:ready", a);

                c.off("glayer:ready", a)

            }, 1000)

        }

    },

    loadGlayers : function(a) {

        if ((!a) || (a.length === 0)) {

            return this

        }

        if (!this._loading) {

            this._startLoading()

        }

        this._glayerReady = false;

        if (typeof(a) === "string") {

            a = [a]

        }

        var f = this, e = a.length, c = 0, d = function() {

            if (++c >= e) {

                f._glayerReady = true;

                $(document).trigger("glayer:ready")

            }

        };

        for (var b = 0; b < e; b++) {

            iAuto.ui.framework.Glayer.load(a[b], d)

        }

        return this

    },

    loadModels : function(b) {

        if ((!b) || (b.length === 0)) {

            return this

        }

        var a = this;

        if (!this._loading) {

            this._startLoading()

        }

        this._modelsReady = false;

        $(document).ready(function() {

            if (typeof(b) === "string") {

                b = [b]

            }

            var c = b.length, e = 0;

            var g = function() {

                if (++e >= c) {

                    a._modelsReady = true;

                    $(document).trigger("model:loaded")

                }

            };

            for (var d = 0; d < c; d++) {

                var f = a.getModelsDir() + b[d] + ".js";

                iAuto.ui.core.AMD.require(f, g)

            }

        });

        return this

    },

    loadFcontrols : function(b) {

        if ((!b) || (b.length === 0)) {

            return this

        }

        var a = this;

        if (!this._loading) {

            this._startLoading()

        }

        a._fcontrolsReady = false;

        $(document).ready(function() {

            if (typeof(b) === "string") {

                b = [b]

            }

            var e = iAuto.ui.framework.FControl, g = b.length, c = 0, f = function() {

                if (++c >= g) {

                    a._fcontrolsReady = true;

                    $(document).trigger("fcontrol:loaded")

                }

            };

            for (var d = 0; d < g; d++) {

                if (e) {

                    e.load(b[d], f)

                }

            }

        });

        return this

    },

    registerSTM : function() {

        var e = this;

        this._stmReady = false;

        if (!this._loading) {

            this._startLoading()

        }

        var g = ["stm/lib/state-view.js", "stm/lib/state-router.js"];

        var d = g.length, a = 0;

        var f = function() {

            if (++a >= d) {

                e._stmReady = true;

                $(document).trigger("stm:ready")

            }

        };

        var c = function() {

            if (++a >= d) {

                e._stmReady = true;

                $(document).trigger("stm:ready")

            }

        };

        for (var b = 0; b < d; b++) {

            iAuto.ui.core.AMD.require(g[b], f, c)

        }

        window.addEventListener("keydown", function(h) {

            if (h.keyCode === 37 || h.keyCode === 8) {

                try {

                    StateRouter.trigger("Back")

                } catch (i) {

                    iAuto.Logger.error(i)

                }

                h.preventDefault()

            }

        }, false);

        this.routeSTM = function(l, n, k) {

            var i = this.getCurrController();

            if (!l || (!n && i)) {

                iAuto.Logger

                        .error("[iAuto.ui.framework.App] stmRoute parameters error.");

                return

            }

            if (!n) {

                this.route(l, null, k);

                return

            }

            var h = iAuto.ui.framework.Controller;

            function j() {

                var o = h.get(l);

                var p = "on" + n.charAt(0).toUpperCase() + n.substr(1);

                if (typeof(o[p]) === "function") {

                    o[p].apply(o)

                }

            }

            if (l !== i) {

                try {

                    this.route(l, j, k)

                } catch (m) {

                    iAuto.Logger.log(m)

                }

            } else {

                return j()

            }

        };

        return this

    },

    isStmDefined : function() {

        return (typeof(StateRouter) !== "undefined")

    },

    getActiveWinscape : function() {

        return this.isStmDefined() ? StateRouter.getCurrWinscapeName() : this

                .getCurrController()

    },

    getPreActiveWinscape : function() {

        return this.isStmDefined() ? StateRouter.getPreWinscapeName() : this

                .getPreActiveWin()

    },

    getAnimationList : function() {

        var a = {

            anim_fade : {

                duration : 800

            },

            anim_slide : {

                duration : 1000

            },

            anim_side : {

                duration : 500

            },

            anim_fall : {

                duration : 1000

            },

            anim_flip : {

                duration : 500,

                direction : "Top"

            },

            anim_carousel : {

                duration : 800,

                direction : "Left"

            },

            anim_move : {

                duration : 1000,

                direction : "Left"

            },

            anim_cube : {

                duration : 400,

                direction : "Left"

            }

        };

        return a

    }

});

iAuto.define("iAuto.ui.framework.ResourceManager", {

    singleton : true,

    _imageUrlPrefix : "resources/img/",

    _imageList : {},

    _stringList : {},

    _messageList : {},

    getMessage : function(c) {

        try {

            var a = this;

            return a._messageList[c]

        } catch (b) {

            iAuto.Logger.error(b)

        }

    },

    getString : function(b) {

        try {

            var a = this;

            return a._stringList[b]

        } catch (c) {

            iAuto.Logger.error(c)

        }

    },

    getImageUrl : function(b) {

        try {

            var c = this;

            var a = c._imageList[b];

            a = "url('" + c._imageUrlPrefix + a + "')";

            return a

        } catch (d) {

            iAuto.Logger.error(d)

        }

    },

    loadMessageList : function(c, d) {

        try {

            var a = this;

            $.getJSON(c, function(e) {

                a._messageList = e;

                if (typeof d === "function") {

                    d()

                }

            })

        } catch (b) {

            iAuto.Logger.error(b)

        }

    },

    loadStringList : function(c, d) {

        try {

            var a = this;

            $.getJSON(c, function(e) {

                a._stringList = e;

                if (typeof d === "function") {

                    d()

                }

            })

        } catch (b) {

            iAuto.Logger.error(b)

        }

    },

    loadJson : function(b, c) {

        try {

            $.getJSON(b, function(d) {

                if (typeof c === "function") {

                    c(d)

                }

            })

        } catch (a) {

            iAuto.Logger.error(a)

        }

    },

    loadImageList : function(c, d) {

        try {

            var a = this;

            $.getJSON(c, function(e) {

                a._imageList = e;

                if (typeof d === "function") {

                    d()

                }

            })

        } catch (b) {

            iAuto.Logger.error(b)

        }

    },

    setImageUrlPrefix : function(b) {

        try {

            var a = this;

            a._imageUrlPrefix = b

        } catch (c) {

            iAuto.Logger.error(c)

        }

    }

});

iAuto.define("iAuto.ui.framework.ScreenInfoManager", {

    singleton : true,

    __screenInfos : {},

    loadAllScreenInfo : function(c) {

        try {

            var a = this;

            $.getJSON(c, function(d) {

                a.__screenInfos = d

            })

        } catch (b) {

            iAuto.Logger.error(b)

        }

    },

    getScreenInfo : function(c) {

        try {

            var a = this;

            if (a.__screenInfos) {

                return a.__screenInfos[c]

            }

        } catch (b) {

            iAuto.Logger.error(b)

        }

    }

});

iAuto.define("iAuto.ui.framework.Controller", {

    singleton : true,

    _instances : {},

    animationObj : {},

    $viewport : $("#viewport"),

    entry : function(e, b, c, a) {

        var d = this.get(e);

        if ($.isObject(a)) {

            this.animationObj = a

        }

        if (d) {

            this._lifeEnter(d, b, c)

        } else {

            this._lifeLoad(e, b, c)

        }

        return this

    },

    leave : function(d, b, c) {

        var a = this.get(d);

        if (!a) {

            iAuto.Logger.warn("[" + d + "] haven't been defined!");

            if ($.isFunction(c)) {

                c()

            }

            return this

        }

        this._unbindEvent(a);

        try {

            a.onHide.call(a)

        } catch (f) {

            if ($.isFunction(c)) {

                c()

            }

            iAuto.Logger.error("[" + d

                    + "] Execute wrong in onHide() function.\n" + f)

        }

        this._removeCmp(a);

        try {

            a.onLeave.call(a)

        } catch (f) {

            iAuto.Logger.error("[" + d

                    + "] Execute wrong in onLeave() function.\n" + f)

        }

        a.items = [];

        a.events = [];

        a.$content = {};

        if (b && b.call) {

            b.call()

        }

        return this

    },

    load : function(c, l, i) {

        var j = iAuto.ui.framework.App, g = iAuto.ui.core.ClassManager, a = this._instances, k, f = 0, d = false, e = iAuto.ui.framework.View, h, b;

        g.loadClass("controller", c, function(r) {

            k = new r();

            k.name = c;

            a[c] = k;

            try {

                k.onLoad.call(k)

            } catch (s) {

                iAuto.Logger.error(s)

            }

            var t = function(x, w, v, y) {

                if ((h = w.getView())) {

                    b = j.getViewsDir() + h;

                    e.load(b, function(z) {

                        w.html = z;

                        x._lifeEnter.call(x, w, v, y)

                    }, function(z) {

                        iAuto.Logger

                                .error("[iAuto.ui.framework.Controller] Load View ["

                                        + h

                                        + "] Error in Controller ["

                                        + c

                                        + "]!");

                        iAuto.Logger.error(z)

                    })

                }

            };

            try {

                if (k.getPreImg()) {

                    var q = k.getPreImg();

                    var u = [];

                    var m = null;

                    f = q.length;

                    if (q.length === 0) {

                        t(me, k, l, i);

                        return

                    }

                    m = setTimeout(function() {

                        d = true;

                        t(me, k, l, i)

                    }, 20);

                    for (var p = 0, n = q.length, o; p < n; p++) {

                        o = new Image();

                        u[u.length] = o

                    }

                    for (p = 0, n = u.length; p < n; p++) {

                        u[p].src = "" + q[p];

                        u[p].onload = function() {

                            f--;

                            if (me.count === 0) {

                                if (d) {

                                    return

                                } else {

                                    clearTimeout(m);

                                    t(me, k, l, i)

                                }

                            }

                        };

                        u[p].onerror = function() {

                            f--;

                            if (f === 0) {

                                if (d) {

                                    return

                                } else {

                                    clearTimeout(m);

                                    t(me, k, l, i)

                                }

                            }

                        }

                    }

                }

            } catch (s) {

                iAuto.Logger.error("preImg not defined");

                t(me, k, l, i)

            }

        }, function() {

            iAuto.Logger

                    .error("[iAuto.ui.framework.Controller] Load Controller ["

                            + c + "] Error!");

            if ($.isFunction(i)) {

                i.call()

            }

        });

        return this

    },

    define : function(a, c) {

        var b = iAuto.ui.core.ClassManager;

        b.define("controller", a, c);

        return this

    },

    _lifeLoad : function(c, n, j) {

        var h = this, f = iAuto.ui.core.ClassManager, a = this._instances, m, d = iAuto.ui.framework.View, k = iAuto.ui.framework.App, i, b, l = iAuto.ui.core.AMD, g = iAuto.ui.framework.App

                .getCssDir(), e;

        f.loadClass("controller", c, function(o) {

            m = new o();

            m.name = c;

            a[c] = m;

            try {

                m.onLoad.call(m)

            } catch (p) {

                iAuto.Logger.error(p)

            }

            if ((i = m.getView())) {

                b = k.getViewsDir() + i;

                d.load(b, function(q) {

                    m.html = q;

                    h._lifeEnter.call(h, m, n, j)

                }, function(q) {

                    iAuto.Logger

                            .error("[iAuto.ui.framework.Controller] Load View ["

                                    + i + "] Error in Controller [" + c + "]!");

                    iAuto.Logger.error(q)

                })

            }

        }, function() {

            iAuto.Logger

                    .error("[iAuto.ui.framework.Controller] Load Controller ["

                            + c + "] Error!")

        });

        e = g + c + ".css";

        l.linkCss(e);

        return this

    },

    _lifeEnter : function(b, a, c) {

        var f = this, d = b.html;

        $content = b.$content = $.create(d());

        patch = iAuto.ui.framework.Patch;

        try {

            b.onEnter.apply(b)

        } catch (g) {

            iAuto.Logger.error("[" + b.name

                    + "] Execute wrong in onEnter() function.");

            iAuto.Logger.error(g)

        }

        if ($content) {

            this.$viewport.append($content)

        }

        patch.loadItems(b).loadEvents(b);

        this._createCmp(b, function(e) {

            f._lifeShow(e, a, c)

        })

    },

    _lifeShow : function(b, a, c) {

        var i = this.$viewport, f = i.children();

        try {

            b.onShowPre.call(b)

        } catch (g) {

            if (c && c.call) {

                c.call()

            }

            iAuto.Logger.error("[" + name

                    + "] Execute wrong in onShowPre() function.");

            iAuto.Logger.error(g);

            return this

        }

        i.addClass("pt-perspective");

        var h = this.animationObj.animationType;

        var d = this.animationObj.parameter;

        if (h) {

            this.setAnimation(h, d, f, i)

        } else {

            if (f.length >= 2) {

                f.get(0).remove()

            }

        }

        this._bindEvent(b);

        try {

            b.onShow.call(b)

        } catch (g) {

            if (c && c.call) {

                c.call()

            }

            iAuto.Logger.error("[" + name

                    + "] Execute wrong in onShow() function.");

            iAuto.Logger.error(g);

            return this

        }

        if ($.isFunction(a)) {

            a()

        }

    },

    _createCmp : function(j, m) {

        var g = this, i = iAuto.ui.framework, f = i.XControl, b = i.FControl, d = i.BControl, e = (j.items = j.items

                || []), k = (j._cmp = j._cmp || {}), l = e.length, a = 0, h, c;

        l = e.length || 0;

        if (l <= 0) {

            if ($.isFunction(m)) {

                m.call(g, j)

            }

            return this

        }

        h = function(n) {

            if (n) {

                k[n.id || n.name] = n

            }

            if (++a >= l) {

                if ($.isFunction(m)) {

                    m.call(g, j)

                }

            }

        };

        e.forEach(function(n) {

            switch (n.type) {

                case "xcontrol" :

                    c = j.$content.find("#" + n.id);

                    if (c.length >= 1) {

                        f._create(n, c, h, h)

                    }

                    break;

                case "bcontrol" :

                    c = j.$content.find("#" + n.id);

                    if (c.length >= 1) {

                        d._create(n, c, h, h)

                    }

                    break;

                case "fcontrol" :

                    b.start(n.name, h, h);

                    break;

                default :

                    h()

            }

        })

    },

    _removeCmp : function(a) {

        var e = iAuto.ui.framework.XControl, b = a._cmp, c, d;

        for (c in b) {

            if (b.hasOwnProperty(c)) {

                d = b[c];

                if (d && d.xtype === "xcontrol") {

                    e._destroy(d)

                }

            }

        }

        a._cmp = {}

    },

    _bindEvent : function(a) {

        var b = (a.events = a.events || []), d = iAuto.ui.framework.Event, c, e;

        b.forEach(function(f) {

            e = f.handler;

            if (!e) {

                e = f.handler = d._getHandler(f.callback, f.context, f.trigger)

            }

            c = a.getCmp(f.item);

            if (c && c.on) {

                c.on(f.name, e)

            } else {

                a.$content.find("#" + f.item).on(f.name, e)

            }

        });

        return this

    },

    _unbindEvent : function(a) {

        var b = (a.events = a.events || []), c, d;

        b.forEach(function(e) {

            d = null;

            c = a.getCmp(e.item);

            if (c && c.off) {

                c.off(e.name, d)

            } else {

                a.$content.find("#" + e.item).off(e.name, d)

            }

        });

        return this

    },

    get : function(a) {

        return this._instances[a]

    },

    setAnimation : function(j, b, m, e) {

        var k, f, a, n, g = "0s", d = "", h = "";

        var c = iAuto.ui.framework.App;

        var l = c.getAnimationList();

        if (l.hasOwnProperty(j) && l[j]) {

            h = l[j]["duration"] + "ms";

            if (l[j]["direction"]) {

                d = l[j]["direction"];

                d = d.substr(0, 1).toUpperCase() + d.substr(1)

            }

        }

        if (b) {

            if (b.duration) {

                h = b.duration + "ms"

            }

            if (b.direction) {

                d = b.direction;

                d = d.substr(0, 1).toUpperCase() + d.substr(1)

            }

        }

        switch (j) {

            case "anim_fade" :

                inCSS = "fadein " + h;

                outCSS = "fadeout " + h;

                var i = function() {

                    $(m.get(0)).css({

                        "-webkit-animation" : ""

                    });

                    $(m.get(1)).one("webkitAnimationEnd", function() {

                        $(m.get(1)).css({

                            "-webkit-animation" : ""

                        })

                    });

                    $(m.get(1)).css({

                        "-webkit-animation" : inCSS

                    });

                    m.get(0).remove();

                    e.get(0).removeChild(e.get(0).children[1])

                };

                if (m.length == 1) {

                    $(m.get(0)).one("webkitAnimationEnd", function() {

                        $(m.get(0)).css({

                            "-webkit-animation" : ""

                        })

                    });

                    $(m.get(0)).css({

                        "-webkit-animation" : inCSS

                    })

                } else {

                    $(m.get(0)).one("webkitAnimationStart", function() {

                        e

                                .append("<div id='mask' style='height:100%;width:100%;position:absolute;top:0;'></div>")

                    });

                    $(m.get(0)).one("webkitAnimationEnd", i);

                    $(m.get(0)).css({

                        "-webkit-animation" : outCSS

                    })

                }

                break;

            case "anim_side" :

                k = "pt-page pt-page-rotateSidesIn";

                f = "pt-page pt-page-rotateSidesOut";

                a = "rotateSidesIn both ease-out " + h;

                n = "rotateSidesOut both ease-out " + h;

                this.SetOtherAnimation(k, f, m, a, n, g, e);

                break;

            case "anim_carousel" :

                k = "pt-page pt-page-rotateCarousel" + d + "In";

                f = "pt-page pt-page-rotateCarousel" + d + "Out";

                a = "rotateCarousel" + d + "In both ease " + h;

                n = "rotateCarousel" + d + "Out both ease " + h;

                this.SetOtherAnimation(k, f, m, a, n, g, e);

                break;

            case "anim_flip" :

                g = h;

                k = "pt-page pt-page-flipIn" + d;

                f = "pt-page pt-page-flipOut" + d;

                a = "flipIn" + d + " both ease-out " + h;

                n = "flipOut" + d + " both ease-out " + h;

                this.SetOtherAnimation(k, f, m, a, n, g, e);

                break;

            case "anim_fall" :

                k = "pt-page";

                f = "pt-page pt-page-rotateFall pt-page-ontop";

                a = "scaleUp ease both " + h;

                n = "rotateFall both ease-in " + h;

                this.SetOtherAnimation(k, f, m, a, n, g, e);

                break;

            case "anim_slide" :

                k = "pt-page";

                f = "pt-page";

                a = "rotateSlideIn both ease " + h;

                n = "rotateSlideOut both ease " + h;

                this.SetOtherAnimation(k, f, m, a, n, g, e);

                break;

            case "anim_move" :

                k = "pt-page";

                f = "pt-page pt-page-ontop";

                a = "scaleUp ease both " + h;

                n = "moveTo" + d + " ease both " + h;

                this.SetOtherAnimation(k, f, m, a, n, g, e);

                break;

            case "anim_cube" :

                k = "pt-page pt-page-rotateCubeLeftIn";

                f = "pt-page pt-page-rotateCubeLeftOut pt-page-ontop";

                a = "rotateCube" + d + "In both ease-in " + h;

                n = "rotateCube" + d + "Out both ease-in " + h;

                this.SetOtherAnimation(k, f, m, a, n, g, e);

                break;

            default :

                if (m.length >= 2) {

                    m.get(0).remove()

                }

                break

        }

        this.animationObj = {}

    },

    SetOtherAnimation : function(d, b, e, g, c, a, f) {

        if (e.length == 1) {

            $(e.get(0)).one("webkitAnimationEnd", function() {

                $(e.get(0)).removeClass(d);

                if (g) {

                    $(e.get(0)).css({

                        "-webkit-animation" : ""

                    })

                }

            });

            $(e.get(0)).addClass(d);

            if (g) {

                $(e.get(0)).css({

                    "-webkit-animation" : g

                })

            }

        } else {

            $(e.get(0)).one("webkitAnimationStart", function() {

                f

                        .append("<div id='mask' style='height:100%;width:100%;position:absolute;top:0;'></div>")

            });

            $(e.get(0)).addClass(b);

            if (c) {

                $(e.get(0)).css({

                    "-webkit-animation" : c

                })

            }

            $(e.get(1)).addClass(d);

            if (g && a) {

                $(e.get(1)).css({

                    "-webkit-animation" : g

                });

                $(e.get(1)).css({

                    "-webkit-animation-delay" : a

                })

            }

            $(e.get(1)).one("webkitAnimationEnd", function() {

                $(e.get(0)).removeClass(b);

                $(e.get(1)).removeClass(d);

                if (g && c && a) {

                    $(e.get(0)).css({

                        "-webkit-animation" : ""

                    });

                    $(e.get(1)).css({

                        "-webkit-animation" : ""

                    });

                    $(e.get(1)).css({

                        "-webkit-animation-delay" : ""

                    })

                }

                e.get(0).remove();

                f.get(0).removeChild(f.get(0).children[1])

            })

        }

    }

});

iAuto.define("iAuto.ui.framework.Event", {

    singleton : "true",

    _hammerLoaded : false,

    events : {

        basic : ["touchstart", "touchmove", "touchend", "touchcancel"],

        hammer : ["tap", "hold", "drag", "dragstart", "dragend", "dragup",

                "dragdown", "dragleft", "dragright", "swipe", "swipeup",

                "swipedown", "swipeleft", "swiperight", "transform",

                "transformstart", "transformend", "rotate", "pinch", "pinchin",

                "pinchout", "touch", "release"]

    },

    $content : null,

    _eventCenter : {},

    _listeners : {},

    fireEvent : function(b) {

        try {

            var f = this;

            var c = [];

            for (var d = 1, a = arguments.length; d < a; d++) {

                c.push(arguments[d])

            }

            $.trigger(f._eventCenter, b, c)

        } catch (g) {

            iAuto.Logger.error(g)

        }

    },

    addEventListener : function(a, c) {

        try {

            var b = this;

            $.bind(b._eventCenter, a, c)

        } catch (d) {

            iAuto.Logger.error(d)

        }

    },

    removeEventListener : function(a, c) {

        iAuto.Logger.debug(

                "[iAuto.ui.framework.Event]-[removeEventListener]: ", [a, c]);

        try {

            var b = this;

            $.unbind(b._eventCenter, a, c)

        } catch (d) {

            iAuto.Logger.error(d)

        }

    },

    on : function(a, f, g, d, b) {

        if (arguments.length < 3 || typeof(g) !== "function") {

            return this

        }

        if (a.length < 1) {

            return this

        } else {

            if (a.length > 1) {

                for (var c = 0; c < a.length; c++) {

                    this.on($(a[c]), f, g, d, b)

                }

                return this

            }

        }

        var e = this;

        if (d) {

            g = $.proxy(g, d)

        }

        if (b) {

            g = e._setTrigger(g, b)

        }

        if (e.events.hammer.indexOf(f) >= 0) {

            if (!e._hammerLoaded) {

                e._setupHammer(window.Hammer, window.$);

                e._hammerLoaded = true

            }

            a.data("hammer", new Hammer(a, {}))

        }

        if ($.is$(a)) {

            a.bind(f, g)

        } else {

            if ($.isObject(a)) {

                if (a.on) {

                    a.on(f, g)

                } else {

                    $.bind(a, f, g)

                }

            }

        }

    },

    off : function(a, e, f, c, b) {

        if (arguments.length < 2) {

            return

        }

        if (typeof a === "string") {

            a = $(a)

        } else {

            if (Object.prototype.toString.call(a) === "[object Array]") {

                var d = this;

                a.forEach(function(g) {

                    d.off(g, e, f, c, b)

                });

                return this

            }

        }

        if ($.is$(a)) {

            a.unbind(e)

        } else {

            if ($.isObject(a)) {

                $.unbind(a, e)

            }

        }

        return this

    },

    addListener : function(a, b) {

        b = b || {};

        if (typeof(a) === "string") {

            if (this.$content) {

                a = this.$content.find("#" + a)

            } else {

                a = $("#" + a)

            }

            if (!a.length) {

                return this

            }

        }

        this.on(a, b.name, b.callback, b.context, b.trigger);

        return this

    },

    removeListeners : function(a, b) {

        if (typeof a === "string") {

            a = this.$content.find(a)

        }

        if ($.is$(a)) {

            a.unbind(b)

        }

    },

    bindHardKey : function() {

        window.addEventListener("keydown", function(c) {

            var b = iAuto.mvc.getCurrentController();

            if (b) {

                var a = "onHardKeyDown";

                if (b[a]) {

                    b[a].apply(b, arguments)

                }

            }

            if (c.keyCode === 37 || c.keyCode === 8) {

                if (StateRouter && typeof StateRouter.trigger === "function") {

                    try {

                        StateRouter.trigger("Back")

                    } catch (d) {

                        iAuto.Logger.warn(d)

                    }

                }

            }

        }, false)

    },

    _getHandler : function(b, d, a) {

        if (!$.isFunction(b)) {

            return function() {

            }

        }

        return function() {

            if (d) {

                b.apply(d, arguments)

            } else {

                b.apply(null, arguments)

            }

            if (a && StateRouter && StateRouter.trigger) {

                try {

                    StateRouter.trigger(a)

                } catch (c) {

                    iAuto.Logger.error(c)

                }

            }

        }

    },

    _setTrigger : function trigger(b, a) {

        return function() {

            b.apply(this, arguments);

            if (a && StateRouter && StateRouter.trigger) {

                try {

                    StateRouter.trigger(a)

                } catch (c) {

                    iAuto.Logger.error(c)

                }

            }

        }

    },

    _setupHammer : function(a, b) {

        a.event.bindDom = function(c, e, d) {

            b(c).on(e, function(f) {

                var g = f.originalEvent || f;

                if (g.pageX === undefined) {

                    g.pageX = f.pageX;

                    g.pageY = f.pageY

                }

                if (!g.target) {

                    g.target = f.target

                }

                if (g.which === undefined) {

                    g.which = g.button

                }

                if (!g.preventDefault) {

                    g.preventDefault = f.preventDefault

                }

                if (!g.stopPropagation) {

                    g.stopPropagation = f.stopPropagation

                }

                d.call(this, g)

            })

        };

        a.Instance.prototype.on = function(c, d) {

            return b(this.element).on(c, d)

        };

        a.Instance.prototype.off = function(c, d) {

            return b(this.element).off(c, d)

        };

        a.Instance.prototype.trigger = function(c, e) {

            var d = b(this.element);

            return d.trigger(c, {

                type : c,

                gesture : e

            })

        }

    }

});

iAuto.define("iAuto.ui.framework.BControl", {

    singleton : true,

    cache : {},

    _create : function(a, c, i, h) {

        var g = ($.is$(c) ? c : $("#" + c)), d = a.name, b = a.config, e = function() {

            if (h && h.call) {

                h.call()

            }

        };

        if (!g || !g.length) {

            iAuto.Logger

                    .error("[iAuto.ui.framework.BControl] cannot create control with none DOM element.");

            e();

            return this

        }

        if (typeof(d) !== "string") {

            iAuto.Logger.error("[iAuto.ui.framework.BControl] Unknown type.");

            e();

            return this

        } else {

            d = d.trim().toLowerCase()

        }

        if (!d || d.length < 2) {

            iAuto.Logger.error("[iAuto.ui.framework.BControl] Have no type.");

            e();

            return this

        }

        var f;

        switch (d) {

            case ("button") :

                f = new iAuto.ui.control.Button(g, b);

                break;

            case ("combobox") :

                f = new iAuto.ui.control.ComboBox(g, b);

                break;

            case ("searchbox") :

                f = new iAuto.ui.control.SearchBox(g, b);

                break;

            case ("toggle") :

                f = new iAuto.ui.control.Toggle(g, b);

                break;

            case ("spinner") :

                f = new iAuto.ui.control.Spinner(g, b);

                break;

            default :

                iAuto.Logger

                        .error("[iAuto.ui.framework.BControl] Unknown basic control type.");

                d = d.trim().toLowerCase();

                return this

        }

        f.id = a.id;

        if (i && i.call) {

            i.call(null, f)

        }

    },

    destroy : function(b) {

        var a = this.cache[b];

        if (!a) {

            return

        }

        if ($.isFunction(a.destroy)) {

            a.destroy()

        }

        delete this.cache[b];

        return this

    },

    create : function(d, a, c) {

        var e = $.is$(a) ? a : $("#" + a), b;

        d = d.trim().toLowerCase();

        if (!e || !e.length) {

            iAuto.Logger

                    .error("[iAuto.ui.framework.BControl] cannot create control with none DOM element.");

            return this

        }

        if (!d || d.length < 2) {

            iAuto.Logger.error("[iAuto.ui.framework.BControl] Have no type.");

            return this

        }

        switch (d) {

            case ("button") :

                b = new iAuto.ui.control.Button(e, c);

                break;

            case ("combobox") :

                b = new iAuto.ui.control.ComboBox(e, c);

                break;

            case ("searchbox") :

                b = new iAuto.ui.control.SearchBox(e, c);

                break;

            case ("toggle") :

                b = new iAuto.ui.control.Toggle(e, c);

                break;

            case ("spinner") :

                b = new iAuto.ui.control.Spinner(e, c);

                break;

            default :

                iAuto.Logger

                        .error("[iAuto.ui.framework.BControl] Unknown basic control type.");

                return this

        }

        this.cache[a] = b;

        return b

    },

    get : function(a) {

        return this.cache[a]

    },

    removeAll : function() {

        this.cache = {}

    }

});

iAuto.define("iAuto.ui.framework.FControl", {

    singleton : true,

    _instances : {},

    _status : {},

    _state : {

        UNLOAD : 0,

        LOADED : 1,

        STARTED : 2,

        STOPED : 1

    },

    load : function(f, c, e) {

        var g = this, b = iAuto.ui.core.ClassManager, h = this._instances, d = this._status, a;

        b.loadClass("fcontrol", f, function(j) {

            if (d[f] >= g._state.LOADED) {

                return

            }

            a = new j();

            h[f] = a;

            a.$name = f;

            try {

                a.onLoad.call(a)

            } catch (k) {

                var i = iAuto.Logger;

                i.error("Function Control [" + f

                        + "] onLoad method goes wrong.");

                if (e && e.call) {

                    e()

                }

            }

            d[f] = g._state.LOADED;

            if ($.isFunction(c)) {

                c.call(g, a)

            }

        }, e)

    },

    define : function(a, b) {

        iAuto.ui.core.ClassManager.define("fcontrol", a, b)

    },

    get : function(b, c) {

        var a = this._instances[b];

        if (a) {

            if ($.isFunction(c)) {

                c.call(a, a)

            }

            return a

        } else {

            if (typeof(c) === "function") {

                return this.load(b, function(d) {

                    c(d)

                }, function() {

                    iAuto.Logger

                            .warn("[iAuto.ui.framework.FControl] Get Function Control ["

                                    + b

                                    + "] failed! Check If you load the Function Control.")

                })

            } else {

                return this

            }

        }

    },

    start : function(d, b, c) {

        var f = this, a = this._instances[d], e = function(h) {

            if (f._status[d] >= f._state.STARTED) {

                if ($.isFunction(b)) {

                    b.call(h, h)

                }

                return f

            }

            try {

                h.onStart.call(h)

            } catch (i) {

                var g = iAuto.Logger;

                g.error("FunctionControl [" + d + "] start it error!");

                if ($.isFunction(c)) {

                    c.call(h, h)

                }

            }

            if ($.isFunction(b)) {

                b.call(h, h)

            }

            f._status[d] = f._state.STARTED

        };

        if (a) {

            e(a)

        } else {

            this.load(d, e)

        }

        return this

    },

    stop : function(c) {

        var a = this._instances[c];

        if (a) {

            try {

                a.onStop.call(a)

            } catch (d) {

                var b = iAuto.Logger;

                b.error("FunctionControl [" + c + "] stop it error!")

            }

        }

        this._status[c] = this._state.STOPED;

        return this

    },

    exist : function(a) {

        return this._instances.hasOwnProperty(a)

    }

});

iAuto.define("iAuto.ui.framework.Model", {

    singleton : true,

    state : {

        STATE_UNLOAD : 0,

        STATE_LOADING : 1,

        STATE_LOADED : 2,

        STATE_REMOVED : 0

    },

    _status : {},

    _instances : {},

    config : {

        baseUrl : iAuto.ui.framework.App.getModelsDir()

    },

    load : function(c, a) {

        var d = this;

        d._status[c] = d._status[c] || {};

        if (d._status[c].state >= d.state.STATE_LOADED) {

            if (typeof(a) === "function") {

                return a()

            } else {

                return null

            }

        }

        if (!d._status[c].state || d._status[c].state < d.state.STATE_LOADING) {

            d._status[c].state = d.state.STATE_LOADING;

            var b = d.getBaseUrl() + c + ".js";

            iAuto.ui.core.require(b)

        }

        d.one(c + ":loaded", function() {

            d._status[c].state = d._status[c].state | d.state.STATE_LOADED;

            if (typeof(a) === "function") {

                return a()

            } else {

                return true

            }

        })

    },

    define : function(a, b) {

        if (this[a]) {

            return this[a]

        }

        b.extend = b.extend || "iAuto.ui.base.Controller";

        iAuto.define("iAuto.ui.framework.Model." + a, b);

        this.trigger(a + ":loaded");

        return this

    },

    create : function(c, d, b) {

        if (!this[c]) {

            iAuto.Logger.error("[iAuto.ui.framework.Model] Model " + c

                    + " has not been failed!");

            return this[c]

        }

        var a = new this[c]();

        if (!a) {

            iAuto.Logger.error("[iAuto.ui.framework.Model] create Model [" + c

                    + "] failed!");

            return this

        }

        a.modelName = c;

        a.id = d || $.uuid();

        this._instances[c] = this._instances[c] || [];

        this._instances[c].push(a);

        return a

    },

    get : function(b, d) {

        if (!this._instances[b] || !d) {

            return

        }

        var c = this._instances[b];

        for (var a in c) {

            if (c[a].id === d) {

                return c[a]

            }

        }

        return

    },

    remove : function(b, d) {

        if (!this._instances[b] || !d) {

            return false

        }

        var c = this._instances[b];

        for (var a in c) {

            if (c[a].id === d) {

                c.split(a, 1)

            }

        }

        return false

    },

    getAll : function(a) {

        return this._instances[a]

    },

    removeAll : function(a) {

        delete this._instances[a]

    }

});

(function(c) {

    c.mvc = c.mvc || {};

    var a = {};

    c.mvc.model = function(e, h, g) {

        var i;

        if (this.__proto__) {

            i = {};

            g = g || this.__proto__;

            i.__proto__ = g

        } else {

            g = g || this;

            var f = {};

            for (var d in g) {

                f[d] = g[d]

            }

            i = Object.create(Object.getPrototypeOf(this))

        }

        h && h.modelName && delete h.modelName;

        h && h.id && delete h.id;

        c.extend(i, h);

        i.modelName = e;

        return i

    };

    c.mvc.model.clone = function(g, f, h) {

        if (h) {

            if (f.__proto__) {

                g.__proto__ = f.__proto__

            } else {

                var e = {};

                for (var d in f.prototype) {

                    e[d] = f.prototype[d]

                }

                g = Object.create(Object.getPrototypeOf(f))

            }

        }

        for (var d in f) {

            if (f.hasOwnProperty(d)) {

                g[d] = f[d]

            }

        }

        return g

    };

    c.mvc.model.prototype = {

        fetch : function(e, f) {

            if (typeof(e) == "string") {

                this.id = e

            }

            var d = this;

            this.storageAdapter().fetch(d, function(g) {

                var h = d._prepareModel(g);

                if (f) {

                    return f(h)

                }

                return h

            }, this.modelName)

        },

        fetchAll : function(e) {

            var d = this;

            this.storageAdapter().fetchAll(d, function(f) {

                var g = [];

                f.forEach(function(h) {

                    g.push(d._prepareModel(h))

                });

                if (e) {

                    return e(g)

                }

                return g

            })

        },

        save : function(d) {

            return this.storageAdapter().save(this, d)

        },

        remove : function(d) {

            return this.storageAdapter().remove(this, d)

        },

        get : function(d) {

            if (this.hasOwnProperty(d)) {

                return this[d]

            }

            return undefined

        },

        set : function(h, g, f) {

            var d = c.mvc.model.clone({}, this);

            if (c.isObject(h)) {

                h && h.modelName && delete h.modelName;

                h && h.id && delete h.id;

                for (var e in h) {

                    if (this.hasOwnProperty(e)) {

                        this[e] = h[e]

                    }

                }

                if (!this._validate(f)) {

                    c.mvc.model.clone(this, d);

                    return false

                }

                return true

            }

            if (h.toLowerCase() != "id" && h.toLowerCase() != "modelname") {

                this[h] = g

            }

            if (!this._validate(f)) {

                c.mvc.model.clone(this, d);

                return false

            }

            return true

        },

        storageAdapter : function() {

            return a[this.modelName]

        },

        valid : function(d) {

            return this.validate(d) === true

        },

        validate : function(d) {

            return true

        },

        _prepareModel : function(e) {

            var d = this;

            var f = c.mvc.model.clone({}, d, true);

            f = c.mvc.model.clone(f, e);

            return f

        },

        _validate : function(e) {

            if (e && e.silent) {

                return true

            }

            var d = this.validate(e);

            if (d === true) {

                return true

            }

            if (e && e.error) {

                e.error(this, d, e)

            }

            return false

        }

    };

    c.mvc.model.extend = function(e, g, d, f) {

        a[e] = d ? d : (b.linkerCache[e] = {}, b);

        return function() {

            return new c.mvc.model(e, g)

        }

    };

    var b = {

        linkerCache : {},

        save : function(d, e) {

            if (!d.id) {

                d.id = c.uuid()

            }

            window.localStorage[d.id] = JSON.stringify(d);

            this.linkerCache[d.modelName][d.id] = 1;

            window.localStorage[d.modelName + "_linker"] = JSON

                    .stringify(this.linkerCache[d.modelName]);

            c(document).trigger(d.modelName + ":save", d);

            if (e) {

                return e(d)

            }

        },

        fetch : function(g, i) {

            var h = g.id;

            var d = window.localStorage.getItem(h);

            try {

                d = JSON.parse(d)

            } catch (f) {

                d = {}

            }

            return i(d)

        },

        fetchAll : function(i, k) {

            var f = i.modelName;

            var h = JSON.parse(window.localStorage.getItem(f + "_linker"));

            var e = [];

            for (var d in h) {

                if (localStorage[d]) {

                    var g = JSON.parse(localStorage[d]);

                    g.id = d;

                    e.push(g)

                } else {

                    delete h[d]

                }

            }

            this.linkerCache[f] = h ? h : {};

            window.localStorage[f + "_linker"] = JSON

                    .stringify(this.linkerCache[f]);

            return k(e)

        },

        remove : function(d, e) {

            window.localStorage.removeItem(d.id);

            delete this.linkerCache[d.modelName][d.id];

            window.localStorage[d.modelName + "_linker"] = JSON

                    .stringify(this.linkerCache[d.modelName]);

            c(document).trigger(d.modelName + ":remove", d.id);

            if (e) {

                return e(d)

            }

        }

    }

})(af);

iAuto.define("iAuto.ui.framework.View", {

    singleton : true,

    views : {},

    state : {

        UNLOAD : 255,

        LOADING : 240,

        LOADED : 0

    },

    directory : {

        controller : "views/",

        xcontrol : "resources/cc/"

    },

    config : {

        dir : iAuto.ui.framework.App.getViewsDir()

    },

    load : function(c, a) {

        var d = this, b = this.views[c];

        if (b) {

            if (b.template) {

                if (a && a.call) {

                    a.call(null, b.template, c)

                }

            } else {

                if (a && a.call) {

                    b.waiting = b.waiting || [];

                    b.waiting.push(a)

                }

            }

        } else {

            $.get(c, function(f) {

                var e = d.template(f);

                b = (d.views[c] = d.views[c] || {});

                b.template = e;

                if (a && a.call) {

                    a.call(null, e, c)

                }

                if (b.waiting) {

                    b.waiting.forEach(function(g) {

                        g(e)

                    });

                    delete b.waiting

                }

            })

        }

    },

    get : function(b) {

        var a = this.views[b];

        if (a) {

            return a.template

        }

        return null

    }

});

(function() {

    var doT = {

        version : "1.0.0",

        templateSettings : {

            evaluate : /\{\{([\s\S]+?\}?)\}\}/g,

            interpolate : /\{\{=([\s\S]+?)\}\}/g,

            encode : /\{\{!([\s\S]+?)\}\}/g,

            use : /\{\{#([\s\S]+?)\}\}/g,

            useParams : /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,

            define : /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,

            defineParams : /^\s*([\w$]+):([\s\S]+)/,

            conditional : /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,

            iterate : /\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,

            varname : "it",

            strip : true,

            append : true,

            selfcontained : false

        },

        template : undefined,

        compile : undefined

    };

    if (typeof module !== "undefined" && module.exports) {

        module.exports = doT

    } else {

        if (typeof define === "function" && define.amd) {

            define(function() {

                return doT

            })

        } else {

            (function() {

                return this || (0, eval)("this")

            }()).doT = doT

        }

    }

    function encodeHTMLSource() {

        var encodeHTMLRules = {

            "&" : "&#38;",

            "<" : "&#60;",

            ">" : "&#62;",

            '"' : "&#34;",

            "'" : "&#39;",

            "/" : "&#47;"

        }, matchHTML = /&(?!#?\w+;)|<|>|"|'|\//g;

        return function() {

            return this ? this.replace(matchHTML, function(m) {

                return encodeHTMLRules[m] || m

            }) : this

        }

    }

    String.prototype.encodeHTML = encodeHTMLSource();

    var startend = {

        append : {

            start : "'+(",

            end : ")+'",

            endencode : "||'').toString().encodeHTML()+'"

        },

        split : {

            start : "';out+=(",

            end : ");out+='",

            endencode : "||'').toString().encodeHTML();out+='"

        }

    }, skip = /$^/;

    function resolveDefs(c, block, def) {

        return ((typeof block === "string") ? block : block.toString())

                .replace(c.define || skip, function(m, code, assign, value) {

                    if (code.indexOf("def.") === 0) {

                        code = code.substring(4)

                    }

                    if (!(code in def)) {

                        if (assign === ":") {

                            if (c.defineParams) {

                                value.replace(c.defineParams, function(m,

                                        param, v) {

                                    def[code] = {

                                        arg : param,

                                        text : v

                                    }

                                })

                            }

                            if (!(code in def)) {

                                def[code] = value

                            }

                        } else {

                            new Function("def", "def['" + code + "']=" + value)(def)

                        }

                    }

                    return ""

                }).replace(c.use || skip, function(m, code) {

                    if (c.useParams) {

                        code = code.replace(c.useParams, function(m, s, d,

                                param) {

                            if (def[d] && def[d].arg && param) {

                                var rw = (d + ":" + param)

                                        .replace(/'|\\/g, "_");

                                def.__exp = def.__exp || {};

                                def.__exp[rw] = def[d].text.replace(new RegExp(

                                        "(^|[^\\w$])" + def[d].arg

                                                + "([^\\w$])", "g"), "$1"

                                        + param + "$2");

                                return s + "def.__exp['" + rw + "']"

                            }

                        })

                    }

                    var v = new Function("def", "return " + code)(def);

                    return v ? resolveDefs(c, v, def) : v

                })

    }

    function unescape(code) {

        return code.replace(/\\('|\\)/g, "$1").replace(/[\r\t\n]/g, " ")

    }

    doT.template = function(tmpl, c, def) {

        c = c || doT.templateSettings;

        var cse = c.append ? startend.append : startend.split, needhtmlencode = false, sid = 0, indv, str = (c.use || c.define)

                ? resolveDefs(c, tmpl, def || {})

                : tmpl;

        str = ("var out='"

                + (c.strip ? str.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g, " ")

                        .replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g, "") : str)

                        .replace(/'|\\/g, "\\$&").replace(

                                c.interpolate || skip, function(m, code) {

                                    return cse.start + unescape(code) + cse.end

                                }).replace(c.encode || skip, function(m, code) {

                            needhtmlencode = true;

                            return cse.start + unescape(code) + cse.endencode

                        }).replace(c.conditional || skip,

                                function(m, elsecase, code) {

                                    return elsecase ? (code

                                            ? "';}else if(" + unescape(code)

                                                    + "){out+='"

                                            : "';}else{out+='") : (code

                                            ? "';if(" + unescape(code)

                                                    + "){out+='"

                                            : "';}out+='")

                                }).replace(c.iterate || skip,

                                function(m, iterate, vname, iname) {

                                    if (!iterate) {

                                        return "';} } out+='"

                                    }

                                    sid += 1;

                                    indv = iname || "i" + sid;

                                    iterate = unescape(iterate);

                                    return "';var arr" + sid + "=" + iterate

                                            + ";if(arr" + sid + "){var "

                                            + vname + "," + indv + "=-1,l"

                                            + sid + "=arr" + sid

                                            + ".length-1;while(" + indv + "<l"

                                            + sid + "){" + vname + "=arr" + sid

                                            + "[" + indv + "+=1];out+='"

                                }).replace(c.evaluate || skip,

                                function(m, code) {

                                    return "';" + unescape(code) + "out+='"

                                }) + "';return out;").replace(/\n/g, "\\n")

                .replace(/\t/g, "\\t").replace(/\r/g, "\\r").replace(

                        /(\s|;|\}|^|\{)out\+='';/g, "$1").replace(/\+''/g, "")

                .replace(/(\s|;|\}|^|\{)out\+=''\+/g, "$1out+=");

        if (needhtmlencode && c.selfcontained) {

            str = "String.prototype.encodeHTML=(" + encodeHTMLSource.toString()

                    + "());" + str

        }

        try {

            return new Function(c.varname, str)

        } catch (e) {

            if (typeof iAuto.Logger !== "undefined") {

                iAuto.Logger

                        .log("Could not create a template function: " + str)

            }

            throw e

        }

    };

    doT.compile = function(tmpl, def) {

        return doT.template(tmpl, null, def)

    };

    iAuto.ui.framework.View.template = doT.template

}(iAuto));

iAuto.define("iAuto.ui.framework.XControl", {

    singleton : true,

    _instances : {},

    classes : {},

    classMgr : iAuto.ui.core.ClassManager,

    _parent : null,

    define : function(a, d) {

        var c = this.classes, b = iAuto.ui.core.ClassManager;

        b.define("xcontrol", a, d, function(e) {

            c[a] = e

        });

        return this

    },

    _create : function(b, e, m, i) {

        var h = this, k = iAuto.ui.core.AMD, j = iAuto.ui.framework.App

                .getXcontrolsDir(), f, a = b.name, d = b.config, g = this.classes[a], l, c = function(

                o, p, n) {

            l = new o();

            l.id = b.id;

            l.$element = ($.is$(p) ? p : $(p));

            h._lifeCreate(l, p, n, m, i)

        };

        if (!g) {

            iAuto.ui.core.ClassManager.loadClass("xcontrol", a, function(n) {

                h.classes[a] = n;

                c(n, e, d)

            });

            f = j + a + "/" + a + ".css";

            k.linkCss(f)

        } else {

            c(g, e, d)

        }

    },

    _lifeCreate : function(o, g, d, q, l) {

        var k = this, c = iAuto.ui.framework.Patch, f = iAuto.ui.framework.View, b = o.name, n, p = o.views, j = p.length, m = iAuto.ui.framework.App

                .getXcontrolsDir(), h = 0, a, i = function(r) {

            try {

                r.onCreate.call(r)

            } catch (s) {

                iAuto.Logger.error(s)

            }

            if (r.$element && r.$content) {

                c.loadItems(r).loadEvents(r);

                k._createCmp.call(k, r, function(t) {

                    k._lifeShow.call(k, t, q, l)

                }, l)

            }

        };

        for (n in d) {

            if (d.hasOwnProperty(n)) {

                var e = "set" + n.charAt(0).toUpperCase() + n.substr(1);

                if (typeof(o[e]) === "function") {

                    o[e](d[n])

                } else {

                    o.config[n] = d[n]

                }

            }

        }

        if (j > 0) {

            p.forEach(function(r) {

                a = m + b + "/" + r;

                (function(s) {

                    f.load(s, function(t) {

                        o._views[s] = t;

                        if (++h >= j) {

                            i(o, q, l)

                        }

                    })

                })(a)

            })

        } else {

            i(o, q, l)

        }

        return this

    },

    _lifeShow : function(b, a, c) {

        b.$element.children().remove();

        b.$element.append(b.$content);

        try {

            this._bindEvent(b);

            b.onShow.call(b)

        } catch (d) {

            if ($.isFunction(c)) {

                c()

            }

            iAuto.Logger.error(d)

        }

        if ($.isFunction(a)) {

            a(b)

        }

    },

    _createCmp : function(c, b, a) {

        iAuto.ui.framework.Controller._createCmp(c, b, a)

    },

    _removeCmp : function(a) {

        iAuto.ui.framework.Controller._removeCmp(a)

    },

    _bindEvent : function(a) {

        iAuto.ui.framework.Controller._bindEvent(a);

        return this

    },

    _unbindEvent : function(a) {

        iAuto.ui.framework.Controller._unbindEvent(a);

        return this

    },

    create : function(d, h, c) {

        var f = this, b = this.classes[d], g = this._instances, a, e = function(

                j, k, i) {

            a = new j();

            a.id = k;

            f._lifeCreate(a, k, i, function(l) {

                g[k] = l

            })

        };

        if (b) {

            e(b, h, c)

        } else {

            iAuto.ui.core.ClassManager.loadClass("xcontrol", d, function(i) {

                f.classes[d] = i;

                e(i, h, c)

            })

        }

    },

    get : function(a) {

        return iAuto.ui.framework.App.getCurrentController().getCmp(a)

                || this._instances[a]

    },

    destroy : function(c) {

        var a = this._instances[c];

        this._unbindEvent(a);

        if (a) {

            try {

                a.onHide(a);

                this._removeCmp(a);

                a.onDestroy(a)

            } catch (b) {

                iAuto.Logger.error(b)

            }

            return delete this._instances[c]

        }

        return false

    },

    _destroy : function(a) {

        this._unbindEvent(a);

        if (a) {

            try {

                if (typeof(a.onHide) === "function") {

                    a.onHide.call(a)

                }

                this._removeCmp(a);

                if (typeof(a.onDestroy) === "function") {

                    a.onDestroy.call(a)

                }

            } catch (b) {

                iAuto.Logger.error(b)

            }

            return delete a

        }

        return false

    },

    _getBaseUrl : function() {

        return iAuto.ui.framework.App.getXcontrolsDir()

    }

});

iAuto.define("iAuto.ui.framework.Glayer", {

    singleton : true,

    _instances : {},

    load : function(a, c) {

        var b = this;

        iAuto.ui.core.ClassManager.loadClass("glayer", a, function(f) {

            var d = new f();

            d.name = a;

            b._instances[a] = d;

            d.$content = $("#glayer");

            try {

                d.onLoad.call(d)

            } catch (g) {

                iAuto.Logger.error(g)

            }

            b._lifeEnter(d, c)

        });

        return this

    },

    define : function(a, c) {

        var b = iAuto.ui.core.ClassManager;

        c.singleton = c.singleton || "true";

        b.define("glayer", a, c);

        return this

    },

    _lifeEnter : function(a, c) {

        var b = this, d = iAuto.ui.framework.Patch;

        d.loadItems(a).loadEvents(a);

        this._createCmp(a, function() {

            b._lifeShow(a, c)

        });

        return this

    },

    _lifeShow : function(a, c) {

        this._bindEvent(a);

        try {

            a.onShow.call(a)

        } catch (b) {

            iAuto.Logger.error("Global Layer [" + name

                    + "] Execute wrong in onShow() function.");

            iAuto.Logger.error(b)

        }

        if ($.isFunction(c)) {

            c.call()

        }

        return this

    },

    _createCmp : function(c, b, a) {

        iAuto.ui.framework.Controller._createCmp(c, b, a)

    },

    _bindEvent : function(a) {

        iAuto.ui.framework.Controller._bindEvent(a)

    },

    getCmp : function(a) {

        return (this._instances && this._instances[a])

    },

    remove : function(b) {

        var a = this.get(b);

        if (!a) {

            iAuto.Logger

                    .error("[iAuto.ui.framework.Glayer] Remove an instance not exist");

            return false

        }

        try {

            a.onRemove.apply(a)

        } catch (c) {

            iAuto.Logger

                    .error("[iAuto.ui.framework.Glayer] error in onRemove method of ["

                            + b + "]");

            iAuto.Logger.error(c);

            return false

        }

        return delete this._instances[b]

    },

    show : function(a) {

        $("#" + a).toggle(true)

    },

    hide : function(a) {

        $("#" + a).toggle(false)

    }

});

iAuto.define("iAuto.ui.framework.Patch", {

    singleton : true,

    loadItems : function(i) {

        var g = iAuto.ui.framework, f = g.XControl, a = g.FControl, d = g.BControl, b = d.create, c = f.create, h = a.start, e = (i.items = i.items

                || []);

        d.create = function(k, l, j) {

            e.push({

                id : l,

                type : "bcontrol",

                name : k,

                config : j

            })

        };

        f.create = function(k, l, j) {

            e.push({

                id : l,

                type : "xcontrol",

                name : k,

                config : j

            })

        };

        a.start = function(j) {

            e.push({

                type : "fcontrol",

                name : j

            })

        };

        i._createCmp_.call(i, i);

        d.create = b;

        f.create = c;

        a.start = h;

        return this

    },

    loadEvents : function(a) {

        var c = (a.events = a.events || []), d = iAuto.ui.framework.Event, b = d.addListener;

        d.addListener = function(f, e) {

            e.item = f;

            c.push(e)

        };

        a._bindEvent_.call(a);

        d.addListener = b;

        return this

    }

});

iAuto.define("iAuto.ui.framework.System", {

    singleton : true,

    mixins : ["iAuto.core.event.Evented"],

    KEY_CODE_UNKNOWN : 0,

    KEY_CODE_HOME : 1,

    KEY_CODE_BACK : 2,

    KEY_CODE_VOLUMEUP : 3,

    KEY_CODE_VOLUMEDOWN : 4,

    KEY_CODE_TRACKUP : 5,

    KEY_CODE_TRACKDOWN : 6,

    KEY_CODE_MAP : 7,

    KEY_CODE_PHONE : 8,

    KEY_CODE_EJECT : 9,

    KEY_CODE_MENU : 10,

    KEY_CODE_ENTER : 11,

    KEY_CODE_POWER : 12,

    KEY_CODE_TONE : 13,

    KEY_CODE_INFO : 14,

    KEY_CODE_FAVORITES : 15,

    KEY_CODE_TAG1SWITCH : 16,

    KEY_CODE_TAG2SWITCH : 17,

    KEY_CODE_TAG3SWITCH : 18,

    KEY_CODE_TAG4SWITCH : 19,

    KEY_CODE_TAG5SWITCH : 20,

    KEY_CODE_TAG6SWITCH : 21,

    KEY_CODE_AUTOSTORE : 22,

    KEY_CODE_SEEKREV : 23,

    KEY_CODE_SEEKFWD : 24,

    KEY_CODE_CONFIG : 25,

    KEY_CODE_CDAUX : 26,

    KEY_CODE_RADIOBAND : 27,

    KEY_CODE_SEEKUP : 28,

    KEY_CODE_SEEKDOWN : 29,

    KEY_CODE_SRC : 30,

    KEY_CODE_VR : 31,

    KEY_CODE_HUNGUP : 32,

    KEY_CODE_RESERVE : 33,

    KEY_CODE_AUDIO : 34,

    KEY_CODE_UP : 35,

    KEY_CODE_DOWN : 36,

    KEY_CODE_TUNE : 37,

    KEY_CODE_NAVI : 38,

    KEY_CODE_DESTINATION : 39,

    KEY_CODE_ON_HOOK : 40,

    KEY_CODE_OFF_HOOK : 41,

    KEY_CODE_RPT : 42,

    KEY_CODE_MUTE : 43,

    KEY_CODE_INKA : 44,

    KEY_CODE_ICALL : 45,

    KEY_CODE_AV : 46,

    KEY_CODE_SOURCE : 47,

    KEY_CODE_HELP : 48,

    KEY_CODE_MUTEOFF : 49,

    KEY_CODE_LEFT : 50,

    KEY_CODE_RIGHT : 51,

    KEY_CODE_REARS : 52,

    KEY_CODE_TOPMENU : 53,

    KEY_CODE_JOYUP : 54,

    KEY_CODE_JOYLEFT : 55,

    KEY_CODE_JOYRIGHT : 56,

    KEY_CODE_JOYDOWN : 57,

    KEY_CODE_SUBTITLE : 58,

    KEY_CODE_ANGLE : 59,

    KEY_CODE_RETURN : 60,

    KEY_CODE_PREV : 61,

    KEY_CODE_PLAY_PAUSE : 62,

    KEY_CODE_NEXT : 63,

    KEY_CODE_STOP : 64,

    KEY_CODE_CAPTURE : 65,

    KEY_CODE_DIAG : 66,

    KEY_CODE_APPROACH : 67,

    KEY_CODE_FARAWAY : 68,

    DEVICE_TYPE_DEFAULT : 0,

    DEVICE_TYPE_MOST : 1,

    DEVICE_TYPE_REMOTE : 2,

    DEVICE_TYPE_STEERING : 3,

    __appId__ : null,

    __webServiceApi__ : null,

    __contentProviderApi__ : null,

    initSystem : function() {

        try {

            var a = this;

            if (a.__webServiceApi__ === null) {

                a.__webServiceApi__ = new iAuto.api.system.WebService(a.__appId__)

            }

            a.__webServiceApi__.one("apiReady", function() {

                a.__webServiceApi__.on("intentGot", function(c) {

                    try {

                        var f = JSON.parse(c);

                        a.trigger("intent", f)

                    } catch (d) {

                        iAuto.Logger.error(d.stack)

                    }

                })

            });

            a.__webServiceApi__.connect()

        } catch (b) {

            iAuto.Logger.error(b.stack)

        }

    },

    setAppId : function(a) {

        this.__appId__ = a

    },

    addTouchRegion : function(g, f, b, a) {

        try {

            var c = this;

            if (c.__webServiceApi__ === null) {

                c.__webServiceApi__ = new iAuto.api.system.WebService(c.__appId__)

            }

            c.__webServiceApi__.one("apiReady", function() {

                c.__webServiceApi__.addTouchRegion(f, g, b, a)

            });

            c.__webServiceApi__.connect()

        } catch (d) {

            iAuto.Logger.error(d.stack)

        }

    },

    removeTouchRegion : function(g, f, b, a) {

        try {

            var c = this;

            if (c.__webServiceApi__ === null) {

                c.__webServiceApi__ = new iAuto.api.system.WebService(c.__appId__)

            }

            c.__webServiceApi__.one("apiReady", function() {

                c.__webServiceApi__.rmTouchRegion(f, g, b, a)

            });

            c.__webServiceApi__.connect()

        } catch (d) {

            iAuto.Logger.error(d.stack)

        }

    },

    addKeyGuard : function(c, a) {

        try {

            var b = this;

            if (b.__webServiceApi__ === null) {

                b.__webServiceApi__ = new iAuto.api.system.WebService(b.__appId__)

            }

            b.__webServiceApi__.one("apiReady", function() {

                b.__webServiceApi__.addKeyGuard(c, a)

            });

            b.__webServiceApi__.connect()

        } catch (d) {

            iAuto.Logger.error(d.stack)

        }

    },

    removeKeyGuard : function(c, a) {

        try {

            var b = this;

            if (b.__webServiceApi__ === null) {

                b.__webServiceApi__ = new iAuto.api.system.WebService(b.__appId__)

            }

            b.__webServiceApi__.one("apiReady", function() {

                b.__webServiceApi__.rmKeyGuard(c, a)

            });

            b.__webServiceApi__.connect()

        } catch (d) {

            iAuto.Logger.error(d.stack)

        }

    },

    __fnQueryCompleted__ : null,

    queryContent : function(g, a, d, b, c) {

        try {

            var f = this;

            if (f.__contentProviderApi__ === null) {

                f.__contentProviderApi__ = new iAuto.api.system.ContentProvider()

            }

            if (f.__fnQueryCompleted__ === null) {

                f.__fnQueryCompleted__ = iAuto.Util.bind(f,

                        function(i, j, k, e) {

                            f.trigger("queryCompleted", i, j, k, e)

                        });

                f.__contentProviderApi__.on("queryCompleted",

                        f.__fnQueryCompleted__)

            }

            f.__contentProviderApi__.one("apiReady", function() {

                f.__contentProviderApi__.query(g, a, d, b, c)

            });

            f.__contentProviderApi__.connect()

        } catch (h) {

            iAuto.Logger.error(h.stack)

        }

    },

    __fnInsertCompleted__ : null,

    insertContent : function(c, a) {

        try {

            var b = this;

            if (b.__contentProviderApi__ === null) {

                b.__contentProviderApi__ = new iAuto.api.system.ContentProvider()

            }

            if (b.__fnInsertCompleted__ === null) {

                b.__fnInsertCompleted__ = iAuto.Util.bind(b, function(e, f) {

                    b.trigger("insertCompleted", e, f)

                });

                b.__contentProviderApi__.on("insertCompleted",

                        b.__fnInsertCompleted__)

            }

            b.__contentProviderApi__.one("apiReady", function() {

                b.__contentProviderApi__.insert(c, a)

            });

            b.__contentProviderApi__.connect()

        } catch (d) {

            iAuto.Logger.error(d.stack)

        }

    },

    __fnUpdateCompleted__ : null,

    updateContent : function(f, a, c, b) {

        try {

            var d = this;

            if (this.__contentProviderApi__ === null) {

                this.__contentProviderApi__ = new iAuto.api.system.ContentProvider()

            }

            if (d.__fnUpdateCompleted__ === null) {

                d.__fnUpdateCompleted__ = iAuto.Util.bind(d, function(h, e) {

                    d.trigger("updateCompleted", h, e)

                });

                d.__contentProviderApi__.on("updateCompleted",

                        d.__fnUpdateCompleted__)

            }

            d.__contentProviderApi__.one("apiReady", function() {

                d.__contentProviderApi__.update(f, a, c, b)

            });

            d.__contentProviderApi__.connect()

        } catch (g) {

            iAuto.Logger.error(g.stack)

        }

    },

    __fnRemoveCompleted__ : null,

    removeContent : function(d, b, a) {

        try {

            var c = this;

            if (c.__contentProviderApi__ === null) {

                c.__contentProviderApi__ = new iAuto.api.system.ContentProvider()

            }

            if (c.__fnRemoveCompleted__ === null) {

                c.__fnRemoveCompleted__ = iAuto.Util.bind(c, function(g, e) {

                    c.trigger("removeCompleted", g, e)

                });

                c.__contentProviderApi__.on("removeCompleted",

                        c.__fnRemoveCompleted__)

            }

            c.__contentProviderApi__.one("apiReady", function() {

                c.__contentProviderApi__.remove(d, b, a)

            });

            c.__contentProviderApi__.connect()

        } catch (f) {

            iAuto.Logger.error(f.stack)

        }

    },

    __fnTypeRetrieved__ : null,

    getContentUriType : function(b) {

        try {

            var a = this;

            if (a.__contentProviderApi__ === null) {

                a.__contentProviderApi__ = new iAuto.api.system.ContentProvider()

            }

            if (a.__fnTypeRetrieved__ === null) {

                a.__fnTypeRetrieved__ = iAuto.Util.bind(a, function(e, d) {

                    a.trigger("typeRetrieved", e, d)

                });

                a.__contentProviderApi__.on("typeRetrieved",

                        a.__fnTypeRetrieved__)

            }

            a.__contentProviderApi__.one("apiReady", function() {

                a.__contentProviderApi__.getType(b)

            });

            a.__contentProviderApi__.connect()

        } catch (c) {

            iAuto.Logger.error(c.stack)

        }

    }

});

iAuto.define("iAuto.ui.base.Controller", {

    xtype : "controller",

    config : {

        view : null,

        preImg : []

    },

    onLoad : function() {

    },

    onEnter : function() {

    },

    _createCmp_ : function() {

    },

    _bindEvent_ : function() {

    },

    onShowPre : function() {

    },

    onShow : function() {

    },

    onHide : function() {

    },

    onLeave : function() {

    },

    onRemove : function() {

    },

    getCmp : function(a) {

        return this._cmp[a]

    }

});

iAuto.define("iAuto.ui.base.FControl", {

    extend : "iAuto.core.event.Evented",

    xtype : "fcontrol",

    _baseUrl : iAuto.ui.framework.App.getFcontrolsDir(),

    config : {},

    onLoad : function() {

    },

    onStart : function() {

    },

    onStop : function() {

    },

    onRemove : function() {

    }

});

iAuto.define("iAuto.ui.base.XControl", {

    xtype : "xcontrol",

    views : null,

    _cmp : null,

    _status : null,

    _baseUrl : iAuto.ui.framework.App.getXcontrolsDir(),

    _views : [],

    $element : null,

    $content : null,

    name : null,

    id : null,

    events : null,

    config : {},

    constructor : function() {

        this._cmp = {};

        this._status = {};

        this._views = {};

        this.events = []

    },

    onCreate : function() {

    },

    _createCmp_ : function() {

    },

    _bindEvent_ : function() {

    },

    onShow : function() {

    },

    onHide : function() {

    },

    onDestroy : function() {

    },

    onRemove : function() {

    },

    getView : function(a) {

        var b = this._baseUrl + this.name + "/" + a;

        return this._views[b]

    },

    setView : function(a, c) {

        var d = this, b = this._baseUrl + this.name + "/" + a;

        iAuto.ui.framework.View.load(b, function(e) {

            d.$content = $.create(e(c))

        }, function() {

            iAuto.Logger.error("view [" + a + "] have not been loaded!")

        })

    },

    show : function() {

        if (this.$element && this.$content) {

            this.$element.append(this.$content)

        }

    },

    updateView : function(a, c) {

        var b = this.getView(a);

        this.$content = $.create(b(c));

        if (this.$element && this.$content) {

            this.$element.removeAll();

            this.$element.append(this.$content)

        }

    },

    hide : function() {

        this.$content = this.$element.children()

    },

    trigger : function() {

        this.$element.trigger.apply(this.$element, arguments)

    },

    on : function() {

        this.$element.on.apply(this.$element, arguments)

    },

    one : function() {

        this.$element.one.apply(this.$element, arguments)

    },

    off : function() {

        this.$element.off.apply(this.$element, arguments)

    },

    getCmp : function(a) {

        return this._cmp[a]

    }

});

iAuto.define("iAuto.ui.base.Model", {

    xtype : "model",

    _dataAdpter : null,

    id : null,

    modelName : null,

    config : {

        type : "localstorage"

    },

    fetch : function(b, c) {

        if (typeof(b) === "string") {

            this.id = b

        }

        var a = this;

        this._dataAdpter.fetch(a, function(d) {

            var e = a._prepareModel(d);

            if (c) {

                return c(e)

            }

            return e

        }, a.modelName)

    },

    fetchAll : function(b, c) {

        var a = this;

        if (this._dataAdpter) {

            this._dataAdpter.fetchAll(a, function(d) {

                var e = [];

                d.forEach(function(f) {

                    e.push(a._prepareModel(f))

                });

                if (c) {

                    return c(e)

                }

                return e

            })

        }

    },

    save : function(a) {

        return this._dataAdpter.save(this, a)

    },

    remove : function(a) {

        return this._dataAdpter.remove(this, a)

    },

    get : function(a) {

        if (this.hasOwnProperty(a)) {

            return this[a]

        }

        return undefined

    },

    set : function(e, d, c) {

        var a = $.extend({}, this);

        if ($.isObject(e)) {

            if (e && e.modelName) {

                delete e.modelName

            }

            if (e && e.id) {

                delete e.id

            }

            for (var b in e) {

                if (this.hasOwnProperty(b)) {

                    this[b] = e[b]

                }

            }

            if (!this._validate(c)) {

                $.extend(this, a);

                return false

            }

            return true

        }

        if (e.toLowerCase() !== "id" && e.toLowerCase() !== "modelname") {

            this[e] = d

        }

        if (!this._validate(c)) {

            $.extend(this, a);

            return false

        }

        return true

    },

    valid : function(a) {

        return this._validata(a) === true

    },

    _validation : function(a) {

        return a

    },

    _prepareModel : function(a) {

        var c = this;

        var b = $.extend({}, c);

        b = $.extend(b, a);

        return b

    }

});

iAuto.define("iAuto.ui.base.Glayer", {

    xtype : "glayer",

    _cmp : null,

    constructor : function() {

        this._cmp = {}

    },

    onLoad : function() {

    },

    _createCmp_ : function() {

    },

    _bindEvent_ : function() {

    },

    onShow : function() {

    },

    onHide : function() {

    },

    onRemove : function() {

    },

    show : function(a) {

        var b = this.$content.find("#" + a);

        b.toggle(true)

    },

    hide : function(a) {

        var b = this.$content.find("#" + a);

        b.toggle(false)

    },

    get : function(a) {

        return this._cmp[a]

    }

});

iAuto.define("iAuto.ui.control.Button", {

    $el : null,

    constructor : function(a, b) {

        var d = this;

        this.$el = a;

        var c = b.pressCls || "c-button-pressing";

        this.$el.on("touchstart", function() {

            d.$el.addClass(c)

        });

        this.$el.on("touchend", function() {

            d.$el.removeClass(c)

        })

    },

    setLabel : function(a) {

        this.$el.find("[data-role=lable]").html(a)

    }

});

iAuto.define("iAuto.ui.control.ComboBox", {

    $el : null,

    $select : null,

    constructor : function(a, b) {

        if (!a) {

            return

        }

        b = b || {};

        this.$el = a;

        this.$select = a.find("select");

        this.setOptions(b.options)

    },

    setOptions : function(a) {

        if (this.$select.length <= 0) {

            return this

        }

        a = a || [];

        for (var b = 0; b < a.length; b++) {

            var c = document.createElement("OPTION");

            c.innerText = a[b];

            this.$select.append(c)

        }

    }

});

iAuto.define("iAuto.ui.control.SearchBox", {

    $el : null,

    $clearbutton : null,

    $input : null,

    constructor : function(a, b) {

        if (!a) {

            return

        }

        b = b || {};

        var c = this;

        this.$el = a;

        this.$clearbutton = this.$el.find("div[data-role='clearbutton']");

        this.$input = this.$el.find("input[data-role='input']");

        itu.event.on(this.$clearbutton, "tap", c.clearValue, c)

    },

    clearValue : function() {

        if (this.$input) {

            this.$input.val("")

        }

    }

});

iAuto.define("iAuto.ui.control.Spinner", {

    $el : null,

    $label : null,

    $btnUp : null,

    $btnDown : null,

    config : {

        btnPressCls : "c-spinner-button-pressed",

        maxValue : 100,

        minValue : 0,

        scale : 1,

        value : 0

    },

    constructor : function(a, b) {

        if (!a || a.length < 1) {

            return

        }

        var d = this, c;

        this.$el = a;

        this.$label = a.find("label");

        this.$btnUp = a.find("div[data-role='up'");

        this.$btnDown = a.find("div[data-role='down']");

        for (c in (b = b || {})) {

            if (b.hasOwnProperty(c)) {

                var e = "set" + c.charAt(0).toUpperCase() + c.substr(1);

                if (this[e]) {

                    this[e](b[c])

                }

            }

        }

        this.showValue(this.getValue());

        itu.event.on(this.$btnUp, "tap", d.onUp, d);

        itu.event.on(this.$btnDown, "tap", d.onDown, d);

        itu.event.on(this.$btnUp, "touchstart", function() {

            d.$btnUp.addClass(d.getBtnPressCls())

        });

        itu.event.on(this.$btnUp, "touchend", function() {

            d.$btnUp.removeClass(d.getBtnPressCls())

        });

        itu.event.on(this.$btnDown, "touchstart", function() {

            d.$btnDown.addClass(d.getBtnPressCls())

        });

        itu.event.on(this.$btnDown, "touchend", function() {

            d.$btnDown.removeClass(d.getBtnPressCls())

        })

    },

    onUp : function() {

        var a = this.getValue();

        if ((a += this.getScale()) <= this.getMaxValue()) {

            this.setValue(a);

            this.showValue(a)

        }

    },

    onDown : function() {

        var a = this.getValue();

        if ((a -= this.getScale()) >= this.getMinValue()) {

            this.setValue(a);

            this.showValue(a)

        }

    },

    showValue : function() {

        this.$label.text(this.getValue())

    }

});

iAuto.define("iAuto.ui.control.Toggle", {

    $el : null,

    $thumb : null,

    config : {

        toggleOnCls : "c-toggle-on",

        thumbOnCls : "c-thumb-on",

        on : false

    },

    constructor : function(a, b) {

        if (!a || a.length < 1) {

            return

        }

        b = b || {};

        var c = this;

        this.$el = a;

        this.$thumb = a.find("div[data-role='thumb']");

        $.extend(this.config, b);

        itu.event.on(this.$el, "tap", c.toggle, c)

    },

    toggle : function() {

        if (this.getOn() === false || "false" === this.getOn().toString()) {

            this.setOn(true);

            this.$el.addClass(this.getToggleOnCls());

            this.$thumb.addClass(this.getThumbOnCls())

        } else {

            this.setOn(false);

            this.$el.removeClass(this.getToggleOnCls());

            this.$thumb.removeClass(this.getThumbOnCls())

        }

    },

    getStatus : function() {

        return this.getOn()

    }

});

var itu = (function() {

    var b = iAuto.ui.framework, a = {

        app : b.App,

        controller : b.Controller,

        view : b.View,

        model : b.Model,

        bcontrol : b.BControl,

        fcontrol : b.FControl,

        xcontrol : b.XControl,

        glayer : b.Glayer,

        event : b.Event,

        resource : b.ResourceManager

    };

    return a

})();
framework

记得我面试进这个公司的时候,考题里有个叫carousel.js

/**

 * af.web.carousel - a carousel library for App Framework apps

 * @copyright 2011 - Intel

 *

 */

(function($) {

    var cache = [];

    var objId=function(obj){

        if(!obj.afmCarouselId) obj.afmCarouselId=$.uuid();

        return obj.afmCarouselId;

    };

    $.fn.carousel = function(opts) {

        var tmp, id;

        for (var i = 0; i < this.length; i++) {

            //cache system

            id = objId(this[i]);

            if(!cache[id]){

                tmp = new carousel(this[i], opts);

                cache[id] = tmp;

            } else {

                tmp = cache[id];

            }

        }

        return this.length == 1 ? tmp : this;

    };



    var carousel = (function() {

        var translateOpen =$.feat.cssTransformStart;

        var translateClose = $.feat.cssTransformEnd;



        var carousel = function(containerEl, opts) {

            if (typeof containerEl === "string" || containerEl instanceof String) {

                this.container = document.getElementById(containerEl);

            } else {

                this.container = containerEl;

            }

            if (!this.container) {

                alert("Error finding container for carousel " + containerEl);

                return;

            }

            if (this instanceof carousel) {

                for (var j in opts) {

                    if (opts.hasOwnProperty(j)) {

                        this[j] = opts[j];

                    }

                }

            } else {



                return new carousel(containerEl, opts);

            }





            var that = this;

            af(this.container).bind('destroy', function(e){

                var id = that.container.afmCarouselId;

                //window event need to be cleaned up manually, remaining binds are automatically killed in the dom cleanup process

               window.removeEventListener("orientationchange", that.orientationHandler, false);

               if(cache[id]) delete cache[id];

               e.stopPropagation();

            });



            this.pagingDiv = this.pagingDiv ? document.getElementById(this.pagingDiv) : null;





            // initial setup

            this.container.style.overflow = "hidden";

            if (this.vertical) {

                this.horizontal = false;

            }



            var el = document.createElement("div");

            this.container.appendChild(el);

            var $el=$(el);

            var $container=$(this.container);

            var data = Array.prototype.slice.call(this.container.childNodes);

            while(data.length>0)

            {

                var myEl=data.splice(0,1);

                myEl=$container.find(myEl);

                if(myEl.get(0)===el)

                   continue;

                $el.append(myEl.get(0));

            }

            if (this.horizontal) {

                el.style.display = "block";

                el.style['float']="left";

            }

            else {

                el.style.display = "block";

            }



            this.el = el;

            this.refreshItems();

            var afEl = af(el);

            afEl.bind('touchmove', function(e) {that.touchMove(e);});

            afEl.bind('touchend', function(e) {that.touchEnd(e);});

            afEl.bind('touchstart', function(e) {that.touchStart(e);});

            this.orientationHandler = function() {that.onMoveIndex(that.carouselIndex,0);};

            window.addEventListener("orientationchange", this.orientationHandler, false);



        };



        carousel.prototype = {

            wrap:true,

            startX: 0,

            startY: 0,

            dx: 0,

            dy: 0,

            glue: false,

            myDivWidth: 0,

            myDivHeight: 0,

            cssMoveStart: 0,

            childrenCount: 0,

            carouselIndex: 0,

            vertical: false,

            horizontal: true,

            el: null,

            movingElement: false,

            container: null,

            pagingDiv: null,

            pagingCssName: "carousel_paging",

            pagingCssNameSelected: "carousel_paging_selected",

            pagingFunction: null,

            lockMove:false,

            okToMove: false,



            // handle the moving function

            touchStart: function(e) {

                this.okToMove = false;

                this.myDivWidth = numOnly(this.container.clientWidth);

                this.myDivHeight = numOnly(this.container.clientHeight);

                this.lockMove=false;

                if (e.touches[0].target && e.touches[0].target.type !== undefined) {

                    var tagname = e.touches[0].target.tagName.toLowerCase();

                    if (tagname === "select" || tagname === "input" || tagname === "button")  // stuff we need to allow

                    {

                        return;

                    }

                }

                if (e.touches.length === 1) {



                    this.movingElement = true;

                    this.startY = e.touches[0].pageY;

                    this.startX = e.touches[0].pageX;

                    var cssMatrix=$.getCssMatrix(this.el);



                    if (this.vertical) {

                        try {

                            this.cssMoveStart = numOnly(cssMatrix.f);

                        } catch (ex1) {

                            this.cssMoveStart = 0;

                        }

                    } else {

                        try {

                            this.cssMoveStart = numOnly(cssMatrix.e);

                        } catch (ex1) {

                            this.cssMoveStart = 0;

                        }

                    }

                }

            },

            touchMove: function(e) {

                if(!this.movingElement)

                   return;

                if (e.touches.length > 1) {

                    return this.touchEnd(e);

                }



                var rawDelta = {

                    x: e.touches[0].pageX - this.startX,

                    y: e.touches[0].pageY - this.startY

                };



                if (this.vertical) {

                    var movePos = { x: 0, y: 0 };

                    this.dy = e.touches[0].pageY - this.startY;



                    this.dy += this.cssMoveStart;

                    movePos.y = this.dy;



                    e.preventDefault();

                    //e.stopPropagation();

                } else {

                    if ((!this.lockMove&&isHorizontalSwipe(rawDelta.x, rawDelta.y))||Math.abs(this.dx)>5) {



                        var movePos = {x: 0,y: 0};

                        this.dx = e.touches[0].pageX - this.startX;

                        this.dx += this.cssMoveStart;

                        e.preventDefault();

                      //  e.stopPropagation();

                        movePos.x = this.dx;

                    }

                    else

                       return this.lockMove=true;

                }



                var totalMoved = this.vertical ? ((this.dy % this.myDivHeight) / this.myDivHeight * 100) * -1 : ((this.dx % this.myDivWidth) / this.myDivWidth * 100) * -1; // get a percentage of movement.



                if (!this.okToMove) {

                    oldStateOkToMove= this.okToMove;

                    this.okToMove = this.glue ? Math.abs(totalMoved) > this.glue  && Math.abs(totalMoved) < (100 - this.glue) : true;

                    if (this.okToMove && !oldStateOkToMove) {

                        $.trigger(this,"movestart",[this.el]);

                    }

                }



                if  (this.okToMove && movePos)

                   this.moveCSS3(this.el, movePos);



            },

            touchEnd: function(e) {

                if (!this.movingElement) {

                    return;

                }

                $.trigger(this,"movestop",[this.el]);

                // e.preventDefault();

                // e.stopPropagation();

                var runFinal = false;

              //  try {

                    var cssMatrix=$.getCssMatrix(this.el);

                    var endPos = this.vertical ? numOnly(cssMatrix.f) : numOnly(cssMatrix.e);



                    if (1==2&&endPos > 0) {

                        this.moveCSS3(this.el, {

                            x: 0,

                            y: 0

                        }, "300");

                    } else {

                        var totalMoved = this.vertical ? ((this.dy % this.myDivHeight) / this.myDivHeight * 100) * -1 : ((this.dx % this.myDivWidth) / this.myDivWidth * 100) * -1; // get a percentage of movement.

                        // Only need

                        // to drag 3% to trigger an event

                        var currInd = this.carouselIndex;

                        if (endPos < this.cssMoveStart && totalMoved > 3) {

                            currInd++; // move right/down

                        } else if ((endPos > this.cssMoveStart && totalMoved < 97)) {

                            currInd--; // move left/up

                        }

                        var toMove=currInd;

                        //Checks for infinite - moves to placeholders

                        if(this.wrap){

                            if (currInd > (this.childrenCount - 1)) {

                                currInd = 0;

                                toMove=this.childrenCount;

                            }

                            if (currInd < 0) {

                                currInd = this.childrenCount-1;

                                toMove=-1;

                            }

                        }

                        else {

                            if(currInd<0)

                                currInd=0;

                            if(currInd>this.childrenCount-1)

                                currInd=this.childrenCount-1;

                            toMove=currInd;

                        }



                        var movePos = {

                            x: 0,

                            y: 0

                        };

                        if (this.vertical) {

                            movePos.y = (toMove * this.myDivHeight * -1);

                        }

                        else {

                            movePos.x = (toMove * this.myDivWidth * -1);

                        }



                        this.moveCSS3(this.el, movePos, "150");



                        if (this.pagingDiv && this.carouselIndex !== currInd) {

                            document.getElementById(this.container.id + "_" + this.carouselIndex).className = this.pagingCssName;

                            document.getElementById(this.container.id + "_" + currInd).className = this.pagingCssNameSelected;

                        }

                        if (this.carouselIndex != currInd)

                            runFinal = true;

                        this.carouselIndex = currInd;



                        //This is for the infinite ends - will move to the correct position after animation

                        if(this.wrap){

                            if(toMove!=currInd){

                                var that=this;

                                window.setTimeout(function(){

                                    that.onMoveIndex(currInd,"1ms");

                                },155);

                           }

                        }

                    }

                //} catch (e) {

                //    console.log(e);

               // }

                this.dx = 0;

                this.movingElement = false;

                this.startX = 0;

                this.dy = 0;

                this.startY = 0;

                if (runFinal && this.pagingFunction && typeof this.pagingFunction == "function")

                    this.pagingFunction(this.carouselIndex);

            },

            onMoveIndex: function(newInd,transitionTime) {



                this.myDivWidth = numOnly(this.container.clientWidth);

                this.myDivHeight = numOnly(this.container.clientHeight);

                var runFinal = false;



                    if(document.getElementById(this.container.id + "_" + this.carouselIndex))

                        document.getElementById(this.container.id + "_" + this.carouselIndex).className = this.pagingCssName;



                    var newTime = Math.abs(newInd - this.carouselIndex);



                    var ind = newInd;

                    if (ind < 0)

                        ind = 0;

                    if (ind > this.childrenCount - 1) {

                        ind = this.childrenCount - 1;

                    }

                    var movePos = {

                        x: 0,

                        y: 0

                    };

                    if (this.vertical) {

                        movePos.y = (ind * this.myDivHeight * -1);

                    }

                    else {

                        movePos.x = (ind * this.myDivWidth * -1);

                    }



                    var time =transitionTime?transitionTime: 50 + parseInt((newTime * 20));

                    this.moveCSS3(this.el, movePos, time);

                    if (this.carouselIndex != ind)

                        runFinal = true;

                    this.carouselIndex = ind;

                    if (this.pagingDiv) {

                        var tmpEl = document.getElementById(this.container.id + "_" + this.carouselIndex);

                        if(tmpEl) tmpEl.className = this.pagingCssNameSelected;

                    }



                if (runFinal && this.pagingFunction && typeof this.pagingFunction == "function")

                    this.pagingFunction(currInd);

            },



            moveCSS3: function(el, distanceToMove, time, timingFunction) {

                if (!time)

                    time = 0;

                else

                    time = parseInt(time);

                if (!timingFunction)

                    timingFunction = "linear";

                el.style[$.feat.cssPrefix+"Transform"] = "translate" + translateOpen + distanceToMove.x + "px," + distanceToMove.y + "px" + translateClose;

                el.style[$.feat.cssPrefix+"TransitionDuration"] = time + "ms";

                el.style[$.feat.cssPrefix+"BackfaceVisibility"] = "hidden";

                el.style[$.feat.cssPrefix+"TransformStyle"] = "preserve-3d";

                el.style[$.feat.cssPrefix+"TransitionTimingFunction"] = timingFunction;

            },



            addItem: function(el) {

                if (el && el.nodeType) {



                    this.container.childNodes[0].appendChild(el);

                    this.refreshItems();

                }

            },

            refreshItems: function() {

                var childrenCounter = 0;

                var that = this;

                var el = this.el;

                $(el).children().find(".prevBuffer").remove();

                $(el).children().find(".nextBuffer").remove();

                n = el.childNodes[0];

                var widthParam;

                var heightParam = "100%";

                var elems = [];



                for (; n; n = n.nextSibling) {

                    if (n.nodeType === 1) {

                        elems.push(n);

                        childrenCounter++;

                    }

                }

                //Let's put the buffers at the start/end

                if(this.wrap){

                    var prep=$(elems[elems.length-1]).clone().get(0);

                    $(el).prepend(prep);

                    var tmp=$(elems[0]).clone().get(0);

                    $(el).append(tmp);

                    elems.push(tmp);

                    elems.unshift(prep);

                    tmp.style.position="absolute";

                    prep.style.position="absolute";

                }



                var param = (100 / childrenCounter) + "%";

                this.childrenCount = childrenCounter;

                widthParam = parseFloat(100 / childrenCounter) + "%";



                for (var i = 0; i < elems.length; i++) {

                    if (this.horizontal) {

                        elems[i].style.width = widthParam;

                        elems[i].style.height = "100%";

                        elems[i].style['float']="left";

                    }

                    else {

                        elems[i].style.height = widthParam;

                        elems[i].style.width = "100%";

                        elems[i].style.display = "block";

                    }

                }

                //Clone the first and put it at the end

                



                this.moveCSS3(el, {

                    x: 0,

                    y: 0

                });

                if (this.horizontal) {

                    el.style.width = Math.ceil((this.childrenCount) * 100) + "%";

                    el.style.height = "100%";

                    el.style['min-height'] = "100%"

                    if(this.wrap){

                        prep.style.left="-"+widthParam;

                        tmp.style.left="100%";

                    }

                }

                else {

                    el.style.width = "100%";

                    el.style.height = Math.ceil((this.childrenCount) * 100) + "%";

                    el.style['min-height'] = Math.ceil((this.childrenCount) * 100) + "%";

                    if(this.wrap){

                        prep.style.top="-"+widthParam;

                        tmp.style.top="100%";

                    }

                }

                // Create the paging dots

                if (this.pagingDiv) {

                    this.pagingDiv.innerHTML = ""

                    for (i = 0; i < this.childrenCount; i++) {



                        var pagingEl = document.createElement("div");

                        pagingEl.id = this.container.id + "_" + i;

                        pagingEl.pageId = i;

                        if (i !== this.carouselIndex) {

                            pagingEl.className = this.pagingCssName;

                        }

                        else {

                            pagingEl.className = this.pagingCssNameSelected;

                        }

                        pagingEl.onclick = function() {

                            that.onMoveIndex(this.pageId);

                        };

                        var spacerEl = document.createElement("div");



                        spacerEl.style.width = "20px";

                        if(this.horizontal){

                            spacerEl.style.display = "inline-block";

                            spacerEl.innerHTML = "&nbsp;";

                        }

                        else{

                           spacerEl.innerHTML="&nbsp;";

                           spacerEl.style.display="block";

                        }



                        this.pagingDiv.appendChild(pagingEl);

                        if (i + 1 < (this.childrenCount))

                            this.pagingDiv.appendChild(spacerEl);

                        pagingEl = null;

                        spacerEl = null;

                    }

                    if(this.horizontal){

                        this.pagingDiv.style.width = (this.childrenCount) * 50 + "px";

                        this.pagingDiv.style.height = "25px";

                    }

                    else {

                        this.pagingDiv.style.height = (this.childrenCount) * 50 + "px";

                        this.pagingDiv.style.width = "25px";

                    }

                }

                this.onMoveIndex(this.carouselIndex);



            }



        };

        return carousel;

    })();



    function isHorizontalSwipe(xAxis, yAxis) {

                var X = xAxis;

                var Y = yAxis;

                var Z = Math.round(Math.sqrt(Math.pow(X,2)+Math.pow(Y,2))); //the distance - rounded - in pixels

                var r = Math.atan2(Y,X); //angle in radians

                var swipeAngle = Math.round(r*180/Math.PI); //angle in degrees

                if ( swipeAngle < 0 ) { swipeAngle =  360 - Math.abs(swipeAngle); } // for negative degree values

                if (((swipeAngle <= 215) && (swipeAngle >= 155)) || ((swipeAngle <= 45) && (swipeAngle >= 0)) || ((swipeAngle <= 360) && (swipeAngle >= 315))) // horizontal angles with threshold

                {return true; }

                else {return false}

    }



})(af);
carousel.js

当时看源码觉得很多方法不知道哪里来的,也就是framework里面的东西。

采用的是目前流行的命名空间写法,整体结构大致上就是:

(function($) {

    "use strict";

    

    var cache = {};

    var ... = function(...) {};

    $.fn.scroller=function(...){

        return this.length == 1 ? tmp : this;

    };

    if(!$.mixin) {

        $.mixin = {};

    }

    if(!$.scroller) {

        $.scroller = {};

    }

    var mixin = $.mixin,

        scroller = $.scroller;

       mixin.scrollerMixin = {

        ...: ...,

        ...: ...,

         wrapper: '<div class="c-scroller">' +     

        '</div>',



        initScroller: function() {

            this.initData();

            this....();

        },

        ...: function() {

            this.... = {

                x: 0,

                y: 0

            };

        },

        ...: function() {

            return this.position;

        },

            var event = new Object();

            event.data = new Object();

            event.data.gesture = new Object();

            event.data.gesture.srcEvent = new Object();

            event.data.gesture.srcEvent.... = new Array();

            event.data.gesture.srcEvent....[0] = new Object();

            if ((... === ...) || (... === .....)) { 

                event.data.gesture.srcEvent....[0].pageX = this.....x;

                event.data.gesture.srcEvent....[0].pageY = this.....y;

            }    

            else {

                return;

            }

            this.dragStart(event);

            var ... = this;

            setTimeout(function() {

                me....(event, ...);

                me...(event);

            }, 50); 

            setTimeout(function() {

                me....(event, ...);

                me.drag(event);

            }, 50);

            setTimeout(function() {

                me....(event, ...);

                me....(event);

            }, 50);

        },

        modifyEvent: function(event, keyCode) {

            return event;

        },

        addWrapper: function() {

            var wrapper = this.wrapper,

                element = this.element;

            this.$wrapper = $(wrapper).insertBefore($(element));

            

            this.scrollerElement = this.$wrapper.find('.c-scroller__scroller-content');

            this.scrollerContainerElement = this.$wrapper.find('.c-scroller__scroller-container');

            

            $(element).appendTo(this.scrollerElement);

        },

         deleteWrapper: function() {

            var $wrapper, element, $element;

            $wrapper = this.$wrapper;

            element = this.element;

            $element = $(element);

            $element.remove();

            $element.insertBefore($wrapper);

            $wrapper.remove();

        },

        addResizeListener: function() {

            if ( ) {

            }

        },

        runLoopy: function() {},

        ...: function() {

            var .. = this...;

            this...({

                x: ...width(),

                y: ...height()

            });

        },...: function() {

            var ... = this....;

            this...({

                x: ...width(),

                y: ...height()

            });

        },

        ...: function() {

            var .., ...;

            .. = this....;

            ... = this...;

            if (!..) {

                this... = .. = {};

            }

            if (.. === '..') {

                ...x = true;

                ...y = true;

            } else if (.. === '..') {

                ...y = true;

                this.$wrapper.addClass('..');

            } else if (... === '..') {

                ...x = true;

                this.$wrapper.addClass('..');

            }

        },

        ...: function() {

            this... = iAuto.Util.bind(this, this...);

            $.bind(this, '..', this...);

            this... = iAuto.Util.bind(this, this...);

            $.bind(this, '..', this...);

            this... = iAuto.Util.bind(this, this...);

            $.bind(this, '..', this...);

        },

        ..: function() {

            this...();

        },

        ..: function() {

            this...();

        },

        ..: function(..) {

            return this...[..];

        },

    var Scroller = function(el, opts) {

        this.el = el;

        this.$el = $(el);

        iAuto.copy(this, mixin.scrollerMixin);

        opts = opts || {};

        iAuto.copy(this, opts);

        this.initScroller();

        if(this.showIndicator) {

            iAuto.copy(this, mixin.IndicatorMixin);

            this.initIndicator();

        }

        var me = this;

        this.$el.one('destroy', function(e) {

            var id = el.afscrollerID;

            if(cache[id]) delete cache[id];

            e.stopPropagation();

        });

    };

    Scroller.prototype = {

        element: null

    };

    var cssTranslate = scroller.CssTranslate = function() {}; 

    cssTranslate.prototype = {

        ...

        ...

        ...



        init: function() {},

        setTransformElement: function(transformElement) {},

        translate: function(x, y) {},

        doTranslate: function() {},

        animate: function(easingX, easingY) {},

        stopAnimation: function() {},

        destroy: function() {

            this.stopAnimation();

        }

    };

    var EaseOut = scroller.EaseOut = function() {};

    EaseOut.prototype = {

        ...: ..,

        ...: ..,

        ...: ..,

        init: function() {



        },

     setStartTime: function(startTime) {

            this.startTime = startTime;

            this.reset();

        },

     setStartValue: function(startValue) {},

     reset: function() {},

     setEndValue: function(endValue) {},

     setDuration: function(duration) {},

     setExponent: function(exponent) {},

     getValue: function() {

            ...: ..,

            ...: ..,

            ...: ..,

        if ( ) {}

            return ...;

        }

    };



    var Momentum = scroller.Momentum = function() {};

    Momentum.prototype = {

        ...: ..,

        ...: ..,

        ...: ..,



        init: function() {},

    };



    var Bounce = scroller.Bounce = function() {};

    Bounce.prototype = {

        ...: ..,

        ...: ..,

        ...: ..,

        init: function() {



        },

    };



    var BoundMomentum = scroller.BoundMomentum = function() {};

    BoundMomentum.prototype = {

        ...: ..,

        ...: ..,

        ...: ..,

        init: function() {

            this.initMomentum();

            this.initBounce();

        },

        initMomentum: function() {

            this.momentum = new Momentum();

            this.momentum.init();

        },

        initBounce: function() {

            this.bounce = new Bounce();

            this.bounce.init();

        },

        reset: function() {

            this... = null;

            this... = false;

            this... = false;

            this... = false;

        }

    };

    

})(af);

此处略去很多代码,为的是一目了然。

"use strict"

采用严谨模式的js

"use strict"; 被放在一个 JavaScript 文件或函数的起始位置时 (我不确定 script 标签开头是否可以),才可以开启严格模式。否则 - 在 JavaScript 文件的不是文件开头也不是函数开始的部位声明的话 - 就是一个不使用的一般的字符串,除了浪费几个字节,没什么别的用处。通常实践推荐在所有的函数 (或者所有最外层函数) 的开始处加入 "use strict"; 指令启动严格模式,而绝不推荐在文件的开头处写全局 "use strict" - 相反,这时一些 ES 校验器会给出警告。



全局 "use strict" 为什么不好? 一个重要的原因就是文件合并时,一些文件用了严格模式,而另一些没有。这时这些本来是严格模式的文件,被 merge 后,这个串就到了文件的中间,不仅没有指示严格模式,反而在压缩后浪费了字节。
注意事项

显然function($){}(document,window);是jquery系插件写法。

内部一开始先声明若干变量,把init方法摆出来。

然后有些对象内部的全局变量赋给局部变量,制造一些自定义事件用 new Object();

然后被包裹的内容,不可以定位为absolute,否则成不起来。

你可能感兴趣的:(scroll)