In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Boolean Algebra Calculator

It can calculate Boolean expressions such as 1+-(-0), 1^0, -(1)*-(-0)... and prints the result. It can also use variables like A+B, C*(D^E)... to print a truth table of all possible values the variables could be.
You can also hover/click the upper left of the screen to type the Boolean expression.
Get Adobe Flash player
by CatHobo 31 Aug 2013
    Embed
/**
 * Copyright CatHobo ( http://wonderfl.net/user/CatHobo )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/iQWw
 */

package {
    import flash.display.Sprite;
    import flash.display.Stage;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.system.System;
    import net.hires.debug.Stats;
    import flash.utils.Dictionary;
    public class BooleanCalculator extends Sprite{
        public function BooleanCalculator():void {
            this.addChild(new Stats());
            new Calculator(this);
        } 
    }
}  
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flash.events.TextEvent;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard; //For the enumerations of some characters.
import flash.display.Sprite;
final class Calculator{
    private var CalculatorBody:Sprite=new Sprite();
    //Container for everything.
    private var InputText:TextField=new TextField();
    private static const TheOnlyCharactersAllowed:String=" A-Z0-1()+*\\-\\^";
    //Allows "spaces", A to Z, 0, 1, +, -, *, (, ), and ^ to input as text.
    public function Calculator(DocClass:BooleanCalculator):void{
        var stage_w:Number=DocClass.stage.stageWidth;
        var stage_h:Number=DocClass.stage.stageHeight;
        with(CalculatorBody.graphics){
            lineStyle(2,0x000000);
            beginFill(0x5F5F5F);
            CalculatorBody.x=stage_w/5;
            CalculatorBody.y=2;
            drawRoundRect(0,0,stage_w*3/5,stage_h-2,20,20);
        }
        DocClass.addChildAt(CalculatorBody,0);
        InputText.defaultTextFormat=new TextFormat(
        "System",25,0x000000,true);
        InputText.type=TextFieldType.INPUT;
        //Input characters in textfield.
        /*for(var spam_i1:int=1;spam_i1<=0;spam_i1++){
            for(var spam_i2:int=1;spam_i2<=0;spam_i2++){
                InputText.appendText("a");
            }
            InputText.appendText(spam_i1+"\n");
        }*/
        InputText.restrict=TheOnlyCharactersAllowed;
        InputText.autoSize=TextFieldAutoSize.LEFT;
        InputText.width
        =CalculatorBody.width-42-CustomScrollGUI.BAR_LENGTH;
        InputText.multiline=true;
        InputText.wordWrap=true;
        InputText.addEventListener(
        TextEvent.TEXT_INPUT,UpdateScroll);
        InputText.addEventListener(
        KeyboardEvent.KEY_DOWN,CheckExtraKeys);
        InputText.addEventListener(
        KeyboardEvent.KEY_UP,CheckExtraKeys);
        InputScreen=new CustomScrollGUI(20,20
        ,CalculatorBody.width-40,CalculatorBody.height/3-15);
        CalculatorBody.addChild(InputScreen);
        InputScreen.AddDisplayObject(InputText);
        
        //Adding buttons to interact with the calculator.
        //Using the long way (with hard-coded "Magic Numbers").
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x,InputScreen.y+InputScreen.height+BUTTON_SPACE
        ,70,25,"FALSE(0)",AddCharacters,["0"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+70+BUTTON_SPACE
        ,InputScreen.y+InputScreen.height+BUTTON_SPACE
        ,70,25,"TRUE(1)",AddCharacters,["1"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+140+BUTTON_SPACE*2
        ,InputScreen.y+InputScreen.height+BUTTON_SPACE
        ,70,25,"CLEAR",ClearText,[]));
        
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x,InputScreen.y+InputScreen.height+25+BUTTON_SPACE*2
        ,70,25,"AND  (*)",AddCharacters,["*"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+70+BUTTON_SPACE
        ,InputScreen.y+InputScreen.height+25+BUTTON_SPACE*2
        ,70,25,"OR  (+)",AddCharacters,["+"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+140+BUTTON_SPACE*2
        ,InputScreen.y+InputScreen.height+25+BUTTON_SPACE*2
        ,70,25,"NOT  (-)",AddCharacters,["-"]));
        
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x,InputScreen.y+InputScreen.height+50+BUTTON_SPACE*3
        ,70,25,"XOR(^)",AddCharacters,["^"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+70+BUTTON_SPACE
        ,InputScreen.y+InputScreen.height+50+BUTTON_SPACE*3
        ,70,25,"BACKSP",BackspaceText,[]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+140+BUTTON_SPACE*2
        ,InputScreen.y+InputScreen.height+50+BUTTON_SPACE*3
        ,70,25,"CANCEL",CancelParsing,[])); 
        
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
        ,15,25,"(",AddCharacters,["("]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+15+BUTTON_SPACE
        ,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
        ,15,25,")",AddCharacters,[")"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+30+BUTTON_SPACE*2
        ,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
        ,15,25,"A",AddCharacters,["A"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+45+BUTTON_SPACE*3
        ,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
        ,15,25,"B",AddCharacters,["B"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+60+BUTTON_SPACE*4
        ,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
        ,15,25,"C",AddCharacters,["C"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+75+BUTTON_SPACE*5
        ,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
        ,15,25,"D",AddCharacters,["D"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+90+BUTTON_SPACE*6
        ,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
        ,15,25,"E",AddCharacters,["E"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+105+BUTTON_SPACE*7
        ,InputScreen.y+InputScreen.height+75+BUTTON_SPACE*4
        ,15,25,"F",AddCharacters,["F"]));
        
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
        ,15,25,"G",AddCharacters,["G"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+15+BUTTON_SPACE
        ,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
        ,15,25,"H",AddCharacters,["H"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+30+BUTTON_SPACE*2
        ,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
        ,15,25,"I",AddCharacters,["I"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+45+BUTTON_SPACE*3
        ,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
        ,15,25,"J",AddCharacters,["J"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+60+BUTTON_SPACE*4
        ,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
        ,15,25,"K",AddCharacters,["K"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+75+BUTTON_SPACE*5
        ,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
        ,15,25,"L",AddCharacters,["L"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+90+BUTTON_SPACE*6
        ,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
        ,18,25,"M",AddCharacters,["M"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+90+18+BUTTON_SPACE*7
        ,InputScreen.y+InputScreen.height+100+BUTTON_SPACE*5
        ,18,25,"N",AddCharacters,["N"]));
        
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
        ,15,25,"O",AddCharacters,["O"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+BUTTON_SPACE+15
        ,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
        ,15,25,"P",AddCharacters,["P"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+BUTTON_SPACE*2+30
        ,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
        ,15,25,"Q",AddCharacters,["Q"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+BUTTON_SPACE*3+45
        ,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
        ,15,25,"R",AddCharacters,["R"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+BUTTON_SPACE*4+60
        ,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
        ,15,25,"S",AddCharacters,["S"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+BUTTON_SPACE*5+75
        ,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
        ,15,25,"T",AddCharacters,["T"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+BUTTON_SPACE*6+90
        ,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
        ,15,25,"U",AddCharacters,["U"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+BUTTON_SPACE*7+105
        ,InputScreen.y+InputScreen.height+125+BUTTON_SPACE*6
        ,15,25,"V",AddCharacters,["V"]));
        
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x,InputScreen.y+InputScreen.height+150+BUTTON_SPACE*7
        ,20,25,"W",AddCharacters,["W"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+BUTTON_SPACE+20
        ,InputScreen.y+InputScreen.height+150+BUTTON_SPACE*7
        ,15,25,"X",AddCharacters,["X"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+BUTTON_SPACE*2+15+20
        ,InputScreen.y+InputScreen.height+150+BUTTON_SPACE*7
        ,15,25,"Y",AddCharacters,["Y"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+BUTTON_SPACE*3+30+20
        ,InputScreen.y+InputScreen.height+150+BUTTON_SPACE*7
        ,15,25,"Z",AddCharacters,["Z"]));
        CalculatorBody.addChild(new CustomButton(
        InputScreen.x+BUTTON_SPACE*4+45+20
        ,InputScreen.y+InputScreen.height+150+BUTTON_SPACE*7
        ,120,25,"EVALUATE (=)",EvaluateBooleanString,[]));
    }
    
    
    private static const BUTTON_SPACE:Number=15;
    private function AddCharacters(char:String):void{
        InputText.appendText(char);
        InputScreen.Update();
    }
    private function ClearText():void{
        InputText.text="";
        InputScreen.Update();
    }
    private function BackspaceText():void{
        InputText.text=InputText.text.substr(0,-1);//Remove last character.
        InputScreen.Update();
    }
    private function CancelParsing():void{
        try{
            pbs.CancelParsing=true;
        }catch(E:Error){
        }
    }
    private var pbs:ParseBooleanString;
    private function EvaluateBooleanString():void{
        try{
            pbs=new ParseBooleanString(InputText.text,AddCharacters); 
        }catch(E:Error){
            //Propogate custom errors in ParseBooleanString object
            //to the screen.
            InputText.appendText("\n"+String(E));
            InputScreen.Update();
        } 
    }  
    private function UpdateScroll(e:TextEvent):void{
        if(e.text=="="){
            EvaluateBooleanString();
        } //Short way to EVALUATE when pressing "=".
        InputScreen.Update();
    } 
    private function CheckExtraKeys(e:KeyboardEvent):void{
        switch(e.keyCode){
            case Keyboard.RIGHT:
            case Keyboard.LEFT:
            case Keyboard.UP:
            case Keyboard.DOWN:
            case Keyboard.SHIFT:
            case Keyboard.CONTROL: //Exclude some keys.
                break;
            case Keyboard.ENTER:
                if(e.type==KeyboardEvent.KEY_DOWN){
                    EvaluateBooleanString();
                }//Key Up will just update the scroll.
            default:
                InputScreen.Update();
        }
        //Extra keys such as Backspace, delete don't update the Scroll GUI.
    }
    private var InputScreen:CustomScrollGUI;
}  
import flash.display.Sprite;
import flash.display.SimpleButton;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.events.MouseEvent;
import flash.text.TextFieldAutoSize;
final class CustomButton extends SimpleButton{
    //Makes buttons that connect to functions.
    //Not sure why there is a graphical glitch (Indents in the letters).
    public function CustomButton(
    x:Number,y:Number,width:Number,height:Number,message:String,
    listener_function:Function,arguments:Array):void{
        M=message;
        D=Vector.<Number>([width,height]);
        super(ButtonTemplate(0x9F9F9F), //Mouse not roll over
        ButtonTemplate(0xBFBFBF), //Mouse roll over
        ButtonTemplate(0xFFFF00), //Mouse click
        ButtonTemplate(0xFFFFFF)); //Area to click
        this.x=x;
        this.y=y;
        this.addEventListener(MouseEvent.CLICK,ButtonListener);
        LinkedFunction=listener_function;
        LinkedArguments=arguments;
    } 
    private var LinkedFunction:Function;
    private var LinkedArguments:Array;
    private function ButtonListener(e:MouseEvent):void{
        LinkedFunction.apply(null,LinkedArguments);
    } //Call a function given in the CustomButton constructor.
    private static var D:Vector.<Number>;//Temporary variable for dimensions.
    private static var M:String;//For the message in the button.
    private function ButtonTemplate(color:uint):Sprite{
        var spr_container:Sprite=new Sprite();
        spr_container.graphics.lineStyle(2,0x3F3F3F);
        spr_container.graphics.beginFill(color);
        spr_container.graphics.drawRoundRect(0,0,D[0],D[1],20,20);
        var t:TextField=new TextField();
        t.defaultTextFormat=new TextFormat(
        "Verdana",12,0x00FF00,true);
        t.width=D[0]; //Resize textfield so it can be centered properly.
        t.text=M;
        t.autoSize=TextFieldAutoSize.CENTER; 
        spr_container.addChild(t);//Add to button. 
        return spr_container;
    }
}

import flash.display.Sprite;
import flash.display.Stage;
import flash.display.DisplayObject;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.events.MouseEvent;
final class CustomScrollGUI extends Sprite{
    private var V_ScrollInner:Sprite=new Sprite();
    private var V_ScrollOuter:Sprite=new Sprite();
    private var H_ScrollInner:Sprite=new Sprite();
    private var H_ScrollOuter:Sprite=new Sprite();
    private var ContentsToSee:Sprite=new Sprite();
    private var ContentsRect:Rectangle=new Rectangle();
    private var ContentScrollRect:Rectangle=new Rectangle();
    public static const BAR_LENGTH:int=20;
    public static const SCROLL_TO_END_IF_UPDATED:Boolean=true;
    public function AddDisplayObject(obj:DisplayObject
    ,to_x:Number=0,to_y:Number=0):void{
        obj.x=to_x;
        obj.y=to_y;
        ContentsToSee.addChild(obj);
        Update();
    }//Custom "addChild" for the scrollbar.
    private function GetContentBounds():Rectangle{
        var init_rectangle:Rectangle=new Rectangle();
        for(var i:int=0;i<ContentsToSee.numChildren;i++){
            init_rectangle=init_rectangle.union(
                ContentsToSee.getChildAt(i).getRect(ContentsToSee)
            ); //Get the largest rectangle for all children
            //in the contents of the scrollbar.
        }
        return init_rectangle;
    }
    public function Update():void{
        var LargestRectangle:Rectangle=GetContentBounds();
        ContentsRect.height=LargestRectangle.height;
        ContentsRect.width=LargestRectangle.width; 
        //Update ScrollRect for the scrollbar to work properly.
        if(LargestRectangle.height>ContentScrollRect.height){
            with(V_ScrollOuter.graphics){
                clear(); //Clear to redraw properly.
                lineStyle(2,0x000000);
                beginFill(0xFFFFFF);
                drawRoundRect(0,0
                ,BAR_LENGTH,
                V_ScrollInner.height
                *ContentScrollRect.height/LargestRectangle.height
                ,20,20);
            }
            V_ScrollInner.visible=true;
        }else{
            V_ScrollInner.visible=false;
        } //Show scrollbar if content height is bigger than mask.
        //by redrawing with the ratio of mask height to content height.
        if(LargestRectangle.width>ContentScrollRect.width){
            with(H_ScrollOuter.graphics){
                clear();
                lineStyle(2,0x000000);
                beginFill(0xFFFFFF);
                drawRoundRect(0,0,H_ScrollInner.width
                *ContentScrollRect.width/LargestRectangle.width
                ,BAR_LENGTH,20,20);
            }
            H_ScrollInner.visible=true;
        }else{
            H_ScrollInner.visible=false;
        }
        CheckV_ScrollOutOfBounds();
        CheckH_ScrollOutOfBounds();
    }
    private function CheckV_ScrollOutOfBounds():void{
        /*Console.Print(GetContentBounds(),ContentScrollRect,
        GetContentBounds().height-ContentScrollRect.height,
        GetContentBounds().height>ContentScrollRect.height,
        GetContentBounds().height-ContentScrollRect.height
        <ContentScrollRect.y+0.2," ");*/
        if(GetContentBounds().height>ContentScrollRect.height){
            if(GetContentBounds().height-ContentScrollRect.height
            <ContentScrollRect.y+0.2){
                V_ScrollTo(GetScrollVSpace);
                //Automatically change scrollbar and
                //contents positions if using backspace.
            }else{
                if(SCROLL_TO_END_IF_UPDATED){
                    V_ScrollTo(GetScrollVSpace); 
                }//Extra code for the Boolean Calculator.
            }
        }else{
            V_ScrollTo(0);
            //If cutting a whole textfield, 
            //scroll back up to 0.
        } 
        ContentScrollV();
    }
    private function CheckH_ScrollOutOfBounds():void{
        if(GetContentBounds().width>ContentScrollRect.width){
            if(GetContentBounds().width-ContentScrollRect.width
            <ContentScrollRect.x+0.2){
                H_ScrollTo(GetScrollHSpace);
            }
        }else{
            H_ScrollTo(0);
            //If cutting a whole textfield,
            //scroll back up to 0.
        } 
        ContentScrollH();
        /*Console.Print(GetContentBounds(),ContentScrollRect,
        GetContentBounds().width-ContentScrollRect.width,
        GetContentBounds().width>ContentScrollRect.width,
        GetContentBounds().width-ContentScrollRect.width
        <ContentScrollRect.x+0.2," ");*/
    } 
    public function CustomScrollGUI(init_x:Number,init_y:Number,
    init_width:Number,init_height:Number):void{
        x=init_x;
        y=init_y;
        with(graphics){
            lineStyle(2,0x000000);
            beginFill(0xFFFF9F);
            drawRoundRect(0,0,init_width,init_height,20,20);
        }
        with(V_ScrollInner){
            x=init_width-BAR_LENGTH-2;
            y=2;
            with(graphics){
                lineStyle(2,0x000000);
                beginFill(0xBFBFBF);
                drawRoundRect(0,0,BAR_LENGTH,init_height-BAR_LENGTH,20,20);
            }
        }
        V_ScrollInnerHeight=V_ScrollInner.height;
        V_ScrollInner.visible=false;
        this.addChild(V_ScrollInner);
        with(V_ScrollOuter){
            buttonMode=true;
            with(graphics){
                lineStyle(2,0x000000);
                beginFill(0xFFFFFF);
                drawRoundRect(0,0,BAR_LENGTH,init_height-BAR_LENGTH,20,20);
            }
        }
        V_ScrollInner.addChild(V_ScrollOuter);
        with(H_ScrollInner){
            y=init_height-BAR_LENGTH;
            with(graphics){
                lineStyle(2,0x000000);
                beginFill(0xBFBFBF);
                drawRoundRect(0,0,init_width-BAR_LENGTH,BAR_LENGTH,20,20);
            }
        }
        H_ScrollInnerWidth=H_ScrollInner.width;
        H_ScrollInner.visible=false;
        this.addChild(H_ScrollInner);
        with(H_ScrollOuter){
            buttonMode=true;
            with(graphics){
                lineStyle(2,0x000000);
                beginFill(0xFFFFFF);
                drawRoundRect(0,0,100,BAR_LENGTH,20,20);
            }
        }
        H_ScrollInner.addChild(H_ScrollOuter);
        with(ContentScrollRect){
            width=this.width-BAR_LENGTH-4;
            height=this.height-BAR_LENGTH-4;
        }
        ContentsToSee.scrollRect=ContentScrollRect;
        //Used to scroll the contents with the scrollbars.
        ContentsToSee.cacheAsBitmap=true;
        this.addChild(ContentsToSee);
        this.addEventListener(Event.ADDED_TO_STAGE,AddEventListeners);
        //After "this" is added by addChild, this.root.stage is accessible.
    }
    private function AddEventListeners(e:Event):void{
        V_ScrollInner.addEventListener(MouseEvent.MOUSE_DOWN,V_ScrollByInner);
        this.root.stage.addEventListener(
        MouseEvent.MOUSE_UP,V_ScrollByOuterRemove);
        //Remove scrolling anywhere when mouse is up in the stage.
        H_ScrollInner.addEventListener(MouseEvent.MOUSE_DOWN,H_ScrollByInner);
        this.root.stage.addEventListener(
        MouseEvent.MOUSE_UP,H_ScrollByOuterRemove);
    }
    private var V_ScrollInnerHeight:Number;
    //Since V_ScrollOuter is a child, of V_ScrollInner
    //would change the height. This is to preserve that.
    private function get GetScrollVSpace():Number{
        return V_ScrollInnerHeight-V_ScrollOuter.height;
    } //Magic number to get the number by the difference of V_Scroll bars.
    private function V_ScrollTo(to_y:Number):void{
        var GetScrollVSpace:Number=this.GetScrollVSpace;
        if(to_y<=GetScrollVSpace&&to_y>=0){
            V_ScrollOuter.y=to_y;
        }else if(to_y>GetScrollVSpace){
            V_ScrollOuter.y=GetScrollVSpace;
        }else if(to_y<0){
            V_ScrollOuter.y=0;
        }//Scroll inside the boundaries of ScrollBarInner.
    }
    private function ContentScrollV():void{
        ContentScrollRect.y=(GetScrollVSpace!=0)
        ?(ContentsRect.height-ContentScrollRect.height)
        *V_ScrollOuter.y/GetScrollVSpace
        :(0); //No 0 division.
        ContentsToSee.scrollRect=ContentScrollRect;
        //Change scrolling positions using maths.
    }
    private function V_ScrollByInner(e:MouseEvent):void{
        var GetDisp:DisplayObject=V_ScrollOuter;
        var GetLocal_y:Number=0;
        while(!(GetDisp is Stage)){
            GetDisp=GetDisp.parent;
            GetLocal_y+=GetDisp.y;            
        }//If GUI is nested inside display objects,
        //add all of the y-offsets for the scroll
        //to properly get the local y with respect to V_ScrollInner
        //using e.stageY-GetLocal_y.
//Console.Print(V_ScrollInner.globalToLocal(new Point(0,e.stageY)).y);
        V_ScrollTo(e.stageY-GetLocal_y-V_ScrollOuter.height/2);
        //Scroll in the middle of the mouse y position.
        ContentScrollV(); //Scroll the content vertically.
        this.root.stage.addEventListener(
        MouseEvent.MOUSE_MOVE,V_ScrollByInner);
    }
    private function V_ScrollByOuterRemove(e:MouseEvent):void{
        this.root.stage.removeEventListener(
        MouseEvent.MOUSE_MOVE,V_ScrollByInner);
    } 
    private var H_ScrollInnerWidth:Number;
    private function get GetScrollHSpace():Number{
        return H_ScrollInnerWidth-H_ScrollOuter.width;
    } //Magic number to get the number by the difference of V_Scroll bars.
    private function H_ScrollTo(to_x:Number):void{
        var GetScrollHSpace:Number=this.GetScrollHSpace;
        if(to_x<=GetScrollHSpace&&to_x>=0){
            H_ScrollOuter.x=to_x;
        }else if(to_x>GetScrollHSpace){
            H_ScrollOuter.x=GetScrollHSpace;
        }else if(to_x<0){
            H_ScrollOuter.x=0;
        }//Scroll inside the boundaries of ScrollBarInner. 
    }
    private function ContentScrollH():void{
        ContentScrollRect.x=(GetScrollHSpace!=0)
        ?(ContentsRect.width-ContentScrollRect.width)
        *H_ScrollOuter.x/GetScrollHSpace
        :(0);
        ContentsToSee.scrollRect=ContentScrollRect;
        //Change scrolling positions using maths.
    } 
    private function H_ScrollByInner(e:MouseEvent):void{
        var GetDisp:DisplayObject=H_ScrollOuter;
        var GetLocal_x:Number=0;
        while(!(GetDisp is Stage)){
            GetDisp=GetDisp.parent;
            GetLocal_x+=GetDisp.x;            
        }
        H_ScrollTo(e.stageX-GetLocal_x-H_ScrollOuter.width/2);
        ContentScrollH();
        this.root.stage.addEventListener(
        MouseEvent.MOUSE_MOVE,H_ScrollByInner);    
    }
    private function H_ScrollByOuterRemove(e:MouseEvent):void{
        this.root.stage.removeEventListener(
        MouseEvent.MOUSE_MOVE,H_ScrollByInner);
    }    
}

import flash.events.Event;
import flash.display.Sprite;
final class ParseBooleanString{
        //Not sure if Parse is the right word.
        private static var HandleEvents:Sprite=new Sprite();
        private static const RegCheckSyntax:RegExp
        =/(?:\(*\-?)*\(*[A-Z0-1]\)*(?:[\+\*\^](?:\(*\-?)*\(*[A-Z0-1]\)*)*/;
        //This regexp seems to work for now.
        private static const RegCheckChars:RegExp
        =/([A-Z0-1])/
        public function ParseBooleanString(s:String
        ,print_listener:Function):void{
            PrintToScreen=print_listener;
            if(s==""){
                throw new Error("\nNo characters to evaluate.");                
            }
            s=s.replace(/\s/g,"");//Remove all white spaces.
            if(!(s.match(RegCheckChars) is Array)){
                throw new Error("\nNeeds at least 1 letter/number.");
            }//If capturing any letter/number, don't throw the error.
            var LeftParenthesis:int=s.match(/\(/g).length;
            var RightParenthesis:int=s.match(/\)/g).length;
            if(s.match(RegCheckSyntax)[0].length!=s.length){
                throw new Error("\nInvalid Syntax (Characters/Symbols are not used correctly), or the CLEAR button isn't pressed after an evaluation.");
            }else if(LeftParenthesis>RightParenthesis){
                throw new Error("\nToo many Left Parenthesis ("+LeftParenthesis+" counted). Counted only "+RightParenthesis+" Right Parenthesis.");
            }else if(RightParenthesis>LeftParenthesis){
                throw new Error("\nToo many Right Parenthesis ("+RightParenthesis+" counted). Counted only "+LeftParenthesis+" Left Parenthesis.");
            }//For syntax errors in string.
            GetVariablesFromString(s); //Get string variable names
            //from "A" to "Z".
            PrintToScreen("\nPrinting result(s) for: "+s);
            StringCopy=s;
            DoParsing(s);
        }
        private var PrintToScreen:Function;
        private var StringCopy:String;
        public var CancelParsing:Boolean=false;
        private function DoNextVariableValues(e:Event):void{
            HandleEvents.removeEventListener(Event.ENTER_FRAME,DoNextVariableValues);
            if(!CancelParsing&&NextBooleanArrayValues(BooleanArray)){
                DoParsing(StringCopy); //Do next boolean values.
            }else{
                if(CancelParsing){
                    PrintToScreen("\nCancelled.");
                    return;
                }
                PrintToScreen("\nDone.");
            }
        } 
        private static const RegParenthesis:RegExp
        =/\(\-?[A-Z0-1](?:[\+\*\^]\-?[A-Z0-1])*\)/;
        private static const RegNOTOperator:RegExp=/-[A-Z0-1]/;
        private static const RegXOROperator:RegExp=/[A-Z0-1]\^[A-Z0-1]/;
        private static const RegANDOperator:RegExp=/[A-Z0-1]\*[A-Z0-1]/;
        private static const RegOROperator:RegExp=/[A-Z0-1]\+[A-Z0-1]/;
        private function DoParsing(s:String):void{
            s="("+s+")";
            //Enclose string in parenthesis 
            //for the loop code below.
            //Console.Print(s);
            var Parser:Object=GetStringParser();
            var inner_parenthesis:Array
            =s.match(RegParenthesis);
            //Capture an expression within parenthesis first.
            //match returns an array if it finds any string matches.
            var cloned_parenthesis:Array
            =s.match(RegParenthesis);
            //Clone contents by value (no pass by refernce).
            var operations_array:Array;
            var infinite_loop:int=0;
            while(inner_parenthesis is Array){
                operations_array=inner_parenthesis[0].match(RegNOTOperator);
                while(operations_array is Array){
                    inner_parenthesis[0]
                    =inner_parenthesis[0].replace(operations_array[0]
                    ,BooleanAsString(!Parser[operations_array[0].charAt(1)])
                    );
                    operations_array=inner_parenthesis[0].match(RegNOTOperator);
                } //Evaluate the NOT operators.
                operations_array=inner_parenthesis[0].match(RegXOROperator);
                while(operations_array is Array){
                    inner_parenthesis[0]
                    =inner_parenthesis[0].replace(
                    operations_array[0]
                    ,BooleanAsString(
                    (!Parser[operations_array[0].charAt(0)]
                    &&Parser[operations_array[0].charAt(2)])
                    ||(Parser[operations_array[0].charAt(0)]
                    &&!Parser[operations_array[0].charAt(2)]))
                    ); 
                    operations_array=inner_parenthesis[0].match(RegXOROperator);
                } //Evaluate the XOR operators.   
                operations_array=inner_parenthesis[0].match(RegANDOperator);
                while(operations_array is Array){
                    inner_parenthesis[0]
                    =inner_parenthesis[0].replace(
                    operations_array[0]
                    ,BooleanAsString(
                    Parser[operations_array[0].charAt(0)]
                    &&Parser[operations_array[0].charAt(2)])
                    ); 
                    operations_array=inner_parenthesis[0].match(RegANDOperator);
                } //Evaluate the AND operators.   
                operations_array=inner_parenthesis[0].match(RegOROperator);
                while(operations_array is Array){
                    inner_parenthesis[0]
                    =inner_parenthesis[0].replace(
                    operations_array[0]
                    ,BooleanAsString(
                    Parser[operations_array[0].charAt(0)]
                    ||Parser[operations_array[0].charAt(2)])
                    ); 
                    operations_array=inner_parenthesis[0].match(RegOROperator);
                } //Evaluate the OR operators. 
                s=s.replace(
                cloned_parenthesis
                ,inner_parenthesis[0].charAt(1));
                //Replace a whole string inside parenthesis
                //( Ex: (A+-1*0^-D) ) into 0 or 1.
                if(++infinite_loop>1000){
                    throw new Error("Infinite loop at parser.");
                }
                inner_parenthesis
                =s.match(RegParenthesis);
                cloned_parenthesis
                =s.match(RegParenthesis);
                //Capture any new expressions within parenthesis.
            }
            var TempString:String="";
            for(var i:int=0;i<VariableArray.length;i++){
                TempString+="("+VariableArray[i]
                +"="+BooleanAsString(BooleanArray[i])+") | ";
            }
            PrintToScreen("\n"+TempString+"(Result="+s+")");
            HandleEvents.addEventListener(Event.ENTER_FRAME,DoNextVariableValues);
            //Cycle through the next combination in the truth table.
        }
        private static function BooleanAsString(b:Boolean):String{
            return (b?"1":"0");
        }
        private static const RegFindVariables:RegExp=/[A-Z]/g;
        private var VariableArray:Vector.<String>;
        private var BooleanArray:Vector.<Boolean>;
        private function GetVariablesFromString(str:String):void{
            VariableArray=new Vector.<String>();
            var VariableCache:Object=new Object();
            for each(var var_s:String in str.match(RegFindVariables)){
                if(!VariableCache[var_s]){
                    VariableArray.push(var_s);
                    VariableCache[var_s]=true; 
                }//No duplicates of a string variable.
            } 
            VariableArray.sort(0);
            //Sort alphabetically.
            BooleanArray
            =new Vector.<Boolean>(VariableArray.length);
            for(var i:int=0;i<BooleanArray.length;i++){
                BooleanArray[i]=false;
            }//Fill BooleanArray with false by the length of
            //the VariableArray.
        }
        
        private function GetStringParser():Object{
            var o:Object=new Object();
            o["0"]=false; //0 always false
            o["1"]=true; //1 always true
            for(var i:int=0;i<VariableArray.length;i++){
                o[VariableArray[i]]=BooleanArray[i];
            } //Fill variable names with boolean values.
            return o;
        }
        
        private function NextBooleanArrayValues(
        v_ref:Vector.<Boolean>):Boolean{
            var count_i:int=0;
            while(count_i<v_ref.length){
                if(v_ref[count_i]){
                    v_ref[count_i]=false;
                    count_i++;    
                }else{
                    v_ref[count_i]=true;
                    return true;
                }
            }
            return false;
        }//"Binary Addition by 1. Example: 0b000101+0b1=0b000110"
}