package com.kemsky.support
{
    import avmplus.getQualifiedClassName;

    import com.kemsky.Stream;

    import org.flexunit.asserts.assertEquals;
    import org.flexunit.asserts.assertFalse;
    import org.flexunit.asserts.assertTrue;

    public class TestSupport
    {
        public function TestSupport()
        {
        }

        [Test]
        public function testTypeCache():void
        {
            var n:Number = 1.3;
            var s:String = "test";
            var a:Array = [1, 2, 3];
            var b:Boolean = true;
            var cls:Class = Item;
            var d:Date = new Date(2000);
            var x:XML = <t>test</t>;
            var xl:XMLList = <t href="5">test</t>.@href;
            var item:Item = new Item();

            assertEquals(TypeCache.getQualifiedClassName(n), TypeCache.NUMBER);
            assertEquals(TypeCache.getQualifiedClassName(s), TypeCache.STRING);
            assertEquals(TypeCache.getQualifiedClassName(a), TypeCache.ARRAY);
            assertEquals(TypeCache.getQualifiedClassName(b), TypeCache.BOOLEAN);
            assertEquals(TypeCache.getQualifiedClassName(cls), "Item");
            assertEquals(TypeCache.getQualifiedClassName(Class), "Class");
            assertEquals(TypeCache.getQualifiedClassName(d), TypeCache.DATE);
            assertEquals(TypeCache.getQualifiedClassName(x), TypeCache.XML_TYPE);
            assertEquals(TypeCache.getQualifiedClassName(xl), TypeCache.XML_LIST);
            assertEquals(TypeCache.getQualifiedClassName(undefined), TypeCache.UNDEFINED);
            assertEquals(TypeCache.getQualifiedClassName(item), "Item");

            assertEquals(TypeCache.getQualifiedClassName(n), getQualifiedClassName(n));
            assertEquals(TypeCache.getQualifiedClassName(s), getQualifiedClassName(s));
            assertEquals(TypeCache.getQualifiedClassName(a), getQualifiedClassName(a));
            assertEquals(TypeCache.getQualifiedClassName(b), getQualifiedClassName(b));
            assertEquals(TypeCache.getQualifiedClassName(cls), getQualifiedClassName(cls));
            assertEquals(TypeCache.getQualifiedClassName(Class), getQualifiedClassName(Class));
            assertEquals(TypeCache.getQualifiedClassName(d), getQualifiedClassName(d));
            assertEquals(TypeCache.getQualifiedClassName(x), getQualifiedClassName(x));
            assertEquals(TypeCache.getQualifiedClassName(xl), getQualifiedClassName(xl));
            assertEquals(TypeCache.getQualifiedClassName(item), getQualifiedClassName(item));
            assertEquals(TypeCache.getQualifiedClassName(undefined), getQualifiedClassName(undefined));
        }

        [Test]
        public function testToValue():void
        {
            var date:Date = new Date(2000);

            assertEquals(toValue(undefined, 1), 1);
            assertEquals(toValue(undefined, "test"), "test");
            assertEquals(toValue(undefined, date), date);
            assertEquals(toValue(undefined, null), null);
            assertTrue(toValue(undefined, undefined) === undefined);

            assertTrue(toValue(1, undefined) === undefined);
            assertTrue(toValue("test", undefined) === undefined);
            assertTrue(toValue(date, undefined) === undefined);
            assertTrue(toValue(null, undefined) === undefined);

            var f:Function = function(value:*):*
            {
                return value;
            };

            assertEquals(toValue(1, f), 1);
            assertEquals(toValue("test", f), "test");
            assertEquals(toValue(date, f), date);
            assertTrue(toValue(undefined, f) === undefined);
            assertEquals(toValue(null, f), null);
        }

        [Test]
        public function testCompare():void
        {
            var date:Date = new Date(2000);

            assertEquals(Compare.compare(null, null), 0);
            assertEquals(Compare.compare(null, 1), -1);
            assertEquals(Compare.compare(null, 1, Stream.DESCENDING), 1);
            assertEquals(Compare.compare(1, null), 1);
            assertEquals(Compare.compare(1, 1, Stream.NUMERIC), 0);
            assertEquals(Compare.compare(1, "1"), -1);

            assertEquals(Compare.compare(new Date(), date), 1);
            assertEquals(Compare.compare(date, date), 0);
            assertEquals(Compare.compare(date, new Date()), -1);

            assertEquals(Compare.compare(NaN, 1), -1);
            assertEquals(Compare.compare(NaN, NaN), 0);
            assertEquals(Compare.compare(1, NaN), 1);

            assertEquals(Compare.compare("abc", "def"), -1);
            assertEquals(Compare.compare("t", "t"), 0);
            assertEquals(Compare.compare("def", "abc"), 1);

            var xs1:XML = 123;
            var xs2:XML = 1;
            assertEquals(Compare.compare(xs1, xs2), 1);
            assertEquals(Compare.compare(xs2, xs2), 0);
            assertEquals(Compare.compare(xs2, xs1), -1);

            assertEquals(Compare.compare(xs1, xs2, Stream.NUMERIC), 1);
            assertEquals(Compare.compare(xs2, xs2, Stream.NUMERIC), 0);
            assertEquals(Compare.compare(xs2, xs1, Stream.NUMERIC), -1);

            try
            {
                Compare.compare(new Item(), new Item());
                assertFalse(true);
            }
            catch (e:Error)
            {
            }
        }

    }
}

package com.kemsky.support
{
    import avmplus.getQualifiedClassName;

    import com.kemsky.Stream;
    import com.kemsky.combine;
    import com.kemsky.filters._;

    import org.flexunit.asserts.assertEquals;
    import org.flexunit.asserts.assertFalse;
    import org.flexunit.asserts.assertTrue;

    public class TestSupport
    {
        public function TestSupport()
        {
        }

        [Test]
        public function testCombine():void
        {
            var lower:Function = function(value:String):String
            {
                return value.toLowerCase();
            };
            var first:Function = function(value:String):String
            {
                return value.charAt(0);
            };

            assertEquals(combine()(1), 1);
            assertEquals(combine(_)(1), 1);

            var c:Function = combine(first, lower);
            assertEquals(c("ALEX"), "a");
        }

        [Test]
        public function testTypeCache():void
        {
            var n:Number = 1.3;
            var s:String = "test";
            var a:Array = [1, 2, 3];
            var b:Boolean = true;
            var cls:Class = Item;
            var d:Date = new Date(2000);
            var x:XML = <t>test</t>;
            var xl:XMLList = <t href="5">test</t>.@href;
            var item:Item = new Item();

            assertEquals(TypeCache.getQualifiedClassName(n), TypeCache.NUMBER);
            assertEquals(TypeCache.getQualifiedClassName(s), TypeCache.STRING);
            assertEquals(TypeCache.getQualifiedClassName(a), TypeCache.ARRAY);
            assertEquals(TypeCache.getQualifiedClassName(b), TypeCache.BOOLEAN);
            assertEquals(TypeCache.getQualifiedClassName(cls), "Item");
            assertEquals(TypeCache.getQualifiedClassName(Class), "Class");
            assertEquals(TypeCache.getQualifiedClassName(d), TypeCache.DATE);
            assertEquals(TypeCache.getQualifiedClassName(x), TypeCache.XML_TYPE);
            assertEquals(TypeCache.getQualifiedClassName(xl), TypeCache.XML_LIST);
            assertEquals(TypeCache.getQualifiedClassName(undefined), TypeCache.UNDEFINED);
            assertEquals(TypeCache.getQualifiedClassName(item), "Item");

            assertEquals(TypeCache.getQualifiedClassName(n), getQualifiedClassName(n));
            assertEquals(TypeCache.getQualifiedClassName(s), getQualifiedClassName(s));
            assertEquals(TypeCache.getQualifiedClassName(a), getQualifiedClassName(a));
            assertEquals(TypeCache.getQualifiedClassName(b), getQualifiedClassName(b));
            assertEquals(TypeCache.getQualifiedClassName(cls), getQualifiedClassName(cls));
            assertEquals(TypeCache.getQualifiedClassName(Class), getQualifiedClassName(Class));
            assertEquals(TypeCache.getQualifiedClassName(d), getQualifiedClassName(d));
            assertEquals(TypeCache.getQualifiedClassName(x), getQualifiedClassName(x));
            assertEquals(TypeCache.getQualifiedClassName(xl), getQualifiedClassName(xl));
            assertEquals(TypeCache.getQualifiedClassName(item), getQualifiedClassName(item));
            assertEquals(TypeCache.getQualifiedClassName(undefined), getQualifiedClassName(undefined));
        }

        [Test]
        public function testToValue():void
        {
            var date:Date = new Date(2000);

            assertEquals(toValue(undefined, 1), 1);
            assertEquals(toValue(undefined, "test"), "test");
            assertEquals(toValue(undefined, date), date);
            assertEquals(toValue(undefined, null), null);
            assertTrue(toValue(undefined, undefined) === undefined);

            assertTrue(toValue(1, undefined) === undefined);
            assertTrue(toValue("test", undefined) === undefined);
            assertTrue(toValue(date, undefined) === undefined);
            assertTrue(toValue(null, undefined) === undefined);

            var f:Function = function(value:*):*
            {
                return value;
            };

            assertEquals(toValue(1, f), 1);
            assertEquals(toValue("test", f), "test");
            assertEquals(toValue(date, f), date);
            assertTrue(toValue(undefined, f) === undefined);
            assertEquals(toValue(null, f), null);
        }

        [Test]
        public function testCompare():void
        {
            var date:Date = new Date(2000);

            assertEquals(Compare.compare(null, null), 0);
            assertEquals(Compare.compare(null, 1), -1);
            assertEquals(Compare.compare(null, 1, Stream.DESCENDING), 1);
            assertEquals(Compare.compare(1, null), 1);
            assertEquals(Compare.compare(1, 1, Stream.NUMERIC), 0);
            assertEquals(Compare.compare(1, "1"), -1);

            assertEquals(Compare.compare(new Date(), date), 1);
            assertEquals(Compare.compare(date, date), 0);
            assertEquals(Compare.compare(date, new Date()), -1);

            assertEquals(Compare.compare(NaN, 1), -1);
            assertEquals(Compare.compare(NaN, NaN), 0);
            assertEquals(Compare.compare(1, NaN), 1);

            assertEquals(Compare.compare("abc", "def"), -1);
            assertEquals(Compare.compare("t", "t"), 0);
            assertEquals(Compare.compare("def", "abc"), 1);

            var xs1:XML = 123;
            var xs2:XML = 1;
            assertEquals(Compare.compare(xs1, xs2), 1);
            assertEquals(Compare.compare(xs2, xs2), 0);
            assertEquals(Compare.compare(xs2, xs1), -1);

            assertEquals(Compare.compare(xs1, xs2, Stream.NUMERIC), 1);
            assertEquals(Compare.compare(xs2, xs2, Stream.NUMERIC), 0);
            assertEquals(Compare.compare(xs2, xs1, Stream.NUMERIC), -1);

            try
            {
                Compare.compare(new Item(), new Item());
                assertFalse(true);
            }
            catch (e:Error)
            {
            }
        }

    }
}

test combine

test combine


package aerys.minko.scene.controller.mesh
{
	import aerys.minko.ns.minko_math;
	import aerys.minko.render.geometry.Geometry;
	import aerys.minko.scene.controller.AbstractController;
	import aerys.minko.scene.node.Group;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.scene.node.Mesh;
	import aerys.minko.scene.node.Scene;
	import aerys.minko.scene.node.camera.AbstractCamera;
	import aerys.minko.type.binding.DataBindings;
	import aerys.minko.type.binding.DataProvider;
	import aerys.minko.type.enum.FrustumCulling;
	import aerys.minko.type.math.BoundingBox;
	import aerys.minko.type.math.BoundingSphere;
	import aerys.minko.type.math.Matrix4x4;
	import aerys.minko.type.math.Vector4;

	/**
	 * The MeshVisibilityController watches the Mesh and the active Camera of a Scene
	 * to determine whether the object is actually inside the view frustum or not.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public final class MeshVisibilityController extends AbstractController
	{
		use namespace minko_math;

		private static const TMP_VECTOR4		: Vector4	= new Vector4();

		private static const STATE_UNDEFINED	: uint		= 0;
		private static const STATE_INSIDE		: uint		= 1;
		private static const STATE_OUTSIDE		: uint		= 2;

		private var _mesh			    : Mesh;
		private var _state			    : uint;
		private var _lastTest		    : int;
		private var _boundingBox	    : BoundingBox;
		private var _boundingSphere	    : BoundingSphere;

		private var _data				: DataProvider;

        private var _frustumCulling     : uint;
        private var _insideFrustum      : Boolean;

		public function get frustumCulling() : uint
		{
			return _frustumCulling;
		}
		public function set frustumCulling(value : uint) : void
		{
			_frustumCulling = value;
			if (_mesh && _mesh.root is Scene)
            	testCulling();
		}

		public function get insideFrustum() : Boolean
		{
			return _insideFrustum;
		}

        public function get computedVisibility() : Boolean
        {
            return _data.computedVisibility;
        }

		public function MeshVisibilityController()
		{
			super(Mesh);

			initialize();
		}

		private function initialize() : void
		{
			_data = new DataProvider();
			_data.setProperty('computedVisibility', false);

			_boundingBox = new BoundingBox(Vector4.ZERO, Vector4.ONE);
			_boundingSphere = new BoundingSphere(Vector4.ZERO, 0.);

            _state = STATE_UNDEFINED;

			targetAdded.add(targetAddedHandler);
			targetRemoved.add(targetRemovedHandler);
		}

		private function targetAddedHandler(ctrl	: MeshVisibilityController,
											target	: Mesh) : void
		{
			if (_mesh != null)
				throw new Error();

			_mesh = target;

			target.added.add(addedHandler);
			target.removed.add(removedHandler);

			if (target.root is Scene)
				addedHandler(target, target.root as Scene);

			if (_frustumCulling)
				testCulling();
		}

		private function targetRemovedHandler(ctrl		: MeshVisibilityController,
											  target	: Mesh) : void
		{
			_mesh = null;

			target.added.remove(addedHandler);
			target.removed.remove(removedHandler);

			if (target.root is Scene)
				removedHandler(target, target.root as Scene);
		}

		private function addedHandler(mesh : Mesh, ancestor : Group) : void
		{
			var scene : Scene = mesh.scene;

			if (!scene)
				return ;

			scene.bindings.addCallback('worldToScreen', worldToScreenChangedHandler);

            meshLocalToWorldChangedHandler(mesh, mesh.getLocalToWorldTransform());
			mesh.localToWorldTransformChanged.add(meshLocalToWorldChangedHandler);
            mesh.computedVisibilityChanged.add(computedVisiblityChangedHandler);
            mesh.bindings.addProvider(_data);
		}

		private function removedHandler(mesh : Mesh, ancestor : Group) : void
		{
			var scene : Scene = ancestor.scene;

			if (!scene)
				return ;

			scene.bindings.removeCallback('worldToScreen', worldToScreenChangedHandler);

			mesh.localToWorldTransformChanged.remove(meshLocalToWorldChangedHandler);
            mesh.computedVisibilityChanged.remove(computedVisiblityChangedHandler);
            mesh.bindings.removeProvider(_data);
		}

        private function computedVisiblityChangedHandler(node               : ISceneNode,
                                                         computedVisibility : Boolean) : void
        {
            _data.computedVisibility = computedVisibility;
        }

		private function worldToScreenChangedHandler(bindings	    : DataBindings,
                                                     propertyName	: String,
                                                     oldValue		: Matrix4x4,
                                                     newValue		: Matrix4x4) : void
		{
			testCulling();
		}

		private function meshLocalToWorldChangedHandler(mesh : Mesh, transform : Matrix4x4) : void
		{
			var geom 	: Geometry 	= _mesh.geometry;
			var culling	: uint		= _frustumCulling;

			if (!geom.boundingBox || !geom.boundingSphere || culling == FrustumCulling.DISABLED)
				return ;

			if (culling & FrustumCulling.BOX)
				transform.transformRawVectors(geom.boundingBox._vertices, _boundingBox._vertices);

			if (culling & FrustumCulling.SPHERE)
			{
				var center 	: Vector4 	= transform.transformVector(geom.boundingSphere.center);
				var scale 	: Vector4 	= transform.deltaTransformVector(Vector4.ONE);
				var radius	: Number	= geom.boundingSphere.radius * Math.max(
					Math.abs(scale.x), Math.abs(scale.y), Math.abs(scale.z)
				);

				_boundingSphere.update(center, radius);
			}

			testCulling();
		}

		private function testCulling() : void
		{
			var culling	: uint	= _frustumCulling;

			if (culling != FrustumCulling.DISABLED)
			{
				_data.computedVisibility = true;
				return;
			}

			if (_mesh && _mesh.geometry.boundingBox && _mesh.visible)
			{
				var camera : AbstractCamera = (_mesh.root as Scene).activeCamera;

				if (!camera)
					return ;

				_lastTest = camera.frustum.testBoundingVolume(
					_boundingSphere,
					_boundingBox,
					null,
					culling,
					_lastTest
				);

				var inside : Boolean = _lastTest == -1;

				if (inside && _state != STATE_INSIDE)
				{
					_insideFrustum = true;
                    _data.computedVisibility = _mesh.parent.computedVisibility && _mesh.visible;
                    _mesh.computedVisibilityChanged.execute(_mesh, computedVisibility);
					_state = STATE_INSIDE;
				}
				else if (!inside && _state != STATE_OUTSIDE)
				{
					_insideFrustum = false;
                    _data.computedVisibility = false;
                    _mesh.computedVisibilityChanged.execute(_mesh, false);
					_state = STATE_OUTSIDE;
				}
			}
		}

		override public function clone() : AbstractController
		{
			return new MeshVisibilityController();
		}
	}
}

package aerys.minko.scene.controller.mesh
{
	import aerys.minko.ns.minko_math;
	import aerys.minko.render.geometry.Geometry;
	import aerys.minko.scene.controller.AbstractController;
	import aerys.minko.scene.node.Group;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.scene.node.Mesh;
	import aerys.minko.scene.node.Scene;
	import aerys.minko.scene.node.camera.AbstractCamera;
	import aerys.minko.type.binding.DataBindings;
	import aerys.minko.type.binding.DataProvider;
	import aerys.minko.type.enum.DataProviderUsage;
	import aerys.minko.type.enum.FrustumCulling;
	import aerys.minko.type.math.BoundingBox;
	import aerys.minko.type.math.BoundingSphere;
	import aerys.minko.type.math.Matrix4x4;
	import aerys.minko.type.math.Vector4;

	/**
	 * The MeshVisibilityController watches the Mesh and the active Camera of a Scene
	 * to determine whether the object is actually inside the view frustum or not.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public final class MeshVisibilityController extends AbstractController
	{
		use namespace minko_math;

		private static const TMP_VECTOR4		: Vector4	= new Vector4();

		private static const STATE_UNDEFINED	: uint		= 0;
		private static const STATE_INSIDE		: uint		= 1;
		private static const STATE_OUTSIDE		: uint		= 2;

		private var _mesh			    : Mesh;
		private var _state			    : uint;
		private var _lastTest		    : int;
		private var _boundingBox	    : BoundingBox;
		private var _boundingSphere	    : BoundingSphere;

		private var _data				: DataProvider;

        private var _frustumCulling     : uint;
        private var _insideFrustum      : Boolean;

		public function get frustumCulling() : uint
		{
			return _frustumCulling;
		}
		public function set frustumCulling(value : uint) : void
		{
			_frustumCulling = value;
			if (_mesh && _mesh.root is Scene)
            	testCulling();
		}

		public function get insideFrustum() : Boolean
		{
			return _insideFrustum;
		}

        public function get computedVisibility() : Boolean
        {
            return _data.computedVisibility;
        }

		public function MeshVisibilityController()
		{
			super(Mesh);

			initialize();
		}

		private function initialize() : void
		{
			_data = new DataProvider(
				{ computedVisibility : false },
				'MeshVisibilityDataProvider',
				DataProviderUsage.EXCLUSIVE
			);

			_boundingBox = new BoundingBox(Vector4.ZERO, Vector4.ONE);
			_boundingSphere = new BoundingSphere(Vector4.ZERO, 0.);

            _state = STATE_UNDEFINED;

			targetAdded.add(targetAddedHandler);
			targetRemoved.add(targetRemovedHandler);
		}

		private function targetAddedHandler(ctrl	: MeshVisibilityController,
											target	: Mesh) : void
		{
			if (_mesh != null)
				throw new Error();

			_mesh = target;

			target.added.add(addedHandler);
			target.removed.add(removedHandler);

			if (target.root is Scene)
				addedHandler(target, target.root as Scene);

			if (_frustumCulling)
				testCulling();
		}

		private function targetRemovedHandler(ctrl		: MeshVisibilityController,
											  target	: Mesh) : void
		{
			_mesh = null;

			target.added.remove(addedHandler);
			target.removed.remove(removedHandler);

			if (target.root is Scene)
				removedHandler(target, target.root as Scene);
		}

		private function addedHandler(mesh : Mesh, ancestor : Group) : void
		{
			var scene : Scene = mesh.scene;

			if (!scene)
				return ;

			scene.bindings.addCallback('worldToScreen', worldToScreenChangedHandler);

            meshLocalToWorldChangedHandler(mesh, mesh.getLocalToWorldTransform());
			mesh.localToWorldTransformChanged.add(meshLocalToWorldChangedHandler);
            mesh.computedVisibilityChanged.add(computedVisiblityChangedHandler);
            mesh.bindings.addProvider(_data);
		}

		private function removedHandler(mesh : Mesh, ancestor : Group) : void
		{
			var scene : Scene = ancestor.scene;

			if (!scene)
				return ;

			scene.bindings.removeCallback('worldToScreen', worldToScreenChangedHandler);

			mesh.localToWorldTransformChanged.remove(meshLocalToWorldChangedHandler);
            mesh.computedVisibilityChanged.remove(computedVisiblityChangedHandler);
            mesh.bindings.removeProvider(_data);
		}

        private function computedVisiblityChangedHandler(node               : ISceneNode,
                                                         computedVisibility : Boolean) : void
        {
            _data.computedVisibility = computedVisibility;
        }

		private function worldToScreenChangedHandler(bindings	    : DataBindings,
                                                     propertyName	: String,
                                                     oldValue		: Matrix4x4,
                                                     newValue		: Matrix4x4) : void
		{
			testCulling();
		}

		private function meshLocalToWorldChangedHandler(mesh : Mesh, transform : Matrix4x4) : void
		{
			var geom 	: Geometry 	= _mesh.geometry;
			var culling	: uint		= _frustumCulling;

			if (!geom.boundingBox || !geom.boundingSphere || culling == FrustumCulling.DISABLED)
				return ;

			if (culling & FrustumCulling.BOX)
				transform.transformRawVectors(geom.boundingBox._vertices, _boundingBox._vertices);

			if (culling & FrustumCulling.SPHERE)
			{
				var center 	: Vector4 	= transform.transformVector(geom.boundingSphere.center);
				var scale 	: Vector4 	= transform.deltaTransformVector(Vector4.ONE);
				var radius	: Number	= geom.boundingSphere.radius * Math.max(
					Math.abs(scale.x), Math.abs(scale.y), Math.abs(scale.z)
				);

				_boundingSphere.update(center, radius);
			}

			testCulling();
		}

		private function testCulling() : void
		{
			var culling	: uint	= _frustumCulling;

			if (culling != FrustumCulling.DISABLED)
			{
				_data.computedVisibility = true;
				return;
			}

			if (_mesh && _mesh.geometry.boundingBox && _mesh.visible)
			{
				var camera : AbstractCamera = (_mesh.root as Scene).activeCamera;

				if (!camera)
					return ;

				_lastTest = camera.frustum.testBoundingVolume(
					_boundingSphere,
					_boundingBox,
					null,
					culling,
					_lastTest
				);

				var inside : Boolean = _lastTest == -1;

				if (inside && _state != STATE_INSIDE)
				{
					_insideFrustum = true;
                    _data.computedVisibility = _mesh.parent.computedVisibility && _mesh.visible;
                    _mesh.computedVisibilityChanged.execute(_mesh, computedVisibility);
					_state = STATE_INSIDE;
				}
				else if (!inside && _state != STATE_OUTSIDE)
				{
					_insideFrustum = false;
                    _data.computedVisibility = false;
                    _mesh.computedVisibilityChanged.execute(_mesh, false);
					_state = STATE_OUTSIDE;
				}
			}
		}

		override public function clone() : AbstractController
		{
			return new MeshVisibilityController();
		}
	}
}

fix MeshVisibilityController to set its data provider usage to DataProviderUsage.EXCLUSIVE in order to make sure cloning the mesh nodes won't cause duplicate binding properties errors


// Nenya library - tools for developing networked games
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/nenya/
//
// 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.media {

import flash.events.TimerEvent;
import flash.utils.Timer;

/**
 * Registers objects that wish to be sent a tick() call once per frame.
 */
public class Ticker
{
    public function start () :void
    {
        _t.addEventListener(TimerEvent.TIMER, handleTimer);
        _start = new Date().time;
        _t.start();
    }

    public function stop () :void
    {
        _t.removeEventListener(TimerEvent.TIMER, handleTimer);
        _t.stop();

    }

    public function handleTimer (event :TimerEvent) :void
    {
        tick(int(new Date().time - _start));
    }

    protected function tick (tickStamp :int) :void
    {
        for each (var tickable :Tickable in _tickables) {
            tickable.tick(tickStamp);
        }
    }

    public function registerTickable (tickable :Tickable) :void
    {
        _tickables.push(tickable);
    }

    public function removeTickable (tickable :Tickable) :void
    {
        _tickables.remove(tickable);
    }

    /** Everyone who wants to hear about our ticks. */
    protected var _tickables :Array = [];

    /** A timer that will fire every "frame". */
    protected var _t :Timer = new Timer(1);

    /** What time our ticker started running - tickStamps will be relative to this time. */
    protected var _start :Number;
}
}

// Nenya library - tools for developing networked games
// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/nenya/
//
// 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.media {

import flash.events.TimerEvent;
import flash.utils.Timer;

import com.threerings.util.ArrayUtil;

/**
 * Registers objects that wish to be sent a tick() call once per frame.
 */
public class Ticker
{
    public function start () :void
    {
        _t.addEventListener(TimerEvent.TIMER, handleTimer);
        _start = new Date().time;
        _t.start();
    }

    public function stop () :void
    {
        _t.removeEventListener(TimerEvent.TIMER, handleTimer);
        _t.stop();

    }

    public function handleTimer (event :TimerEvent) :void
    {
        tick(int(new Date().time - _start));
    }

    protected function tick (tickStamp :int) :void
    {
        for each (var tickable :Tickable in _tickables) {
            tickable.tick(tickStamp);
        }
    }

    public function registerTickable (tickable :Tickable) :void
    {
        _tickables.push(tickable);
    }

    public function removeTickable (tickable :Tickable) :void
    {
        ArrayUtil.removeFirst(_tickables, tickable);
    }

    /** Everyone who wants to hear about our ticks. */
    protected var _tickables :Array = [];

    /** A timer that will fire every "frame". */
    protected var _t :Timer = new Timer(1);

    /** What time our ticker started running - tickStamps will be relative to this time. */
    protected var _start :Number;
}
}

Make the proper call here - there's no remove() on arrays...

git-svn-id: b675b909355d5cf946977f44a8ec5a6ceb3782e4@1002 ed5b42cb-e716-0410-a449-f6a68f950b19


package
{
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.net.Socket;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.events.SecurityErrorEvent;
    import flash.utils.ByteArray;

    public class swfcat extends Sprite
    {
        /* David's relay (nickname 3VXRyxz67OeRoqHn) that also serves a
           crossdomain policy. */
        private const DEFAULT_TOR_ADDR:Object = {
            host: "173.255.221.44",
            port: 9001
        };

        private var output_text:TextField;

        // Socket to facilitator.
        private var s_f:Socket;

        private var fac_addr:Object;

        public function puts(s:String):void
        {
            output_text.appendText(s + "\n");
            output_text.scrollV = output_text.maxScrollV;
        }

        public function swfcat()
        {
            output_text = new TextField();
            output_text.width = 400;
            output_text.height = 300;
            output_text.background = true;
            output_text.backgroundColor = 0x001f0f;
            output_text.textColor = 0x44CC44;
            addChild(output_text);

            puts("Starting.");
            // Wait until the query string parameters are loaded.
            this.loaderInfo.addEventListener(Event.COMPLETE, loaderinfo_complete);
        }

        private function loaderinfo_complete(e:Event):void
        {
            var fac_spec:String;
            var tor_spec:String;

            puts("Parameters loaded.");
            fac_spec = this.loaderInfo.parameters["facilitator"];
            if (!fac_spec) {
                puts("Error: no \"facilitator\" specification provided.");
                return;
            }
            puts("Facilitator spec: \"" + fac_spec + "\"");
            fac_addr = parse_addr_spec(fac_spec);
            if (!fac_addr) {
                puts("Error: Facilitator spec must be in the form \"host:port\".");
                return;
            }

            main();
        }

        /* The main logic begins here, after start-up issues are taken care of. */
        private function main():void
        {
            s_f = new Socket();

            s_f.addEventListener(Event.CONNECT, fac_connected);
            s_f.addEventListener(Event.CLOSE, function (e:Event):void {
                puts("Facilitator: closed connection.");
            });
            s_f.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
                puts("Facilitator: I/O error: " + e.text + ".");
            });
            s_f.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
                puts("Facilitator: security error: " + e.text + ".");
            });

            puts("Facilitator: connecting to " + fac_addr.host + ":" + fac_addr.port + ".");
            s_f.connect(fac_addr.host, fac_addr.port);
        }

        private function fac_connected(e:Event):void
        {
            puts("Facilitator: connected.");

            s_f.addEventListener(ProgressEvent.SOCKET_DATA, fac_data);

            s_f.writeUTFBytes("GET / HTTP/1.0\r\n\r\n");
        }

        private function fac_data(e:ProgressEvent):void
        {
            var client_spec:String;
            var client_addr:Object;
            var proxy_pair:Object;

            client_spec = s_f.readMultiByte(e.bytesLoaded, "utf-8");
            puts("Facilitator: got \"" + client_spec + "\"");

            client_addr = parse_addr_spec(client_spec);
            if (!client_addr) {
                puts("Error: Client spec must be in the form \"host:port\".");
                return;
            }
            if (client_addr.host == "0.0.0.0" && client_addr.port == 0) {
                puts("Error: Facilitator has no clients.");
                return;
            }

            proxy_pair = new ProxyPair(this, client_addr, DEFAULT_TOR_ADDR);
        }

        /* Parse an address in the form "host:port". Returns an Object with
           keys "host" (String) and "port" (int). Returns null on error. */
        private static function parse_addr_spec(spec:String):Object
        {
            var parts:Array;
            var addr:Object;

            parts = spec.split(":", 2);
            if (parts.length != 2 || !parseInt(parts[1]))
                return null;
            addr = {}
            addr.host = parts[0];
            addr.port = parseInt(parts[1]);

            return addr;
        }
    }
}

import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.net.Socket;
import flash.utils.ByteArray;

/* An instance of a client-relay connection. */
class ProxyPair
{
    // Address ({host, port}) of client.
    private var addr_c:Object;
    // Address ({host, port}) of relay.
    private var addr_r:Object;

    // Socket to client.
    private var s_c:Socket;
    // Socket to relay.
    private var s_r:Socket;

    // Parent swfcat, for UI updates.
    private var ui:swfcat;

    private function log(msg:String):void
    {
        ui.puts(id() + ": " + msg)
    }

    // String describing this pair for output.
    private function id():String
    {
        return "<" + this.addr_c.host + ":" + this.addr_c.port +
            "," + this.addr_r.host + ":" + this.addr_r.port + ">";
    }

    public function ProxyPair(ui:swfcat, addr_c:Object, addr_r:Object)
    {
        this.ui = ui;
        this.addr_c = addr_c;
        this.addr_r = addr_r;
    }

    public function connect():void
    {
        s_r = new Socket();

        s_r.addEventListener(Event.CONNECT, tor_connected);
        s_r.addEventListener(Event.CLOSE, function (e:Event):void {
            log("Tor: closed.");
            if (s_c.connected)
                s_c.close();
        });
        s_r.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
            log("Tor: I/O error: " + e.text + ".");
            if (s_c.connected)
                s_c.close();
        });
        s_r.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
            log("Tor: security error: " + e.text + ".");
            if (s_c.connected)
                s_c.close();
        });

        log("Tor: connecting to " + addr_r.host + ":" + addr_r.port + ".");
        s_r.connect(addr_r.host, addr_r.port);
    }

    private function tor_connected(e:Event):void
    {
        log("Tor: connected.");

        s_c = new Socket();

        s_c.addEventListener(Event.CONNECT, client_connected);
        s_c.addEventListener(Event.CLOSE, function (e:Event):void {
            log("Client: closed.");
            if (s_r.connected)
                s_r.close();
        });
        s_c.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
            log("Client: I/O error: " + e.text + ".");
            if (s_r.connected)
                s_r.close();
        });
        s_c.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
            log("Client: security error: " + e.text + ".");
            if (s_r.connected)
                s_r.close();
        });

        log("Client: connecting to " + addr_c.host + ":" + addr_c.port + ".");
        s_c.connect(addr_c.host, addr_c.port);
    }

    private function client_connected(e:Event):void
    {
        log("Client: connected.");

        s_r.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
            var bytes:ByteArray = new ByteArray();
            s_r.readBytes(bytes, 0, e.bytesLoaded);
            log("Tor: read " + bytes.length + ".");
            s_c.writeBytes(bytes);
        });
        s_c.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
            var bytes:ByteArray = new ByteArray();
            s_c.readBytes(bytes, 0, e.bytesLoaded);
            log("Client: read " + bytes.length + ".");
            s_r.writeBytes(bytes);
        });
    }
}

package
{
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.net.Socket;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.events.SecurityErrorEvent;
    import flash.utils.ByteArray;

    public class swfcat extends Sprite
    {
        /* David's relay (nickname 3VXRyxz67OeRoqHn) that also serves a
           crossdomain policy. */
        private const DEFAULT_TOR_ADDR:Object = {
            host: "173.255.221.44",
            port: 9001
        };

        private var output_text:TextField;

        // Socket to facilitator.
        private var s_f:Socket;

        public function puts(s:String):void
        {
            output_text.appendText(s + "\n");
            output_text.scrollV = output_text.maxScrollV;
        }

        public function swfcat()
        {
            output_text = new TextField();
            output_text.width = 400;
            output_text.height = 300;
            output_text.background = true;
            output_text.backgroundColor = 0x001f0f;
            output_text.textColor = 0x44CC44;
            addChild(output_text);

            puts("Starting.");
            // Wait until the query string parameters are loaded.
            this.loaderInfo.addEventListener(Event.COMPLETE, loaderinfo_complete);
        }

        private function loaderinfo_complete(e:Event):void
        {
            var fac_spec:String;
            var fac_addr:Object;

            puts("Parameters loaded.");
            fac_spec = this.loaderInfo.parameters["facilitator"];
            if (!fac_spec) {
                puts("Error: no \"facilitator\" specification provided.");
                return;
            }
            puts("Facilitator spec: \"" + fac_spec + "\"");
            fac_addr = parse_addr_spec(fac_spec);
            if (!fac_addr) {
                puts("Error: Facilitator spec must be in the form \"host:port\".");
                return;
            }

            main(fac_addr);
        }

        /* The main logic begins here, after start-up issues are taken care of. */
        private function main(fac_addr:Object):void
        {
            s_f = new Socket();

            s_f.addEventListener(Event.CONNECT, fac_connected);
            s_f.addEventListener(Event.CLOSE, function (e:Event):void {
                puts("Facilitator: closed connection.");
            });
            s_f.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
                puts("Facilitator: I/O error: " + e.text + ".");
            });
            s_f.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
                puts("Facilitator: security error: " + e.text + ".");
            });

            puts("Facilitator: connecting to " + fac_addr.host + ":" + fac_addr.port + ".");
            s_f.connect(fac_addr.host, fac_addr.port);
        }

        private function fac_connected(e:Event):void
        {
            puts("Facilitator: connected.");

            s_f.addEventListener(ProgressEvent.SOCKET_DATA, fac_data);

            s_f.writeUTFBytes("GET / HTTP/1.0\r\n\r\n");
        }

        private function fac_data(e:ProgressEvent):void
        {
            var client_spec:String;
            var client_addr:Object;
            var proxy_pair:Object;

            client_spec = s_f.readMultiByte(e.bytesLoaded, "utf-8");
            puts("Facilitator: got \"" + client_spec + "\"");

            client_addr = parse_addr_spec(client_spec);
            if (!client_addr) {
                puts("Error: Client spec must be in the form \"host:port\".");
                return;
            }
            if (client_addr.host == "0.0.0.0" && client_addr.port == 0) {
                puts("Error: Facilitator has no clients.");
                return;
            }

            proxy_pair = new ProxyPair(this, client_addr, DEFAULT_TOR_ADDR);
        }

        /* Parse an address in the form "host:port". Returns an Object with
           keys "host" (String) and "port" (int). Returns null on error. */
        private static function parse_addr_spec(spec:String):Object
        {
            var parts:Array;
            var addr:Object;

            parts = spec.split(":", 2);
            if (parts.length != 2 || !parseInt(parts[1]))
                return null;
            addr = {}
            addr.host = parts[0];
            addr.port = parseInt(parts[1]);

            return addr;
        }
    }
}

import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.net.Socket;
import flash.utils.ByteArray;

/* An instance of a client-relay connection. */
class ProxyPair
{
    // Address ({host, port}) of client.
    private var addr_c:Object;
    // Address ({host, port}) of relay.
    private var addr_r:Object;

    // Socket to client.
    private var s_c:Socket;
    // Socket to relay.
    private var s_r:Socket;

    // Parent swfcat, for UI updates.
    private var ui:swfcat;

    private function log(msg:String):void
    {
        ui.puts(id() + ": " + msg)
    }

    // String describing this pair for output.
    private function id():String
    {
        return "<" + this.addr_c.host + ":" + this.addr_c.port +
            "," + this.addr_r.host + ":" + this.addr_r.port + ">";
    }

    public function ProxyPair(ui:swfcat, addr_c:Object, addr_r:Object)
    {
        this.ui = ui;
        this.addr_c = addr_c;
        this.addr_r = addr_r;
    }

    public function connect():void
    {
        s_r = new Socket();

        s_r.addEventListener(Event.CONNECT, tor_connected);
        s_r.addEventListener(Event.CLOSE, function (e:Event):void {
            log("Tor: closed.");
            if (s_c.connected)
                s_c.close();
        });
        s_r.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
            log("Tor: I/O error: " + e.text + ".");
            if (s_c.connected)
                s_c.close();
        });
        s_r.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
            log("Tor: security error: " + e.text + ".");
            if (s_c.connected)
                s_c.close();
        });

        log("Tor: connecting to " + addr_r.host + ":" + addr_r.port + ".");
        s_r.connect(addr_r.host, addr_r.port);
    }

    private function tor_connected(e:Event):void
    {
        log("Tor: connected.");

        s_c = new Socket();

        s_c.addEventListener(Event.CONNECT, client_connected);
        s_c.addEventListener(Event.CLOSE, function (e:Event):void {
            log("Client: closed.");
            if (s_r.connected)
                s_r.close();
        });
        s_c.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
            log("Client: I/O error: " + e.text + ".");
            if (s_r.connected)
                s_r.close();
        });
        s_c.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
            log("Client: security error: " + e.text + ".");
            if (s_r.connected)
                s_r.close();
        });

        log("Client: connecting to " + addr_c.host + ":" + addr_c.port + ".");
        s_c.connect(addr_c.host, addr_c.port);
    }

    private function client_connected(e:Event):void
    {
        log("Client: connected.");

        s_r.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
            var bytes:ByteArray = new ByteArray();
            s_r.readBytes(bytes, 0, e.bytesLoaded);
            log("Tor: read " + bytes.length + ".");
            s_c.writeBytes(bytes);
        });
        s_c.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
            var bytes:ByteArray = new ByteArray();
            s_c.readBytes(bytes, 0, e.bytesLoaded);
            log("Client: read " + bytes.length + ".");
            s_r.writeBytes(bytes);
        });
    }
}

Make fac_addr a local variable.

Make fac_addr a local variable.


#if __SWF_VERSION__ == 5
// create a _global object, since it doesn't have one, these are ver 6 values
_global = new_empty_object ();
_global.ASSetNative = ASSetNative;
_global.ASSetNativeAccessor = ASSetNativeAccessor;
_global.ASSetPropFlags = ASSetPropFlags;
_global.ASconstructor = ASconstructor;
_global.ASnative = ASnative;
_global.Accessibility = Accessibility;
_global.Array = Array;
_global.AsBroadcaster = AsBroadcaster;
_global.AsSetupError = AsSetupError;
_global.Boolean = Boolean;
_global.Button = Button;
_global.Camera = Camera;
_global.Color = Color;
_global.ContextMenu = ContextMenu;
_global.ContextMenuItem = ContextMenuItem;
_global.Date = Date;
_global.Error = Error;
_global.Function = Function;
_global.Infinity = Infinity;
_global.Key = Key;
_global.LoadVars = LoadVars;
_global.LocalConnection = LocalConnection;
_global.Math = Math;
_global.Microphone = Microphone;
_global.Mouse = Mouse;
_global.MovieClip = MovieClip;
_global.MovieClipLoader = MovieClipLoader;
_global.NaN = NaN;
_global.NetConnection = NetConnection;
_global.NetStream = NetStream;
_global.Number = Number;
_global.Object = Object;
_global.PrintJob = PrintJob;
_global.RemoteLSOUsage = RemoteLSOUsage;
_global.Selection = Selection;
_global.SharedObject = SharedObject;
_global.Sound = Sound;
_global.Stage = Stage;
_global.String = String;
_global.System = System;
_global.TextField = TextField;
_global.TextFormat = TextFormat;
_global.TextSnapshot = TextSnapshot;
_global.Video = Video;
_global.XML = XML;
_global.XMLNode = XMLNode;
_global.XMLSocket = XMLSocket;
_global.clearInterval = clearInterval;
_global.clearTimeout = clearTimeout;
_global.enableDebugConsole = enableDebugConsole;
_global.escape = escape;
_global.flash = flash;
_global.isFinite = isFinite;
_global.isNaN = isNaN;
_global.o = o;
_global.parseFloat = parseFloat;
_global.parseInt = parseInt;
_global.setInterval = setInterval;
_global.setTimeout = setTimeout;
_global.showRedrawRegions = showRedrawRegions;
_global.textRenderer = textRenderer;
_global.trace = trace;
_global.unescape = unescape;
_global.updateAfterEvent = updateAfterEvent;
#endif

function new_empty_object () {
  var hash = new Object ();
  ASSetPropFlags (hash, null, 0, 7);
  for (var prop in hash) {
    hash[prop] = "to-be-deleted";
    delete hash[prop];
  }
  return hash;
}

function hasOwnProperty (o, prop)
{
  if (o.hasOwnProperty != undefined)
    return o.hasOwnProperty (prop);

  o.hasOwnProperty = ASnative (101, 5);
  var result = o.hasOwnProperty (prop);
  delete o.hasOwnProperty;
  return result;
}

function new_info () {
  return new_empty_object ();
}

function set_info (info, prop, id, value) {
  info[prop + "_-_" + id] = value;
}

function get_info (info, prop, id) {
  return info[prop + "_-_" + id];
}

function is_blaclisted (o, prop)
{
  if (prop == "mySecretId" || prop == "globalSecretId")
    return true;

  if (o == _global.Camera && prop == "names")
    return true;

  if (o == _global.Microphone && prop == "names")
    return true;

#if __SWF_VERSION__ < 6
  if (prop == "__proto__" && o[prop] == undefined)
    return true;
#endif

  return false;
}

function trace_properties_recurse (o, prefix, identifier, level)
{
  // to collect info about different properties
  var info = new_info ();

  // calculate indentation
  var indentation = "";
  for (var j = 0; j < level; j++) {
    indentation = indentation + "  ";
  }

  // mark the ones that are not hidden
  for (var prop in o)
  {
    // only get the ones that are not only in the __proto__
    if (is_blaclisted (o, prop) == false) {
      if (hasOwnProperty (o, prop) == true)
	set_info (info, prop, "hidden", false);
    }
  }

  // unhide everything
  ASSetPropFlags (o, null, 0, 1);

  var all = new Array ();
  var hidden = new Array ();
  for (var prop in o)
  {
    // only get the ones that are not only in the __proto__
    if (is_blaclisted (o, prop) == false) {
      if (hasOwnProperty (o, prop) == true) {
	all.push (prop);
	if (get_info (info, prop, "hidden") != false) {
	  set_info (info, prop, "hidden", true);
	  hidden.push (prop);
	}
      }
    }
  }
  all.sort ();

  // hide the ones that were already hidden
  ASSetPropFlags (o, hidden, 1, 0);

  if (all.length == 0) {
    trace (indentation + "no children");
    return nextSecretId;
  }

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // try changing value
    var old = o[prop];
    var val = "hello " + o[prop];
    o[prop] = val;
    if (o[prop] != val)
    {
      set_info (info, prop, "constant", true);

      // try changing value after removing constant propflag
      ASSetPropFlags (o, prop, 0, 4);
      o[prop] = val;
      if (o[prop] != val) {
	set_info (info, prop, "superconstant", true);
      } else {
	set_info (info, prop, "superconstant", false);
	o[prop] = old;
      }
      ASSetPropFlags (o, prop, 4);
    }
    else
    {
      set_info (info, prop, "constant", false);
      set_info (info, prop, "superconstant", false);
      o[prop] = old;
    }
  }

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // remove constant flag
    ASSetPropFlags (o, prop, 0, 4);

    // try deleting
    var old = o[prop];
    delete o[prop];
    if (hasOwnProperty (o, prop))
    {
      set_info (info, prop, "permanent", true);
    }
    else
    {
      set_info (info, prop, "permanent", false);
      o[prop] = old;
    }

    // put constant flag back, if it was set
    if (get_info (info, prop, "constant") == true)
      ASSetPropFlags (o, prop, 4);
  }

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    // format propflags
    var flags = "";
    if (get_info (info, prop, "hidden") == true) {
      flags += "h";
    }
    if (get_info (info, prop, "superpermanent") == true) {
      flags += "P";
    } else if (get_info (info, prop, "permanent") == true) {
      flags += "p";
    }
    if (get_info (info, prop, "superconstant") == true) {
      flags += "C";
    } else if (get_info (info, prop, "constant") == true) {
      flags += "c";
    }
    if (flags != "")
      flags = " (" + flags + ")";

    var value = "";
    // add value depending on the type
    if (typeof (o[prop]) == "number" || typeof (o[prop]) == "boolean") {
      value += " : " + o[prop];
    } else if (typeof (o[prop]) == "string") {
      value += " : \"" + o[prop] + "\"";
    }

    // recurse if it's object or function and this is the place it has been
    // named after
    if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function")
    {
      if (prefix + (prefix != "" ? "." : "") + identifier + "." + prop ==
	  o[prop]["mySecretId"])
      {
	trace (indentation + prop + flags + " = " + typeof (o[prop]));
	trace_properties_recurse (o[prop], prefix + (prefix != "" ? "." : "") +
	    identifier, prop, level + 1);
      }
      else
      {
	trace (indentation + prop + flags + " = " + o[prop]["mySecretId"]);
      }
    }
    else
    {
      trace (indentation + prop + flags + " = " + typeof (o[prop]) + value);
    }
  }
}

function generate_names (o, prefix, identifier)
{
  // mark the ones that are not hidden
  var nothidden = new Array ();
  for (var prop in o) {
    nothidden.push (prop);
  }

  // unhide everything
  ASSetPropFlags (o, null, 0, 1);

  var all = new Array ();
  for (var prop in o)
  {
    if (is_blaclisted (o, prop) == false) {
      // only get the ones that are not only in the __proto__
      if (hasOwnProperty (o, prop) == true) {
	all.push (prop);
      }
    }
  }
  all.sort ();

  // hide the ones that were already hidden
  ASSetPropFlags (o, null, 1, 0);
  ASSetPropFlags (o, nothidden, 0, 1);

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function") {
      if (hasOwnProperty (o[prop], "mySecretId")) {
	all[i] = null; // don't recurse to it again
      } else {
	o[prop]["mySecretId"] = prefix + (prefix != "" ? "." : "") +
	  identifier + "." + prop;
      }
    }
  }

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    if (prop != null) {
      if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function")
	generate_names (o[prop], prefix + (prefix != "" ? "." : "") +
	    identifier, prop);
    }
  }
}

function trace_properties (o, prefix, identifier)
{
  _global["mySecretId"] = "_global";
  _global.Object["mySecretId"] = "_global.Object";
  _global.XMLNode["mySecretId"] = "_global.XMLNode";
  generate_names (_global.Object, "_global", "Object");
  generate_names (_global.XMLNode, "_global", "XMLNode");
  generate_names (_global, "", "_global");

  if (typeof (o) == "object" || typeof (o) == "function")
  {
    if (!o.hasOwnProperty ("mySecretId")) {
      o["mySecretId"] = prefix + (prefix != "" ? "." : "") + identifier;
      generate_names (o, prefix, identifier);
    }

    if (prefix + (prefix != "" ? "." : "") + identifier == o["mySecretId"])
    {
      trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	  typeof (o));
    }
    else
    {
      trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	  o["mySecretId"]);
    }
    trace_properties_recurse (o, prefix, identifier, 1);
  }
  else
  {
    var value = "";
    if (typeof (o) == "number" || typeof (o) == "boolean") {
      value += " : " + o;
    } else if (typeof (o) == "string") {
      value += " : \"" + o + "\"";
    }
    trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	typeof (o) + value);
  }
}

#if __SWF_VERSION__ == 5
// create a _global object, since it doesn't have one, these are ver 6 values
_global = new_empty_object ();
_global.ASSetNative = ASSetNative;
_global.ASSetNativeAccessor = ASSetNativeAccessor;
_global.ASSetPropFlags = ASSetPropFlags;
_global.ASconstructor = ASconstructor;
_global.ASnative = ASnative;
_global.Accessibility = Accessibility;
_global.Array = Array;
_global.AsBroadcaster = AsBroadcaster;
_global.AsSetupError = AsSetupError;
_global.Boolean = Boolean;
_global.Button = Button;
_global.Camera = Camera;
_global.Color = Color;
_global.ContextMenu = ContextMenu;
_global.ContextMenuItem = ContextMenuItem;
_global.Date = Date;
_global.Error = Error;
_global.Function = Function;
_global.Infinity = Infinity;
_global.Key = Key;
_global.LoadVars = LoadVars;
_global.LocalConnection = LocalConnection;
_global.Math = Math;
_global.Microphone = Microphone;
_global.Mouse = Mouse;
_global.MovieClip = MovieClip;
_global.MovieClipLoader = MovieClipLoader;
_global.NaN = NaN;
_global.NetConnection = NetConnection;
_global.NetStream = NetStream;
_global.Number = Number;
_global.Object = Object;
_global.PrintJob = PrintJob;
_global.RemoteLSOUsage = RemoteLSOUsage;
_global.Selection = Selection;
_global.SharedObject = SharedObject;
_global.Sound = Sound;
_global.Stage = Stage;
_global.String = String;
_global.System = System;
_global.TextField = TextField;
_global.TextFormat = TextFormat;
_global.TextSnapshot = TextSnapshot;
_global.Video = Video;
_global.XML = XML;
_global.XMLNode = XMLNode;
_global.XMLSocket = XMLSocket;
_global.clearInterval = clearInterval;
_global.clearTimeout = clearTimeout;
_global.enableDebugConsole = enableDebugConsole;
_global.escape = escape;
_global.flash = flash;
_global.isFinite = isFinite;
_global.isNaN = isNaN;
_global.o = o;
_global.parseFloat = parseFloat;
_global.parseInt = parseInt;
_global.setInterval = setInterval;
_global.setTimeout = setTimeout;
_global.showRedrawRegions = showRedrawRegions;
_global.textRenderer = textRenderer;
_global.trace = trace;
_global.unescape = unescape;
_global.updateAfterEvent = updateAfterEvent;
#endif

function new_empty_object () {
  var hash = new Object ();
  ASSetPropFlags (hash, null, 0, 7);
  for (var prop in hash) {
    hash[prop] = "to-be-deleted";
    delete hash[prop];
  }
  return hash;
}

function hasOwnProperty_inner (o, prop)
{
  if (o.hasOwnProperty != undefined)
    return o.hasOwnProperty (prop);

  o.hasOwnProperty = ASnative (101, 5);
  var result = o.hasOwnProperty (prop);
  delete o.hasOwnProperty;
  return result;
}

function hasOwnProperty (o, prop)
{
  var result = hasOwnProperty_inner (o, prop);
#if __SWF_VERSION__ != 6
  if (result == false) {
    ASSetPropFlags (o, prop, 0, 256);
    result = hasOwnProperty_inner (o, prop);
    if (result)
      ASSetPropFlags (o, prop, 256);
  }
#endif
  return result;
}

function new_info () {
  return new_empty_object ();
}

function set_info (info, prop, id, value) {
  info[prop + "_-_" + id] = value;
}

function get_info (info, prop, id) {
  return info[prop + "_-_" + id];
}

function is_blaclisted (o, prop)
{
  if (prop == "mySecretId" || prop == "globalSecretId")
    return true;

  if (o == _global.Camera && prop == "names")
    return true;

  if (o == _global.Microphone && prop == "names")
    return true;

#if __SWF_VERSION__ < 6
  if (prop == "__proto__" && o[prop] == undefined)
    return true;
#endif

  return false;
}

function trace_properties_recurse (o, prefix, identifier, level)
{
  // to collect info about different properties
  var info = new_info ();

  // calculate indentation
  var indentation = "";
  for (var j = 0; j < level; j++) {
    indentation = indentation + "  ";
  }

  // mark the ones that are not hidden
  for (var prop in o)
  {
    // only get the ones that are not only in the __proto__
    if (is_blaclisted (o, prop) == false) {
      if (hasOwnProperty (o, prop) == true)
	set_info (info, prop, "hidden", false);
    }
  }

  // unhide everything
  ASSetPropFlags (o, null, 0, 1);

  var all = new Array ();
  var hidden = new Array ();
  for (var prop in o)
  {
    // only get the ones that are not only in the __proto__
    if (is_blaclisted (o, prop) == false) {
      if (hasOwnProperty (o, prop) == true) {
	all.push (prop);
	if (get_info (info, prop, "hidden") != false) {
	  set_info (info, prop, "hidden", true);
	  hidden.push (prop);
	}
      }
    }
  }
  all.sort ();

  // hide the ones that were already hidden
  ASSetPropFlags (o, hidden, 1, 0);

  if (all.length == 0) {
    trace (indentation + "no children");
    return nextSecretId;
  }

#if __SWF_VERSION__ != 6
  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // try changing value
    if (!hasOwnProperty_inner(o, prop) && hasOwnProperty(o, prop))
    {
      set_info (info, prop, "not6", true);
    }
    else
    {
      set_info (info, prop, "not6", false);
    }
  }
#endif

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // try changing value
    var old = o[prop];
    var val = "hello " + o[prop];
    o[prop] = val;
    if (o[prop] != val)
    {
      set_info (info, prop, "constant", true);

      // try changing value after removing constant propflag
      ASSetPropFlags (o, prop, 0, 4);
      o[prop] = val;
      if (o[prop] != val) {
	set_info (info, prop, "superconstant", true);
      } else {
	set_info (info, prop, "superconstant", false);
	o[prop] = old;
      }
      ASSetPropFlags (o, prop, 4);
    }
    else
    {
      set_info (info, prop, "constant", false);
      set_info (info, prop, "superconstant", false);
      o[prop] = old;
    }
  }

  for (var i = 0; i < all.length; i++)
  {
    var prop = all[i];

    // remove constant flag
    ASSetPropFlags (o, prop, 0, 4);

    // try deleting
    var old = o[prop];
    delete o[prop];
    if (hasOwnProperty (o, prop))
    {
      set_info (info, prop, "permanent", true);
    }
    else
    {
      set_info (info, prop, "permanent", false);
      o[prop] = old;
    }

    // put constant flag back, if it was set
    if (get_info (info, prop, "constant") == true)
      ASSetPropFlags (o, prop, 4);
  }

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    // format propflags
    var flags = "";
    if (get_info (info, prop, "hidden") == true) {
      flags += "h";
    }
    if (get_info (info, prop, "superpermanent") == true) {
      flags += "P";
    } else if (get_info (info, prop, "permanent") == true) {
      flags += "p";
    }
    if (get_info (info, prop, "superconstant") == true) {
      flags += "C";
    } else if (get_info (info, prop, "constant") == true) {
      flags += "c";
    }
    if (get_info (info, prop, "not6") == true) {
      flags += "6";
    }
    if (flags != "")
      flags = " (" + flags + ")";

    var value = "";
    // add value depending on the type
    if (typeof (o[prop]) == "number" || typeof (o[prop]) == "boolean") {
      value += " : " + o[prop];
    } else if (typeof (o[prop]) == "string") {
      value += " : \"" + o[prop] + "\"";
    }

    // recurse if it's object or function and this is the place it has been
    // named after
    if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function")
    {
      if (prefix + (prefix != "" ? "." : "") + identifier + "." + prop ==
	  o[prop]["mySecretId"])
      {
	trace (indentation + prop + flags + " = " + typeof (o[prop]));
	trace_properties_recurse (o[prop], prefix + (prefix != "" ? "." : "") +
	    identifier, prop, level + 1);
      }
      else
      {
	trace (indentation + prop + flags + " = " + o[prop]["mySecretId"]);
      }
    }
    else
    {
      trace (indentation + prop + flags + " = " + typeof (o[prop]) + value);
    }
  }
}

function generate_names (o, prefix, identifier)
{
  // mark the ones that are not hidden
  var nothidden = new Array ();
  for (var prop in o) {
    nothidden.push (prop);
  }

  // unhide everything
  ASSetPropFlags (o, null, 0, 1);

  var all = new Array ();
  for (var prop in o)
  {
    if (is_blaclisted (o, prop) == false) {
      // only get the ones that are not only in the __proto__
      if (hasOwnProperty (o, prop) == true) {
	all.push (prop);
      }
    }
  }
  all.sort ();

  // hide the ones that were already hidden
  ASSetPropFlags (o, null, 1, 0);
  ASSetPropFlags (o, nothidden, 0, 1);

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function") {
      if (hasOwnProperty (o[prop], "mySecretId")) {
	all[i] = null; // don't recurse to it again
      } else {
	o[prop]["mySecretId"] = prefix + (prefix != "" ? "." : "") +
	  identifier + "." + prop;
      }
    }
  }

  for (var i = 0; i < all.length; i++) {
    var prop = all[i];

    if (prop != null) {
      if (typeof (o[prop]) == "object" || typeof (o[prop]) == "function")
	generate_names (o[prop], prefix + (prefix != "" ? "." : "") +
	    identifier, prop);
    }
  }
}

function trace_properties (o, prefix, identifier)
{
  _global["mySecretId"] = "_global";
  _global.Object["mySecretId"] = "_global.Object";
  _global.XMLNode["mySecretId"] = "_global.XMLNode";
  generate_names (_global.Object, "_global", "Object");
  generate_names (_global.XMLNode, "_global", "XMLNode");
  generate_names (_global, "", "_global");

  if (typeof (o) == "object" || typeof (o) == "function")
  {
    if (!o.hasOwnProperty ("mySecretId")) {
      o["mySecretId"] = prefix + (prefix != "" ? "." : "") + identifier;
      generate_names (o, prefix, identifier);
    }

    if (prefix + (prefix != "" ? "." : "") + identifier == o["mySecretId"])
    {
      trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	  typeof (o));
    }
    else
    {
      trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	  o["mySecretId"]);
    }
    trace_properties_recurse (o, prefix, identifier, 1);
  }
  else
  {
    var value = "";
    if (typeof (o) == "number" || typeof (o) == "boolean") {
      value += " : " + o;
    } else if (typeof (o) == "string") {
      value += " : \"" + o + "\"";
    }
    trace (prefix + (prefix != "" ? "." : "") + identifier + " = " +
	typeof (o) + value);
  }
}

Make trace_properties.as detect properties with "not 6" flag and mark it

This only works on versions other than 6


// vim: tabstop=4 shiftwidth=4

// Copyright (c) 2010 , 杨博 (Yang Bo) All rights reserved.
//
//         pop.atry@gmail.com
//
// Use, modification and distribution are subject to the "New BSD License"
// as listed at <url: http://www.opensource.org/licenses/bsd-license.php >.

package com.netease.protobuf {
	import flash.utils.*
	public final class VarintWriter extends ByteArray {
		private var bitsLeft:uint = 0
		public function end():void {
			if (length == 1) {
				this[0] &= 0x7F
			} else {
				for (var i:uint = length; i > 0; i--) {
					const byte:uint = this[i - 1]
					if (byte != 0x80) {
						this[i - 1] = 0x7F & byte
						length = i
						return
					}
				}
			}
		}
		public function write(number:uint, bits:uint):void {
			if (bits <= bitsLeft) {
				this[length - 1] |= number << (7 - bitsLeft)
				bitsLeft -= bits
			} else {
				if (bitsLeft != 0) {
					this[length - 1] |= number << (7 - bitsLeft)
					bits -= bitsLeft
					number >>>= bitsLeft
				}
				while (bits >= 7) {
					writeByte(0x80 | number)
					number >>>= 7
					bits -= 7
				}
				writeByte(0x80 | number)
				bitsLeft = 7 - bits
			}
		}
	}
}

// vim: tabstop=4 shiftwidth=4

// Copyright (c) 2010 , 杨博 (Yang Bo) All rights reserved.
//
//         pop.atry@gmail.com
//
// Use, modification and distribution are subject to the "New BSD License"
// as listed at <url: http://www.opensource.org/licenses/bsd-license.php >.

package com.netease.protobuf {
	import flash.utils.*;
	public final class VarintWriter extends ByteArray {
		private var bitsLeft:uint = 0
		public function end():void {
			if (length == 1) {
				this[0] &= 0x7F
			} else {
				for (var i:uint = length; i > 0;) {
					const l:uint = i - 1
					const byte:uint = this[l]
					if (byte != 0x80) {
						this[l] = byte & 0x7F
						length = i
						return
					}
					i = l
				}
				this[0] = 0
				length = 1
			}
		}
		public function write(number:uint, bits:uint):void {
			if (bits <= bitsLeft) {
				this[length - 1] |= number << (7 - bitsLeft)
				bitsLeft -= bits
			} else {
				if (bitsLeft != 0) {
					this[length - 1] |= number << (7 - bitsLeft)
					bits -= bitsLeft
					number >>>= bitsLeft
				}
				while (bits >= 7) {
					writeByte(0x80 | number)
					number >>>= 7
					bits -= 7
				}
				writeByte(0x80 | number)
				bitsLeft = 7 - bits
			}
		}
	}
}

修复 Varint 大于 127 时组包错误的问题

修复 Varint 大于 127 时组包错误的问题


////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You 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 spark.skins.ios7
{

import flash.display.DisplayObject;

import mx.core.DPIClassification;
import mx.core.mx_internal;
import mx.events.FlexEvent;

import spark.components.supportClasses.StyleableTextField;
import spark.skins.ios7.assets.Button_up;
import spark.skins.mobile.supportClasses.ButtonSkinBase;

use namespace mx_internal;

/**
 *  ActionScript-based skin for Button controls in mobile applications. The skin supports
 *  iconClass and labelPlacement. It uses FXG classes to
 *  implement the vector drawing.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
public class ButtonSkin extends ButtonSkinBase
{
    //--------------------------------------------------------------------------
    //
    //  Class constants
    //
    //--------------------------------------------------------------------------

    /**
     * An array of color distribution ratios.
     * This is used in the chrome color fill.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    mx_internal static const CHROME_COLOR_RATIOS:Array = [0, 127.5];

    /**
     * An array of alpha values for the corresponding colors in the colors array.
     * This is used in the chrome color fill.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    mx_internal static const CHROME_COLOR_ALPHAS:Array = [1, 1];

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    /**
     *  Constructor.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function ButtonSkin()
    {
        super();
		//In iOS7, buttons look like simple links, without any shape containing the text
		//We still need to assign an asset to determine the size of the button
		//Button_up is a simple transparent graphic object
		upBorderSkin = spark.skins.ios7.assets.Button_up;
		downBorderSkin = spark.skins.ios7.assets.Button_up;
		layoutCornerEllipseSize = 0;

        switch (applicationDPI)
        {
			case DPIClassification.DPI_640:
			{

				layoutGap = 20;
				layoutPaddingLeft = 40;
				layoutPaddingRight = 40;
				layoutPaddingTop = 40;
				layoutPaddingBottom = 40;
				layoutBorderSize = 2;
				measuredDefaultWidth = 128;
				measuredDefaultHeight = 172;

				break;
			}
			case DPIClassification.DPI_480:
			{

				layoutGap = 14;
				layoutPaddingLeft = 30;
				layoutPaddingRight = 30;
				layoutPaddingTop = 30;
				layoutPaddingBottom = 30;
				layoutBorderSize = 2;
				measuredDefaultWidth = 96;
				measuredDefaultHeight = 130;

				break;
			}
            case DPIClassification.DPI_320:
            {

                layoutGap = 10;
                layoutPaddingLeft = 20;
                layoutPaddingRight = 20;
                layoutPaddingTop = 20;
                layoutPaddingBottom = 20;
                layoutBorderSize = 2;
                measuredDefaultWidth = 64;
                measuredDefaultHeight = 86;

                break;
            }
			case DPIClassification.DPI_240:
			{

				layoutGap = 7;
				layoutPaddingLeft = 15;
				layoutPaddingRight = 15;
				layoutPaddingTop = 15;
				layoutPaddingBottom = 15;
				layoutBorderSize = 1;
				measuredDefaultWidth = 48;
				measuredDefaultHeight = 65;

				break;
			}
			case DPIClassification.DPI_120:
			{

				layoutGap = 4;
				layoutPaddingLeft = 8;
				layoutPaddingRight = 8;
				layoutPaddingTop = 8;
				layoutPaddingBottom = 8;
				layoutBorderSize = 1;
				measuredDefaultWidth = 24;
				measuredDefaultHeight = 33;

				break;
			}
            default:
            {

                layoutGap = 5;
                layoutPaddingLeft = 10;
                layoutPaddingRight = 10;
                layoutPaddingTop = 10;
                layoutPaddingBottom = 10;
                layoutBorderSize = 1;
                measuredDefaultWidth = 32;
                measuredDefaultHeight = 43;

                break;
            }
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Layout variables
    //
    //--------------------------------------------------------------------------

    /**
     *  Defines the corner radius.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected var layoutCornerEllipseSize:uint;

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
    private var _border:DisplayObject;

    private var changeFXGSkin:Boolean = false;

    private var borderClass:Class;

    mx_internal var fillColorStyleName:String = "chromeColor";

    /**
     *  Defines the shadow for the Button control's label.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public var labelDisplayShadow:StyleableTextField;

    /**
     *  Read-only button border graphic. Use getBorderClassForCurrentState()
     *  to specify a graphic per-state.
     *
     *  @see #getBorderClassForCurrentState()
     */
    protected function get border():DisplayObject
    {
        return _border;
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    /**
     *  Class to use for the border in the up state.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     *
     *  @default Button_up
     */
    protected var upBorderSkin:Class;

    /**
     *  Class to use for the border in the down state.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     *
     *  @default Button_down
     */
    protected var downBorderSkin:Class;

    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function createChildren():void
    {
        super.createChildren();

        if (!labelDisplayShadow && labelDisplay)
        {
            labelDisplayShadow = StyleableTextField(createInFontContext(StyleableTextField));
            labelDisplayShadow.styleName = this;
            labelDisplayShadow.colorName = "textShadowColor";
            labelDisplayShadow.useTightTextBounds = false;

            // add shadow before display
            addChildAt(labelDisplayShadow, getChildIndex(labelDisplay));
        }

        setStyle("textAlign", "center");
    }

    /**
     *  @private
     */
    override protected function commitCurrentState():void
    {
        super.commitCurrentState();

        borderClass = getBorderClassForCurrentState();

        if (!(_border is borderClass))
            changeFXGSkin = true;

        // update borderClass and background
        invalidateDisplayList();
    }

    /**
     *  @private
     */
    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.layoutContents(unscaledWidth, unscaledHeight);

        // size the FXG background
        if (changeFXGSkin)
        {
            changeFXGSkin = false;

            if (_border)
            {
                removeChild(_border);
                _border = null;
            }

            if (borderClass)
            {
                _border = new borderClass();
                addChildAt(_border, 0);
            }
        }

        layoutBorder(unscaledWidth, unscaledHeight);

        // update label shadow
        labelDisplayShadow.alpha = getStyle("textShadowAlpha");
        labelDisplayShadow.commitStyles();

        // don't use tightText positioning on shadow
        setElementPosition(labelDisplayShadow, labelDisplay.x, labelDisplay.y + 1);
        setElementSize(labelDisplayShadow, labelDisplay.width, labelDisplay.height);

        // if labelDisplay is truncated, then push it down here as well.
        // otherwise, it would have gotten pushed in the labelDisplay_valueCommitHandler()
        if (labelDisplay.isTruncated)
            labelDisplayShadow.text = labelDisplay.text;
    }

    /**
     *  Position the background of the skin. Override this function to re-position the background.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    mx_internal function layoutBorder(unscaledWidth:Number, unscaledHeight:Number):void
    {
        setElementSize(border, unscaledWidth, unscaledHeight);
        setElementPosition(border, 0, 0);
    }

    /**
     *  Returns the borderClass to use based on the currentState.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected function getBorderClassForCurrentState():Class
    {
        if (currentState == "down")
            return downBorderSkin;
        else
            return upBorderSkin;
    }

    //--------------------------------------------------------------------------
    //
    //  Event Handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function labelDisplay_valueCommitHandler(event:FlexEvent):void
    {
        super.labelDisplay_valueCommitHandler(event);
        labelDisplayShadow.text = labelDisplay.text;
    }

}
}

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You 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 spark.skins.ios7
{

import flash.display.DisplayObject;

import mx.core.DPIClassification;
import mx.core.mx_internal;
import mx.events.FlexEvent;

import spark.components.supportClasses.StyleableTextField;
import spark.skins.ios7.assets.Button_up;
import spark.skins.mobile.supportClasses.ButtonSkinBase;

use namespace mx_internal;

/**
 *  ActionScript-based skin for Button controls in mobile applications. The skin supports
 *  iconClass and labelPlacement. It uses FXG classes to
 *  implement the vector drawing.
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
public class ButtonSkin extends ButtonSkinBase
{
    //--------------------------------------------------------------------------
    //
    //  Class constants
    //
    //--------------------------------------------------------------------------

    /**
     * An array of color distribution ratios.
     * This is used in the chrome color fill.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    mx_internal static const CHROME_COLOR_RATIOS:Array = [0, 127.5];

    /**
     * An array of alpha values for the corresponding colors in the colors array.
     * This is used in the chrome color fill.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    mx_internal static const CHROME_COLOR_ALPHAS:Array = [1, 1];

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    /**
     *  Constructor.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function ButtonSkin()
    {
        super();
		//In iOS7, buttons look like simple links, without any shape containing the text
		//We still need to assign an asset to determine the size of the button
		//Button_up is a simple transparent graphic object
		upBorderSkin = spark.skins.ios7.assets.Button_up;
		downBorderSkin = spark.skins.ios7.assets.Button_up;
		layoutCornerEllipseSize = 0;

        switch (applicationDPI)
        {
			case DPIClassification.DPI_640:
			{

				layoutGap = 20;
				layoutPaddingLeft = 40;
				layoutPaddingRight = 40;
				layoutPaddingTop = 40;
				layoutPaddingBottom = 40;
				layoutBorderSize = 2;
				measuredDefaultWidth = 128;
				measuredDefaultHeight = 172;

				break;
			}
			case DPIClassification.DPI_480:
			{

				layoutGap = 14;
				layoutPaddingLeft = 30;
				layoutPaddingRight = 30;
				layoutPaddingTop = 30;
				layoutPaddingBottom = 30;
				layoutBorderSize = 2;
				measuredDefaultWidth = 96;
				measuredDefaultHeight = 130;

				break;
			}
            case DPIClassification.DPI_320:
            {

                layoutGap = 10;
                layoutPaddingLeft = 20;
                layoutPaddingRight = 20;
                layoutPaddingTop = 20;
                layoutPaddingBottom = 20;
                layoutBorderSize = 2;
                measuredDefaultWidth = 64;
                measuredDefaultHeight = 86;

                break;
            }
			case DPIClassification.DPI_240:
			{

				layoutGap = 7;
				layoutPaddingLeft = 15;
				layoutPaddingRight = 15;
				layoutPaddingTop = 15;
				layoutPaddingBottom = 15;
				layoutBorderSize = 1;
				measuredDefaultWidth = 48;
				measuredDefaultHeight = 65;

				break;
			}
			case DPIClassification.DPI_120:
			{

				layoutGap = 4;
				layoutPaddingLeft = 8;
				layoutPaddingRight = 8;
				layoutPaddingTop = 8;
				layoutPaddingBottom = 8;
				layoutBorderSize = 1;
				measuredDefaultWidth = 24;
				measuredDefaultHeight = 33;

				break;
			}
            default:
            {

                layoutGap = 5;
                layoutPaddingLeft = 10;
                layoutPaddingRight = 10;
                layoutPaddingTop = 10;
                layoutPaddingBottom = 10;
                layoutBorderSize = 1;
                measuredDefaultWidth = 32;
                measuredDefaultHeight = 43;

                break;
            }
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Layout variables
    //
    //--------------------------------------------------------------------------

    /**
     *  Defines the corner radius.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected var layoutCornerEllipseSize:uint;

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
    private var _border:DisplayObject;

    private var changeFXGSkin:Boolean = false;

    private var borderClass:Class;

    mx_internal var fillColorStyleName:String = "chromeColor";

    /**
     *  Defines the shadow for the Button control's label.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public var labelDisplayShadow:StyleableTextField;

    /**
     *  Read-only button border graphic. Use getBorderClassForCurrentState()
     *  to specify a graphic per-state.
     *
     *  @see #getBorderClassForCurrentState()
     */
    protected function get border():DisplayObject
    {
        return _border;
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    /**
     *  Class to use for the border in the up state.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     *
     *  @default Button_up
     */
    protected var upBorderSkin:Class;

    /**
     *  Class to use for the border in the down state.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     *
     *  @default Button_down
     */
    protected var downBorderSkin:Class;

    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function createChildren():void
    {
        super.createChildren();
        setStyle("textAlign", "center");
    }

    /**
     *  @private
     */
    override protected function commitCurrentState():void
    {
        super.commitCurrentState();

        borderClass = getBorderClassForCurrentState();

        if (!(_border is borderClass))
            changeFXGSkin = true;

        // update borderClass and background
        invalidateDisplayList();
    }

    /**
     *  @private
     */
    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.layoutContents(unscaledWidth, unscaledHeight);

        // size the FXG background
        if (changeFXGSkin)
        {
            changeFXGSkin = false;

            if (_border)
            {
                removeChild(_border);
                _border = null;
            }

            if (borderClass)
            {
                _border = new borderClass();
                addChildAt(_border, 0);
            }
        }

        layoutBorder(unscaledWidth, unscaledHeight);

    }

    /**
     *  Position the background of the skin. Override this function to re-position the background.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    mx_internal function layoutBorder(unscaledWidth:Number, unscaledHeight:Number):void
    {
        setElementSize(border, unscaledWidth, unscaledHeight);
        setElementPosition(border, 0, 0);
    }

    /**
     *  Returns the borderClass to use based on the currentState.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected function getBorderClassForCurrentState():Class
    {
        if (currentState == "down")
            return downBorderSkin;
        else
            return upBorderSkin;
    }

    //--------------------------------------------------------------------------
    //
    //  Event Handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function labelDisplay_valueCommitHandler(event:FlexEvent):void
    {
        super.labelDisplay_valueCommitHandler(event);
    }

}
}

Remove labeldisplayshadow since it is not required


/* ***** BEGIN LICENSE BLOCK *****
 *
 * This file is part of Weave.
 *
 * The Initial Developer of Weave is the Institute for Visualization
 * and Perception Research at the University of Massachusetts Lowell.
 * Portions created by the Initial Developer are Copyright (C) 2008-2015
 * the Initial Developer. All Rights Reserved.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * ***** END LICENSE BLOCK ***** */

package weavejs.util
{
	public class DateUtils
	{
		/**
		 * This must be set externally.
		 */
		public static var moment:Object;

		public static function parse(date:Object, moment_fmt:String, force_utc:Boolean = false, force_local:Boolean = false):Date
		{
			if (moment_fmt)
				return moment(date, moment_fmt, true).toDate();
			return moment(date).toDate();
		}
		public static function format(date:Object, moment_fmt:String):String
		{
			return moment(date).format(moment_fmt);
		}
		public static function formatDuration(date:Object):String
		{
			return moment.duration(date).humanize();
		}
		public static function detectFormats(dates:Array/*/<string>/*/, moment_formats:Array/*/<string>/*/):Array/*/<string>/*/
		{
			var validFormatsSparse:Array = [].concat(moment_formats);
			var fmt:String;

			for each (var date:String in dates)
			{
				for (var fmtIdx:String in validFormatsSparse)
				{
					fmt = validFormatsSparse[fmtIdx];
					if (!fmt)
						continue;

					var m:Object = new moment(date, fmt, true);
					if (!m.isValid())
					{
						validFormatsSparse[fmtIdx] = null;
					}
				}
			}

			var validFormats:Array = [];
			for each (fmt in validFormatsSparse)
			{
				if (fmt !== null)
				{
					validFormats.push(fmt);
				}
			}

			return validFormats;
		}
	}
}

/* ***** BEGIN LICENSE BLOCK *****
 *
 * This file is part of Weave.
 *
 * The Initial Developer of Weave is the Institute for Visualization
 * and Perception Research at the University of Massachusetts Lowell.
 * Portions created by the Initial Developer are Copyright (C) 2008-2015
 * the Initial Developer. All Rights Reserved.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * ***** END LICENSE BLOCK ***** */

package weavejs.util
{
	public class DateUtils
	{
		/**
		 * This must be set externally.
		 */
		public static var moment:Object;

		public static function parse(date:Object, moment_fmt:String, force_utc:Boolean = false, force_local:Boolean = false):Date
		{
			if (moment_fmt)
				return moment(date, moment_fmt, true).toDate();
			return moment(date).toDate();
		}
		public static function format(date:Object, moment_fmt:String):String
		{
			return moment(date).format(moment_fmt);
		}
		public static function formatDuration(date:Object):String
		{
			return !isNaN(date as Number) ? moment.duration(date).humanize() : "";
		}
		public static function detectFormats(dates:Array/*/<string>/*/, moment_formats:Array/*/<string>/*/):Array/*/<string>/*/
		{
			var validFormatsSparse:Array = [].concat(moment_formats);
			var fmt:String;

			for each (var date:String in dates)
			{
				for (var fmtIdx:String in validFormatsSparse)
				{
					fmt = validFormatsSparse[fmtIdx];
					if (!fmt)
						continue;

					var m:Object = new moment(date, fmt, true);
					if (!m.isValid())
					{
						validFormatsSparse[fmtIdx] = null;
					}
				}
			}

			var validFormats:Array = [];
			for each (fmt in validFormatsSparse)
			{
				if (fmt !== null)
				{
					validFormats.push(fmt);
				}
			}

			return validFormats;
		}
	}
}

Add check for NaN in formatDuration. #WEAVE-616 Fixed Spent time 1h


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

	class com.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");
		}

	}

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