Table of Contents

Shortnote

Under certain circumstances, minified and obfuscated code can also lead to a performance gain. More precisely, when running code under an interpreter, the interpreter performs an identifier name lookup while it is reading the code. If, for example, you have a lot of lookups, for example in a loop, the time needed for that lookup can matter since longer variable names will require more time. When it comes to transferring code or storing code, the length of the code matters as well since more text has to be fetched. This applies in particular to environments with a high relative traffic, for example, web development where the browser has to fetch the contents of the page before it can be rendered.

Features

Limitations and TODO

Algorithm

  1. Delete everything between /* and */ using multi-line pattern matching.
  2. Strip any single-line commands using pattern matching.
  3. Delete newline, tabs and carriage returns.
  4. Go character-by-character through the LSL script and eliminate whitespaces, except in string constants.
  5. Split the script in two arrays: an array containing the code and an array containing the string constants.
    1. Replace the variables in the code array with a padded character relying on PHP's character arithmetic.
    2. Interpolate API constants in the code array.
    3. Merge the two arrays back together.
  6. Print out the result.

Benchmarks

Standard script: Starting tests...
Standard script: Ack(3,4): 125
Standard script: Tak(9,6,3): 6
Standard script: Fib(3): 3
Standard script: Tak(3.0,2,1): 2
Standard script: Finished tests in 0.589509s
Minified script: Starting tests...
Minified script: o(3,4): 125
Minified script: m(9,6,3): 6
Minified script: l(3): 3
Minified script: m(3.0,2,1): 2
Minified script: Finished tests in 0.384484s


Minified script: Starting tests...
Minified script: o(3,4): 125
Minified script: m(9,6,3): 6
Minified script: l(3): 3
Minified script: m(3.0,2,1): 2
Minified script: Finished tests in 0.244382s
Standard script: Starting tests...
Standard script: Ack(3,4): 125
Standard script: Tak(9,6,3): 6
Standard script: Fib(3): 3
Standard script: Tak(3.0,2,1): 2
Standard script: Finished tests in 0.314938s


====== ==================================================================================================

Standard script: Starting tests...
Standard script: P4
Standard script: 10 10
Standard script: 0x00000100078007C03FC0FF803FC007C007800100
Standard script: Finished tests in 0.108110s
Minified script: Starting tests...
Minified script: P4
Minified script: 10 10
Minified script: 0x00000100078007C03FC0FF803FC007C007800100
Minified script: Finished tests in 0.110667s

Minified script: Starting tests...
Minified script: P4
Minified script: 10 10
Minified script: 0x00000100078007C03FC0FF803FC007C007800100
Minified script: Finished tests in 0.109718s
Standard script: Starting tests...
Standard script: P4
Standard script: 10 10
Standard script: 0x00000100078007C03FC0FF803FC007C007800100
Standard script: Finished tests in 0.087156s

====== ==================================================================================================

Standard script: Starting tests...
Standard script: 3 (2/3)^k
Standard script: 30.194040 k^-0.5
Standard script: 0.996016 1/k(k+1)
Standard script: 4.806856 Flint Hills
Standard script: 42.991420 Cookson Hills
Standard script: 6.100676 Harmonic
Standard script: 1.640942 Riemann Zeta
Standard script: 0.691151 Alternating Harmonic
Standard script: 0.784398 Gregory
Standard script: Finished tests in 0.044383s
Minified script: Starting tests...
Minified script: 3 (2/3)^k
Minified script: 30.194040 k^-0.5
Minified script: 0.996016 1/g(k+1)
Minified script: 4.806856 Flint Hills
Minified script: 42.991420 Cookson Hills
Minified script: 6.100676 Harmonic
Minified script: 1.640942 Riemann Zeta
Minified script: 0.691151 Alternating Harmonic
Minified script: 0.784398 Gregory
Minified script: Finished tests in 0.044694s

Minified script: Starting tests...
Minified script: 3 (2/3)^k
Minified script: 30.194040 k^-0.5
Minified script: 0.996016 1/g(k+1)
Minified script: 4.806856 Flint Hills
Minified script: 42.991420 Cookson Hills
Minified script: 6.100676 Harmonic
Minified script: 1.640942 Riemann Zeta
Minified script: 0.691151 Alternating Harmonic
Minified script: 0.784398 Gregory
Minified script: Finished tests in 0.109784s
Standard script: Starting tests...
Standard script: 3 (2/3)^k
Standard script: 30.194040 k^-0.5
Standard script: 0.996016 1/k(k+1)
Standard script: 4.806856 Flint Hills
Standard script: 42.991420 Cookson Hills
Standard script: 6.100676 Harmonic
Standard script: 1.640942 Riemann Zeta
Standard script: 0.691151 Alternating Harmonic
Standard script: 0.784398 Gregory
Standard script: Finished tests in 0.113589s

====== ==================================================================================================

Standard script: Starting tests...
Standard script: Primes up to 128 31
Standard script: Finished tests in 0.572010s
Minified script: Starting tests...
Minified script: Primes up to 128 31
Minified script: Finished tests in 0.491805s

Standard script: Starting tests...
Standard script: Primes up to 128 31
Standard script: Finished tests in 0.572010s
Minified script: Starting tests...
Minified script: Primes up to 128 31
Minified script: Finished tests in 0.491805s

====== ==================================================================================================

Standard script: Starting tests...
Standard script: Primes up to 128 31
Standard script: Finished tests in 0.353490s
Minified script: Starting tests...
Minified script: Primes up to 128 31
Minified script: Finished tests in 0.334270u

Minified script: Starting tests...
Minified script: Primes up to 128 31
Minified script: Finished tests in 0.291267u
Standard script: Starting tests...
Standard script: Primes up to 128 31
Standard script: Finished tests in 0.380846s

====== ==================================================================================================

Standard script: Starting tests...
Standard script: Primes up to 128 31
Standard script: Finished tests in 0.382070s
Minified script: Starting tests...
Minified script: Primes up to 128 31
Minified script: Finished tests in 0.493327s

Minified script: Starting tests...
Minified script: Primes up to 128 31
Minified script: Finished tests in 0.356598s
Standard script: Starting tests...
Standard script: Primes up to 128 31
Standard script: Finished tests in 0.376642s

====== ==================================================================================================

Standard script: (Mono) used=22752, free=42784, change=0     Start of tests
Standard script: (Mono) used=22752, free=42784, change=0     after adding the first element to a list
Standard script: (Mono) used=22752, free=42784, change=0     after filling a list with 1000 zeros
Standard script: (Mono) used=22752, free=42784, change=0     after clearing the previous list
Standard script: (Mono) used=22752, free=42784, change=0     after filling the list again with 1000 zeros
Minified script: (Mono) used=22752, free=42784, change=0     Start of tests
Minified script: (Mono) used=22752, free=42784, change=0     after adding the first element to a list
Minified script: (Mono) used=22752, free=42784, change=0     after filling a list with 1000 zeros
Minified script: (Mono) used=22752, free=42784, change=0     after clearing the previous list
Minified script: (Mono) used=22752, free=42784, change=0     after filling the list again with 1000 zeros

Minified script: (Mono) used=22752, free=42784, change=0     Start of tests
Minified script: (Mono) used=22752, free=42784, change=0     after adding the first element to a list
Minified script: (Mono) used=22752, free=42784, change=0     after filling a list with 1000 zeros
Minified script: (Mono) used=22752, free=42784, change=0     after clearing the previous list
Minified script: (Mono) used=22752, free=42784, change=0     after filling the list again with 1000 zeros
Standard script: (Mono) used=22278, free=43258, change=0     Start of tests
Standard script: (Mono) used=22278, free=43258, change=0     after adding the first element to a list
Standard script: (Mono) used=22278, free=43258, change=0     after filling a list with 1000 zeros
Standard script: (Mono) used=22752, free=42784, change=-474     after clearing the previous list
Standard script: (Mono) used=22752, free=42784, change=0     after filling the list again with 1000 zeros

Code: minify.php

minify.php
<?php
 
/*
 * LSL Minify
 *
 * Copyright (c) 2012 Wizardry and Steamworks
 *
 * Licensed under the GNU GPLv3 license:
 *   http://www.gnu.org/licenses/gpl-3.0.html
 * 
 * Project home:
 *   http://grimore.org/secondlife:minify
 *
 */
 
// Read the entire LSL file
if(!isset($_POST['code'])) {
    print 'No data sent';
    die;
}
$data=$_POST['code'];
 
/* 
 * Constants from indra/newview/app_settings/keywords.ini
 * Last updated 19 October 2012.
 */
$CONSTANT_CSV_DATA = <<<EOD
	TRUE|1|
	FALSE|0|
	STATUS_PHYSICS|1|
	STATUS_PHANTOM|16|
	STATUS_ROTATE_X|2|
	STATUS_ROTATE_Y|4|
	STATUS_ROTATE_Z|8|
	STATUS_SANDBOX|32|
	STATUS_BLOCK_GRAB|64|
	STATUS_DIE_AT_EDGE|128|
	STATUS_RETURN_AT_EDGE|256|
	STATUS_CAST_SHADOWS|512|
	AGENT|1|
	AGENT_BY_USERNAME|16|
	AGENT_BY_LEGACY_NAME|1|
	ACTIVE|2|
	PASSIVE|4|
	SCRIPTED|8|
	CONTROL_FWD|1|
	CONTROL_BACK|2|
	CONTROL_LEFT|4|
	CONTROL_RIGHT|8|
	CONTROL_ROT_LEFT|256|
	CONTROL_ROT_RIGHT|512|
	CONTROL_UP|16|
	CONTROL_DOWN|32|
	CONTROL_LBUTTON|268435456|
	CONTROL_ML_LBUTTON|1073741824|
	PERMISSION_DEBIT|2|
	PERMISSION_TAKE_CONTROLS|4|
	PERMISSION_TRIGGER_ANIMATION|16|
	PERMISSION_ATTACH|32|
	PERMISSION_CHANGE_LINKS|128|
	PERMISSION_TRACK_CAMERA|1024|
	PERMISSION_CONTROL_CAMERA|2048|
	DEBUG_CHANNEL|2147483647|
	PUBLIC_CHANNEL|0|
	AGENT_FLYING|1|
	AGENT_ATTACHMENTS|2|
	AGENT_SCRIPTED|4|
	AGENT_SITTING|16|
	AGENT_ON_OBJECT|32|
	AGENT_MOUSELOOK|8|
	AGENT_AWAY|64|
	AGENT_WALKING|128|
	AGENT_IN_AIR|256|
	AGENT_TYPING|512|
	AGENT_CROUCHING|1024|
	AGENT_BUSY|2048|
	AGENT_ALWAYS_RUN|4096|
	AGENT_AUTOPILOT|8192|
	HTTP_METHOD|0|
	PSYS_PART_FLAGS|0|
	PSYS_PART_START_ALPHA|2|
	PSYS_PART_END_COLOR|3|
	PSYS_PART_END_SCALE|6|
	PSYS_PART_BOUNCE_MASK|4|
	PSYS_PART_INTERP_COLOR_MASK|1|
	PSYS_PART_FOLLOW_SRC_MASK|16|
	PSYS_PART_TARGET_POS_MASK|64|
	PSYS_PART_TARGET_LINEAR_MASK|128|
	PSYS_SRC_INNERANGLE|10|
	PSYS_SRC_OUTERANGLE|11|
	PSYS_SRC_ANGLE_BEGIN|22|
	PSYS_SRC_BURST_RATE|13|
	PSYS_SRC_BURST_RADIUS|16|
	PSYS_SRC_BURST_SPEED_MAX|18|
	PSYS_SRC_ACCEL|8|
	PSYS_SRC_TARGET_KEY|20|
	PSYS_SRC_PATTERN_DROP|1|
	PSYS_SRC_PATTERN_ANGLE|4|
	PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY|16|
	OBJECT_NAME|1|
	OBJECT_DESC|2|
	OBJECT_POS|3|
	OBJECT_ROT|4|
	OBJECT_VELOCITY|5|
	OBJECT_OWNER|6|
	OBJECT_GROUP|7|
	OBJECT_CREATOR|8|
	OBJECT_RUNNING_SCRIPT_COUNT|9|
	OBJECT_TOTAL_SCRIPT_COUNT|10|
	OBJECT_SCRIPT_MEMORY|11|
	OBJECT_SCRIPT_TIME|12|
	VEHICLE_TYPE_NONE|0|
	VEHICLE_TYPE_CAR|2|
	VEHICLE_TYPE_AIRPLANE|4|
	VEHICLE_REFERENCE_FRAME|44|
	VEHICLE_LINEAR_FRICTION_TIMESCALE|16|
	VEHICLE_ANGULAR_FRICTION_TIMESCALE|17|
	VEHICLE_LINEAR_MOTOR_DIRECTION|18|
	VEHICLE_LINEAR_MOTOR_OFFSET|20|
	VEHICLE_ANGULAR_MOTOR_DIRECTION|19|
	VEHICLE_HOVER_HEIGHT|24|
	VEHICLE_HOVER_EFFICIENCY|25|
	VEHICLE_HOVER_TIMESCALE|26|
	VEHICLE_BUOYANCY|27|
	VEHICLE_LINEAR_DEFLECTION_EFFICIENCY|28|
	VEHICLE_LINEAR_DEFLECTION_TIMESCALE|29|
	VEHICLE_LINEAR_MOTOR_TIMESCALE|30|
	VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE|31|
	VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY|32|
	VEHICLE_ANGULAR_DEFLECTION_TIMESCALE|33|
	VEHICLE_ANGULAR_MOTOR_TIMESCALE|34|
	VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE|35|
	VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY|36|
	VEHICLE_VERTICAL_ATTRACTION_TIMESCALE|37|
	VEHICLE_BANKING_EFFICIENCY|38|
	VEHICLE_BANKING_MIX|39|
	VEHICLE_BANKING_TIMESCALE|40|
	VEHICLE_FLAG_NO_DEFLECTION_UP|1|
	VEHICLE_FLAG_LIMIT_ROLL_ONLY|2|
	VEHICLE_FLAG_HOVER_WATER_ONLY|4|
	VEHICLE_FLAG_HOVER_TERRAIN_ONLY|8|
	VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT|16|
	VEHICLE_FLAG_HOVER_UP_ONLY|32|
	VEHICLE_FLAG_LIMIT_MOTOR_UP|64|
	VEHICLE_FLAG_MOUSELOOK_STEER|128|
	VEHICLE_FLAG_MOUSELOOK_BANK|256|
	VEHICLE_FLAG_CAMERA_DECOUPLED|512|
	CAMERA_PITCH|0|
	CAMERA_FOCUS_OFFSET|1|
	CAMERA_POSITION_LAG|5|
	CAMERA_FOCUS_LAG|6|
	CAMERA_DISTANCE|7|
	CAMERA_BEHINDNESS_ANGLE|8|
	CAMERA_BEHINDNESS_LAG|9|
	CAMERA_POSITION_THRESHOLD|10|
	CAMERA_FOCUS_THRESHOLD|11|
	CAMERA_ACTIVE|12|
	CAMERA_POSITION|13|
	CAMERA_FOCUS|17|
	CAMERA_POSITION_LOCKED|21|
	CAMERA_FOCUS_LOCKED|22|
	INVENTORY_TEXTURE|0|
	INVENTORY_SOUND|1|
	INVENTORY_OBJECT|6|
	INVENTORY_SCRIPT|10|
	INVENTORY_LANDMARK|3|
	INVENTORY_CLOTHING|5|
	INVENTORY_NOTECARD|7|
	INVENTORY_BODYPART|13|
	INVENTORY_ANIMATION|20|
	INVENTORY_GESTURE|21|
	INVENTORY_ALL|-1|
	INVENTORY_NONE|-1|
	ATTACH_CHEST|1|
	ATTACH_HEAD|2|
	ATTACH_LSHOULDER|3|
	ATTACH_RSHOULDER|4|
	ATTACH_LHAND|5|
	ATTACH_RHAND|6|
	ATTACH_LFOOT|7|
	ATTACH_RFOOT|8|
	ATTACH_BACK|9|
	ATTACH_PELVIS|10|
	ATTACH_MOUTH|11|
	ATTACH_CHIN|12|
	ATTACH_LEAR|13|
	ATTACH_REAR|14|
	ATTACH_LEYE|15|
	ATTACH_REYE|16|
	ATTACH_NOSE|17|
	ATTACH_RUARM|18|
	ATTACH_RLARM|19|
	ATTACH_LUARM|20|
	ATTACH_LLARM|21|
	ATTACH_RHIP|22|
	ATTACH_RULEG|23|
	ATTACH_RLLEG|24|
	ATTACH_LHIP|25|
	ATTACH_LULEG|26|
	ATTACH_LLLEG|27|
	ATTACH_BELLY|28|
	ATTACH_RPEC|29|
	ATTACH_LPEC|30|
	LAND_LEVEL|0|
	LAND_RAISE|1|
	LAND_LOWER|2|
	LAND_SMOOTH|3|
	LAND_NOISE|4|
	LAND_REVERT|5|
	LAND_SMALL_BRUSH|1|
	LAND_MEDIUM_BRUSH|2|
	LAND_LARGE_BRUSH|3|
	DATA_PAYINFO|8|
	DATA_ONLINE|1|
	DATA_NAME|2|
	DATA_BORN|3|
	DATA_RATING|4|
	DATA_SIM_POS|5|
	DATA_SIM_STATUS|6|
	DATA_SIM_RATING|7|
	PAYMENT_INFO_ON_FILE|1|
	PAYMENT_INFO_USED|2|
	ANIM_ON|1|
	LOOP|2|
	REVERSE|4|
	PING_PONG|8|
	SMOOTH|16|
	ROTATE|32|
	SCALE|64|
	ALL_SIDES|-1|
	LINK_SET|-1|
	LINK_ROOT|1|
	LINK_ALL_OTHERS|-2|
	LINK_ALL_CHILDREN|-3|
	LINK_THIS|-4|
	CHANGED_INVENTORY|1|
	CHANGED_COLOR|2|
	CHANGED_SHAPE|4|
	CHANGED_SCALE|8|
	CHANGED_TEXTURE|16|
	CHANGED_LINK|32|
	CHANGED_ALLOWED_DROP|64|
	CHANGED_OWNER|128|
	CHANGED_REGION|256|
	CHANGED_TELEPORT|512|
	CHANGED_REGION_START|1024|
	CHANGED_MEDIA|2048|
	TYPE_INTEGER|1|
	TYPE_FLOAT|2|
	TYPE_STRING|3|
	TYPE_KEY|4|
	TYPE_VECTOR|5|
	TYPE_ROTATION|6|
	TYPE_INVALID|0|
	REMOTE_DATA_REQUEST|2|
	REMOTE_DATA_REPLY|3|
	PRIM_MATERIAL|2|
	PRIM_PHYSICS|3|
	PRIM_FLEXIBLE|21|
	PRIM_POINT_LIGHT|23|
	PRIM_TEMP_ON_REZ|4|
	PRIM_PHANTOM|5|
	PRIM_CAST_SHADOWS|24|
	PRIM_POSITION|6|
	PRIM_SIZE|7|
	PRIM_ROTATION|8|
	PRIM_TEXTURE|17|
	PRIM_COLOR|18|
	PRIM_BUMP_SHINY|19|
	PRIM_FULLBRIGHT|20|
	PRIM_TEXGEN|22|
	PRIM_GLOW|25|
	PRIM_TEXT|26|
	PRIM_NAME|27|
	PRIM_DESC|28|
	PRIM_TYPE_BOX|0|
	PRIM_TYPE_CYLINDER|1|
	PRIM_TYPE_PRISM|2|
	PRIM_TYPE_SPHERE|3|
	PRIM_TYPE_TORUS|4|
	PRIM_TYPE_TUBE|5|
	PRIM_TYPE_RING|6|
	PRIM_TYPE_SCULPT|7|
	PRIM_HOLE_DEFAULT|0|
	PRIM_HOLE_SQUARE|32|
	PRIM_HOLE_CIRCLE|16|
	PRIM_HOLE_TRIANGLE|48|
	PRIM_MATERIAL_STONE|0|
	PRIM_MATERIAL_METAL|1|
	PRIM_MATERIAL_GLASS|2|
	PRIM_MATERIAL_WOOD|3|
	PRIM_MATERIAL_FLESH|4|
	PRIM_MATERIAL_PLASTIC|5|
	PRIM_MATERIAL_RUBBER|6|
	PRIM_MATERIAL_LIGHT|7|
	PRIM_SHINY_NONE|0|
	PRIM_SHINY_LOW|1|
	PRIM_SHINY_MEDIUM|2|
	PRIM_SHINY_HIGH|3|
	PRIM_BUMP_NONE|0|
	PRIM_BUMP_BRIGHT|1|
	PRIM_BUMP_DARK|2|
	PRIM_BUMP_WOOD|3|
	PRIM_BUMP_BARK|4|
	PRIM_BUMP_BRICKS|5|
	PRIM_BUMP_CHECKER|6|
	PRIM_BUMP_CONCRETE|7|
	PRIM_BUMP_TILE|8|
	PRIM_BUMP_STONE|9|
	PRIM_BUMP_DISKS|10|
	PRIM_BUMP_GRAVEL|11|
	PRIM_BUMP_BLOBS|12|
	PRIM_BUMP_SIDING|13|
	PRIM_BUMP_LARGETILE|14|
	PRIM_BUMP_STUCCO|15|
	PRIM_BUMP_SUCTION|16|
	PRIM_BUMP_WEAVE|17|
	PRIM_TEXGEN_DEFAULT|0|
	PRIM_TEXGEN_PLANAR|1|
	PRIM_SCULPT_TYPE_SPHERE|1|
	PRIM_SCULPT_TYPE_TORUS|2|
	PRIM_SCULPT_TYPE_PLANE|3|
	PRIM_SCULPT_TYPE_CYLINDER|4|
	PRIM_SCULPT_TYPE_MASK|7|
	PRIM_SCULPT_FLAG_INVERT|64|
	PRIM_SCULPT_FLAG_MIRROR|128|
	MASK_BASE|0|
	MASK_OWNER|1|
	MASK_GROUP|2|
	MASK_EVERYONE|3|
	MASK_NEXT|4|
	PERM_TRANSFER|8192|
	PERM_MODIFY|16384|
	PERM_COPY|32768|
	PERM_MOVE|524288|
	PERM_ALL|2147483647|
	PARCEL_MEDIA_COMMAND_STOP|0|
	PARCEL_MEDIA_COMMAND_PAUSE|1|
	PARCEL_MEDIA_COMMAND_PLAY|2|
	PARCEL_MEDIA_COMMAND_LOOP|3|
	PARCEL_MEDIA_COMMAND_TEXTURE|4|
	PARCEL_MEDIA_COMMAND_URL|5|
	PARCEL_MEDIA_COMMAND_TYPE|10|
	PARCEL_MEDIA_COMMAND_DESC|12|
	PARCEL_MEDIA_COMMAND_TIME|6|
	PARCEL_MEDIA_COMMAND_SIZE|11|
	PARCEL_MEDIA_COMMAND_AGENT|7|
	PARCEL_MEDIA_COMMAND_UNLOAD|8|
	PARCEL_MEDIA_COMMAND_AUTO_ALIGN|9|
	PAY_HIDE|-1|
	PAY_DEFAULT|-2|
	LIST_STAT_MAX|2|
	LIST_STAT_MIN|1|
	LIST_STAT_MEAN|3|
	LIST_STAT_MEDIAN|4|
	LIST_STAT_STD_DEV|5|
	LIST_STAT_SUM|6|
	LIST_STAT_SUM_SQUARES|7|
	LIST_STAT_NUM_COUNT|8|
	LIST_STAT_GEOMETRIC_MEAN|9|
	LIST_STAT_RANGE|0|
	PARCEL_FLAG_ALLOW_FLY|1|
	PARCEL_FLAG_ALLOW_GROUP_SCRIPTS|33554432|
	PARCEL_FLAG_ALLOW_SCRIPTS|2|
	PARCEL_FLAG_ALLOW_LANDMARK|8|
	PARCEL_FLAG_ALLOW_TERRAFORM|16|
	PARCEL_FLAG_ALLOW_DAMAGE|32|
	PARCEL_FLAG_ALLOW_CREATE_OBJECTS|64|
	PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS|67108864|
	PARCEL_FLAG_USE_ACCESS_GROUP|256|
	PARCEL_FLAG_USE_ACCESS_LIST|512|
	PARCEL_FLAG_USE_BAN_LIST|1024|
	PARCEL_FLAG_USE_LAND_PASS_LIST|2048|
	PARCEL_FLAG_LOCAL_SOUND_ONLY|32768|
	PARCEL_FLAG_RESTRICT_PUSHOBJECT|2097152|
	PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY|134217728|
	PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY|268435456|
	REGION_FLAG_ALLOW_DAMAGE|1|
	REGION_FLAG_FIXED_SUN|16|
	REGION_FLAG_BLOCK_TERRAFORM|64|
	REGION_FLAG_SANDBOX|256|
	REGION_FLAG_DISABLE_COLLISIONS|4096|
	REGION_FLAG_DISABLE_PHYSICS|16384|
	REGION_FLAG_BLOCK_FLY|524288|
	REGION_FLAG_ALLOW_DIRECT_TELEPORT|1048576|
	REGION_FLAG_RESTRICT_PUSHOBJECT|4194304|
	HTTP_MIMETYPE|1|
	HTTP_BODY_MAXLENGTH|2|
	HTTP_VERIFY_CERT|3|
	HTTP_BODY_TRUNCATED|0|
	PARCEL_COUNT_TOTAL|0|
	PARCEL_COUNT_OWNER|1|
	PARCEL_COUNT_GROUP|2|
	PARCEL_COUNT_OTHER|3|
	PARCEL_COUNT_SELECTED|4|
	PARCEL_COUNT_TEMP|5|
	PARCEL_DETAILS_NAME|0|
	PARCEL_DETAILS_DESC|1|
	PARCEL_DETAILS_OWNER|2|
	PARCEL_DETAILS_GROUP|3|
	PARCEL_DETAILS_AREA|4|
	PARCEL_DETAILS_ID|5|
	PARCEL_DETAILS_SEE_AVATARS|6|
	STRING_TRIM_HEAD|1|
	STRING_TRIM_TAIL|2|
	STRING_TRIM|3|
	CLICK_ACTION_NONE|0|
	CLICK_ACTION_TOUCH|0|
	CLICK_ACTION_SIT|1|
	CLICK_ACTION_BUY|2|
	CLICK_ACTION_PAY|3|
	CLICK_ACTION_OPEN|4|
	CLICK_ACTION_PLAY|5|
	CLICK_ACTION_OPEN_MEDIA|6|
	CLICK_ACTION_ZOOM|<-1.00000, -1.00000, 0.00000>|
	TOUCH_INVALID_TEXCOORD|<0.00000, 0.00000, 0.00000>|
	TOUCH_INVALID_VECTOR|-1|
	TOUCH_INVALID_FACE|0|
	PRIM_MEDIA_ALT_IMAGE_ENABLE|1|
	PRIM_MEDIA_CONTROLS|2|
	PRIM_MEDIA_CURRENT_URL|3|
	PRIM_MEDIA_HOME_URL|4|
	PRIM_MEDIA_AUTO_LOOP|5|
	PRIM_MEDIA_AUTO_PLAY|6|
	PRIM_MEDIA_AUTO_SCALE|7|
	PRIM_MEDIA_AUTO_ZOOM|8|
	PRIM_MEDIA_FIRST_CLICK_INTERACT|9|
	PRIM_MEDIA_WIDTH_PIXELS|10|
	PRIM_MEDIA_HEIGHT_PIXELS|11|
	PRIM_MEDIA_WHITELIST_ENABLE|12|
	PRIM_MEDIA_WHITELIST|13|
	PRIM_MEDIA_PERMS_INTERACT|14|
	PRIM_MEDIA_PERMS_CONTROL|14|
	PRIM_MEDIA_PARAM_MAX|0|
	PRIM_MEDIA_CONTROLS_STANDARD|1|
	PRIM_MEDIA_CONTROLS_MINI|0|
	PRIM_MEDIA_PERM_NONE|1|
	PRIM_MEDIA_PERM_OWNER|2|
	PRIM_MEDIA_PERM_GROUP|4|
	PRIM_MEDIA_PERM_ANYONE|1024|
	PRIM_MEDIA_MAX_URL_LENGTH|1024|
	PRIM_MEDIA_MAX_WHITELIST_SIZE|64|
	PRIM_MEDIA_MAX_WHITELIST_COUNT|2048|
	PRIM_MEDIA_MAX_WIDTH_PIXELS|2048|
	PRIM_MEDIA_MAX_HEIGHT_PIXELS|0|
	STATUS_OK|1000|
	STATUS_MALFORMED_PARAMS|1001|
	STATUS_TYPE_MISMATCH|1002|
	STATUS_BOUNDS_ERROR|1003|
	STATUS_NOT_FOUND|1004|
	STATUS_NOT_SUPPORTED|1999|
	STATUS_INTERNAL_ERROR|2001|
	TEXTURE_BLANK|5748decc-f629-461c-9a36-a35a221fe21f|
	TEXTURE_DEFAULT|89556747-24cb-43ed-920b-47caed15465f|
	TEXTURE_MEDIA|8b5fec65-8d8d-9dc5-cda8-8fdf2716e361|
	TEXTURE_PLYWOOD|89556747-24cb-43ed-920b-47caed15465f|
	TEXTURE_TRANSPARENT|8dcd4a48-2d37-4909-9f78-f7a9eb4ef903|
	URL_REQUEST_GRANTED|URL_REQUEST_GRANTED|
	URL_REQUEST_DENIED|URL_REQUEST_DENIED|
	PI|3.141593|
	TWO_PI|6.283185|
	PI_BY_TWO|1.570796|
	DEG_TO_RAD|0.017453|
	RAD_TO_DEG|57.29578|
	SQRT2|1.414214|
	ZERO_VECTOR|<0.00000, 0.00000, 0.00000>|
	ZERO_ROTATION|<0.00000, 0.00000, 0.00000, 1>
EOD;
 
	// Strip any multi-line comments.
	$data=preg_replace('/\/\*.*?\*\//s', '', $data);
	// Strip any single-line comments.
	$data=preg_replace('/(\s|^)+\/\/+?.*/', '', $data);
	// Remove any newlines, tabs or carriage returns.
	$data=preg_replace('/[\t\n\r]*?/s', '', $data);
 
	/*
	 * Go through the string and replaces all spaces whilst paying attention
	 * to variable declarations by matching types. Uses a stack to keep track
	 * of the quotes.
	 */
	$data=str_split($data);
	$stack=array();
	$space=array();
	$store='';
	foreach($data as $char) {
		switch($char) {
			case '"':
				$quote=array_pop($stack);
				if($quote=='"') {
					array_push($space, $char);
					break;
				}
				array_push($stack, $char);
				array_push($space, $char);
				break;
			case ' ':
				$quote=array_pop($stack);
				if($quote=='"') {
					array_push($space, $char);
					array_push($stack, $quote);
					break;
				}
				if(substr($store, -6) == "string" || substr($store, -6) == "vector" || substr($store, -6) == "return" ||
					substr($store, -7) == "integer" || 
					substr($store, -5) == "float" || substr($store, -5) == "state" ||
					substr($store, -4) == "list" || substr($store, -4) == "jump" || substr($store, -4) == "else" ||
					substr($store, -3) == "key" || substr($store, -8) == "rotation") {
						array_push($space, $char);
						$store='';
					}
				break;
			default:
				$store.=$char;
				array_push($space, $char);
			break;
 
		}
	}
	$data=implode($space);
 
	/*
	 * Rename all variables using lowercase letters. This relies on PHP's way
	 * of handling character arithmetic. 'z'+1 is "aa", "aa"+1 is "ab", etc...
	 */
	preg_match_all('/(string|integer|vector|float|state|list|jump|key|return|rotation)\s([A-Za-z0-9_]+)/', $data, $matches);
	$data=preg_split('/"/', $data);
	// Stride two elements from zero to obtain strings.
	$strings=$data;
	foreach (range(0, count($strings), 2) as $key) {
		unset($strings[$key]);
	}
	$strings=array_merge($strings);
	// Stride two elements from one to obtain code.
	$code=$data;
	foreach (range(1, count($code), 2) as $key) {
	  unset($code[$key]);
	}
	$code=array_merge($code);
 
	// Pad the starting variable name by the amount of variables
	// in order to avoid collisions with user-defined variables.
	$varsm='a';
	foreach($matches[0] as $var) {
		++$varsm;
	}
	// Replace each variable using PHP character arithmetic.
	foreach($matches[0] as $var) {
		$var=preg_replace('/(string|integer|vector|float|state|list|jump|key|return|rotation)\s/', '', $var);
		if($var == "default") continue;
		$code=preg_replace('/\b'.$var.'\b/', $varsm++, $code);
	}
 
	/*
	 * Interpolate constants - the trick is to first substitute large strings 
	 * such as AGENT_BY_LEGACY_NAME before substituting AGENT.
	 */
	$CONSTANT_CSV_DATA=explode('|', preg_replace('/[\n\s]+?/', '', $CONSTANT_CSV_DATA));
	$constants=array();
	do {
		$value=array_pop($CONSTANT_CSV_DATA);
		$key=array_pop($CONSTANT_CSV_DATA);
		$constants[$key]=$value;
	} while(count($CONSTANT_CSV_DATA));
	function constants_sort($a,$b){
	    return strlen($b)-strlen($a);
	}
	uksort($constants,'constants_sort');
	foreach($constants as $key=>$value) {
		$code=preg_replace("/\b$key\b/", $value, $code);
	}
 
	// Reconstruct the data array from code and strings.
	$code=array_reverse($code);
	$strings=array_reverse($strings);
	$data=array();
	do {
		array_push($data, array_pop($code));
		array_push($data, '"'.array_pop($strings).'"');
	} while(count($strings));
	array_push($data,array_pop($code));
 
	// Convert from array to string.
	$data=implode(array_merge($data));
 
	/*
	 * Print out the data.
	 */
	print $data;
	print "\n";
 
?>

Code: minify.html

The HTML part sends the contents of the textarea to the minify.php script using AJAX and returns the value.

minify.html
<html>
<head>
<title>the title</title>
<script src="http://code.jquery.com/jquery-latest.js"></script>
   <script type="text/javascript" language="javascript">
  $(document).ready(function() {
      $("#driver").click(function(event){
          $.post(
             "/toy/sl/minify.php",
             { code: $('#stage').val() },
             function(data) {
                $('#stage').val(data);
             }
          );
      });
   });
   </script>
</head>
<body>
   <textarea id="stage" style="border: 1px solid; width: 100%; height: 90%"></textarea> <br/>
   <input type="button" id="driver" value="Minify" />
</body>
</html>