package krewfw.builtin_actor {

    import krewfw.core.KrewActor;

    /**
     * State Object for KrewStateMachine.
     */
    //------------------------------------------------------------
    public class KrewState extends KrewActor {

        /** KrewStateMachine gives its reference to a state on registration. */
        private var _stateMachine:KrewStateMachine;

        private var _stateId:String;
        private var _nextStateId:String;

        /** Handler called when state starts. */
        private var _onEnterHandler:Function;

        /** Handler called during state or its sub-state is selected. */
        private var _onUpdateHandler:Function;

        /** Handler called when state ends. */
        private var _onExitHandler:Function;

        /** Conditions of transitions by event. */
        private var _guardFunc:Function;

        private var _listenList:Array;
        public  var isListening:Boolean = false;

        private var _parentState:KrewState;
        private var _childStates:Vector.<KrewState>;

        //------------------------------------------------------------
        // accessors
        //------------------------------------------------------------

        public function set stateMachine(fsm:KrewStateMachine):void { _stateMachine = fsm; }

        public function get stateId():String { return _stateId; }

        public function get nextStateId():String { return _nextStateId; }
        public function set nextStateId(id:String):void { _nextStateId = id; }

        public function get onEnterHandler() :Function { return _onEnterHandler; }
        public function get onUpdateHandler():Function { return _onUpdateHandler; }
        public function get onExitHandler()  :Function { return _onExitHandler; }
        public function get guardFunc()      :Function { return _guardFunc; }

        public function get listenList():Array { return _listenList; }

        public function get childStates():Vector.<KrewState> { return _childStates; }
        public function hasChildren():Boolean { return (_childStates != null); }

        public function get parentState():KrewState { return _parentState; }
        public function set parentState(state:KrewState):void { _parentState = state; }
        public function hasParent():Boolean { return (_parentState != null); }

        //------------------------------------------------------------

        /**
         * Create state with Object key-values.
         *
         * @param stateDef Object including state options such as:
         *

         *
(Required) id      : {String} - State name.

         *
(Optional) next    : {String} - Next state name. progress() will proceed state to the next.
         *           If omitted, next Array element is used as next state.

         *
(Optional) enter   : {Function(state:KrewState):void} - Called when state starts.

         *
(Optional) update  : {Function(state:KrewState, passedTime:Number):void} -
         *           Called during state or sub-state is selected.

         *
(Optional) exit    : {Function(state:KrewState):void} - Called when state ends.

         *
(Optional) guard   : {Function(state:KrewState):Boolean} - Called when event triggered.
         *           Return false to prevent transition and bubbling event.

         *
(Optional) listen  : {Object or Array} - Ex.) [{event: "event_name", to:"target_state_name"}] -
         *           event で指定したイベントを受け取ったとき、to で指定した state に遷移する。
         *           KrewStateMachine はイベントをまず現在の state に渡す。 state は自分で解決できない
         *           イベントだった場合は親 state に委譲していく

         *
(Optional) children: {Array} - Sub state definition list.

         *

         */
        public function KrewState(stateDef:Object) {
            displayable = false;

            if (!stateDef.id) { throw new Error("[new KrewState] id is required."); }

            _stateId     = stateDef.id;
            _nextStateId = stateDef.next || null;

            _onEnterHandler  = stateDef.enter  || null;
            _onUpdateHandler = stateDef.update || null;
            _onExitHandler   = stateDef.exit   || null;
            _guardFunc       = stateDef.guard  || null;

            // listen to event
            if (stateDef.listen != null) {
                if (stateDef.listen is Array) {
                    _listenList = stateDef.listen;
                } else {
                    _listenList = [stateDef.listen];
                }
            }

            // sub states
            if (stateDef.children != null) {
                for each (var subStateDef:* in stateDef.children) {
                    addState(subStateDef);
                }
            }
        }

        protected override function onDispose():void {
            _stateMachine = null;
            _listenList   = null;
            _parentState  = null;
            _childStates  = null;
        }

        /**
         * @see addState
         */
        public static function makeState(stateDef:*):KrewState {
            var state:KrewState;
            if (stateDef is KrewState) {
                return stateDef;
            }
            else if (stateDef is Object) {
                return new KrewState(stateDef);
            }

            throw new Error("[KrewState] Invalid state definition: " + stateDef);
        }

        //------------------------------------------------------------
        // public
        //------------------------------------------------------------

        /**
         * Add sub state.
         *
         * @param stateDef KrewState のインスタンスか、State 定義情報を含む Object.
         *                 Object のフォーマットについては KrewState 及び KrewStateMachine の
         *                 コンストラクタのドキュメントを見よ。
         */
        public function addState(stateDef:*):void {
            var state:KrewState = KrewState.makeState(stateDef);
            state.parentState = this;

            if (!_childStates) {
                _childStates = new Vector.<KrewState>;
            }
            _childStates.push(state);

            krew.log(" $ added [" + _stateId + "] -> " + state.stateId);  // debug
        }

        /** Go on the next state. */
        public function proceed():void {
            if (!_nextStateId) {
                throw new Error("[KrewState] Next state not defined in: " + _stateId);
            }

            _stateMachine.changeState(_nextStateId);
        }

        //------------------------------------------------------------
        // called by KrewStateMachine
        //------------------------------------------------------------

        /**
         * Iterate state tree downward. Passes itself and children to iterator function.
         * @param iterator function(state:KrewState):void
         */
        public function eachChild(iterator:Function):void {
            iterator(this);

            if (_childStates == null) { return; }

            for each (var childState:KrewState in _childStates) {
                childState.eachChild(iterator);
            }
        }

        /**
         * Iterate state tree upward. Passes itself and parents to iterator function.
         * @param iterator function(state:KrewState):void
         */
        public function eachParent(iterator:Function):void {
            iterator(this);

            if (!hasParent()) { return; }

            _parentState.eachParent(iterator);
        }

        /**
         * @private
         * State を開始する。親たちを含めて event の listen を始める.
         *
         * [Note] krewFramework のメッセージングの仕組みで listen を行うのは
         *        KrewStateMachine 側。KrewStateMachine はメッセージを受け取ると
         *        それを現在の State に渡す。State は自分で解決できない場合は
         *        親 State にそれを委譲する
         */
        public function enter():void {
            eachParent(function(state:KrewState):void {
                if (state.listenList == null) { return; }

                for each (var listenInfo:Object in state.listenList) {
                    var event:String       = listenInfo.event;
                    var targetState:String = listenInfo.to;
                    _listenToEvent(state, event, targetState);
                }
            });
        }

        private function _listenToEvent(state:KrewState, event:String, targetState:String):void {
            _stateMachine.listenToStateEvent(event);
            state.isListening = true;
        }

        /**
         * @private
         * State を終了する。親たちを含めて event の listen をやめる
         */
        public function exit():void {
            eachParent(function(state:KrewState):void {
                if (state.listenList == null) { return; }

                for each (var listenInfo:Object in state.listenList) {
                    var event:String = listenInfo.event;
                    _stateMachine.stopListeningToStateEvent(event);
                    state.isListening = false;
                }
            });
        }

        public function onEvent(args:Object, event:String):void {
            if (_isListeningTo(event)) {
                if (_guardFunc != null  &&  !_guardFunc(this)) { return; }

                var targetStateId:String = _getTargetStateIdWith(event)
                _stateMachine.changeState(targetStateId);
                return;
            }

            // delegate to parent state
            if (hasParent()) {
                _parentState.onEvent(args, event);
                return;
            }

            krew.log("[KrewState] Warning: Unexpected case in onEvent: " + event);
        }

        //------------------------------------------------------------
        // private
        //------------------------------------------------------------

        private function _isListeningTo(event:String):Boolean {
            // [Note] listenList が大きくならない想定で、配列を走査して検索
            for each (var listenInfo:Object in listenList) {
                if (listenInfo.event == event) { return true; }
            }
            return false;
        }

        private function _getTargetStateIdWith(event:String):String {
            // [Note] listenList が大きくならない想定で、配列を走査して検索
            for each (var listenInfo:Object in listenList) {
                if (listenInfo.event == event) { return listenInfo.to; }
            }
            return null;
        }

        //------------------------------------------------------------
        // debug method
        //------------------------------------------------------------

        public function dump():void {
            krew.log(krew.str.repeat("v", 50));

            krew.log("_stateId: " + _stateId);
            krew.log("_nextStateId: " + _nextStateId);

            if (isListening) {
                krew.log("isListening: true");
                for each (var listenInfo:Object in listenList) {
                    krew.log("  - " + listenInfo.event);
                }
            } else {
                krew.log("isListening: false");
            }

            krew.log(krew.str.repeat("^", 50));
        }

        public function dumpTree(level:int=0):void {
            var indent:String = krew.str.repeat(" ", level * 4);

            var toList:Array  = [];
            if (listenList != null) {
                listenList.map(function(elem:Object, index:int, array:Array):String {
                    return elem.to;
                });
            }

            krew.log(indent + _stateId + " --> " + _nextStateId
                     + "  (" + toList.join(", ") + ")");

            if (!_childStates) { return; }

            for each (var childState:KrewState in _childStates) {
                childState.dumpTree(level + 1);
            }
        }

    }
}

package krewfw.builtin_actor {

    import krewfw.core.KrewActor;

    /**
     * State Object for KrewStateMachine.
     */
    //------------------------------------------------------------
    public class KrewState extends KrewActor {

        /** KrewStateMachine gives its reference to a state on registration. */
        private var _stateMachine:KrewStateMachine;

        private var _stateId:String;
        private var _nextStateId:String;

        /** Handler called when state starts. */
        private var _onEnterHandler:Function;

        /** Handler called during state or its sub-state is selected. */
        private var _onUpdateHandler:Function;

        /** Handler called when state ends. */
        private var _onExitHandler:Function;

        /** Conditions of transitions by event. */
        private var _guardFunc:Function;

        private var _listenList:Array;
        public  var isListening:Boolean = false;

        private var _parentState:KrewState;
        private var _childStates:Vector.<KrewState>;

        //------------------------------------------------------------
        // accessors
        //------------------------------------------------------------

        public function set stateMachine(fsm:KrewStateMachine):void { _stateMachine = fsm; }

        public function get stateId():String { return _stateId; }

        public function get nextStateId():String { return _nextStateId; }
        public function set nextStateId(id:String):void { _nextStateId = id; }

        public function get onEnterHandler() :Function { return _onEnterHandler; }
        public function get onUpdateHandler():Function { return _onUpdateHandler; }
        public function get onExitHandler()  :Function { return _onExitHandler; }
        public function get guardFunc()      :Function { return _guardFunc; }

        public function get listenList():Array { return _listenList; }

        public function get childStates():Vector.<KrewState> { return _childStates; }
        public function hasChildren():Boolean { return (_childStates != null); }

        public function get parentState():KrewState { return _parentState; }
        public function set parentState(state:KrewState):void { _parentState = state; }
        public function hasParent():Boolean { return (_parentState != null); }

        //------------------------------------------------------------

        /**
         * Create state with Object key-values.
         *
         * @param stateDef Object including state options such as:
         *

         *
(Required) id      : {String} - State name.

         *
(Optional) next    : {String} - Next state name. progress() will proceed state to the next.
         *           If omitted, next Array element is used as next state.

         *
(Optional) enter   : {Function(state:KrewState):void} - Called when state starts.

         *
(Optional) update  : {Function(state:KrewState, passedTime:Number):void} -
         *           Called during state or sub-state is selected.

         *
(Optional) exit    : {Function(state:KrewState):void} - Called when state ends.

         *
(Optional) guard   : {Function(state:KrewState):Boolean} - Called when event triggered.
         *           Return false to prevent transition and bubbling event.

         *
(Optional) listen  : {Object or Array} - Ex.) [{event: "event_name", to:"target_state_name"}] -
         *           event で指定したイベントを受け取ったとき、to で指定した state に遷移する。
         *           KrewStateMachine はイベントをまず現在の state に渡す。 state は自分で解決できない
         *           イベントだった場合は親 state に委譲していく

         *
(Optional) children: {Array} - Sub state definition list.

         *

         */
        public function KrewState(stateDef:Object) {
            displayable = false;

            if (!stateDef.id) { throw new Error("[new KrewState] id is required."); }

            _stateId     = stateDef.id;
            _nextStateId = stateDef.next || null;

            _onEnterHandler  = stateDef.enter  || null;
            _onUpdateHandler = stateDef.update || null;
            _onExitHandler   = stateDef.exit   || null;
            _guardFunc       = stateDef.guard  || null;

            // listen to event
            if (stateDef.listen != null) {
                if (stateDef.listen is Array) {
                    _listenList = stateDef.listen;
                } else {
                    _listenList = [stateDef.listen];
                }
            }

            // sub states
            if (stateDef.children != null) {
                for each (var subStateDef:* in stateDef.children) {
                    addState(subStateDef);
                }
            }
        }

        protected override function onDispose():void {
            _stateMachine = null;
            _listenList   = null;
            _parentState  = null;
            _childStates  = null;
        }

        /**
         * @see addState
         */
        public static function makeState(stateDef:*):KrewState {
            var state:KrewState;
            if (stateDef is KrewState) {
                return stateDef;
            }
            else if (stateDef is Object) {
                return new KrewState(stateDef);
            }

            throw new Error("[KrewState] Invalid state definition: " + stateDef);
        }

        //------------------------------------------------------------
        // public
        //------------------------------------------------------------

        /**
         * Add sub state.
         *
         * @param stateDef KrewState のインスタンスか、State 定義情報を含む Object.
         *                 Object のフォーマットについては KrewState 及び KrewStateMachine の
         *                 コンストラクタのドキュメントを見よ。
         */
        public function addState(stateDef:*):void {
            var state:KrewState = KrewState.makeState(stateDef);
            state.parentState = this;

            if (!_childStates) {
                _childStates = new Vector.<KrewState>;
            }
            _childStates.push(state);

            krew.log(" $ added [" + _stateId + "] -> " + state.stateId);  // debug
        }

        /** Go on the next state. */
        public function proceed():void {
            if (!_nextStateId) {
                throw new Error("[KrewState] Next state not defined in: " + _stateId);
            }

            _stateMachine.changeState(_nextStateId);
        }

        //------------------------------------------------------------
        // called by KrewStateMachine
        //------------------------------------------------------------

        /**
         * Iterate state tree downward. Passes itself and children to iterator function.
         * @param iterator function(state:KrewState):void
         */
        public function eachChild(iterator:Function):void {
            iterator(this);

            if (_childStates == null) { return; }

            for each (var childState:KrewState in _childStates) {
                childState.eachChild(iterator);
            }
        }

        /**
         * Iterate state tree upward. Passes itself and parents to iterator function.
         * @param iterator function(state:KrewState):void
         */
        public function eachParent(iterator:Function):void {
            iterator(this);

            if (!hasParent()) { return; }

            _parentState.eachParent(iterator);
        }

        /**
         * @private
         * State を開始する。親たちを含めて event の listen を始める.
         *
         * [Note] krewFramework のメッセージングの仕組みで listen を行うのは
         *        KrewStateMachine 側。KrewStateMachine はメッセージを受け取ると
         *        それを現在の State に渡す。State は自分で解決できない場合は
         *        親 State にそれを委譲する
         */
        public function enter():void {
            eachParent(function(state:KrewState):void {
                if (state.listenList == null) { return; }

                for each (var listenInfo:Object in state.listenList) {
                    var event:String       = listenInfo.event;
                    var targetState:String = listenInfo.to;
                    _listenToEvent(state, event, targetState);
                }
            });
        }

        private function _listenToEvent(state:KrewState, event:String, targetState:String):void {
            _stateMachine.listenToStateEvent(event);
            state.isListening = true;
        }

        /**
         * @private
         * State を終了する。親たちを含めて event の listen をやめる
         */
        public function exit():void {
            eachParent(function(state:KrewState):void {
                if (state.listenList == null) { return; }

                for each (var listenInfo:Object in state.listenList) {
                    var event:String = listenInfo.event;
                    _stateMachine.stopListeningToStateEvent(event);
                    state.isListening = false;
                }
            });
        }

        public function onEvent(args:Object, event:String):void {
            if (_isListeningTo(event)) {
                if (_guardFunc != null  &&  !_guardFunc(this)) { return; }

                var targetStateId:String = _getTargetStateIdWith(event)
                _stateMachine.changeState(targetStateId);
                return;
            }

            // delegate to parent state
            if (hasParent()) {
                _parentState.onEvent(args, event);
                return;
            }

            krew.log("[KrewState] Warning: Unexpected case in onEvent: " + event);
        }

        //------------------------------------------------------------
        // private
        //------------------------------------------------------------

        private function _isListeningTo(event:String):Boolean {
            // [Note] listenList が大きくならない想定で、配列を走査して検索
            for each (var listenInfo:Object in listenList) {
                if (listenInfo.event == event) { return true; }
            }
            return false;
        }

        private function _getTargetStateIdWith(event:String):String {
            // [Note] listenList が大きくならない想定で、配列を走査して検索
            for each (var listenInfo:Object in listenList) {
                if (listenInfo.event == event) { return listenInfo.to; }
            }
            return null;
        }

        //------------------------------------------------------------
        // debug method
        //------------------------------------------------------------

        public function dump():void {
            krew.log(krew.str.repeat("v", 50));

            krew.log("_stateId: " + _stateId);
            krew.log("_nextStateId: " + _nextStateId);

            if (isListening) {
                krew.log("isListening: true");
                for each (var listenInfo:Object in listenList) {
                    krew.log("  - " + listenInfo.event);
                }
            } else {
                krew.log("isListening: false");
            }

            krew.log(krew.str.repeat("^", 50));
        }

        public function dumpTree(level:int=0):void {
            var indent:String = krew.str.repeat(" ", level * 4);

            var toList:Array = [];
            if (listenList != null) {
                toList = listenList.map(function(elem:Object, index:int, array:Array):String {
                    return elem.to;
                });
            }

            krew.log(indent + _stateId + " --> " + _nextStateId
                     + "  (" + toList.join(", ") + ")");

            if (!_childStates) { return; }

            for each (var childState:KrewState in _childStates) {
                childState.dumpTree(level + 1);
            }
        }

    }
}

Fix little bug

Fix little bug


package org.mangui.chromeless {
    import org.mangui.hls.utils.ScaleVideo;
    import org.mangui.hls.model.AudioTrack;
    import org.mangui.hls.HLSSettings;
    import org.mangui.hls.event.HLSError;
    import org.mangui.hls.event.HLSEvent;
    import org.mangui.hls.HLS;

    import flash.net.URLStream;

    import org.mangui.hls.model.Level;

    import flash.display.*;
    import flash.events.*;
    import flash.external.ExternalInterface;
    import flash.geom.Rectangle;
    import flash.media.Video;
    import flash.media.SoundTransform;
    import flash.media.StageVideo;
    import flash.media.StageVideoAvailability;
    import flash.utils.setTimeout;

    // import com.sociodox.theminer.*;
    public class ChromelessPlayer extends Sprite {
        /** reference to the framework. **/
        protected var _hls : HLS;
        /** Sheet to place on top of the video. **/
        protected var _sheet : Sprite;
        /** Reference to the stage video element. **/
        protected var _stageVideo : StageVideo = null;
        /** Reference to the video element. **/
        protected var _video : Video = null;
        /** Video size **/
        protected var _videoWidth : int = 0;
        protected var _videoHeight : int = 0;
        /** current media position */
        protected var _media_position : Number;
        protected var _duration : Number;
        /** URL autoload feature */
        protected var _autoLoad : Boolean = false;

        /** Initialization. **/
        public function ChromelessPlayer() {
            _setupStage();
            _setupSheet();
            _setupExternalGetters();
            _setupExternalCallers();

            setTimeout(_pingJavascript, 50);
        };

        protected function _setupExternalGetters() : void {
            ExternalInterface.addCallback("getLevel", _getLevel);
            ExternalInterface.addCallback("getPlaybackLevel", _getPlaybackLevel);
            ExternalInterface.addCallback("getLevels", _getLevels);
            ExternalInterface.addCallback("getAutoLevel", _getAutoLevel);
            ExternalInterface.addCallback("getDuration", _getDuration);
            ExternalInterface.addCallback("getPosition", _getPosition);
            ExternalInterface.addCallback("getPlaybackState", _getPlaybackState);
            ExternalInterface.addCallback("getSeekState", _getSeekState);
            ExternalInterface.addCallback("getType", _getType);
            ExternalInterface.addCallback("getmaxBufferLength", _getmaxBufferLength);
            ExternalInterface.addCallback("getminBufferLength", _getminBufferLength);
            ExternalInterface.addCallback("getlowBufferLength", _getlowBufferLength);
            ExternalInterface.addCallback("getbufferLength", _getbufferLength);
            ExternalInterface.addCallback("getLogDebug", _getLogDebug);
            ExternalInterface.addCallback("getLogDebug2", _getLogDebug2);
            ExternalInterface.addCallback("getCapLeveltoStage", _getCapLeveltoStage);
            ExternalInterface.addCallback("getflushLiveURLCache", _getflushLiveURLCache);
            ExternalInterface.addCallback("getstartFromLevel", _getstartFromLevel);
            ExternalInterface.addCallback("getseekFromLowestLevel", _getseekFromLevel);
            ExternalInterface.addCallback("getJSURLStream", _getJSURLStream);
            ExternalInterface.addCallback("getPlayerVersion", _getPlayerVersion);
            ExternalInterface.addCallback("getAudioTrackList", _getAudioTrackList);
            ExternalInterface.addCallback("getAudioTrackId", _getAudioTrackId);
        };

        protected function _setupExternalCallers() : void {
            ExternalInterface.addCallback("playerLoad", _load);
            ExternalInterface.addCallback("playerPlay", _play);
            ExternalInterface.addCallback("playerPause", _pause);
            ExternalInterface.addCallback("playerResume", _resume);
            ExternalInterface.addCallback("playerSeek", _seek);
            ExternalInterface.addCallback("playerStop", _stop);
            ExternalInterface.addCallback("playerVolume", _volume);
            ExternalInterface.addCallback("playerSetLevel", _setLevel);
            ExternalInterface.addCallback("playerSmoothSetLevel", _smoothSetLevel);
            ExternalInterface.addCallback("playerSetmaxBufferLength", _setmaxBufferLength);
            ExternalInterface.addCallback("playerSetminBufferLength", _setminBufferLength);
            ExternalInterface.addCallback("playerSetlowBufferLength", _setlowBufferLength);
            ExternalInterface.addCallback("playerSetflushLiveURLCache", _setflushLiveURLCache);
            ExternalInterface.addCallback("playerSetstartFromLevel", _setstartFromLevel);
            ExternalInterface.addCallback("playerSetseekFromLevel", _setseekFromLevel);
            ExternalInterface.addCallback("playerSetLogDebug", _setLogDebug);
            ExternalInterface.addCallback("playerSetLogDebug2", _setLogDebug2);
            ExternalInterface.addCallback("playerCapLeveltoStage", _setCapLeveltoStage);
            ExternalInterface.addCallback("playerSetAudioTrack", _setAudioTrack);
            ExternalInterface.addCallback("playerSetJSURLStream", _setJSURLStream);
        };

        protected function _setupStage() : void {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
            stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, _onStageVideoState);
            stage.addEventListener(Event.RESIZE, _onStageResize);
        }

        protected function _setupSheet() : void {
            // Draw sheet for catching clicks
            _sheet = new Sprite();
            _sheet.graphics.beginFill(0x000000, 0);
            _sheet.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
            _sheet.addEventListener(MouseEvent.CLICK, _clickHandler);
            _sheet.buttonMode = true;
            addChild(_sheet);
        }

        /** Notify javascript the framework is ready. **/
        protected function _pingJavascript() : void {
            ExternalInterface.call("onHLSReady", ExternalInterface.objectID);
        };

        /** Forward events from the framework. **/
        protected function _completeHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onComplete");
            }
        };

        protected function _errorHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                var hlsError : HLSError = event.error;
                ExternalInterface.call("onError", hlsError.code, hlsError.url, hlsError.msg);
            }
        };

        protected function _fragmentLoadedHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onFragmentLoaded", event.loadMetrics.bandwidth, event.loadMetrics.level, stage.stageWidth);
            }
        };

        protected function _fragmentPlayingHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onFragmentPlaying", event.playMetrics);
            }
        };

        protected function _manifestHandler(event : HLSEvent) : void {
            _duration = event.levels[_hls.startlevel].duration;

            if (_autoLoad) {
                _play(-1);
            }

            if (ExternalInterface.available) {
                ExternalInterface.call("onManifest", _duration);
            }
        };

        protected function _mediaTimeHandler(event : HLSEvent) : void {
            _duration = event.mediatime.duration;
            _media_position = event.mediatime.position;
            if (ExternalInterface.available) {
                ExternalInterface.call("onPosition", event.mediatime.position, event.mediatime.duration, event.mediatime.live_sliding, event.mediatime.buffer, event.mediatime.program_date);
            }

            var videoWidth : int = _video ? _video.videoWidth : _stageVideo.videoWidth;
            var videoHeight : int = _video ? _video.videoHeight : _stageVideo.videoHeight;

            if (videoWidth && videoHeight) {
                var changed : Boolean = _videoWidth != videoWidth || _videoHeight != videoHeight;
                if (changed) {
                    _videoHeight = videoHeight;
                    _videoWidth = videoWidth;
                    _resize();
                    if (ExternalInterface.available) {
                        ExternalInterface.call("onVideoSize", _videoWidth, _videoHeight);
                    }
                }
            }
        };

        protected function _stateHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onState", event.state);
            }
        };

        protected function _levelSwitchHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onSwitch", event.level);
            }
        };

        protected function _audioTracksListChange(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onAudioTracksListChange", _getAudioTrackList());
            }
        }

        protected function _audioTrackChange(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onAudioTrackChange", event.audioTrack);
            }
        }

        /** Javascript getters. **/
        protected function _getLevel() : int {
            return _hls.level;
        };

        protected function _getPlaybackLevel() : int {
            return _hls.playbacklevel;
        };

        protected function _getLevels() : Vector.<Level> {
            return _hls.levels;
        };

        protected function _getAutoLevel() : Boolean {
            return _hls.autolevel;
        };

        protected function _getDuration() : Number {
            return _duration;
        };

        protected function _getPosition() : Number {
            return _hls.position;
        };

        protected function _getPlaybackState() : String {
            return _hls.playbackState;
        };

        protected function _getSeekState() : String {
            return _hls.seekState;
        };

        protected function _getType() : String {
            return _hls.type;
        };

        protected function _getbufferLength() : Number {
            return _hls.bufferLength;
        };

        protected function _getmaxBufferLength() : Number {
            return HLSSettings.maxBufferLength;
        };

        protected function _getminBufferLength() : Number {
            return HLSSettings.minBufferLength;
        };

        protected function _getlowBufferLength() : Number {
            return HLSSettings.lowBufferLength;
        };

        protected function _getflushLiveURLCache() : Boolean {
            return HLSSettings.flushLiveURLCache;
        };

        protected function _getstartFromLevel() : int {
            return HLSSettings.startFromLevel;
        };

        protected function _getseekFromLevel() : int {
            return HLSSettings.seekFromLevel;
        };

        protected function _getLogDebug() : Boolean {
            return HLSSettings.logDebug;
        };

        protected function _getLogDebug2() : Boolean {
            return HLSSettings.logDebug2;
        };

        protected function _getCapLeveltoStage() : Boolean {
            return HLSSettings.capLevelToStage;
        };

        protected function _getJSURLStream() : Boolean {
            return (_hls.URLstream is JSURLStream);
        };

        protected function _getPlayerVersion() : Number {
            return 2;
        };

        protected function _getAudioTrackList() : Array {
            var list : Array = [];
            var vec : Vector.<AudioTrack> = _hls.audioTracks;
            for (var i : Object in vec) {
                list.push(vec[i]);
            }
            return list;
        };

        protected function _getAudioTrackId() : int {
            return _hls.audioTrack;
        };

        /** Javascript calls. **/
        protected function _load(url : String) : void {
            _hls.load(url);
        };

        protected function _play(position : Number) : void {
            _hls.stream.play(null, position);
        };

        protected function _pause() : void {
            _hls.stream.pause();
        };

        protected function _resume() : void {
            _hls.stream.resume();
        };

        protected function _seek(position : Number) : void {
            _hls.stream.seek(position);
        };

        protected function _stop() : void {
            _hls.stream.close();
        };

        protected function _volume(percent : Number) : void {
            _hls.stream.soundTransform = new SoundTransform(percent / 100);
        };

        protected function _setLevel(level : int) : void {
            _smoothSetLevel(level);
            if (!isNaN(_media_position) && level != -1) {
                _hls.stream.seek(_media_position);
            }
        };

        protected function _smoothSetLevel(level : int) : void {
            if (level != _hls.level) {
                _hls.level = level;
            }
        };

        protected function _setmaxBufferLength(new_len : Number) : void {
            HLSSettings.maxBufferLength = new_len;
        };

        protected function _setminBufferLength(new_len : Number) : void {
            HLSSettings.minBufferLength = new_len;
        };

        protected function _setlowBufferLength(new_len : Number) : void {
            HLSSettings.lowBufferLength = new_len;
        };

        protected function _setflushLiveURLCache(flushLiveURLCache : Boolean) : void {
            HLSSettings.flushLiveURLCache = flushLiveURLCache;
        };

        protected function _setstartFromLevel(startFromLevel : int) : void {
            HLSSettings.startFromLevel = startFromLevel;
        };

        protected function _setseekFromLevel(seekFromLevel : int) : void {
            HLSSettings.seekFromLevel = seekFromLevel;
        };

        protected function _setLogDebug(debug : Boolean) : void {
            HLSSettings.logDebug = debug;
        };

        protected function _setLogDebug2(debug2 : Boolean) : void {
            HLSSettings.logDebug2 = debug2;
        };

        protected function _setCapLeveltoStage(value : Boolean) : void {
            HLSSettings.capLevelToStage = value;
        };

        protected function _setJSURLStream(jsURLstream : Boolean) : void {
            if (jsURLstream) {
                _hls.URLstream = JSURLStream as Class;
            } else {
                _hls.URLstream = URLStream as Class;
            }
        };

        protected function _setAudioTrack(val : int) : void {
            if (val == _hls.audioTrack) return;
            _hls.audioTrack = val;
            if (!isNaN(_media_position)) {
                _hls.stream.seek(_media_position);
            }
        };

        /** Mouse click handler. **/
        protected function _clickHandler(event : MouseEvent) : void {
            if (stage.displayState == StageDisplayState.FULL_SCREEN_INTERACTIVE || stage.displayState == StageDisplayState.FULL_SCREEN) {
                stage.displayState = StageDisplayState.NORMAL;
            } else {
                stage.displayState = StageDisplayState.FULL_SCREEN;
            }
        };

        /** StageVideo detector. **/
        protected function _onStageVideoState(event : StageVideoAvailabilityEvent) : void {
            var available : Boolean = (event.availability == StageVideoAvailability.AVAILABLE);
            _hls = new HLS();
            _hls.stage = stage;
            _hls.addEventListener(HLSEvent.PLAYBACK_COMPLETE, _completeHandler);
            _hls.addEventListener(HLSEvent.ERROR, _errorHandler);
            _hls.addEventListener(HLSEvent.FRAGMENT_LOADED, _fragmentLoadedHandler);
            _hls.addEventListener(HLSEvent.FRAGMENT_PLAYING, _fragmentPlayingHandler);
            _hls.addEventListener(HLSEvent.MANIFEST_LOADED, _manifestHandler);
            _hls.addEventListener(HLSEvent.MEDIA_TIME, _mediaTimeHandler);
            _hls.addEventListener(HLSEvent.PLAYBACK_STATE, _stateHandler);
            _hls.addEventListener(HLSEvent.LEVEL_SWITCH, _levelSwitchHandler);
            _hls.addEventListener(HLSEvent.AUDIO_TRACKS_LIST_CHANGE, _audioTracksListChange);
            _hls.addEventListener(HLSEvent.AUDIO_TRACK_CHANGE, _audioTrackChange);

            if (available && stage.stageVideos.length > 0) {
                _stageVideo = stage.stageVideos[0];
                _stageVideo.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
                _stageVideo.attachNetStream(_hls.stream);
            } else {
                _video = new Video(stage.stageWidth, stage.stageHeight);
                addChild(_video);
                _video.smoothing = true;
                _video.attachNetStream(_hls.stream);
            }
            stage.removeEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, _onStageVideoState);

            var autoLoadUrl : String = root.loaderInfo.parameters.url as String;
            if (autoLoadUrl != null) {
                _autoLoad = true;
                _load(autoLoadUrl);
            }
        };

        protected function _onStageResize(event : Event) : void {
            stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
            _sheet.width = stage.stageWidth;
            _sheet.height = stage.stageHeight;
            _resize();
        };

        protected function _resize() : void {
            var rect : Rectangle;
            rect = ScaleVideo.resizeRectangle(_videoWidth, _videoHeight, stage.stageWidth, stage.stageHeight);
            // resize video
            if (_video) {
                _video.width = rect.width;
                _video.height = rect.height;
                _video.x = rect.x;
                _video.y = rect.y;
            } else if (_stageVideo && rect.width > 0) {
                _stageVideo.viewPort = rect;
            }
        }
    }
}

package org.mangui.chromeless {
    import org.mangui.hls.utils.ScaleVideo;
    import org.mangui.hls.model.AudioTrack;
    import org.mangui.hls.HLSSettings;
    import org.mangui.hls.event.HLSError;
    import org.mangui.hls.event.HLSEvent;
    import org.mangui.hls.HLS;

    import flash.net.URLStream;

    import org.mangui.hls.model.Level;

    import flash.display.*;
    import flash.events.*;
    import flash.external.ExternalInterface;
    import flash.geom.Rectangle;
    import flash.media.Video;
    import flash.media.SoundTransform;
    import flash.media.StageVideo;
    import flash.media.StageVideoAvailability;
    import flash.utils.setTimeout;

    // import com.sociodox.theminer.*;
    public class ChromelessPlayer extends Sprite {
        /** reference to the framework. **/
        protected var _hls : HLS;
        /** Sheet to place on top of the video. **/
        protected var _sheet : Sprite;
        /** Reference to the stage video element. **/
        protected var _stageVideo : StageVideo = null;
        /** Reference to the video element. **/
        protected var _video : Video = null;
        /** Video size **/
        protected var _videoWidth : int = 0;
        protected var _videoHeight : int = 0;
        /** current media position */
        protected var _media_position : Number;
        protected var _duration : Number;
        /** URL autoload feature */
        protected var _autoLoad : Boolean = false;

        /** Initialization. **/
        public function ChromelessPlayer() {
            _setupStage();
            _setupSheet();
            _setupExternalGetters();
            _setupExternalCallers();

            setTimeout(_pingJavascript, 50);
        };

        protected function _setupExternalGetters() : void {
            ExternalInterface.addCallback("getLevel", _getLevel);
            ExternalInterface.addCallback("getPlaybackLevel", _getPlaybackLevel);
            ExternalInterface.addCallback("getLevels", _getLevels);
            ExternalInterface.addCallback("getAutoLevel", _getAutoLevel);
            ExternalInterface.addCallback("getDuration", _getDuration);
            ExternalInterface.addCallback("getPosition", _getPosition);
            ExternalInterface.addCallback("getPlaybackState", _getPlaybackState);
            ExternalInterface.addCallback("getSeekState", _getSeekState);
            ExternalInterface.addCallback("getType", _getType);
            ExternalInterface.addCallback("getmaxBufferLength", _getmaxBufferLength);
            ExternalInterface.addCallback("getminBufferLength", _getminBufferLength);
            ExternalInterface.addCallback("getlowBufferLength", _getlowBufferLength);
            ExternalInterface.addCallback("getbufferLength", _getbufferLength);
            ExternalInterface.addCallback("getLogDebug", _getLogDebug);
            ExternalInterface.addCallback("getLogDebug2", _getLogDebug2);
            ExternalInterface.addCallback("getCapLeveltoStage", _getCapLeveltoStage);
            ExternalInterface.addCallback("getflushLiveURLCache", _getflushLiveURLCache);
            ExternalInterface.addCallback("getstartFromLevel", _getstartFromLevel);
            ExternalInterface.addCallback("getseekFromLowestLevel", _getseekFromLevel);
            ExternalInterface.addCallback("getJSURLStream", _getJSURLStream);
            ExternalInterface.addCallback("getPlayerVersion", _getPlayerVersion);
            ExternalInterface.addCallback("getAudioTrackList", _getAudioTrackList);
            ExternalInterface.addCallback("getAudioTrackId", _getAudioTrackId);
        };

        protected function _setupExternalCallers() : void {
            ExternalInterface.addCallback("playerLoad", _load);
            ExternalInterface.addCallback("playerPlay", _play);
            ExternalInterface.addCallback("playerPause", _pause);
            ExternalInterface.addCallback("playerResume", _resume);
            ExternalInterface.addCallback("playerSeek", _seek);
            ExternalInterface.addCallback("playerStop", _stop);
            ExternalInterface.addCallback("playerVolume", _volume);
            ExternalInterface.addCallback("playerSetLevel", _setLevel);
            ExternalInterface.addCallback("playerSmoothSetLevel", _smoothSetLevel);
            ExternalInterface.addCallback("playerSetmaxBufferLength", _setmaxBufferLength);
            ExternalInterface.addCallback("playerSetminBufferLength", _setminBufferLength);
            ExternalInterface.addCallback("playerSetlowBufferLength", _setlowBufferLength);
            ExternalInterface.addCallback("playerSetflushLiveURLCache", _setflushLiveURLCache);
            ExternalInterface.addCallback("playerSetstartFromLevel", _setstartFromLevel);
            ExternalInterface.addCallback("playerSetseekFromLevel", _setseekFromLevel);
            ExternalInterface.addCallback("playerSetLogDebug", _setLogDebug);
            ExternalInterface.addCallback("playerSetLogDebug2", _setLogDebug2);
            ExternalInterface.addCallback("playerCapLeveltoStage", _setCapLeveltoStage);
            ExternalInterface.addCallback("playerSetAudioTrack", _setAudioTrack);
            ExternalInterface.addCallback("playerSetJSURLStream", _setJSURLStream);
        };

        protected function _setupStage() : void {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
            stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, _onStageVideoState);
            stage.addEventListener(Event.RESIZE, _onStageResize);
        }

        protected function _setupSheet() : void {
            // Draw sheet for catching clicks
            _sheet = new Sprite();
            _sheet.graphics.beginFill(0x000000, 0);
            _sheet.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
            _sheet.addEventListener(MouseEvent.CLICK, _clickHandler);
            _sheet.buttonMode = true;
            addChild(_sheet);
        }

        /** Notify javascript the framework is ready. **/
        protected function _pingJavascript() : void {
            ExternalInterface.call("onHLSReady", ExternalInterface.objectID);
        };

        /** Forward events from the framework. **/
        protected function _completeHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onComplete");
            }
        };

        protected function _errorHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                var hlsError : HLSError = event.error;
                ExternalInterface.call("onError", hlsError.code, hlsError.url, hlsError.msg);
            }
        };

        protected function _fragmentLoadedHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onFragmentLoaded", event.loadMetrics.bandwidth, event.loadMetrics.level, stage.stageWidth);
            }
        };

        protected function _fragmentPlayingHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onFragmentPlaying", event.playMetrics);
            }
        };

        protected function _manifestHandler(event : HLSEvent) : void {
            _duration = event.levels[_hls.startlevel].duration;

            if (_autoLoad) {
                _play(-1);
            }

            if (ExternalInterface.available) {
                ExternalInterface.call("onManifest", _duration);
            }
        };

        protected function _mediaTimeHandler(event : HLSEvent) : void {
            _duration = event.mediatime.duration;
            _media_position = event.mediatime.position;
            if (ExternalInterface.available) {
                ExternalInterface.call("onPosition", event.mediatime.position, event.mediatime.duration, event.mediatime.live_sliding, event.mediatime.buffer, event.mediatime.program_date);
            }

            var videoWidth : int = _video ? _video.videoWidth : _stageVideo.videoWidth;
            var videoHeight : int = _video ? _video.videoHeight : _stageVideo.videoHeight;

            if (videoWidth && videoHeight) {
                var changed : Boolean = _videoWidth != videoWidth || _videoHeight != videoHeight;
                if (changed) {
                    _videoHeight = videoHeight;
                    _videoWidth = videoWidth;
                    _resize();
                    if (ExternalInterface.available) {
                        ExternalInterface.call("onVideoSize", _videoWidth, _videoHeight);
                    }
                }
            }
        };

        protected function _stateHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onState", event.state);
            }
        };

        protected function _levelSwitchHandler(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onSwitch", event.level);
            }
        };

        protected function _audioTracksListChange(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onAudioTracksListChange", _getAudioTrackList());
            }
        }

        protected function _audioTrackChange(event : HLSEvent) : void {
            if (ExternalInterface.available) {
                ExternalInterface.call("onAudioTrackChange", event.audioTrack);
            }
        }

        /** Javascript getters. **/
        protected function _getLevel() : int {
            return _hls.level;
        };

        protected function _getPlaybackLevel() : int {
            return _hls.playbacklevel;
        };

        protected function _getLevels() : Vector.<Level> {
            return _hls.levels;
        };

        protected function _getAutoLevel() : Boolean {
            return _hls.autolevel;
        };

        protected function _getDuration() : Number {
            return _duration;
        };

        protected function _getPosition() : Number {
            return _hls.position;
        };

        protected function _getPlaybackState() : String {
            return _hls.playbackState;
        };

        protected function _getSeekState() : String {
            return _hls.seekState;
        };

        protected function _getType() : String {
            return _hls.type;
        };

        protected function _getbufferLength() : Number {
            return _hls.bufferLength;
        };

        protected function _getmaxBufferLength() : Number {
            return HLSSettings.maxBufferLength;
        };

        protected function _getminBufferLength() : Number {
            return HLSSettings.minBufferLength;
        };

        protected function _getlowBufferLength() : Number {
            return HLSSettings.lowBufferLength;
        };

        protected function _getflushLiveURLCache() : Boolean {
            return HLSSettings.flushLiveURLCache;
        };

        protected function _getstartFromLevel() : int {
            return HLSSettings.startFromLevel;
        };

        protected function _getseekFromLevel() : int {
            return HLSSettings.seekFromLevel;
        };

        protected function _getLogDebug() : Boolean {
            return HLSSettings.logDebug;
        };

        protected function _getLogDebug2() : Boolean {
            return HLSSettings.logDebug2;
        };

        protected function _getCapLeveltoStage() : Boolean {
            return HLSSettings.capLevelToStage;
        };

        protected function _getJSURLStream() : Boolean {
            return (_hls.URLstream is JSURLStream);
        };

        protected function _getPlayerVersion() : Number {
            return 2;
        };

        protected function _getAudioTrackList() : Array {
            var list : Array = [];
            var vec : Vector.<AudioTrack> = _hls.audioTracks;
            for (var i : Object in vec) {
                list.push(vec[i]);
            }
            return list;
        };

        protected function _getAudioTrackId() : int {
            return _hls.audioTrack;
        };

        /** Javascript calls. **/
        protected function _load(url : String) : void {
            _hls.load(url);
        };

        protected function _play(position : Number=-1) : void {
            _hls.stream.play(null, position);
        };

        protected function _pause() : void {
            _hls.stream.pause();
        };

        protected function _resume() : void {
            _hls.stream.resume();
        };

        protected function _seek(position : Number) : void {
            _hls.stream.seek(position);
        };

        protected function _stop() : void {
            _hls.stream.close();
        };

        protected function _volume(percent : Number) : void {
            _hls.stream.soundTransform = new SoundTransform(percent / 100);
        };

        protected function _setLevel(level : int) : void {
            _smoothSetLevel(level);
            if (!isNaN(_media_position) && level != -1) {
                _hls.stream.seek(_media_position);
            }
        };

        protected function _smoothSetLevel(level : int) : void {
            if (level != _hls.level) {
                _hls.level = level;
            }
        };

        protected function _setmaxBufferLength(new_len : Number) : void {
            HLSSettings.maxBufferLength = new_len;
        };

        protected function _setminBufferLength(new_len : Number) : void {
            HLSSettings.minBufferLength = new_len;
        };

        protected function _setlowBufferLength(new_len : Number) : void {
            HLSSettings.lowBufferLength = new_len;
        };

        protected function _setflushLiveURLCache(flushLiveURLCache : Boolean) : void {
            HLSSettings.flushLiveURLCache = flushLiveURLCache;
        };

        protected function _setstartFromLevel(startFromLevel : int) : void {
            HLSSettings.startFromLevel = startFromLevel;
        };

        protected function _setseekFromLevel(seekFromLevel : int) : void {
            HLSSettings.seekFromLevel = seekFromLevel;
        };

        protected function _setLogDebug(debug : Boolean) : void {
            HLSSettings.logDebug = debug;
        };

        protected function _setLogDebug2(debug2 : Boolean) : void {
            HLSSettings.logDebug2 = debug2;
        };

        protected function _setCapLeveltoStage(value : Boolean) : void {
            HLSSettings.capLevelToStage = value;
        };

        protected function _setJSURLStream(jsURLstream : Boolean) : void {
            if (jsURLstream) {
                _hls.URLstream = JSURLStream as Class;
            } else {
                _hls.URLstream = URLStream as Class;
            }
        };

        protected function _setAudioTrack(val : int) : void {
            if (val == _hls.audioTrack) return;
            _hls.audioTrack = val;
            if (!isNaN(_media_position)) {
                _hls.stream.seek(_media_position);
            }
        };

        /** Mouse click handler. **/
        protected function _clickHandler(event : MouseEvent) : void {
            if (stage.displayState == StageDisplayState.FULL_SCREEN_INTERACTIVE || stage.displayState == StageDisplayState.FULL_SCREEN) {
                stage.displayState = StageDisplayState.NORMAL;
            } else {
                stage.displayState = StageDisplayState.FULL_SCREEN;
            }
        };

        /** StageVideo detector. **/
        protected function _onStageVideoState(event : StageVideoAvailabilityEvent) : void {
            var available : Boolean = (event.availability == StageVideoAvailability.AVAILABLE);
            _hls = new HLS();
            _hls.stage = stage;
            _hls.addEventListener(HLSEvent.PLAYBACK_COMPLETE, _completeHandler);
            _hls.addEventListener(HLSEvent.ERROR, _errorHandler);
            _hls.addEventListener(HLSEvent.FRAGMENT_LOADED, _fragmentLoadedHandler);
            _hls.addEventListener(HLSEvent.FRAGMENT_PLAYING, _fragmentPlayingHandler);
            _hls.addEventListener(HLSEvent.MANIFEST_LOADED, _manifestHandler);
            _hls.addEventListener(HLSEvent.MEDIA_TIME, _mediaTimeHandler);
            _hls.addEventListener(HLSEvent.PLAYBACK_STATE, _stateHandler);
            _hls.addEventListener(HLSEvent.LEVEL_SWITCH, _levelSwitchHandler);
            _hls.addEventListener(HLSEvent.AUDIO_TRACKS_LIST_CHANGE, _audioTracksListChange);
            _hls.addEventListener(HLSEvent.AUDIO_TRACK_CHANGE, _audioTrackChange);

            if (available && stage.stageVideos.length > 0) {
                _stageVideo = stage.stageVideos[0];
                _stageVideo.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
                _stageVideo.attachNetStream(_hls.stream);
            } else {
                _video = new Video(stage.stageWidth, stage.stageHeight);
                addChild(_video);
                _video.smoothing = true;
                _video.attachNetStream(_hls.stream);
            }
            stage.removeEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, _onStageVideoState);

            var autoLoadUrl : String = root.loaderInfo.parameters.url as String;
            if (autoLoadUrl != null) {
                _autoLoad = true;
                _load(autoLoadUrl);
            }
        };

        protected function _onStageResize(event : Event) : void {
            stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
            _sheet.width = stage.stageWidth;
            _sheet.height = stage.stageHeight;
            _resize();
        };

        protected function _resize() : void {
            var rect : Rectangle;
            rect = ScaleVideo.resizeRectangle(_videoWidth, _videoHeight, stage.stageWidth, stage.stageHeight);
            // resize video
            if (_video) {
                _video.width = rect.width;
                _video.height = rect.height;
                _video.x = rect.x;
                _video.y = rect.y;
            } else if (_stageVideo && rect.width > 0) {
                _stageVideo.viewPort = rect;
            }
        }
    }
}

ChromelessPlayer.as: add default play() position : set it to -1


package Controller.logic
{
	import Controller.ArgumentController;

	import Model.AGORAModel;
	import Model.ArgumentTypeModel;
	import Model.StatementModel;

	import ValueObjects.AGORAParameters;

	import components.ArgSelector;
	import components.ArgumentPanel;
	import components.MenuPanel;

	import classes.Language;

	import mx.controls.Alert;
	import mx.core.FlexGlobals;

	public class ModusTollens extends ParentArg
	{
		public var andOr:String;
		private var _isExp:Boolean;
		private static var instance:ModusTollens;

		public function ModusTollens()
		{
			langTypes = ["If-then","Implies","Whenever","Only if","Provided that","Sufficient condition","Necessary condition"];
			//dbLangTypeNames = ["ifthen","implies","whenever","onlyif","providedthat","sufficient","necessary"];
			expLangTypes = ["Only if"];	// Expandable with both And and Or
			label = AGORAParameters.getInstance().MOD_TOL;

		}

		public static function getInstance():ModusTollens{
			if(instance == null){
				instance = new ModusTollens;
			}
			return instance;
		}

		override public function getLabel():String{
			return label;
		}

		override public function formText(argumentTypeModel:ArgumentTypeModel):void{
			var output:String = "";
			var reasonText:String = "";
			var reasonModels:Vector.<StatementModel> = argumentTypeModel.reasonModels;
			var claimModel:StatementModel = argumentTypeModel.claimModel;
			var argSelector:ArgSelector = MenuPanel(FlexGlobals.topLevelApplication.map.agoraMap.menuPanelsHash[argumentTypeModel.ID]).schemeSelector;
			var i:int;

			switch(argumentTypeModel.language){
				case langTypes[0]:
					reasonText = reasonModels[0].statement.positiveText;
					output = Language.lookup("ArgIf") + claimModel.statement.positiveText +
						Language.lookup("ArgThen") + reasonText;
					break;
				case langTypes[1]:
					output = claimModel.statement.positiveText + Language.lookup("ArgImplies") + reasonModels[0].statement.positiveText;
					break;
				case langTypes[2]:
					reasonText = reasonModels[0].statement.positiveText;
					output = Language.lookup("ArgWhenever") + claimModel.statement.positiveText + ", " + reasonText;
					break;
				case langTypes[3]:
					//if many reasons
<<<<<<< HEAD
					if(argumentTypeModel.reasonModels.length > 1){
						output = "Select how you want to connect the reasons"; //TODO: Translate
=======
					var params:AGORAParameters = AGORAParameters.getInstance();
					if(argumentTypeModel.reasonModels.length > 1 && argumentTypeModel.lSubOption == null){
						output = "Select how you want to connect the reasons";
>>>>>>> ab3ad67409fc862e89b120320e0ec04ce3153aee
						argSelector.andor.x = argSelector.typeSelector.x + argSelector.typeSelector.width;
						argSelector.andor.dataProvider = [params.AND, params.OR];
						argSelector.andor.visible = argSelector.typeSelector.visible;
						//if one reason
					}else if(argumentTypeModel.reasonModels.length == 1){
						reasonText = reasonModels[0].statement.positiveText;
						output = claimModel.statement.positiveText + Language.lookup("ArgOnlyIf");
						output = output + reasonText;
					}else{
						output = claimModel.statement.positiveText + Language.lookup("ArgOnlyIf");
						for(i=0; i<reasonModels.length - 1; i++){
							reasonText = reasonText + reasonModels[i].statement.positiveText + " " + argumentTypeModel.lSubOption + " ";
						}
						reasonText = reasonText + reasonModels[reasonModels.length - 1].statement.positiveText;
						output = output + reasonText;
						argSelector.andor.x = argSelector.typeSelector.x + argSelector.typeSelector.width;
						argSelector.andor.dataProvider = [params.AND, params.OR];
						argSelector.andor.visible = argSelector.typeSelector.visible;
					}
					break;
				case langTypes[4]:
					//provided that
					reasonText = reasonModels[0].statement.positiveText ;
					output = reasonText + Language.lookup("ArgProvidedThat") + claimModel.statement.positiveText;
					break;
				case langTypes[5]:
					//sufficient condition
					reasonText = reasonModels[0].statement.positiveText;
					output = claimModel.statement.positiveText + Language.lookup("ArgSufficientCond") + reasonText;
					break;
				case langTypes[6]:
					//necessary condition
					reasonText = reasonModels[0].statement.positiveText
					output = reasonText + Language.lookup("ArgNecessaryCond") + claimModel.statement.positiveText;
					break;
			}

			argumentTypeModel.inferenceModel.statements[0].text = claimModel.statement.text;
			argumentTypeModel.inferenceModel.statements[1].text = reasonText;
			argumentTypeModel.inferenceModel.statement.text = output;
		}

		override public function formTextWithSubOption(argumentTypeModel:ArgumentTypeModel):void{
			//must be only if:
			var output:String = "";
			var reasonModels:Vector.<StatementModel> = argumentTypeModel.reasonModels;
			var claimModel:StatementModel = argumentTypeModel.claimModel;
			var argSelector:ArgSelector = MenuPanel(FlexGlobals.topLevelApplication.map.agoraMap.menuPanelsHash[argumentTypeModel.ID]).schemeSelector;
			var i:int;

			if(argumentTypeModel.language == langTypes[4]){
				output = claimModel.statement.positiveText + Language.lookup("ArgOnlyIf") + reasonModels[0].statement.positiveText;
				for(i=1; i < reasonModels.length; i++){
					output = " " + argumentTypeModel.lSubOption + " " + reasonModels[i].statement.positiveText;
				}
			}
			else{
				trace("ModusTollens::formTextWithSubOption: Should not be any other language type other than only if");
			}

			argumentTypeModel.inferenceModel.statement.text = output;
		}

		override public function deleteLinks(argumentTypeModel:ArgumentTypeModel):void{
			var reasonModels:Vector.<StatementModel> = argumentTypeModel.reasonModels;
			var claimModel:StatementModel = argumentTypeModel.claimModel;
			//var inferenceModel:StatementModel = argumentTypeModel.inferenceModel;
			//if first claim's argument, then make it non-negative
			if(claimModel.firstClaim){
				claimModel.negated = false;
				//the first inference statement is the one to be removed
			}
			removeDependence(claimModel.statement, argumentTypeModel.inferenceModel.statements[0]);
			//make reason models non-negative
			for each(var reason:StatementModel in reasonModels){
				reason.negated = false;
				removeDependence(reason.statement, argumentTypeModel.inferenceModel.statements[1]);
			}
		}

		override public function link(argumentTypeModel:ArgumentTypeModel):void{
			var reasonModels:Vector.<StatementModel> = argumentTypeModel.reasonModels;
			var claimModel:StatementModel = argumentTypeModel.claimModel;
			var inferenceModel:StatementModel = argumentTypeModel.inferenceModel;

			if(claimModel.firstClaim){
				claimModel.negated = true;
			}

			inferenceModel.connectingString = StatementModel.IMPLICATION;

			//claimModel.statement.forwardList.push(inferenceModel.statements[0]);
			claimModel.statement.addDependentStatement(inferenceModel.statements[0]);

			for each(var reason:StatementModel in reasonModels){
				reason.negated = true;
				//reason.statement.forwardList.push(inferenceModel.statements[1]);
				reason.statement.addDependentStatement(inferenceModel.statements[1]);
			}
		}
	}
}

package Controller.logic
{
	import Controller.ArgumentController;

	import Model.AGORAModel;
	import Model.ArgumentTypeModel;
	import Model.StatementModel;

	import ValueObjects.AGORAParameters;

	import components.ArgSelector;
	import components.ArgumentPanel;
	import components.MenuPanel;

	import classes.Language;

	import mx.controls.Alert;
	import mx.core.FlexGlobals;

	public class ModusTollens extends ParentArg
	{
		public var andOr:String;
		private var _isExp:Boolean;
		private static var instance:ModusTollens;

		public function ModusTollens()
		{
			langTypes = ["If-then","Implies","Whenever","Only if","Provided that","Sufficient condition","Necessary condition"];
			//dbLangTypeNames = ["ifthen","implies","whenever","onlyif","providedthat","sufficient","necessary"];
			expLangTypes = ["Only if"];	// Expandable with both And and Or
			label = AGORAParameters.getInstance().MOD_TOL;

		}

		public static function getInstance():ModusTollens{
			if(instance == null){
				instance = new ModusTollens;
			}
			return instance;
		}

		override public function getLabel():String{
			return label;
		}

		override public function formText(argumentTypeModel:ArgumentTypeModel):void{
			var output:String = "";
			var reasonText:String = "";
			var reasonModels:Vector.<StatementModel> = argumentTypeModel.reasonModels;
			var claimModel:StatementModel = argumentTypeModel.claimModel;
			var argSelector:ArgSelector = MenuPanel(FlexGlobals.topLevelApplication.map.agoraMap.menuPanelsHash[argumentTypeModel.ID]).schemeSelector;
			var i:int;

			switch(argumentTypeModel.language){
				case langTypes[0]:
					reasonText = reasonModels[0].statement.positiveText;
					output = Language.lookup("ArgIf") + claimModel.statement.positiveText +
						Language.lookup("ArgThen") + reasonText;
					break;
				case langTypes[1]:
					output = claimModel.statement.positiveText + Language.lookup("ArgImplies") + reasonModels[0].statement.positiveText;
					break;
				case langTypes[2]:
					reasonText = reasonModels[0].statement.positiveText;
					output = Language.lookup("ArgWhenever") + claimModel.statement.positiveText + ", " + reasonText;
					break;
				case langTypes[3]:
					//if many reasons
					var params:AGORAParameters = AGORAParameters.getInstance();
					if(argumentTypeModel.reasonModels.length > 1 && argumentTypeModel.lSubOption == null){
						output = "Select how you want to connect the reasons";
						argSelector.andor.x = argSelector.typeSelector.x + argSelector.typeSelector.width;
						argSelector.andor.dataProvider = [params.AND, params.OR];
						argSelector.andor.visible = argSelector.typeSelector.visible;
						//if one reason
					}else if(argumentTypeModel.reasonModels.length == 1){
						reasonText = reasonModels[0].statement.positiveText;
						output = claimModel.statement.positiveText + Language.lookup("ArgOnlyIf");
						output = output + reasonText;
					}else{
						output = claimModel.statement.positiveText + Language.lookup("ArgOnlyIf");
						for(i=0; i<reasonModels.length - 1; i++){
							reasonText = reasonText + reasonModels[i].statement.positiveText + " " + argumentTypeModel.lSubOption + " ";
						}
						reasonText = reasonText + reasonModels[reasonModels.length - 1].statement.positiveText;
						output = output + reasonText;
						argSelector.andor.x = argSelector.typeSelector.x + argSelector.typeSelector.width;
						argSelector.andor.dataProvider = [params.AND, params.OR];
						argSelector.andor.visible = argSelector.typeSelector.visible;
					}
					break;
				case langTypes[4]:
					//provided that
					reasonText = reasonModels[0].statement.positiveText ;
					output = reasonText + Language.lookup("ArgProvidedThat") + claimModel.statement.positiveText;
					break;
				case langTypes[5]:
					//sufficient condition
					reasonText = reasonModels[0].statement.positiveText;
					output = claimModel.statement.positiveText + Language.lookup("ArgSufficientCond") + reasonText;
					break;
				case langTypes[6]:
					//necessary condition
					reasonText = reasonModels[0].statement.positiveText
					output = reasonText + Language.lookup("ArgNecessaryCond") + claimModel.statement.positiveText;
					break;
			}

			argumentTypeModel.inferenceModel.statements[0].text = claimModel.statement.text;
			argumentTypeModel.inferenceModel.statements[1].text = reasonText;
			argumentTypeModel.inferenceModel.statement.text = output;
		}

		override public function formTextWithSubOption(argumentTypeModel:ArgumentTypeModel):void{
			//must be only if:
			var output:String = "";
			var reasonModels:Vector.<StatementModel> = argumentTypeModel.reasonModels;
			var claimModel:StatementModel = argumentTypeModel.claimModel;
			var argSelector:ArgSelector = MenuPanel(FlexGlobals.topLevelApplication.map.agoraMap.menuPanelsHash[argumentTypeModel.ID]).schemeSelector;
			var i:int;

			if(argumentTypeModel.language == langTypes[4]){
				output = claimModel.statement.positiveText + Language.lookup("ArgOnlyIf") + reasonModels[0].statement.positiveText;
				for(i=1; i < reasonModels.length; i++){
					output = " " + argumentTypeModel.lSubOption + " " + reasonModels[i].statement.positiveText;
				}
			}
			else{
				trace("ModusTollens::formTextWithSubOption: Should not be any other language type other than only if");
			}

			argumentTypeModel.inferenceModel.statement.text = output;
		}

		override public function deleteLinks(argumentTypeModel:ArgumentTypeModel):void{
			var reasonModels:Vector.<StatementModel> = argumentTypeModel.reasonModels;
			var claimModel:StatementModel = argumentTypeModel.claimModel;
			//var inferenceModel:StatementModel = argumentTypeModel.inferenceModel;
			//if first claim's argument, then make it non-negative
			if(claimModel.firstClaim){
				claimModel.negated = false;
				//the first inference statement is the one to be removed
			}
			removeDependence(claimModel.statement, argumentTypeModel.inferenceModel.statements[0]);
			//make reason models non-negative
			for each(var reason:StatementModel in reasonModels){
				reason.negated = false;
				removeDependence(reason.statement, argumentTypeModel.inferenceModel.statements[1]);
			}
		}

		override public function link(argumentTypeModel:ArgumentTypeModel):void{
			var reasonModels:Vector.<StatementModel> = argumentTypeModel.reasonModels;
			var claimModel:StatementModel = argumentTypeModel.claimModel;
			var inferenceModel:StatementModel = argumentTypeModel.inferenceModel;

			if(claimModel.firstClaim){
				claimModel.negated = true;
			}

			inferenceModel.connectingString = StatementModel.IMPLICATION;

			//claimModel.statement.forwardList.push(inferenceModel.statements[0]);
			claimModel.statement.addDependentStatement(inferenceModel.statements[0]);

			for each(var reason:StatementModel in reasonModels){
				reason.negated = true;
				//reason.statement.forwardList.push(inferenceModel.statements[1]);
				reason.statement.addDependentStatement(inferenceModel.statements[1]);
			}
		}
	}
}

Fix merge issue from last night

Fix merge issue from last night


package ageofai.unit.utils
{
    import ageofai.home.vo.HomeVO;
    import ageofai.home.vo.MapNodeVO;
    import ageofai.map.constant.CMapNodeType;
    import ageofai.map.geom.IntPoint;
    import ageofai.map.model.IMapModel;
    import ageofai.map.model.MapNode;
    import ageofai.unit.base.IUnitView;
    import ageofai.villager.constant.CVillagerStatus;
    import ageofai.villager.model.IVillagerModel;
    import ageofai.villager.vo.VillagerVO;
    import flash.geom.Point;
	/**
     * ...
     * @author
     */
    public class VillagerAI implements IUnitAI
    {
        private var surroundings:Array = [[ -1, 0 ], [ 0, -1 ], [ 1, 0 ], [ 0, 1 ]];

        public function tick(villager:VillagerVO, mapModel:IMapModel, home:HomeVO):IntPoint
        {
            if ( villager.status == CVillagerStatus.IDLE )
            {
                var newPoint:IntPoint;

                // Check surrounding
                var objectFounds:Vector.<MapNodeVO> = new Vector.<MapNodeVO>();
                for (var i:int = 0, count:int = surroundings.length; i < count; i++)
                {
                    var newX:int = villager.position.x + surroundings[i][0];
                    var newY:int = villager.position.y + surroundings[i][1];

                    if (newX < 0 || newY < 0 || newX >= mapModel.map[0].length || newY >= mapModel.map.length)
                    {
                        continue;
                    }

                    newPoint = new IntPoint(newX, newY);

                    if (mapModel.map[newY][newX].objectType != CMapNodeType.OBJECT_NULL)
                    {
                        var nodeVO:MapNodeVO = new MapNodeVO();
                        nodeVO.pos = newPoint;
                        nodeVO.node = mapModel.map[newY][newX];
                        objectFounds[objectFounds.length] = nodeVO;
                    }
                }

                home.objectFounds = home.objectFounds.concat(objectFounds);

                if ( home.objectFounds.length == 0 )
                {
                    // Move randomly
                    do {
                        var newPos:int = Math.round(Math.random() * 4);
                        newX = villager.position.x + surroundings[newPos][0];
                        newY = villager.position.y + surroundings[newPos][1];

                        if (newX < 0 || newY < 0 || newX >= mapModel.map[0].length || newY >= mapModel.map.length)
                        {
                            continue;
                        }

                        newPoint = new IntPoint(newX, newY);
                    } while (newPoint.x < 0 || newPoint.y < 0 || newPoint.x >= mapModel.map[0].length || newPoint.y >= mapModel.map.length ||
                        !mapModel.map[newPoint.y][newPoint.x].walkable);
                }
                else
                {
                    // Go to object
                    //mapModel.getPath(, )
                }
            }
            else
            {
                // Is current task still valid?
            }

            return newPoint;
        }
    }

}

package ageofai.unit.utils
{
    import ageofai.home.vo.HomeVO;
    import ageofai.home.vo.MapNodeVO;
    import ageofai.map.constant.CMapNodeType;
    import ageofai.map.geom.IntPoint;
    import ageofai.map.model.IMapModel;
    import ageofai.map.model.MapNode;
    import ageofai.unit.base.IUnitView;
    import ageofai.villager.constant.CVillagerStatus;
    import ageofai.villager.model.IVillagerModel;
    import ageofai.villager.vo.VillagerVO;
    import flash.geom.Point;
	/**
     * ...
     * @author
     */
    public class VillagerAI implements IUnitAI
    {
        private var surroundings:Array = [[ -1, 0 ], [ 0, -1 ], [ 1, 0 ], [ 0, 1 ]];

        public function tick(villager:VillagerVO, mapModel:IMapModel, home:HomeVO):IntPoint
        {
            if ( villager.status == CVillagerStatus.IDLE )
            {
                var newPoint:IntPoint;

                // Check surrounding
                var objectFounds:Vector.<MapNodeVO> = new Vector.<MapNodeVO>();
                for (var i:int = 0, count:int = surroundings.length; i < count; i++)
                {
                    var newX:int = villager.position.x + surroundings[i][0];
                    var newY:int = villager.position.y + surroundings[i][1];

                    if (newX < 0 || newY < 0 || newX >= mapModel.map[0].length || newY >= mapModel.map.length)
                    {
                        continue;
                    }

                    newPoint = new IntPoint(newX, newY);

                    if (mapModel.map[newY][newX].objectType != CMapNodeType.OBJECT_NULL)
                    {
                        var nodeVO:MapNodeVO = new MapNodeVO();
                        nodeVO.pos = newPoint;
                        nodeVO.node = mapModel.map[newY][newX];
                        objectFounds[objectFounds.length] = nodeVO;
                    }
                }

                home.objectFounds = home.objectFounds.concat(objectFounds);

                if ( home.objectFounds.length == 0 )
                {
                    // Move randomly
                    do {
                        var newPos:int = Math.round(Math.random() * 3);
                        newX = villager.position.x + surroundings[newPos][0];
                        newY = villager.position.y + surroundings[newPos][1];

                        if (newX < 0 || newY < 0 || newX >= mapModel.map[0].length || newY >= mapModel.map.length)
                        {
                            continue;
                        }

                        newPoint = new IntPoint(newX, newY);
                    } while (newPoint.x < 0 || newPoint.y < 0 || newPoint.x >= mapModel.map[0].length || newPoint.y >= mapModel.map.length ||
                        !mapModel.map[newPoint.y][newPoint.x].walkable);
                }
                else
                {
                    // Go to object
                    //mapModel.getPath(, )
                }
            }
            else
            {
                // Is current task still valid?
            }

            return newPoint;
        }
    }

}

Fix 2

Fix 2