                     names[i] = new TypeName(name, types);
                     break;
                     
-				default:
-					throw new Error("invalid kind " + data[data.position-1])
-				}
-
-			infoPrint("Cpool names count "+ n +" size "+(data.position-start)+" "+int(100*(data.position-start)/data.length)+" %")
-			start = data.position
-
-			namespaces[0] = publicNs
-			strings[0] = "*"
-		}
-		
-		function parseMethodInfos()
-		{
-			var start:int = data.position
-			names[0] = new QName(publicNs,"*")
-			var method_count:int = readU32()
-			methods = []
-			for (var i:int=0; i < method_count; i++)
-			{
-				var m = methods[i] = new MethodInfo()
-				var param_count:int = readU32()
-				m.returnType = names[readU32()]
-				m.paramTypes = []
-				for (var j:int=0; j < param_count; j++)
-					m.paramTypes[j] = names[readU32()]
-				m.debugName = strings[readU32()]
-				m.flags = data.readByte()
-				if (m.flags & HAS_OPTIONAL)
-				{
-					// has_optional
-					var optional_count:int = readU32();
-					m.optionalValues = []
-					for( var k:int = param_count-optional_count; k < param_count; ++k)
-					{
-						var index = readU32()    // optional value index
-						var kind:int = data.readByte() // kind byte for each default value
-						if (index == 0)
-						{
-							// kind is ignored, default value is based on type
-							m.optionalValues[k] = undefined
-						}
-						else
-						{
-							if (!defaults[kind])
-								print("ERROR kind="+kind+" method_id " + i)
+                default:
+                    throw new Error("invalid kind " + data[data.position-1])
+                }
+
+            infoPrint("Cpool names count "+ n +" size "+(data.position-start)+" "+int(100*(data.position-start)/data.length)+" %")
+            start = data.position
+
+            namespaces[0] = publicNs
+            strings[0] = "*"
+        }
+        
+        function parseMethodInfos()
+        {
+            var start:int = data.position
+            names[0] = new QName(publicNs,"*")
+            var method_count:int = readU32()
+            methods = []
+            for (var i:int=0; i < method_count; i++)
+            {
+                var m = methods[i] = new MethodInfo()
+                var param_count:int = readU32()
+                m.returnType = names[readU32()]
+                m.paramTypes = []
+                for (var j:int=0; j < param_count; j++)
+                    m.paramTypes[j] = names[readU32()]
+                m.debugName = strings[readU32()]
+                m.flags = data.readByte()
+                if (m.flags & HAS_OPTIONAL)
+                {
+                    // has_optional
+                    var optional_count:int = readU32();
+                    m.optionalValues = []
+                    for( var k:int = param_count-optional_count; k < param_count; ++k)
+                    {
+                        var index = readU32()    // optional value index
+                        var kind:int = data.readByte() // kind byte for each default value
+                        if (index == 0)
+                        {
+                            // kind is ignored, default value is based on type
+                            m.optionalValues[k] = undefined
+                        }
+                        else
+                        {
+                            if (!defaults[kind])
+                                print("ERROR kind="+kind+" method_id " + i)
                             else
-							    m.optionalValues[k] = defaults[kind][index]
-						}
-					}
-				}
-				if (m.flags & HAS_ParamNames)
-				{
-					// has_paramnames
-					for( var k:int = 0; k < param_count; ++k)
+                                m.optionalValues[k] = defaults[kind][index]
+                        }
+                    }
+                }
+                if (m.flags & HAS_ParamNames)
+                {
+                    // has_paramnames
+                    for( var k:int = 0; k < param_count; ++k)
                     {
                         readU32();
                     }
                 }
-			}
-			infoPrint("MethodInfo count " +method_count+ " size "+(data.position-start)+" "+int(100*(data.position-start)/data.length)+" %")
-		}
-
-		function parseMetadataInfos()
-		{
-			var count:int = readU32()
-			metadata = []
-			for (var i:int=0; i < count; i++)
-	        {
-				// MetadataInfo
-				var m = metadata[i] = new MetaData()
-				m.name = strings[readU32()];
-	            var values_count:int = readU32();
-	            var names:Array = []
-	            for(var q:int = 0; q < values_count; ++q)
-					names[q] = strings[readU32()] // name 
-				for(var q:int = 0; q < values_count; ++q)
-					m[names[q]] = strings[readU32()] // value
-			}
-		}
-
-		function parseInstanceInfos()
-		{
-			var start:int = data.position
-			var count:int = readU32()
-			instances = []
-			for (var i:int=0; i < count; i++)
-	        {
-	        	var t = instances[i] = new Traits()
-	        	t.name = names[readU32()]
-	        	t.base = names[readU32()]
-	        	t.flags = data.readByte()
-				if (t.flags & 8)
-					t.protectedNs = namespaces[readU32()]
-	        	var interface_count = readU32()
-	        	for (var j:int=0; j < interface_count; j++)
-	        		t.interfaces[i] = names[readU32()]
-	        	var m = t.init = methods[readU32()]
-	        	m.name = t.name
-	        	m.kind = TRAIT_Method
-	        	m.id = -1
-	        	parseTraits(t)
-	        }
-			infoPrint("InstanceInfo size "+(data.position-start)+" "+int(100*(data.position-start)/data.length)+" %")
-		}
-		
-		function parseTraits(t:Traits)
-		{
-			var namecount = readU32()
-			for (var i:int=0; i < namecount; i++)
-			{
-				var name = names[readU32()]
-				var tag = data.readByte()
-				var kind = tag & 0xf
-				var member
-				switch(kind) {
-				case TRAIT_Slot:
-				case TRAIT_Const:
-				case TRAIT_Class:
-					var slot = member = new SlotInfo()
-					slot.id = readU32()
-					t.slots[slot.id] = slot
-					if (kind==TRAIT_Slot || kind==TRAIT_Const)
-					{
-						slot.type = names[readU32()]
-						var index=readU32()
-						if (index)
-							slot.value = defaults[data.readByte()][index]
-					}
-					else // (kind == TRAIT_Class)
-					{
-						slot.value = classes[readU32()]
-					}
-					break;
-				case TRAIT_Method:
-				case TRAIT_Getter:
-				case TRAIT_Setter:
-					var disp_id = readU32()
-					var method = member = methods[readU32()]
-					t.methods[disp_id] = method
-					method.id = disp_id
-					//print("\t",traitKinds[kind],name,disp_id,method,"// disp_id", disp_id)
-					break;
-				}
-				if (!member)
-					print("error trait kind "+kind)
-				member.kind = kind
-				member.name = name
-				t.names[String(name)] = t.members[i] = member
-				
-	            if ( (tag >> 4) & ATTR_metadata ) {
-					member.metadata = []
-					for(var j:int=0, mdCount:int=readU32(); j < mdCount; ++j)
-						member.metadata[j] = metadata[readU32()]
-				}
-			}
-		}
-
-		function parseClassInfos()
-		{
-			var start:int = data.position
-			var count:int = instances.length
-			classes = []
-			for (var i:int=0; i < count; i++)
-	        {
-	        	var t:Traits = classes[i] = new Traits()
-	        	t.init = methods[readU32()]
-	        	t.base = "Class"
-	        	t.itraits = instances[i]
-	        	t.name = t.itraits.name + "$"
-	        	t.init.name = t.itraits.name + "$cinit"
-	        	t.init.kind = TRAIT_Method
-	        	parseTraits(t)
-			}			
-			infoPrint("ClassInfo size "+(data.position-start)+" "+int(100*(data.position-start)/data.length)+"%")
-		}
-
-		function parseScriptInfos()
-		{
-			var start:int = data.position
-			var count:int = readU32()
-			scripts = []
-			for (var i:int=0; i < count; i++)
-	        {
-	        	var t = new Traits()
-				scripts[i] = t
-	        	t.name = "script" + i
-	        	t.base = names[0] // Object
-	        	t.init = methods[readU32()]
-	        	t.init.name = t.name + "$init"
-				t.init.kind = TRAIT_Method	    
-	        	parseTraits(t)
-	        }
-			infoPrint("ScriptInfo size "+(data.position-start)+" "+int(100*(data.position-start)/data.length)+" %")
-		}
-
-		function parseMethodBodies()
-		{
-			var start:int = data.position
-			var count:int = readU32()
-			for (var i:int=0; i < count; i++)
-	        {
-	        	var m = methods[readU32()]
-				m.max_stack = readU32()
-	        	m.local_count = readU32()
-	        	var initScopeDepth = readU32()
-	        	var maxScopeDepth = readU32()
-	        	m.max_scope = maxScopeDepth - initScopeDepth
-	        	var code_length = readU32()
-	        	m.code = new ByteArray()
-				m.code.endian = "littleEndian"
-	        	if (code_length > 0)
-		        	data.readBytes(m.code, 0, code_length)
-	       		var ex_count = readU32()
-	       		for (var j:int = 0; j < ex_count; j++)
-	       		{
-	       			var from = readU32()
-	       			var to = readU32()
-	       			var target = readU32()
-	       			var type = names[readU32()]
-					//print("magic " + magic.toString(16))
-					//if (magic >= (46<<16|16))
-						var name = names[readU32()];
-	       		}
-	       		parseTraits(m.activation = new Traits)
-	        }
-			infoPrint("MethodBodies size "+(data.position-start)+" "+int(100*(data.position-start)/data.length)+" %")
-		}
-		
-		function dump(indent:String="")
-		{
-		    for each (var t in scripts)
-		    {
-			    dumpPrint(indent+t.name)
-			    t.dump(this,indent)
-			    t.init.dump(this,indent)
-		    }
-
-		    for each (var m in methods)
-		    {
-			    if (m.anon) {
-				    m.dump(this,indent)
-			    }
-		    }
-
-			infoPrint("OPCODE\tSIZE\t% OF "+totalSize)
-			var done = []
-			for (;;)
-			{
-				var max:int = -1;
-				var maxsize:int = 0;
-				for (var i:int=0; i < 256; i++)
-				{
-					if (opSizes[i] > maxsize && !done[i])
-					{
-						max = i;
-						maxsize = opSizes[i];
-					}
-				}
-				if (max == -1)
-					break;
-				done[max] = 1;
-				infoPrint(opNames[max]+"\t"+int(opSizes[max])+"\t"+int(100*opSizes[max]/totalSize)+"%")
-			}
-		}
-	}
-	
-	class Rect
-	{
-		var nBits:int
-		var xMin:int, xMax:int
-		var yMin:int, yMax:int
-		public function toString()
-		{
-			return "[Rect "+xMin+" "+yMin+" "+xMax+" "+yMax+"]"
-		}
-	}
-	
-	const stagDoABC					:int = 72;   // embedded .abc (AVM+) bytecode
-	const stagSymbolClass				:int = 76;
+            }
+            infoPrint("MethodInfo count " +method_count+ " size "+(data.position-start)+" "+int(100*(data.position-start)/data.length)+" %")
+        }
+
+        function parseMetadataInfos()
+        {
+            var count:int = readU32()
+            metadata = []
+            for (var i:int=0; i < count; i++)
+            {
+                // MetadataInfo
+                var m = metadata[i] = new MetaData()
+                m.name = strings[readU32()];
+                var values_count:int = readU32();
+                var names:Array = []
+                for(var q:int = 0; q < values_count; ++q)
+                    names[q] = strings[readU32()] // name 
+                for(var q:int = 0; q < values_count; ++q)
+                    m[names[q]] = strings[readU32()] // value
+            }
+        }
+
+        function parseInstanceInfos()
+        {
+            var start:int = data.position
+            var count:int = readU32()
+            instances = []
+            for (var i:int=0; i < count; i++)
+            {
+                var t = instances[i] = new Traits()
+                t.name = names[readU32()]
+                t.base = names[readU32()]
+                t.flags = data.readByte()
+                if (t.flags & 8)
+                    t.protectedNs = namespaces[readU32()]
+                var interface_count = readU32()
+                for (var j:int=0; j < interface_count; j++)
+                    t.interfaces[i] = names[readU32()]
+                var m = t.init = methods[readU32()]
+                m.name = t.name
+                m.kind = TRAIT_Method
+                m.id = -1
+                parseTraits(t)
+            }
+            infoPrint("InstanceInfo size "+(data.position-start)+" "+int(100*(data.position-start)/data.length)+" %")
+        }
+        
+        function parseTraits(t:Traits)
+        {
+            var namecount = readU32()
+            for (var i:int=0; i < namecount; i++)
+            {
+                var name = names[readU32()]
+                var tag = data.readByte()
+                var kind = tag & 0xf
+                var member
+                switch(kind) {
+                case TRAIT_Slot:
+                case TRAIT_Const:
+                case TRAIT_Class:
+                    var slot = member = new SlotInfo()
+                    slot.id = readU32()
+                    t.slots[slot.id] = slot
+                    if (kind==TRAIT_Slot || kind==TRAIT_Const)
+                    {
+                        slot.type = names[readU32()]
+                        var index=readU32()
+                        if (index)
+                            slot.value = defaults[data.readByte()][index]
+                    }
+                    else // (kind == TRAIT_Class)
+                    {
+                        slot.value = classes[readU32()]
+                    }
+                    break;
+                case TRAIT_Method:
+                case TRAIT_Getter:
+                case TRAIT_Setter:
+                    var disp_id = readU32()
+                    var method = member = methods[readU32()]
+                    t.methods[disp_id] = method
+                    method.id = disp_id
+                    //print("\t",traitKinds[kind],name,disp_id,method,"// disp_id", disp_id)
+                    break;
+                }
+                if (!member)
+                    print("error trait kind "+kind)
+                member.kind = kind
+                member.name = name
+                t.names[String(name)] = t.members[i] = member
+                
+                if ( (tag >> 4) & ATTR_metadata ) {
+                    member.metadata = []
+                    for(var j:int=0, mdCount:int=readU32(); j < mdCount; ++j)
+                        member.metadata[j] = metadata[readU32()]
+                }
+            }
+        }
+
+        function parseClassInfos()
+        {
+            var start:int = data.position
+            var count:int = instances.length
+            classes = []
+            for (var i:int=0; i < count; i++)
+            {
+                var t:Traits = classes[i] = new Traits()
+                t.init = methods[readU32()]
+                t.base = "Class"
+                t.itraits = instances[i]
+                t.name = t.itraits.name + "$"
+                t.init.name = t.itraits.name + "$cinit"
+                t.init.kind = TRAIT_Method
+                parseTraits(t)
+            }           
+            infoPrint("ClassInfo size "+(data.position-start)+" "+int(100*(data.position-start)/data.length)+"%")
+        }
+
+        function parseScriptInfos()
+        {
+            var start:int = data.position
+            var count:int = readU32()
+            scripts = []
+            for (var i:int=0; i < count; i++)
+            {
+                var t = new Traits()
+                scripts[i] = t
+                t.name = "script" + i
+                t.base = names[0] // Object
+                t.init = methods[readU32()]
+                t.init.name = t.name + "$init"
+                t.init.kind = TRAIT_Method      
+                parseTraits(t)
+            }
+            infoPrint("ScriptInfo size "+(data.position-start)+" "+int(100*(data.position-start)/data.length)+" %")
+        }
+
+        function parseMethodBodies()
+        {
+            var start:int = data.position
+            var count:int = readU32()
+            for (var i:int=0; i < count; i++)
+            {
+                var m = methods[readU32()]
+                m.max_stack = readU32()
+                m.local_count = readU32()
+                var initScopeDepth = readU32()
+                var maxScopeDepth = readU32()
+                m.max_scope = maxScopeDepth - initScopeDepth
+                var code_length = readU32()
+                m.code = new ByteArray()
+                m.code.endian = "littleEndian"
+                if (code_length > 0)
+                    data.readBytes(m.code, 0, code_length)
+                var ex_count = readU32()
+                for (var j:int = 0; j < ex_count; j++)
+                {
+                    var from = readU32()
+                    var to = readU32()
+                    var target = readU32()
+                    var type = names[readU32()]
+                    //print("magic " + magic.toString(16))
+                    //if (magic >= (46<<16|16))
+                        var name = names[readU32()];
+                }
+                parseTraits(m.activation = new Traits)
+            }
+            infoPrint("MethodBodies size "+(data.position-start)+" "+int(100*(data.position-start)/data.length)+" %")
+        }
+        
+        function dump(indent:String="")
+        {
+            for each (var t in scripts)
+            {
+                dumpPrint(indent+t.name)
+                t.dump(this,indent)
+                t.init.dump(this,indent)
+            }
+
+            for each (var m in methods)
+            {
+                if (m.anon) {
+                    m.dump(this,indent)
+                }
+            }
+
+            infoPrint("OPCODE\tSIZE\t% OF "+totalSize)
+            var done = []
+            for (;;)
+            {
+                var max:int = -1;
+                var maxsize:int = 0;
+                for (var i:int=0; i < 256; i++)
+                {
+                    if (opSizes[i] > maxsize && !done[i])
+                    {
+                        max = i;
+                        maxsize = opSizes[i];
+                    }
+                }
+                if (max == -1)
+                    break;
+                done[max] = 1;
+                infoPrint(opNames[max]+"\t"+int(opSizes[max])+"\t"+int(100*opSizes[max]/totalSize)+"%")
+            }
+        }
+    }
+    
+    class Rect
+    {
+        var nBits:int
+        var xMin:int, xMax:int
+        var yMin:int, yMax:int
+        public function toString()
+        {
+            return "[Rect "+xMin+" "+yMin+" "+xMax+" "+yMax+"]"
+        }
+    }
+    
+    const stagDoABC                 :int = 72;   // embedded .abc (AVM+) bytecode
+    const stagSymbolClass               :int = 76;
     const stagDoABC2                  :int = 82;   // revised ABC version with a name
 
-	var tagNames:Array = [
-		"End",					// 00
-		"ShowFrame",			// 01
-		"DefineShape",			// 02
-		"FreeCharacter",		// 03
-		"PlaceObject",			// 04
-		"RemoveObject",			// 05
-		"DefineBits",			// 06
-		"DefineButton",			// 07
-		"JPEGTables",			// 08
-		"SetBackgroundColor",	// 09
-
-		"DefineFont",			// 10
-		"DefineText",			// 11
-		"DoAction",				// 12
-		"DefineFontInfo",		// 13
-
-		"DefineSound",			// 14
-		"StartSound",			// 15
-		"StopSound",			// 16
-
-		"DefineButtonSound",	// 17
-
-		"SoundStreamHead",		// 18
-		"SoundStreamBlock",		// 19
-
-		"DefineBitsLossless",	// 20
-		"DefineBitsJPEG2",		// 21
-
-		"DefineShape2",			// 22
-		"DefineButtonCxform",	// 23
-
-		"Protect",				// 24
-
-		"PathsArePostScript",	// 25
-
-		"PlaceObject2",			// 26
-		"27 (invalid)",			// 27
-		"RemoveObject2",		// 28
-
-		"SyncFrame",			// 29
-		"30 (invalid)",			// 30
-		"FreeAll",				// 31
-
-		"DefineShape3",			// 32
-		"DefineText2",			// 33
-		"DefineButton2",		// 34
-		"DefineBitsJPEG3",		// 35
-		"DefineBitsLossless2",	// 36
-		"DefineEditText",		// 37
-
-		"DefineVideo",			// 38
-
-		"DefineSprite",			// 39
-		"NameCharacter",		// 40
-		"ProductInfo",			// 41
-		"DefineTextFormat",		// 42
-		"FrameLabel",			// 43
-		"DefineBehavior",		// 44
-		"SoundStreamHead2",		// 45
-		"DefineMorphShape",		// 46
-		"FrameTag",				// 47
-		"DefineFont2",			// 48
-		"GenCommand",			// 49
-		"DefineCommandObj",		// 50
-		"CharacterSet",			// 51
-		"FontRef",				// 52
-
-		"DefineFunction",		// 53
-		"PlaceFunction",		// 54
-
-		"GenTagObject",			// 55
-
-		"ExportAssets",			// 56
-		"ImportAssets",			// 57
-
-		"EnableDebugger",		// 58
-
-		"DoInitAction",			// 59
-		"DefineVideoStream",	// 60
-		"VideoFrame",			// 61
-
-		"DefineFontInfo2",		// 62
-		"DebugID", 				// 63
-		"EnableDebugger2", 		// 64
-        "ScriptLimits", 		// 65
-
-        "SetTabIndex", 			// 66
-
-		"DefineShape4", 		// 67
-		"DefineMorphShape2", 	// 68
-
-		"FileAttributes", 		// 69
-
-		"PlaceObject3", 		// 70
-		"ImportAssets2", 		// 71
-
-		"DoABC", 				// 72
-		"73 (invalid)",			// 73
-		"74 (invalid)",			// 74
-		"75 (invalid)",			// 75
-		"SymbolClass",			// 76
+    var tagNames:Array = [
+        "End",                  // 00
+        "ShowFrame",            // 01
+        "DefineShape",          // 02
+        "FreeCharacter",        // 03
+        "PlaceObject",          // 04
+        "RemoveObject",         // 05
+        "DefineBits",           // 06
+        "DefineButton",         // 07
+        "JPEGTables",           // 08
+        "SetBackgroundColor",   // 09
+
+        "DefineFont",           // 10
+        "DefineText",           // 11
+        "DoAction",             // 12
+        "DefineFontInfo",       // 13
+
+        "DefineSound",          // 14
+        "StartSound",           // 15
+        "StopSound",            // 16
+
+        "DefineButtonSound",    // 17
+
+        "SoundStreamHead",      // 18
+        "SoundStreamBlock",     // 19
+
+        "DefineBitsLossless",   // 20
+        "DefineBitsJPEG2",      // 21
+
+        "DefineShape2",         // 22
+        "DefineButtonCxform",   // 23
+
+        "Protect",              // 24
+
+        "PathsArePostScript",   // 25
+
+        "PlaceObject2",         // 26
+        "27 (invalid)",         // 27
+        "RemoveObject2",        // 28
+
+        "SyncFrame",            // 29
+        "30 (invalid)",         // 30
+        "FreeAll",              // 31
+
+        "DefineShape3",         // 32
+        "DefineText2",          // 33
+        "DefineButton2",        // 34
+        "DefineBitsJPEG3",      // 35
+        "DefineBitsLossless2",  // 36
+        "DefineEditText",       // 37
+
+        "DefineVideo",          // 38
+
+        "DefineSprite",         // 39
+        "NameCharacter",        // 40
+        "ProductInfo",          // 41
+        "DefineTextFormat",     // 42
+        "FrameLabel",           // 43
+        "DefineBehavior",       // 44
+        "SoundStreamHead2",     // 45
+        "DefineMorphShape",     // 46
+        "FrameTag",             // 47
+        "DefineFont2",          // 48
+        "GenCommand",           // 49
+        "DefineCommandObj",     // 50
+        "CharacterSet",         // 51
+        "FontRef",              // 52
+
+        "DefineFunction",       // 53
+        "PlaceFunction",        // 54
+
+        "GenTagObject",         // 55
+
+        "ExportAssets",         // 56
+        "ImportAssets",         // 57
+
+        "EnableDebugger",       // 58
+
+        "DoInitAction",         // 59
+        "DefineVideoStream",    // 60
+        "VideoFrame",           // 61
+
+        "DefineFontInfo2",      // 62
+        "DebugID",              // 63
+        "EnableDebugger2",      // 64
+        "ScriptLimits",         // 65
+
+        "SetTabIndex",          // 66
+
+        "DefineShape4",         // 67
+        "DefineMorphShape2",    // 68
+
+        "FileAttributes",       // 69
+
+        "PlaceObject3",         // 70
+        "ImportAssets2",        // 71
+
+        "DoABC",                // 72
+        "73 (invalid)",         // 73
+        "74 (invalid)",         // 74
+        "75 (invalid)",         // 75
+        "SymbolClass",          // 76
         "77 (invalid)",         // 77
         "78 (invalid)",         // 78
         "79 (invalid)",         // 79

/* -*- tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1

        "81 (invalid)",         // 81
        "DoABC2",               // 82
        "83 (invalid)"          // 83
    ]
    
    
    class Swf
    {
        private var bitPos:int
        private var bitBuf:int
        
        private var data:ByteArray

        function Swf(data:ByteArray)
        {
            this.data = data
            infoPrint("size "+decodeRect())
            infoPrint("frame rate "+(data.readUnsignedByte()<<8|data.readUnsignedByte()))
            infoPrint("frame count "+data.readUnsignedShort())
            decodeTags()            
        }
        
        private function decodeTags()
        {
            var type:int, h:int, length:int
            var offset:int
    
            while (data.position < data.length)
            {
                type = (h = data.readUnsignedShort()) >> 6;
    
                if (((length = h & 0x3F) == 0x3F))
                    length = data.readInt();

                infoPrint(tagNames[type]+" "+length+"b "+int(100*length/data.length)+"%")
                switch (type)
                {
                case 0: return
                case stagDoABC2:
                    var pos1:int = data.position
                    data.readInt()
                    infoPrint("\nabc name "+readString())
                    length -= (data.position-pos1)
                    // fall through
                case stagDoABC:
                    var data2 = new ByteArray
                    data2.endian = "littleEndian"
                    data.readBytes(data2,0,length)
                    new Abc(data2).dump("  ")
                    infoPrint("")
                    break 
                default:
                    data.position += length
                }
            }
        }

        private function readString():String
        {
            var s:String = ""
            var c:int

            while (c=data.readUnsignedByte())
                s += String.fromCharCode(c)

            return s
        }
        
        private function syncBits() 
        {
            bitPos = 0
        }
        
        private function decodeRect():Rect
        {
            syncBits();
    
            var rect:Rect = new Rect();
    
            var nBits:int = readUBits(5)
            rect.xMin = readSBits(nBits);
            rect.xMax = readSBits(nBits);
            rect.yMin = readSBits(nBits);
            rect.yMax = readSBits(nBits);
    
            return rect;
        }
        
        function readSBits(numBits:int):int
        {
            if (numBits > 32)
                throw new Error("Number of bits > 32");

            var num:int = readUBits(numBits);
            var shift:int = 32-numBits;
            // sign extension
            num = (num << shift) >> shift;
            return num;
        }
        
        function readUBits(numBits:int):uint
        {
            if (numBits == 0)
                return 0
    
            var bitsLeft:int = numBits;
            var result:int = 0;
    
            if (bitPos == 0) //no value in the buffer - read a byte
            {
                bitBuf = data.readUnsignedByte()
                bitPos = 8;
            }
    
            while (true)
            {
                var shift:int = bitsLeft - bitPos;
                if (shift > 0)
                {
                    // Consume the entire buffer
                    result |= bitBuf << shift;
                    bitsLeft -= bitPos;
    
                    // Get the next byte from the input stream
                    bitBuf = data.readUnsignedByte();
                    bitPos = 8;
                }
                else
                {
                    // Consume a portion of the buffer
                    result |= bitBuf >> -shift;
                    bitPos -= bitsLeft;
                    bitBuf &= 0xff >> (8 - bitPos); // mask off the consumed bits
    
    //                if (print) System.out.println("  read"+numBits+" " + result);
                    return result;
                }
            }
        }
    }

    function help()
    {
        print(usage);
        System.exit(1)
    }

    function processArg(arg:String)
    {
        if (arg == '-a')
            doExtractAbc = true;
        else if (arg == '-i')
            doExtractInfo = true;
        else 
        {
            print('Unknown option '+arg)
            help()
        }
    } 

    function nextAbcFname():String
    {
        var s = currentFname
        if (currentFcount>0)
            s = s.concat(currentFcount);
        currentFcount++
        return s+'.abc'
    }   
    
    // main
    var doExtractAbc = false
    var doExtractInfo = false
    var currentFname = ''
    var currentFcount = 0
    for each (var file in System.argv)
    {
        if (file.indexOf('-')==0) 
        {
            processArg(file)
            continue
        }
        
        var x;
        if ((x = file.lastIndexOf(".swf")) != -1 || (x = file.lastIndexOf(".swc")) != -1)
            currentFname = file.substring(0,x);
        else
            currentFname = file;
        var data:ByteArray = ByteArray.readFile(file)
        data.endian = "littleEndian"
        var version:uint = data.readUnsignedInt()
        switch (version) {
        case 46<<16|14:
        case 46<<16|15:
        case 46<<16|16:
            var abc:Abc = new Abc(data)
            abc.dump()
            break
        case 67|87<<8|83<<16|10<<24: // SWC10
        case 67|87<<8|83<<16|9<<24: // SWC9
        case 67|87<<8|83<<16|8<<24: // SWC8
        case 67|87<<8|83<<16|7<<24: // SWC7
        case 67|87<<8|83<<16|6<<24: // SWC6
            var udata:ByteArray = new ByteArray
            udata.endian = "littleEndian"
            data.position = 8
            data.readBytes(udata,0,data.length-data.position)
            var csize:int = udata.length
            udata.uncompress()
            infoPrint("decompressed swf "+csize+" -> "+udata.length)
            udata.position = 0
            /*var swf:Swf =*/ new Swf(udata)
            break
        case 70|87<<8|83<<16|10<<24: // SWC10
        case 70|87<<8|83<<16|9<<24: // SWC9
        case 70|87<<8|83<<16|8<<24: // SWC8
        case 70|87<<8|83<<16|7<<24: // SWC7
        case 70|87<<8|83<<16|6<<24: // SWC6
        case 70|87<<8|83<<16|5<<24: // SWC5
        case 70|87<<8|83<<16|4<<24: // SWC4
            data.position = 8 // skip header and length
            /*var swf:Swf =*/ new Swf(data)
            break
        default:
            print('unknown format '+version)
            break
        }
    }

    if (System.argv<2)
        help();
}

