package com.gsolo.encryption {
	public class SHA1 {
		/*
		 * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
		 * in FIPS PUB 180-1
		 * Version 2.1a Copyright Paul Johnston 2000 - 2002.
		 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
		 * Distributed under the BSD License
		 * See http://pajhome.org.uk/crypt/md5 for details.
		 *
		 * Converted to AS3 By Geoffrey Williams
		 */

		/*
		 * Configurable variables. You may need to tweak these to be compatible with
		 * the server-side, but the defaults work in most cases.
		 */

		public static const HEX_FORMAT_LOWERCASE:uint = 0;
		public static const HEX_FORMAT_UPPERCASE:uint = 1;

		public static const BASE64_PAD_CHARACTER_DEFAULT_COMPLIANCE:String = "";
		public static const BASE64_PAD_CHARACTER_RFC_COMPLIANCE:String = "=";

		public static const BITS_PER_CHAR_ASCII:uint = 8;
		public static const BITS_PER_CHAR_UNICODE:uint = 8;

		public static var hexcase:uint = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
		public static var b64pad:String  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
		public static var chrsz:uint   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

		public static function encrypt (string:String):String {
			return hex_sha1 (string);
		}

		/*
		 * These are the functions you'll usually want to call
		 * They take string arguments and return either hex or base-64 encoded strings
		 */
		public static function hex_sha1 (string:String):String {
			return binb2hex (core_sha1( str2binb(string), string.length * chrsz));
		}

		public static function b64_sha1 (string:String):String {
			return binb2b64 (core_sha1 (str2binb (string), string.length * chrsz));
		}

		public static function str_sha1 (string:String):String {
			return binb2str (core_sha1 (str2binb (string), string.length * chrsz));
		}

		public static function hex_hmac_sha1 (key:String, data:String):String {
			return binb2hex (core_hmac_sha1 (key, data));
		}

		public static function b64_hmac_sha1 (key:String, data:String):String {
			return binb2b64 (core_hmac_sha1 (key, data));
		}

		public static function str_hmac_sha1 (key:String, data:String):String {
			return binb2str (core_hmac_sha1 (key, data));
		}

		/*
		 * Perform a simple self-test to see if the VM is working
		 */
		public static function sha1_vm_test ():Boolean {
		  return hex_sha1 ("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
		}

		/*
		 * Calculate the SHA-1 of an array of big-endian words, and a bit length
		 */
		public static function core_sha1 (x:Array, len:Number):Array {
			/* append padding */
			x[len >> 5] |= 0x80 << (24 - len % 32);
			x[((len + 64 >> 9) << 4) + 15] = len;

			var w:Array = Array(80);
			var a:Number =  1732584193;
			var b:Number = -271733879;
			var c:Number = -1732584194;
			var d:Number =  271733878;
			var e:Number = -1009589776;

			for(var i:Number = 0; i < x.length; i += 16) {
				var olda:Number = a;
				var oldb:Number = b;
				var oldc:Number = c;
				var oldd:Number = d;
				var olde:Number = e;

				for(var j:Number = 0; j < 80; j++) {
					if(j < 16) w[j] = x[i + j];
				     else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
					var t:Number = safe_add (safe_add (rol (a, 5), sha1_ft (j, b, c, d)), safe_add (safe_add (e, w[j]), sha1_kt (j)));
					e = d;
					d = c;
					c = rol(b, 30);
					b = a;
					a = t;
				}

				a = safe_add(a, olda);
				b = safe_add(b, oldb);
				c = safe_add(c, oldc);
				d = safe_add(d, oldd);
				e = safe_add(e, olde);
			}

			return [a, b, c, d, e];
		}

		/*
		 * Perform the appropriate triplet combination function for the current
		 * iteration
		 */
		public static function sha1_ft (t:Number, b:Number, c:Number, d:Number):Number {
			if(t < 20) return (b & c) | ((~b) & d);
			if(t < 40) return b ^ c ^ d;
			if(t < 60) return (b & c) | (b & d) | (c & d);
			return b ^ c ^ d;
		}

		/*
		 * Determine the appropriate additive constant for the current iteration
		 */
		public static function sha1_kt (t:Number):Number {
			return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 : (t < 60) ? -1894007588 : -899497514;
		}

		/*
		 * Calculate the HMAC-SHA1 of a key and some data
		 */
		public static function core_hmac_sha1 (key:String, data:String):Array {
		  var bkey:Array = str2binb (key);
		  if (bkey.length > 16) bkey = core_sha1 (bkey, key.length * chrsz);

		  var ipad:Array = Array(16), opad:Array = Array(16);
		  for(var i:Number = 0; i < 16; i++) {
			ipad[i] = bkey[i] ^ 0x36363636;
			opad[i] = bkey[i] ^ 0x5C5C5C5C;
		  }

		  var hash:Array = core_sha1 (ipad.concat (str2binb(data)), 512 + data.length * chrsz);
		  return core_sha1 (opad.concat (hash), 512 + 160);
		}

		/*
		 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
		 * to work around bugs in some JS interpreters.
		 */
		public static function safe_add (x:Number, y:Number):Number {
			var lsw:Number = (x & 0xFFFF) + (y & 0xFFFF);
			var msw:Number = (x >> 16) + (y >> 16) + (lsw >> 16);
			return (msw << 16) | (lsw & 0xFFFF);
		}

		/*
		 * Bitwise rotate a 32-bit number to the left.
		 */
		public static function rol (num:Number, cnt:Number):Number {
			return (num << cnt) | (num >>> (32 - cnt));
		}

		/*
		 * Convert an 8-bit or 16-bit string to an array of big-endian words
		 * In 8-bit function, characters >255 have their hi-byte silently ignored.
		 */
		public static function str2binb (str:String):Array {
		  var bin:Array = new Array ();
		  var mask:Number = (1 << chrsz) - 1;
		  for (var i:Number = 0; i < str.length * chrsz; i += chrsz) bin[i>>5] |= (str.charCodeAt (i / chrsz) & mask) << (32 - chrsz - i%32);
		  return bin;
		}

		/*
		 * Convert an array of big-endian words to a string
		 */
		public static function binb2str (bin:Array):String {
			var str:String = "";
			var mask:Number = (1 << chrsz) - 1;
			for (var i:Number = 0; i < bin.length * 32; i += chrsz) str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
			return str;
		}

		/*
		 * Convert an array of big-endian words to a hex string.
		 */
		public static function binb2hex (binarray:Array):String {
			var hex_tab:String = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
			var str:String = "";
			for(var i:Number = 0; i < binarray.length * 4; i++) {
			str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
			          hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
			}
			return str;
		}

		/*
		 * Convert an array of big-endian words to a base-64 string
		 */
		public static function binb2b64 (binarray:Array):String {
			var tab:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
			var str:String = "";
			for(var i:Number = 0; i < binarray.length * 4; i += 3) {
				var triplet:Number = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
		                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
		                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
				for(var j:Number = 0; j < 4; j++) {
					if (i * 8 + j * 6 > binarray.length * 32) str += b64pad;
					else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
				}
			}
			return str;
		}
	}
}

package com.gsolo.encryption {
	public class SHA1 {
		/*
		 * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
		 * in FIPS PUB 180-1
		 * Version 2.1a Copyright Paul Johnston 2000 - 2002.
		 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
		 * Distributed under the BSD License
		 * See http://pajhome.org.uk/crypt/md5 for details.
		 *
		 * Converted to AS3 By Geoffrey Williams
		 */

		/*
		 * Configurable variables. You may need to tweak these to be compatible with
		 * the server-side, but the defaults work in most cases.
		 */

		public static const HEX_FORMAT_LOWERCASE:uint = 0;
		public static const HEX_FORMAT_UPPERCASE:uint = 1;

		public static const BASE64_PAD_CHARACTER_DEFAULT_COMPLIANCE:String = "";
		public static const BASE64_PAD_CHARACTER_RFC_COMPLIANCE:String = "=";

		public static const BITS_PER_CHAR_ASCII:uint = 8;
		public static const BITS_PER_CHAR_UNICODE:uint = 8;

		public static var hexcase:uint = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
		public static var b64pad:String  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
		public static var chrsz:uint   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

		public static function encrypt (string:String):String {
			return hex_sha1 (string);
		}

		/*
		 * These are the functions you'll usually want to call
		 * They take string arguments and return either hex or base-64 encoded strings
		 */
		public static function hex_sha1 (string:String):String {
			return binb2hex (core_sha1( str2binb(string), string.length * chrsz));
		}

		public static function b64_sha1 (string:String):String {
			return binb2b64 (core_sha1 (str2binb (string), string.length * chrsz));
		}

		public static function str_sha1 (string:String):String {
			return binb2str (core_sha1 (str2binb (string), string.length * chrsz));
		}

		public static function hex_hmac_sha1 (key:String, data:String):String {
			return binb2hex (core_hmac_sha1 (key, data));
		}

		public static function b64_hmac_sha1 (key:String, data:String):String {
			return binb2b64 (core_hmac_sha1 (key, data));
		}

		public static function str_hmac_sha1 (key:String, data:String):String {
			return binb2str (core_hmac_sha1 (key, data));
		}

		/*
		 * Perform a simple self-test to see if the VM is working
		 */
		public static function sha1_vm_test ():Boolean {
		  return hex_sha1 ("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
		}

		/*
		 * Calculate the SHA-1 of an array of big-endian words, and a bit length
		 */
		public static function core_sha1 (x:Array, len:Number):Array {
			/* append padding */
			x[len >> 5] |= 0x80 << (24 - len % 32);
			x[((len + 64 >> 9) << 4) + 15] = len;

			var w:Array = new Array(80);
			var a:Number =  1732584193;
			var b:Number = -271733879;
			var c:Number = -1732584194;
			var d:Number =  271733878;
			var e:Number = -1009589776;

			for(var i:Number = 0; i < x.length; i += 16) {
				var olda:Number = a;
				var oldb:Number = b;
				var oldc:Number = c;
				var oldd:Number = d;
				var olde:Number = e;

				for(var j:Number = 0; j < 80; j++) {
					if(j < 16) w[j] = x[i + j];
				     else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
					var t:Number = safe_add (safe_add (rol (a, 5), sha1_ft (j, b, c, d)), safe_add (safe_add (e, w[j]), sha1_kt (j)));
					e = d;
					d = c;
					c = rol(b, 30);
					b = a;
					a = t;
				}

				a = safe_add(a, olda);
				b = safe_add(b, oldb);
				c = safe_add(c, oldc);
				d = safe_add(d, oldd);
				e = safe_add(e, olde);
			}

			return [a, b, c, d, e];
		}

		/*
		 * Perform the appropriate triplet combination function for the current
		 * iteration
		 */
		public static function sha1_ft (t:Number, b:Number, c:Number, d:Number):Number {
			if(t < 20) return (b & c) | ((~b) & d);
			if(t < 40) return b ^ c ^ d;
			if(t < 60) return (b & c) | (b & d) | (c & d);
			return b ^ c ^ d;
		}

		/*
		 * Determine the appropriate additive constant for the current iteration
		 */
		public static function sha1_kt (t:Number):Number {
			return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 : (t < 60) ? -1894007588 : -899497514;
		}

		/*
		 * Calculate the HMAC-SHA1 of a key and some data
		 */
		public static function core_hmac_sha1 (key:String, data:String):Array {
		  var bkey:Array = str2binb (key);
		  if (bkey.length > 16) bkey = core_sha1 (bkey, key.length * chrsz);

		  var ipad:Array = new Array(16), opad:Array = new Array(16);
		  for(var i:Number = 0; i < 16; i++) {
			ipad[i] = bkey[i] ^ 0x36363636;
			opad[i] = bkey[i] ^ 0x5C5C5C5C;
		  }

		  var hash:Array = core_sha1 (ipad.concat (str2binb(data)), 512 + data.length * chrsz);
		  return core_sha1 (opad.concat (hash), 512 + 160);
		}

		/*
		 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
		 * to work around bugs in some JS interpreters.
		 */
		public static function safe_add (x:Number, y:Number):Number {
			var lsw:Number = (x & 0xFFFF) + (y & 0xFFFF);
			var msw:Number = (x >> 16) + (y >> 16) + (lsw >> 16);
			return (msw << 16) | (lsw & 0xFFFF);
		}

		/*
		 * Bitwise rotate a 32-bit number to the left.
		 */
		public static function rol (num:Number, cnt:Number):Number {
			return (num << cnt) | (num >>> (32 - cnt));
		}

		/*
		 * Convert an 8-bit or 16-bit string to an array of big-endian words
		 * In 8-bit function, characters >255 have their hi-byte silently ignored.
		 */
		public static function str2binb (str:String):Array {
		  var bin:Array = new Array ();
		  var mask:Number = (1 << chrsz) - 1;
		  for (var i:Number = 0; i < str.length * chrsz; i += chrsz) bin[i>>5] |= (str.charCodeAt (i / chrsz) & mask) << (32 - chrsz - i%32);
		  return bin;
		}

		/*
		 * Convert an array of big-endian words to a string
		 */
		public static function binb2str (bin:Array):String {
			var str:String = "";
			var mask:Number = (1 << chrsz) - 1;
			for (var i:Number = 0; i < bin.length * 32; i += chrsz) str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
			return str;
		}

		/*
		 * Convert an array of big-endian words to a hex string.
		 */
		public static function binb2hex (binarray:Array):String {
			var hex_tab:String = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
			var str:String = "";
			for(var i:Number = 0; i < binarray.length * 4; i++) {
			str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
			          hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
			}
			return str;
		}

		/*
		 * Convert an array of big-endian words to a base-64 string
		 */
		public static function binb2b64 (binarray:Array):String {
			var tab:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
			var str:String = "";
			for(var i:Number = 0; i < binarray.length * 4; i += 3) {
				var triplet:Number = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
		                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
		                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
				for(var j:Number = 0; j < 4; j++) {
					if (i * 8 + j * 6 > binarray.length * 32) str += b64pad;
					else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
				}
			}
			return str;
		}
	}
}

stop compile warnings.

com/gsolo/encryption/SHA1.as: stop compile warnings.


/*

as3isolib - An open-source ActionScript 3.0 Isometric Library developed to assist
in creating isometrically projected content (such as games and graphics)
targeted for the Flash player platform

http://code.google.com/p/as3isolib/

Copyright (c) 2006 - 2008 J.W.Opitz, All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

*/
package eDpLib.events
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.FocusEvent;
	import flash.events.IEventDispatcher;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;

	/**
	 * EventDispatcherProxy provides a means for intercepting events on behalf of a target and redispatching them as the target of the event.
	 */
	public class EventDispatcherProxy implements IEventDispatcher, IEventDispatcherProxy
	{
		////////////////////////////////////////////////////////////////////////
		//	PROXY TARGET
		////////////////////////////////////////////////////////////////////////

		/**
		 * @private
		 */
		private var _proxyTarget:IEventDispatcher; //the item that we are intercepting and redispatching, this being the target, should be set in subclasses

		/**
		 * @private
		 */
		public function get proxyTarget ():IEventDispatcher
		{
			return _proxyTarget;
		}

		/**
		 * @inheritDoc
		 */
		public function set proxyTarget (value:IEventDispatcher):void
		{
			if (_proxyTarget != value)
			{
				_proxyTarget = value;
				updateProxyListeners();
			}
		}

		////////////////////////////////////////////////////////////////////////
		//	PROXY
		////////////////////////////////////////////////////////////////////////

		/**
		 * @private
		 */
		private var _proxy:IEventDispatcher;

		/**
		 * @private
		 */
		public function get proxy ():IEventDispatcher
		{
			return _proxy;
		}

		/**
		 * @inheritDoc
		 */
		public function set proxy (target:IEventDispatcher):void
		{
			if (_proxy != target)
			{
				_proxy = target;
				eventDispatcher = new EventDispatcher(_proxy);
			}
		}

		////////////////////////////////////////////////////////////////////////
		//	CONSTRUCTOR
		////////////////////////////////////////////////////////////////////////

		/**
		 * Constructor
		 */
		public function EventDispatcherProxy ()
		{
			proxy = this;
		}

		////////////////////////////////////////////////////////////////////////
		//	LISTENER HASH
		////////////////////////////////////////////////////////////////////////

		/**
		 * @private
		 *
		 * A hash table following a basic format:
		 *
		 * hash[eventType] = ListenerHash() - a collection of listener objects with some convenience methods.
		 */
		private var listenerHashTable:Object = {};

		/**
		 * @private
		 *
		 * Adds a listener for a given event type.
		 */
		private function setListenerHashProperty (type:String, listener:Function):void
		{
			var hash:ListenerHash;
			if (!listenerHashTable.hasOwnProperty(type))
			{
				hash = new ListenerHash();
				hash.addListener(listener);

				listenerHashTable[type] = hash;
			}

			else
			{
				hash = ListenerHash(listenerHashTable[type]);
				hash.addListener(listener);
			}
		}

		/**
		 * @private
		 *
		 * Checks to see if a particular event type has been set up within the hash table.
		 */
		private function hasListenerHashProperty (type:String):Boolean
		{
			return listenerHashTable.hasOwnProperty(type);
		}

		/**
		 * @private
		 *
		 * Returns an array of listeners for a given event type.
		 */
		private function getListenersForEventType (type:String):Array
		{
			if (listenerHashTable.hasOwnProperty(type))
				return ListenerHash(listenerHashTable[type]).listeners;

			else
				return [];
		}

		/**
		 * @private
		 *
		 * Removes the listeners and the event type from the hash table.
		 */
		private function removeListenerHashProperty (type:String):Boolean
		{
			if (listenerHashTable.hasOwnProperty(type))
			{
				listenerHashTable[type] = null;
				delete listenerHashTable[type];

				return true;
			}

			return false;
		}

		////////////////////////////////////////////////////////////////////////
		//	MISC. PROXY METHODS
		////////////////////////////////////////////////////////////////////////

		/**
		 * @private
		 *
		 * An array of events to check against that could be dispatched from an interactive target.
		 */
		public var interceptedEventTypes:Array = generateEventTypes();

		/**
		 * Creates an array of interactive object events to check against during event proxying.
		 * To add more event types to check for, subclasses should override this.
		 *
		 * @return Array An array of event types.
		 */
		protected function generateEventTypes ():Array
		{
			var evtTypes:Array = [];
			evtTypes.push
			(
				//REGULAR EVENTS
				Event.ADDED,
				Event.ADDED_TO_STAGE,
				Event.ENTER_FRAME,
				Event.REMOVED,
				Event.REMOVED_FROM_STAGE,
				Event.RENDER,
				Event.TAB_CHILDREN_CHANGE,
				Event.TAB_ENABLED_CHANGE,
				Event.TAB_INDEX_CHANGE,

				//FOCUS EVENTS
				FocusEvent.FOCUS_IN,
				FocusEvent.FOCUS_OUT,
				FocusEvent.KEY_FOCUS_CHANGE,
				FocusEvent.MOUSE_FOCUS_CHANGE,

				//MOUSE EVENTS
				MouseEvent.CLICK,
				MouseEvent.DOUBLE_CLICK,
				MouseEvent.MOUSE_DOWN,
				MouseEvent.MOUSE_MOVE,
				MouseEvent.MOUSE_OUT,
				MouseEvent.MOUSE_OVER,
				MouseEvent.MOUSE_UP,
				MouseEvent.MOUSE_WHEEL,
				MouseEvent.ROLL_OUT,
				MouseEvent.ROLL_OVER,

				//KEYBOARD EVENTS
				KeyboardEvent.KEY_DOWN,
				KeyboardEvent.KEY_UP
			);

			return evtTypes;
		}

		/**
		 * @private
		 *
		 * For a given event type, check to see if it is intended for interception.
		 * InteractiveObject event types will return true since the non-visual class that proxies the proxyTarget needs to dispatch those events on the target's behalf.
		 */
		private function checkForInteceptedEventType (type:String):Boolean
		{
			var evtType:String;
			for each (evtType in interceptedEventTypes)
			{
				if (type == evtType)
					return true;
			}

			return false;
		}

		/**
		 * @private
		 *
		 * A generic event handler that stops event propogation of InteractiveObject event types.
		 * Once stopped, it checks for listeners for the given event type and triggers them.
		 *
		 * Depending on specific developer needs, this method can be overridden by subclasses.
		 */
		protected function eventDelegateFunction (evt:Event):void
		{
			evt.stopImmediatePropagation(); //prevent from further bubbling up thru display list
			var pEvt:ProxyEvent = new ProxyEvent(proxy, evt);
			pEvt.proxyTarget = proxyTarget;

			var func:Function;
			var listeners:Array;
			if (hasListenerHashProperty(evt.type))
			{
				listeners = getListenersForEventType(evt.type);
				for each (func in listeners)
					func.call(this, pEvt);
			}
		}

		/**
		 * A flag indicating if the queue is a one-time use, where other visual assets may not receive the same handlers.
		 */
		public var deleteQueueAfterUpdate:Boolean = true;

		/**
		 * If a proxyTarget has not been set, then a queue of event handlers has been set up.
		 * Once the proxyTarget is created, it iterates through each queue item and assigns the listeners.
		 */
		protected function updateProxyListeners ():void
		{
			var queueItem:Object
			for each (queueItem in _proxyTargetListenerQueue)
				proxyTarget.addEventListener(queueItem.type, eventDelegateFunction, queueItem.useCapture, queueItem.priority, queueItem.useWeakReference);

			if (deleteQueueAfterUpdate)
				_proxyTargetListenerQueue = [];
		}

		////////////////////////////////////////////////////////////////////////
		//	EVENT DISPATCHER HOOKS
		////////////////////////////////////////////////////////////////////////

		/**
		 * @private
		 *
		 * A queue of events a proxy target will listen for and hand off to the proxy.
		 */
		private var _proxyTargetListenerQueue:Array = [];

		/**
		 * @private
		 */
		private var eventDispatcher:EventDispatcher;

		/**
		 * @inheritDoc
		 */
		public function hasEventListener (type:String):Boolean
		{
			if (checkForInteceptedEventType(type))
			{
				if (proxyTarget)
					return proxyTarget.hasEventListener(type);

				else
					return false;
			}

			else
				return eventDispatcher.hasEventListener(type);
		}

		/**
		 * @inheritDoc
		 */
		public function willTrigger (type:String):Boolean
		{
			if (checkForInteceptedEventType(type))
			{
				if (proxyTarget)
					return proxyTarget.willTrigger(type);

				else
					return false;
			}

			else
				return eventDispatcher.willTrigger(type);
		}

		/**
		 * @inheritDoc
		 */
		public function addEventListener (type:String, listener:Function, useCapture:Boolean = false, priority:int = 0.0, useWeakReference:Boolean = false):void
		{
			if (checkForInteceptedEventType(type))
			{
				setListenerHashProperty(type, listener);

				if (proxyTarget)
					proxyTarget.addEventListener(type, eventDelegateFunction, useCapture, priority, useWeakReference);

				else
				{
					var queueItem:Object = {type:type, useCapture:useCapture, priority:priority, useWeakReference:useWeakReference};
					_proxyTargetListenerQueue.push(queueItem);
				}
			}

			else
				eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
		}

		/**
		 * @inheritDoc
		 */
		public function removeEventListener (type:String, listener:Function, useCapture:Boolean = false):void
		{
			if (checkForInteceptedEventType(type))
			{
				if (hasListenerHashProperty(type))
				{
					removeListenerHashProperty(type);

					if (proxyTarget)
						proxyTarget.removeEventListener(type ,eventDelegateFunction, useCapture);

					else
					{
						var quequeItem:Object;

						var i:uint;
						var l:uint = _proxyTargetListenerQueue.length;
						for (i; i < l; i++)
						{
							quequeItem = _proxyTargetListenerQueue[i];
							if (quequeItem.type == type)
							{
								_proxyTargetListenerQueue.splice(i, 1);
								return;
							}
						}
					}
				}
			}

			else
				eventDispatcher.addEventListener(type, listener, useCapture);
		}

		/**
		 * @inheritDoc
		 */
		public function dispatchEvent (event:Event):Boolean
		{
			if (event.bubbles || checkForInteceptedEventType(event.type))
				return proxyTarget.dispatchEvent(new ProxyEvent(this, event));

			else
				return eventDispatcher.dispatchEvent(event);
		}
	}
}

/*

as3isolib - An open-source ActionScript 3.0 Isometric Library developed to assist
in creating isometrically projected content (such as games and graphics)
targeted for the Flash player platform

http://code.google.com/p/as3isolib/

Copyright (c) 2006 - 2008 J.W.Opitz, All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

*/
package eDpLib.events
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.FocusEvent;
	import flash.events.IEventDispatcher;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;

	/**
	 * EventDispatcherProxy provides a means for intercepting events on behalf of a target and redispatching them as the target of the event.
	 */
	public class EventDispatcherProxy implements IEventDispatcher, IEventDispatcherProxy
	{
		////////////////////////////////////////////////////////////////////////
		//	PROXY TARGET
		////////////////////////////////////////////////////////////////////////

		/**
		 * @private
		 */
		private var _proxyTarget:IEventDispatcher; //the item that we are intercepting and redispatching, this being the target, should be set in subclasses

		/**
		 * @private
		 */
		public function get proxyTarget ():IEventDispatcher
		{
			return _proxyTarget;
		}

		/**
		 * @inheritDoc
		 */
		public function set proxyTarget (value:IEventDispatcher):void
		{
			if (_proxyTarget != value)
			{
				_proxyTarget = value;
				updateProxyListeners();
			}
		}

		////////////////////////////////////////////////////////////////////////
		//	PROXY
		////////////////////////////////////////////////////////////////////////

		/**
		 * @private
		 */
		private var _proxy:IEventDispatcher;

		/**
		 * @private
		 */
		public function get proxy ():IEventDispatcher
		{
			return _proxy;
		}

		/**
		 * @inheritDoc
		 */
		public function set proxy (target:IEventDispatcher):void
		{
			if (_proxy != target)
			{
				_proxy = target;
				eventDispatcher = new EventDispatcher(_proxy);
			}
		}

		////////////////////////////////////////////////////////////////////////
		//	CONSTRUCTOR
		////////////////////////////////////////////////////////////////////////

		/**
		 * Constructor
		 */
		public function EventDispatcherProxy ()
		{
			proxy = this;
		}

		////////////////////////////////////////////////////////////////////////
		//	LISTENER HASH
		////////////////////////////////////////////////////////////////////////

		/**
		 * @private
		 *
		 * A hash table following a basic format:
		 *
		 * hash[eventType] = ListenerHash() - a collection of listener objects with some convenience methods.
		 */
		private var listenerHashTable:Object = {};

		/**
		 * @private
		 *
		 * Adds a listener for a given event type.
		 */
		private function setListenerHashProperty (type:String, listener:Function):void
		{
			var hash:ListenerHash;
			if (!listenerHashTable.hasOwnProperty(type))
			{
				hash = new ListenerHash();
				hash.addListener(listener);

				listenerHashTable[type] = hash;
			}

			else
			{
				hash = ListenerHash(listenerHashTable[type]);
				hash.addListener(listener);
			}
		}

		/**
		 * @private
		 *
		 * Checks to see if a particular event type has been set up within the hash table.
		 */
		private function hasListenerHashProperty (type:String):Boolean
		{
			return listenerHashTable.hasOwnProperty(type);
		}

		/**
		 * @private
		 *
		 * Returns an array of listeners for a given event type.
		 */
		private function getListenersForEventType (type:String):Array
		{
			if (listenerHashTable.hasOwnProperty(type))
				return ListenerHash(listenerHashTable[type]).listeners;

			else
				return [];
		}

		/**
		 * @private
		 *
		 * Removes the listeners and the event type from the hash table.
		 */
		private function removeListenerHashProperty (type:String):Boolean
		{
			if (listenerHashTable.hasOwnProperty(type))
			{
				listenerHashTable[type] = null;
				delete listenerHashTable[type];

				return true;
			}

			return false;
		}

		////////////////////////////////////////////////////////////////////////
		//	MISC. PROXY METHODS
		////////////////////////////////////////////////////////////////////////

		/**
		 * @private
		 *
		 * An array of events to check against that could be dispatched from an interactive target.
		 */
		public var interceptedEventTypes:Array = generateEventTypes();

		/**
		 * Creates an array of interactive object events to check against during event proxying.
		 * To add more event types to check for, subclasses should override this.
		 *
		 * @return Array An array of event types.
		 */
		protected function generateEventTypes ():Array
		{
			var evtTypes:Array = [];
			evtTypes.push
			(
				//REGULAR EVENTS
				Event.ADDED,
				Event.ADDED_TO_STAGE,
				Event.ENTER_FRAME,
				Event.REMOVED,
				Event.REMOVED_FROM_STAGE,
				Event.RENDER,
				Event.TAB_CHILDREN_CHANGE,
				Event.TAB_ENABLED_CHANGE,
				Event.TAB_INDEX_CHANGE,

				//FOCUS EVENTS
				FocusEvent.FOCUS_IN,
				FocusEvent.FOCUS_OUT,
				FocusEvent.KEY_FOCUS_CHANGE,
				FocusEvent.MOUSE_FOCUS_CHANGE,

				//MOUSE EVENTS
				MouseEvent.CLICK,
				MouseEvent.DOUBLE_CLICK,
				MouseEvent.MOUSE_DOWN,
				MouseEvent.MOUSE_MOVE,
				MouseEvent.MOUSE_OUT,
				MouseEvent.MOUSE_OVER,
				MouseEvent.MOUSE_UP,
				MouseEvent.MOUSE_WHEEL,
				MouseEvent.ROLL_OUT,
				MouseEvent.ROLL_OVER,

				//KEYBOARD EVENTS
				KeyboardEvent.KEY_DOWN,
				KeyboardEvent.KEY_UP
			);

			return evtTypes;
		}

		/**
		 * @private
		 *
		 * For a given event type, check to see if it is intended for interception.
		 * InteractiveObject event types will return true since the non-visual class that proxies the proxyTarget needs to dispatch those events on the target's behalf.
		 */
		private function checkForInteceptedEventType (type:String):Boolean
		{
			var evtType:String;
			for each (evtType in interceptedEventTypes)
			{
				if (type == evtType)
					return true;
			}

			return false;
		}

		/**
		 * @private
		 *
		 * A generic event handler that stops event propogation of InteractiveObject event types.
		 * Once stopped, it checks for listeners for the given event type and triggers them.
		 *
		 * Depending on specific developer needs, this method can be overridden by subclasses.
		 */
		protected function eventDelegateFunction (evt:Event):void
		{
			evt.stopImmediatePropagation(); //prevent from further bubbling up thru display list
			var pEvt:ProxyEvent = new ProxyEvent(proxy, evt);
			pEvt.proxyTarget = proxyTarget;

			var func:Function;
			var listeners:Array;
			if (hasListenerHashProperty(evt.type))
			{
				listeners = getListenersForEventType(evt.type);
				for each (func in listeners)
					func.call(this, pEvt);
			}
		}

		/**
		 * A flag indicating if the queue is a one-time use, where other visual assets may not receive the same handlers.
		 */
		public var deleteQueueAfterUpdate:Boolean = true;

		/**
		 * If a proxyTarget has not been set, then a queue of event handlers has been set up.
		 * Once the proxyTarget is created, it iterates through each queue item and assigns the listeners.
		 */
		protected function updateProxyListeners ():void
		{
			var queueItem:Object
			for each (queueItem in _proxyTargetListenerQueue)
				proxyTarget.addEventListener(queueItem.type, eventDelegateFunction, queueItem.useCapture, queueItem.priority, queueItem.useWeakReference);

			if (deleteQueueAfterUpdate)
				_proxyTargetListenerQueue = [];
		}

		////////////////////////////////////////////////////////////////////////
		//	EVENT DISPATCHER HOOKS
		////////////////////////////////////////////////////////////////////////

		/**
		 * @private
		 *
		 * A queue of events a proxy target will listen for and hand off to the proxy.
		 */
		private var _proxyTargetListenerQueue:Array = [];

		/**
		 * @private
		 */
		private var eventDispatcher:EventDispatcher;

		/**
		 * @inheritDoc
		 */
		public function hasEventListener (type:String):Boolean
		{
			if (checkForInteceptedEventType(type))
			{
				if (proxyTarget)
					return proxyTarget.hasEventListener(type);

				else
					return false;
			}

			else
				return eventDispatcher.hasEventListener(type);
		}

		/**
		 * @inheritDoc
		 */
		public function willTrigger (type:String):Boolean
		{
			if (checkForInteceptedEventType(type))
			{
				if (proxyTarget)
					return proxyTarget.willTrigger(type);

				else
					return false;
			}

			else
				return eventDispatcher.willTrigger(type);
		}

		/**
		 * @inheritDoc
		 */
		public function addEventListener (type:String, listener:Function, useCapture:Boolean = false, priority:int = 0.0, useWeakReference:Boolean = false):void
		{
			if (checkForInteceptedEventType(type))
			{
				setListenerHashProperty(type, listener);

				if (proxyTarget)
					proxyTarget.addEventListener(type, eventDelegateFunction, useCapture, priority, useWeakReference);

				else
				{
					var queueItem:Object = {type:type, useCapture:useCapture, priority:priority, useWeakReference:useWeakReference};
					_proxyTargetListenerQueue.push(queueItem);
				}
			}

			else
				eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
		}

		/**
		 * @inheritDoc
		 */
		public function removeEventListener (type:String, listener:Function, useCapture:Boolean = false):void
		{
			if (checkForInteceptedEventType(type))
			{
				if (hasListenerHashProperty(type))
				{
					removeListenerHashProperty(type);

					if (proxyTarget)
						proxyTarget.removeEventListener(type ,eventDelegateFunction, useCapture);

					else
					{
						var quequeItem:Object;

						var i:uint;
						var l:uint = _proxyTargetListenerQueue.length;
						for (i; i < l; i++)
						{
							quequeItem = _proxyTargetListenerQueue[i];
							if (quequeItem.type == type)
							{
								_proxyTargetListenerQueue.splice(i, 1);
								return;
							}
						}
					}
				}
			}

			else
				eventDispatcher.removeEventListener(type, listener, useCapture);
		}

		/**
		 * @inheritDoc
		 */
		public function dispatchEvent (event:Event):Boolean
		{
			if (event.bubbles || checkForInteceptedEventType(event.type))
				return proxyTarget.dispatchEvent(new ProxyEvent(this, event));

			else
				return eventDispatcher.dispatchEvent(event);
		}
	}
}

fix for fp9 trunk

fix for fp9 trunk


//
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.util {

import flash.utils.ByteArray;
import flash.utils.getQualifiedClassName;

public class Util
{
    /**
     * Initialize the target object with values present in the initProps object and the defaults
     * object. Neither initProps nor defaults will be modified.
     * @throws ReferenceError if a property cannot be set on the target object.
     *
     * @param target any object or class instance.
     * @param initProps a plain Object hash containing names and properties to set on the target
     *                  object.
     * @param defaults a plain Object hash containing names and properties to set on the target
     *                 object, only if the same property name does not exist in initProps.
     * @param maskProps a plain Object hash containing names of properties to omit setting
     *                  from the initProps object. This allows you to add custom properties to
     *                  initProps without having to modify the value from your callers.
     */
    public static function init (
        target :Object, initProps :Object, defaults :Object = null, maskProps :Object = null) :void
    {
        var prop :String;
        for (prop in initProps) {
            if (maskProps == null || !(prop in maskProps)) {
                target[prop] = initProps[prop];
            }
        }

        if (defaults != null) {
            for (prop in defaults) {
                if (initProps == null || !(prop in initProps)) {
                    target[prop] = defaults[prop];
                }
            }
        }
    }

    /**
     * Returns true if the specified object is just a regular old associative hash.
     */
    public static function isPlainObject (obj :Object) :Boolean
    {
        return getQualifiedClassName(obj) == "Object";
    }

    /**
     * Is the specified object 'simple': one of the basic built-in flash types.
     */
    public static function isSimple (obj :Object) :Boolean
    {
        var type :String = typeof(obj);
        switch (type) {
        case "number":
        case "string":
        case "boolean":
            return true;

        case "object":
            return (obj is Date) || (obj is Array);

        default:
            return false;
        }
    }

    /**
     * Get an array containing the property keys of the specified object, in their
     * natural iteration order.
     */
    public static function keys (obj :Object) :Array
    {
        var arr :Array = [];
        for (var k :* in obj) { // no "each": iterate over keys
            arr.push(k);
        }
        return arr;
    }

    /**
     * Get an array containing the property values of the specified object, in their
     * natural iteration order.
     */
    public static function values (obj :Object) :Array
    {
        var arr :Array = [];
        for each (var v :* in obj) { // "each" iterates over values
            arr.push(v);
        }
        return arr;
    }

    /**
     * Parse the 'value' object into XML safely. This is equivalent to new XML(value)
     * but offers protection from other code that may have changing the default settings
     * used for parsing XML. Also, if you would like to use non-standard parsing settings
     * this method will protect other code from being broken by you.
     *
     * @param value the value to parse into XML.
     * @param settings an Object containing your desired XML settings, or null (or omitted) to
     * use the default settings.
     * @see XML#setSettings()
     */
    public static function newXML (value :Object, settings :Object = null) :XML
    {
        return safeXMLOp(function () :* {
            return new XML(value);
        }, settings) as XML;
    }

    /**
     * Call toString() on the specified XML object safely. This is equivalent to
     * xml.toString() but offers protection from other code that may have changed
     * the default settings used for stringing XML. Also, if you would like to use the
     * non-standard printing settings this method will protect other code from being
     * broken by you.
     *
     * @param xml the xml value to Stringify.
     * @param settings an Object containing your desired XML settings, or null (or omitted) to
     * use the default settings.
     * @see XML#toString()
     * @see XML#setSettings()
     */
    public static function XMLtoString (xml :XML, settings :Object = null) :String
    {
        return safeXMLOp(function () :* {
            return xml.toString();
        }, settings) as String;
    }

    /**
     * Call toXMLString() on the specified XML object safely. This is equivalent to
     * xml.toXMLString() but offers protection from other code that may have changed
     * the default settings used for stringing XML. Also, if you would like to use the
     * non-standard printing settings this method will protect other code from being
     * broken by you.
     *
     * @param xml the xml value to Stringify.
     * @param settings an Object containing your desired XML settings, or null (or omitted) to
     * use the default settings.
     * @see XML#toXMLString()
     * @see XML#setSettings()
     */
    public static function XMLtoXMLString (xml :XML, settings :Object = null) :String
    {
        return safeXMLOp(function () :* {
            return xml.toXMLString();
        }, settings) as String;
    }

    /**
     * Perform an operation on XML that takes place using the specified settings, and
     * restores the XML settings to their previous values.
     *
     * @param fn a function to be called with no arguments.
     * @param settings an Object containing your desired XML settings, or null (or omitted) to
     * use the default settings.
     *
     * @return the return value of your function, if any.
     * @see XML#setSettings()
     * @see XML#settings()
     */
    public static function safeXMLOp (fn :Function, settings :Object = null) :*
    {
        var oldSettings :Object = XML.settings();
        try {
            XML.setSettings(settings); // setting to null resets to all the defaults
            return fn();
        } finally {
            XML.setSettings(oldSettings);
        }
    }

    /**
     * A nice utility method for testing equality in a better way.
     * If the objects are Equalable, then that will be tested. Arrays
     * and ByteArrays are also compared and are equal if they have
     * elements that are equals (deeply).
     */
    public static function equals (obj1 :Object, obj2 :Object) :Boolean
    {
        // catch various common cases (both primitive or null)
        if (obj1 === obj2) {
            return true;

        } else if (obj1 is Equalable) {
            // if obj1 is Equalable, then that decides it
            return (obj1 as Equalable).equals(obj2);

        } else if ((obj1 is Array) && (obj2 is Array)) {
            return ArrayUtil.equals(obj1 as Array, obj2 as Array);

        } else if ((obj1 is ByteArray) && (obj2 is ByteArray)) {
            var ba1 :ByteArray = (obj1 as ByteArray);
            var ba2 :ByteArray = (obj2 as ByteArray);
            if (ba1.length != ba2.length) {
                return false;
            }
            for (var ii :int = 0; ii < ba1.length; ii++) {
                if (ba1[ii] != ba2[ii]) {
                    return false;
                }
            }
            return true;
        }

        return false;
    }

    /**
     * If you call a varargs method by passing it an array, the array
     * will end up being arg 1.
     */
    public static function unfuckVarargs (args :Array) :Array
    {
        return (args.length == 1 && (args[0] is Array)) ? (args[0] as Array)
                                                        : args;
    }
}
}

//
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.util {

import flash.utils.ByteArray;
import flash.utils.getQualifiedClassName;

public class Util
{
    /**
     * Initialize the target object with values present in the initProps object and the defaults
     * object. Neither initProps nor defaults will be modified.
     * @throws ReferenceError if a property cannot be set on the target object.
     *
     * @param target any object or class instance.
     * @param initProps a plain Object hash containing names and properties to set on the target
     *                  object.
     * @param defaults a plain Object hash containing names and properties to set on the target
     *                 object, only if the same property name does not exist in initProps.
     * @param maskProps a plain Object hash containing names of properties to omit setting
     *                  from the initProps object. This allows you to add custom properties to
     *                  initProps without having to modify the value from your callers.
     */
    public static function init (
        target :Object, initProps :Object, defaults :Object = null, maskProps :Object = null) :void
    {
        var prop :String;
        for (prop in initProps) {
            if (maskProps == null || !(prop in maskProps)) {
                target[prop] = initProps[prop];
            }
        }

        if (defaults != null) {
            for (prop in defaults) {
                if (initProps == null || !(prop in initProps)) {
                    target[prop] = defaults[prop];
                }
            }
        }
    }

    /**
     * Return a var-args function that will attempt to pass only the arguments accepted by the
     * passed-in function. Does not work if the passed-in function is varargs, and anyway
     * then you don't need adapting, do you?
     */
    public static function adapt (fn :Function) :Function
    {
        return function (... args) :* {
            args.length = fn.length; // fit the args to the fn, filling in 'undefined' if growing
            return fn.apply(null, args);
        }
    }

    /**
     * Returns true if the specified object is just a regular old associative hash.
     */
    public static function isPlainObject (obj :Object) :Boolean
    {
        return getQualifiedClassName(obj) == "Object";
    }

    /**
     * Is the specified object 'simple': one of the basic built-in flash types.
     */
    public static function isSimple (obj :Object) :Boolean
    {
        var type :String = typeof(obj);
        switch (type) {
        case "number":
        case "string":
        case "boolean":
            return true;

        case "object":
            return (obj is Date) || (obj is Array);

        default:
            return false;
        }
    }

    /**
     * Get an array containing the property keys of the specified object, in their
     * natural iteration order.
     */
    public static function keys (obj :Object) :Array
    {
        var arr :Array = [];
        for (var k :* in obj) { // no "each": iterate over keys
            arr.push(k);
        }
        return arr;
    }

    /**
     * Get an array containing the property values of the specified object, in their
     * natural iteration order.
     */
    public static function values (obj :Object) :Array
    {
        var arr :Array = [];
        for each (var v :* in obj) { // "each" iterates over values
            arr.push(v);
        }
        return arr;
    }

    /**
     * Parse the 'value' object into XML safely. This is equivalent to new XML(value)
     * but offers protection from other code that may have changing the default settings
     * used for parsing XML. Also, if you would like to use non-standard parsing settings
     * this method will protect other code from being broken by you.
     *
     * @param value the value to parse into XML.
     * @param settings an Object containing your desired XML settings, or null (or omitted) to
     * use the default settings.
     * @see XML#setSettings()
     */
    public static function newXML (value :Object, settings :Object = null) :XML
    {
        return safeXMLOp(function () :* {
            return new XML(value);
        }, settings) as XML;
    }

    /**
     * Call toString() on the specified XML object safely. This is equivalent to
     * xml.toString() but offers protection from other code that may have changed
     * the default settings used for stringing XML. Also, if you would like to use the
     * non-standard printing settings this method will protect other code from being
     * broken by you.
     *
     * @param xml the xml value to Stringify.
     * @param settings an Object containing your desired XML settings, or null (or omitted) to
     * use the default settings.
     * @see XML#toString()
     * @see XML#setSettings()
     */
    public static function XMLtoString (xml :XML, settings :Object = null) :String
    {
        return safeXMLOp(function () :* {
            return xml.toString();
        }, settings) as String;
    }

    /**
     * Call toXMLString() on the specified XML object safely. This is equivalent to
     * xml.toXMLString() but offers protection from other code that may have changed
     * the default settings used for stringing XML. Also, if you would like to use the
     * non-standard printing settings this method will protect other code from being
     * broken by you.
     *
     * @param xml the xml value to Stringify.
     * @param settings an Object containing your desired XML settings, or null (or omitted) to
     * use the default settings.
     * @see XML#toXMLString()
     * @see XML#setSettings()
     */
    public static function XMLtoXMLString (xml :XML, settings :Object = null) :String
    {
        return safeXMLOp(function () :* {
            return xml.toXMLString();
        }, settings) as String;
    }

    /**
     * Perform an operation on XML that takes place using the specified settings, and
     * restores the XML settings to their previous values.
     *
     * @param fn a function to be called with no arguments.
     * @param settings an Object containing your desired XML settings, or null (or omitted) to
     * use the default settings.
     *
     * @return the return value of your function, if any.
     * @see XML#setSettings()
     * @see XML#settings()
     */
    public static function safeXMLOp (fn :Function, settings :Object = null) :*
    {
        var oldSettings :Object = XML.settings();
        try {
            XML.setSettings(settings); // setting to null resets to all the defaults
            return fn();
        } finally {
            XML.setSettings(oldSettings);
        }
    }

    /**
     * A nice utility method for testing equality in a better way.
     * If the objects are Equalable, then that will be tested. Arrays
     * and ByteArrays are also compared and are equal if they have
     * elements that are equals (deeply).
     */
    public static function equals (obj1 :Object, obj2 :Object) :Boolean
    {
        // catch various common cases (both primitive or null)
        if (obj1 === obj2) {
            return true;

        } else if (obj1 is Equalable) {
            // if obj1 is Equalable, then that decides it
            return (obj1 as Equalable).equals(obj2);

        } else if ((obj1 is Array) && (obj2 is Array)) {
            return ArrayUtil.equals(obj1 as Array, obj2 as Array);

        } else if ((obj1 is ByteArray) && (obj2 is ByteArray)) {
            var ba1 :ByteArray = (obj1 as ByteArray);
            var ba2 :ByteArray = (obj2 as ByteArray);
            if (ba1.length != ba2.length) {
                return false;
            }
            for (var ii :int = 0; ii < ba1.length; ii++) {
                if (ba1[ii] != ba2[ii]) {
                    return false;
                }
            }
            return true;
        }

        return false;
    }

    /**
     * If you call a varargs method by passing it an array, the array
     * will end up being arg 1.
     */
    public static function unfuckVarargs (args :Array) :Array
    {
        return (args.length == 1 && (args[0] is Array)) ? (args[0] as Array)
                                                        : args;
    }
}
}

Check this out. This little buddy rocks.
I sorta want to make a new FunctionUtil so that I can use it
with impunity everwhere without having to include the other crap in here.

git-svn-id: a1a4b28b82a3276cc491891159dd9963a0a72fae@5730 542714f4-19e9-0310-aa3c-eee0fc999fb1


import mx.transitions.easing.*;
import com.mosesSupposes.fuse.*;

	class menuIdiomes extends MovieClip

	{
		public var fr:MovieClip;

		public function menuIdiomes ()
		{
			this.onRollOver = this.over;
			this.onRollOut = this.out;
			this.onRelease =this.over;
		}

		private function over ()
		{
			fr.colorTo ("#95C60D", 0.3, "easeOutCirc");
		}

		private function out ()
		{
			fr.colorTo ("#010101", 0.3, "easeInCirc");
		}

	}

Update menuIdiomes.as

Update menuIdiomes.as


/*
Copyright 2016 Bowler Hat LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
{
	import com.nextgenactionscript.asconfigc.ASConfigFields;
	import com.nextgenactionscript.asconfigc.CompilerOptions;
	import com.nextgenactionscript.asconfigc.CompilerOptionsParser;
	import com.nextgenactionscript.asconfigc.ConfigName;
	import com.nextgenactionscript.asconfigc.JSOutputType;
	import com.nextgenactionscript.asconfigc.ProjectType;
	import com.nextgenactionscript.flexjs.utils.ApacheFlexJSUtils;
	import com.nextgenactionscript.utils.ActionScriptSDKUtils;

	/**
	 * A command line utility to build a project defined with an asconfig.json
	 * file using the Apache FlexJS SDK.
	 */
	public class ASConfigC
	{
		private static const ASCONFIG_JSON:String = "asconfig.json";

		private static const MXMLC_JARS:Vector.<String> = new <String>
		[
			"falcon-mxmlc.jar",
			"mxmlc-cli.jar",
			"mxmlc.jar",
		];

		private static const COMPC_JARS:Vector.<String> = new <String>
		[
			"falcon-compc.jar",
			"compc-cli.jar",
			"compc.jar",
		];

		public function ASConfigC()
		{
			this.parseArguments();
			if(!this._javaExecutable)
			{
				this._javaExecutable = ApacheFlexJSUtils.findJava();
				if(!this._javaExecutable)
				{
					console.error("Java not found. Cannot run compiler without Java.");
					process.exit(1);
				}
			}
			if(!this._configFilePath)
			{
				//try to find asconfig.json in the current working directory
				var cwdConfigPath:String = path.resolve(process.cwd(), ASCONFIG_JSON);
				if(fs.existsSync(cwdConfigPath))
				{
					this._configFilePath = cwdConfigPath;
				}
				else
				{
					//asconfig.json not found
					this.printUsage();
					process.exit(0);
				}
			}
			process.chdir(path.dirname(this._configFilePath));

			this.parseConfig();
			//validate the SDK after knowing if we're building SWF or JS
			//because JS has stricter SDK requirements
			this.validateSDK();
			this.compileProject();
		}

		private var _flexHome:String;
		private var _javaExecutable:String;
		private var _configFilePath:String;
		private var _projectType:String;
		private var _jsOutputType:String;
		private var _isSWF:Boolean;
		private var _args:Array;

		private function printVersion():void
		{
			var packageJSONString:String = fs.readFileSync(path.join(__dirname, "..", "..", "package.json"), "utf8") as String;
			var packageJSON:Object = JSON.parse(packageJSONString);
			console.info("Version: " + packageJSON.version);
		}

		private function printUsage():void
		{
			this.printVersion();
			console.info("Syntax:   asconfigc [options]");
			console.info();
			console.info("Examples: asconfigc -p .");
			console.info("          asconfigc -p path/to/project");
			console.info();
			console.info("Options:");
			console.info(" -h, --help                          Print this help message.");
			console.info(" -v, --version                       Print the version.");
			console.info(" -p DIRECTORY, --project DIRECTORY   Compile the asconfig.json project in the given directory. If omitted, will look for asconfig.json in current directory.");
			console.info(" --flexHome DIRECTORY                Specify the directory where Apache FlexJS is located. Defaults to checking FLEX_HOME and PATH environment variables.");
		}

		private function parseArguments():void
		{
			var args:Object = minimist(process.argv.slice(2),
			{
				alias:
				{
					h: ["help"],
					p: ["project"],
					v: ["version"]
				}
			});
			for(var key:String in args)
			{
				switch(key)
				{
					case "h":
					case "p":
					case "v":
					{
						//ignore aliases
						break;
					}
					case "_":
					{
						var value:String = args[key] as String;
						if(value)
						{
							console.error("Unknown argument: " + value);
							process.exit(1);
						}
						break;
					}
					case "help":
					{
						this.printUsage();
						process.exit(0);
						break;
					}
					case "flexHome":
					{
						this._flexHome = args[key] as String;
						break;
					}
					case "project":
					{
						var projectDirectoryPath:String = args[key] as String;
						projectDirectoryPath = path.resolve(process.cwd(), projectDirectoryPath);
						if(!fs.existsSync(projectDirectoryPath))
						{
							console.error("Project directory not found: " + projectDirectoryPath);
							process.exit(1);
						}
						if(!fs.statSync(projectDirectoryPath).isDirectory())
						{
							console.error("Project must be a directory: " + projectDirectoryPath);
							process.exit(1);
						}
						var configFilePath:String = path.resolve(projectDirectoryPath, ASCONFIG_JSON);
						if(!fs.existsSync(configFilePath))
						{
							console.error("asconfig.json not found in directory: " + projectDirectoryPath);
							process.exit(1);
						}
						this._configFilePath = configFilePath;
						break;
					}
					case "version":
					{
						this.printVersion();
						process.exit(0);
					}
					default:
					{
						console.error("Unknown argument: " + key);
						process.exit(1);
					}
				}
			}
		}

		private function loadConfig():Object
		{
			var schemaFilePath:String = path.join(__dirname, "..", "..", "schemas", "asconfig.schema.json");
			try
			{
				var schemaText:String = fs.readFileSync(schemaFilePath, "utf8") as String;
			}
			catch(error:Error)
			{
				console.error("Error: Cannot read schema file. " + schemaFilePath);
				process.exit(1);
			}
			try
			{
				var schemaData:Object = JSON.parse(schemaText);
			}
			catch(error:Error)
			{
				console.error("Error: Invalid JSON in schema file. " + schemaFilePath);
				console.error(error);
				process.exit(1);
			}
			try
			{
				var validate:Function = jsen(schemaData);
			}
			catch(error:Error)
			{
				console.error("Error: Invalid schema. " + schemaFilePath);
				console.error(error);
				process.exit(1);
			}
			try
			{
				var configText:String = fs.readFileSync(this._configFilePath, "utf8") as String;
			}
			catch(error:Error)
			{
				console.error("Error: Cannot read file. " + this._configFilePath);
				process.exit(1);
			}
			try
			{
				var configData:Object = JSON.parse(configText);
			}
			catch(error:Error)
			{
				console.error("Error: Invalid JSON in file. " + this._configFilePath);
				console.error(error);
				process.exit(1);
			}
			if(!validate(configData))
			{
				console.error("Error: Invalid asconfig.json file. " + this._configFilePath);
				console.error(validate["errors"]);
				process.exit(1);
			}
			return configData;
		}

		private function parseConfig():void
		{
			this._args = [];
			var configData:Object = this.loadConfig();
			this._projectType = this.readProjectType(configData);
			if(ASConfigFields.CONFIG in configData)
			{
				var configName:String = configData[ASConfigFields.CONFIG] as String;
				this.detectJavaScript(configName);
				this._args.push("+configname=" + configName);
			}
			if(ASConfigFields.COMPILER_OPTIONS in configData)
			{
				var compilerOptions:Object = configData[ASConfigFields.COMPILER_OPTIONS];
				this.readCompilerOptions(compilerOptions);
			}
			if(ASConfigFields.FILES in configData)
			{
				var files:Array = configData[ASConfigFields.FILES] as Array;
				if(this._projectType === ProjectType.LIB)
				{
					CompilerOptionsParser.parse(
					{
						"include-sources": files
					}, this._args);
				}
				else
				{
					var filesCount:int = files.length;
					for(var i:int = 0; i < filesCount; i++)
					{
						var file:String = files[i];
						this._args.push(file);
					}
				}
			}
		}

		private function readProjectType(configData:Object):String
		{
			if(ASConfigFields.TYPE in configData)
			{
				//this was already validated
				return configData[ASConfigFields.TYPE] as String;
			}
			//this field is optional, and this is the default
			return ProjectType.APP;
		}

		private function readCompilerOptions(options:Object):void
		{
			try
			{
				CompilerOptionsParser.parse(options, this._args);
			}
			catch(error:Error)
			{
				console.error(error.message);
				process.exit(1);
			}
			if(CompilerOptions.JS_OUTPUT_TYPE in options)
			{
				//if it is set explicitly, then clear the default
				this._jsOutputType = null;
			}
			else if(this._jsOutputType)
			{
				this._args.push("--" + CompilerOptions.JS_OUTPUT_TYPE + "=" + this._jsOutputType);
			}
		}

		private function detectJavaScript(configName:String):void
		{
			switch(configName)
			{
				case ConfigName.JS:
				{
					this._jsOutputType = JSOutputType.JSC;
					this._isSWF = false;
					break;
				}
				case ConfigName.NODE:
				{
					this._jsOutputType = JSOutputType.NODE;
					this._isSWF = false;
					break;
				}
				case ConfigName.FLEX:
				case ConfigName.AIR:
				case ConfigName.AIRMOBILE:
				{
					this._isSWF = true;
					break;
				}
				default:
				{
					this._jsOutputType = null;
				}
			}
		}

		private function validateSDK():void
		{
			if(this._flexHome)
			{
				//the --flexHome argument was used, so check if it's valid
				if(!ApacheFlexJSUtils.isValidSDK(this._flexHome))
				{
					if(!this._isSWF)
					{
						console.error("Path to Apache FlexJS SDK is not valid: " + this._flexHome);
						process.exit(1);
					}
					else if(!ActionScriptSDKUtils.isValidSDK(this._flexHome))
					{
						console.error("Path to SDK is not valid: " + this._flexHome);
						process.exit(1);
					}
				}
			}
			else
			{
				//the --flexHome argument wasn't passed in, so try to find an SDK
				this._flexHome = ApacheFlexJSUtils.findSDK();
				if(!this._flexHome && this._isSWF)
				{
					//if we're building a SWF, we don't necessarily need
					//FlexJS, so try to find another compatible SDK
					this._flexHome = ActionScriptSDKUtils.findSDK();
				}
				if(!this._flexHome)
				{
					console.error("SDK not found. Set FLEX_HOME, add to PATH, or use --flexHome option.");
					process.exit(1);
				}
			}
		}

		private function findJarPath():String
		{
			var jarPath:String = null;
			var jarNames:Vector.<String> = MXMLC_JARS;
			if(this._projectType === ProjectType.LIB)
			{
				jarNames = COMPC_JARS;
			}
			var jarNamesCount:int = jarNames.length;
			for(var i:int = 0; i < jarNamesCount; i++)
			{
				var jarName:String = jarNames[i];
				if(this._isSWF)
				{
					jarPath = path.join(this._flexHome, "lib", jarName);
				}
				else
				{
					jarPath = path.join(this._flexHome, "js", "lib", jarName);
				}
				if(fs.existsSync(jarPath))
				{
					break;
				}
				jarPath = null;
			}
			return jarPath;
		}

		private function compileProject():void
		{
			var jarPath:String = this.findJarPath();
			if(!jarPath)
			{
				console.error("Compiler not found in SDK. Expected: " + jarPath);
				process.exit(1);
			}
			var frameworkPath:String = path.join(this._flexHome, "frameworks");
			this._args.unshift("+flexlib=" + frameworkPath);
			this._args.unshift(jarPath);
			this._args.unshift("-jar");
			this._args.unshift("-Dflexlib=" + frameworkPath);
			this._args.unshift("-Dflexcompiler=" + this._flexHome);
			try
			{
				var result:Object = child_process.execFileSync(this._javaExecutable, this._args,
				{
					encoding: "utf8"
				});
				console.info(result);
			}
			catch(error:Error)
			{
				process.exit(1);
			}
		}
	}
}

/*
Copyright 2016 Bowler Hat LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
{
	import com.nextgenactionscript.asconfigc.ASConfigFields;
	import com.nextgenactionscript.asconfigc.CompilerOptions;
	import com.nextgenactionscript.asconfigc.CompilerOptionsParser;
	import com.nextgenactionscript.asconfigc.ConfigName;
	import com.nextgenactionscript.asconfigc.JSOutputType;
	import com.nextgenactionscript.asconfigc.ProjectType;
	import com.nextgenactionscript.flexjs.utils.ApacheFlexJSUtils;
	import com.nextgenactionscript.utils.ActionScriptSDKUtils;

	/**
	 * A command line utility to build a project defined with an asconfig.json
	 * file using the Apache FlexJS SDK.
	 */
	public class ASConfigC
	{
		private static const ASCONFIG_JSON:String = "asconfig.json";

		private static const MXMLC_JARS:Vector.<String> = new <String>
		[
			"falcon-mxmlc.jar",
			"mxmlc-cli.jar",
			"mxmlc.jar",
		];

		private static const COMPC_JARS:Vector.<String> = new <String>
		[
			"falcon-compc.jar",
			"compc-cli.jar",
			"compc.jar",
		];

		public function ASConfigC()
		{
			this.parseArguments();
			if(!this._javaExecutable)
			{
				this._javaExecutable = ApacheFlexJSUtils.findJava();
				if(!this._javaExecutable)
				{
					console.error("Java not found. Cannot run compiler without Java.");
					process.exit(1);
				}
			}
			if(!this._configFilePath)
			{
				//try to find asconfig.json in the current working directory
				var cwdConfigPath:String = path.resolve(process.cwd(), ASCONFIG_JSON);
				if(fs.existsSync(cwdConfigPath))
				{
					this._configFilePath = cwdConfigPath;
				}
				else
				{
					//asconfig.json not found
					this.printUsage();
					process.exit(0);
				}
			}
			process.chdir(path.dirname(this._configFilePath));

			this.parseConfig();
			//validate the SDK after knowing if we're building SWF or JS
			//because JS has stricter SDK requirements
			this.validateSDK();
			this.compileProject();
		}

		private var _flexHome:String;
		private var _javaExecutable:String;
		private var _configFilePath:String;
		private var _projectType:String;
		private var _jsOutputType:String;
		private var _isSWF:Boolean;
		private var _args:Array;

		private function printVersion():void
		{
			var packageJSONString:String = fs.readFileSync(path.join(__dirname, "..", "..", "package.json"), "utf8") as String;
			var packageJSON:Object = JSON.parse(packageJSONString);
			console.info("Version: " + packageJSON.version);
		}

		private function printUsage():void
		{
			this.printVersion();
			console.info("Syntax:   asconfigc [options]");
			console.info();
			console.info("Examples: asconfigc -p .");
			console.info("          asconfigc -p path/to/project");
			console.info();
			console.info("Options:");
			console.info(" -h, --help                          Print this help message.");
			console.info(" -v, --version                       Print the version.");
			console.info(" -p DIRECTORY, --project DIRECTORY   Compile the asconfig.json project in the given directory. If omitted, will look for asconfig.json in current directory.");
			console.info(" --flexHome DIRECTORY                Specify the directory where Apache FlexJS is located. Defaults to checking FLEX_HOME and PATH environment variables.");
		}

		private function parseArguments():void
		{
			var args:Object = minimist(process.argv.slice(2),
			{
				alias:
				{
					h: ["help"],
					p: ["project"],
					v: ["version"]
				}
			});
			for(var key:String in args)
			{
				switch(key)
				{
					case "h":
					case "p":
					case "v":
					{
						//ignore aliases
						break;
					}
					case "_":
					{
						var value:String = args[key] as String;
						if(value)
						{
							console.error("Unknown argument: " + value);
							process.exit(1);
						}
						break;
					}
					case "help":
					{
						this.printUsage();
						process.exit(0);
						break;
					}
					case "flexHome":
					{
						this._flexHome = args[key] as String;
						break;
					}
					case "project":
					{
						var projectDirectoryPath:String = args[key] as String;
						projectDirectoryPath = path.resolve(process.cwd(), projectDirectoryPath);
						if(!fs.existsSync(projectDirectoryPath))
						{
							console.error("Project directory not found: " + projectDirectoryPath);
							process.exit(1);
						}
						if(!fs.statSync(projectDirectoryPath).isDirectory())
						{
							console.error("Project must be a directory: " + projectDirectoryPath);
							process.exit(1);
						}
						var configFilePath:String = path.resolve(projectDirectoryPath, ASCONFIG_JSON);
						if(!fs.existsSync(configFilePath))
						{
							console.error("asconfig.json not found in directory: " + projectDirectoryPath);
							process.exit(1);
						}
						this._configFilePath = configFilePath;
						break;
					}
					case "version":
					{
						this.printVersion();
						process.exit(0);
					}
					default:
					{
						console.error("Unknown argument: " + key);
						process.exit(1);
					}
				}
			}
		}

		private function loadConfig():Object
		{
			var schemaFilePath:String = path.join(__dirname, "..", "..", "schemas", "asconfig.schema.json");
			try
			{
				var schemaText:String = fs.readFileSync(schemaFilePath, "utf8") as String;
			}
			catch(error:Error)
			{
				console.error("Error: Cannot read schema file. " + schemaFilePath);
				process.exit(1);
			}
			try
			{
				var schemaData:Object = JSON.parse(schemaText);
			}
			catch(error:Error)
			{
				console.error("Error: Invalid JSON in schema file. " + schemaFilePath);
				console.error(error);
				process.exit(1);
			}
			try
			{
				var validate:Function = jsen(schemaData);
			}
			catch(error:Error)
			{
				console.error("Error: Invalid schema. " + schemaFilePath);
				console.error(error);
				process.exit(1);
			}
			try
			{
				var configText:String = fs.readFileSync(this._configFilePath, "utf8") as String;
			}
			catch(error:Error)
			{
				console.error("Error: Cannot read file. " + this._configFilePath);
				process.exit(1);
			}
			try
			{
				var configData:Object = JSON.parse(configText);
			}
			catch(error:Error)
			{
				console.error("Error: Invalid JSON in file. " + this._configFilePath);
				console.error(error);
				process.exit(1);
			}
			if(!validate(configData))
			{
				console.error("Error: Invalid asconfig.json file. " + this._configFilePath);
				console.error(validate["errors"]);
				process.exit(1);
			}
			return configData;
		}

		private function parseConfig():void
		{
			this._args = [];
			var configData:Object = this.loadConfig();
			this._projectType = this.readProjectType(configData);
			if(ASConfigFields.CONFIG in configData)
			{
				var configName:String = configData[ASConfigFields.CONFIG] as String;
				this.detectJavaScript(configName);
				this._args.push("+configname=" + configName);
			}
			if(ASConfigFields.COMPILER_OPTIONS in configData)
			{
				var compilerOptions:Object = configData[ASConfigFields.COMPILER_OPTIONS];
				this.readCompilerOptions(compilerOptions);
			}
			if(ASConfigFields.FILES in configData)
			{
				var files:Array = configData[ASConfigFields.FILES] as Array;
				if(this._projectType === ProjectType.LIB)
				{
					CompilerOptionsParser.parse(
					{
						"include-sources": files
					}, this._args);
				}
				else
				{
					var filesCount:int = files.length;
					for(var i:int = 0; i < filesCount; i++)
					{
						var file:String = files[i];
						this._args.push(file);
					}
				}
			}
		}

		private function readProjectType(configData:Object):String
		{
			if(ASConfigFields.TYPE in configData)
			{
				//this was already validated
				return configData[ASConfigFields.TYPE] as String;
			}
			//this field is optional, and this is the default
			return ProjectType.APP;
		}

		private function readCompilerOptions(options:Object):void
		{
			try
			{
				CompilerOptionsParser.parse(options, this._args);
			}
			catch(error:Error)
			{
				console.error(error.message);
				process.exit(1);
			}
			if(CompilerOptions.JS_OUTPUT_TYPE in options)
			{
				//if it is set explicitly, then clear the default
				this._jsOutputType = null;
			}
			else if(this._jsOutputType)
			{
				this._args.push("--" + CompilerOptions.JS_OUTPUT_TYPE + "=" + this._jsOutputType);
			}
		}

		private function detectJavaScript(configName:String):void
		{
			switch(configName)
			{
				case ConfigName.JS:
				{
					this._jsOutputType = JSOutputType.JSC;
					this._isSWF = false;
					break;
				}
				case ConfigName.NODE:
				{
					this._jsOutputType = JSOutputType.NODE;
					this._isSWF = false;
					break;
				}
				case ConfigName.FLEX:
				case ConfigName.AIR:
				case ConfigName.AIRMOBILE:
				{
					this._jsOutputType = null;
					this._isSWF = true;
					break;
				}
				default:
				{
					this._jsOutputType = null;
				}
			}
		}

		private function validateSDK():void
		{
			if(this._flexHome)
			{
				//the --flexHome argument was used, so check if it's valid
				if(!ApacheFlexJSUtils.isValidSDK(this._flexHome))
				{
					if(!this._isSWF)
					{
						console.error("Path to Apache FlexJS SDK is not valid: " + this._flexHome);
						process.exit(1);
					}
					else if(!ActionScriptSDKUtils.isValidSDK(this._flexHome))
					{
						console.error("Path to SDK is not valid: " + this._flexHome);
						process.exit(1);
					}
				}
			}
			else
			{
				//the --flexHome argument wasn't passed in, so try to find an SDK
				this._flexHome = ApacheFlexJSUtils.findSDK();
				if(!this._flexHome && this._isSWF)
				{
					//if we're building a SWF, we don't necessarily need
					//FlexJS, so try to find another compatible SDK
					this._flexHome = ActionScriptSDKUtils.findSDK();
				}
				if(!this._flexHome)
				{
					console.error("SDK not found. Set FLEX_HOME, add to PATH, or use --flexHome option.");
					process.exit(1);
				}
			}
		}

		private function findJarPath():String
		{
			var jarPath:String = null;
			var jarNames:Vector.<String> = MXMLC_JARS;
			if(this._projectType === ProjectType.LIB)
			{
				jarNames = COMPC_JARS;
			}
			var jarNamesCount:int = jarNames.length;
			for(var i:int = 0; i < jarNamesCount; i++)
			{
				var jarName:String = jarNames[i];
				if(this._isSWF)
				{
					jarPath = path.join(this._flexHome, "lib", jarName);
				}
				else
				{
					jarPath = path.join(this._flexHome, "js", "lib", jarName);
				}
				if(fs.existsSync(jarPath))
				{
					break;
				}
				jarPath = null;
			}
			return jarPath;
		}

		private function compileProject():void
		{
			var jarPath:String = this.findJarPath();
			if(!jarPath)
			{
				console.error("Compiler not found in SDK. Expected: " + jarPath);
				process.exit(1);
			}
			var frameworkPath:String = path.join(this._flexHome, "frameworks");
			this._args.unshift("+flexlib=" + frameworkPath);
			this._args.unshift(jarPath);
			this._args.unshift("-jar");
			this._args.unshift("-Dflexlib=" + frameworkPath);
			this._args.unshift("-Dflexcompiler=" + this._flexHome);
			try
			{
				var result:Object = child_process.execFileSync(this._javaExecutable, this._args,
				{
					encoding: "utf8"
				});
				console.info(result);
			}
			catch(error:Error)
			{
				process.exit(1);
			}
		}
	}
}

clear js-output-type when compiling a SWF