line breaks, arg

line breaks, arg

--- src/SoundManager2_SMSound_AS3.as
+++ src/SoundManager2_SMSound_AS3.as
@@ -1,651 +1,649 @@
-/*
-   SoundManager 2: Javascript Sound for the Web
-   ----------------------------------------------
-   http://schillmania.com/projects/soundmanager2/
-
-   Copyright (c) 2007, Scott Schiller. All rights reserved.
-   Code licensed under the BSD License:
-   http://www.schillmania.com/projects/soundmanager2/license.txt
-
-   Flash 9 / ActionScript 3 version
-*/
-
-package {
-
-  import flash.external.*;
-  import flash.events.*;
-  import flash.display.Sprite;
-  import flash.display.StageDisplayState;
-  import flash.display.StageScaleMode;
-  import flash.display.StageAlign;
-  import flash.geom.Rectangle;
-  import flash.media.Sound;
-  import flash.media.SoundChannel;
-  import flash.media.SoundLoaderContext;
-  import flash.media.SoundTransform;
-  import flash.media.SoundMixer;
-  import flash.media.Video;
-  import flash.net.URLRequest;
-  import flash.utils.ByteArray;
-  import flash.utils.getTimer;
-  import flash.net.NetConnection;
-  import flash.net.NetStream;
-
-  public class SoundManager2_SMSound_AS3 extends Sound {
-
-    public var sm: SoundManager2_AS3 = null;
-    // externalInterface references (for Javascript callbacks)
-    public var baseJSController: String = "soundManager";
-    public var baseJSObject: String = baseJSController + ".sounds";
-    public var soundChannel: SoundChannel = new SoundChannel();
-    public var urlRequest: URLRequest;
-    public var soundLoaderContext: SoundLoaderContext;
-    public var waveformData: ByteArray = new ByteArray();
-    public var waveformDataArray: Array = [];
-    public var eqData: ByteArray = new ByteArray();
-    public var eqDataArray: Array = [];
-    public var usePeakData: Boolean = false;
-    public var useWaveformData: Boolean = false;
-    public var useEQData: Boolean = false;
-    public var sID: String;
-    public var sURL: String;
-    public var justBeforeFinishOffset: int;
-    public var didJustBeforeFinish: Boolean;
-    public var didFinish: Boolean;
-    public var loaded: Boolean;
-    public var connected: Boolean;
-    public var failed: Boolean;
-    public var paused: Boolean;
-    public var finished: Boolean;
-    public var duration: Number;
-    public var totalBytes: Number;
-    public var handledDataError: Boolean = false;
-    public var ignoreDataError: Boolean = false;
-    public var autoPlay: Boolean = false;
-    public var autoLoad: Boolean = false;
-    public var pauseOnBufferFull: Boolean = true;
-    public var loops: Number = 1;
-    public var lastValues: Object = {
-      bytes: 0,
-      position: 0,
-      volume: 100,
-      pan: 0,
-      loops: 1,
-      leftPeak: 0,
-      rightPeak: 0,
-      waveformDataArray: null,
-      eqDataArray: null,
-      isBuffering: null,
-      bufferLength: 0
-    };
-    public var didLoad: Boolean = false;
-    public var useEvents: Boolean = false;
-    public var sound: Sound = new Sound();
-
-    public var cc: Object;
-    public var nc: NetConnection;
-    public var ns: NetStream = null;
-    public var st: SoundTransform;
-    public var useNetstream: Boolean;
-    public var useVideo: Boolean = false;
-    public var bufferTime: Number = 3; // previously 0.1
-    public var bufferTimes: Array;     // an array of integers (for specifying multiple buffers)
-    public var lastNetStatus: String = null;
-    public var serverUrl: String = null;
-
-    public var oVideo: Video = null;
-    public var videoWidth: Number = 0;
-    public var videoHeight: Number = 0;
-
-    public var start_time: Number;
-    public var connect_time: Number;
-    public var play_time: Number;
-    public var recordStats: Boolean = false;
-
-    public function SoundManager2_SMSound_AS3(oSoundManager: SoundManager2_AS3, sIDArg: String = null, sURLArg: String = null, usePeakData: Boolean = false, useWaveformData: Boolean = false, useEQData: Boolean = false, useNetstreamArg: Boolean = false, useVideoArg: Boolean = false, netStreamBufferTime: Number = 1, serverUrl: String = null, duration: Number = 0, totalBytes: Number = 0, autoPlay: Boolean = false, useEvents: Boolean = false, bufferTimes: Array = null, recordStats: Boolean = false, autoLoad: Boolean = false) {
-      this.sm = oSoundManager;
-      this.sID = sIDArg;
-      this.sURL = sURLArg;
-      this.usePeakData = usePeakData;
-      this.useWaveformData = useWaveformData;
-      this.useEQData = useEQData;
-      this.urlRequest = new URLRequest(sURLArg);
-      this.justBeforeFinishOffset = 0;
-      this.didJustBeforeFinish = false;
-      this.didFinish = false; // non-MP3 formats only
-      this.loaded = false;
-      this.connected = false;
-      this.failed = false;
-      this.finished = false;
-      this.soundChannel = null;
-      this.lastNetStatus = null;
-      this.useNetstream = useNetstreamArg;
-      this.serverUrl = serverUrl;
-      this.duration = duration;
-      this.totalBytes = totalBytes;
-      this.recordStats = recordStats;
-      this.useEvents = useEvents;
-      this.useVideo = useVideoArg;
-      this.autoLoad = autoLoad;
-      if (netStreamBufferTime) {
-        this.bufferTime = netStreamBufferTime;
-      }
-      // Use bufferTimes instead of bufferTime
-      if (bufferTimes !== null) {
-        this.bufferTimes = bufferTimes;
-      } else {
-        this.bufferTimes = [this.bufferTime];
-      }
-      setAutoPlay(autoPlay);
-
-      if (recordStats) {
-        this.start_time = getTimer();
-      }
-
-      writeDebug('SoundManager2_SMSound_AS3: Got duration: '+duration+', totalBytes: '+totalBytes+', autoPlay: '+autoPlay);
-
-      if (this.useNetstream) {
-
-        this.cc = new Object();
-        this.nc = new NetConnection();
-
-        // Handle FMS bandwidth check callback.
-        // @see onBWDone
-        // @see http://www.adobe.com/devnet/flashmediaserver/articles/dynamic_stream_switching_04.html
-        // @see http://www.johncblandii.com/index.php/2007/12/fms-a-quick-fix-for-missing-onbwdone-onfcsubscribe-etc.html
-        this.nc.client = this;
-
-        // TODO: security/IO error handling
-        // this.nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, doSecurityError);
-        nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
-
-        if (this.serverUrl != null) {
-          writeDebug('SoundManager2_SMSound_AS3: NetConnection: connecting to server ' + this.serverUrl + '...');
-        }
-        this.nc.connect(serverUrl);
-      } else {
-        this.connect_time = this.start_time;
-        this.connected = true;
-      }
-
-    }
-
-    public function netStatusHandler(event:NetStatusEvent):void {
-
-      if (this.useEvents) {
-        writeDebug('netStatusHandler: '+event.info.code);
-      }
-
-      switch (event.info.code) {
-
-        case "NetConnection.Connect.Success":
-          writeDebug('NetConnection: connected');
-          try {
-            this.ns = new NetStream(this.nc);
-            this.ns.checkPolicyFile = true;
-            // bufferTime reference: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/net/NetStream.html#bufferTime
-            this.ns.bufferTime = getStartBuffer(); // set to 0.1 or higher. 0 is reported to cause playback issues with static files.
-            this.st = new SoundTransform();
-            this.cc.onMetaData = this.metaDataHandler;
-            this.ns.client = this.cc;
-            this.ns.receiveAudio(true);
-            this.addNetstreamEvents();
-
-            if (this.useVideo) {
-              this.oVideo = new Video();
-              this.ns.receiveVideo(true);
-              this.sm.stage.addEventListener(Event.RESIZE, this.resizeHandler);
-              this.oVideo.smoothing = true; // http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/Video.html#smoothing
-              this.oVideo.visible = false; // hide until metadata received
-              this.sm.addChild(this.oVideo);
-              this.oVideo.attachNetStream(this.ns);
-              writeDebug('setting video w/h to stage: ' + this.sm.stage.stageWidth + 'x' + this.sm.stage.stageHeight);
-              this.oVideo.width = this.sm.stage.stageWidth;
-              this.oVideo.height = this.sm.stage.stageHeight;
-            }
-            this.connected = true;
-            if (recordStats) {
-              this.recordConnectTime();
-            }
-            if (this.useEvents) {
-              writeDebug('firing _onconnect for '+this.sID);
-              ExternalInterface.call(this.sm.baseJSObject + "['" + this.sID + "']._onconnect", 1);
-            }
-          } catch(e: Error) {
-            this.failed = true;
-            writeDebug('netStream error: ' + e.toString());
-            ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Connection failed!', event.info.level, event.info.code);
-          }
-          break;
-
-        case "NetStream.Play.StreamNotFound":
-          this.failed = true;
-          writeDebug("NetConnection: Stream not found!");
-          ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Stream not found!', event.info.level, event.info.code);
-          break;
-
-        // This is triggered when the sound loses the connection with the server.
-        // In some cases one could just try to reconnect to the server and resume playback.
-        // However for streams protected by expiring tokens, I don't think that will work.
-        //
-        // Flash says that this is not an error code, but a status code...
-        // should this call the onFailure handler?
-        case "NetConnection.Connect.Closed":
-          this.failed = true;
-          ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Connection closed!', event.info.level, event.info.code);
-          writeDebug("NetConnection: Connection closed!");
-          break;
-
-        // Couldn't establish a connection with the server. Attempts to connect to the server
-        // can also fail if the permissible number of socket connections on either the client
-        // or the server computer is at its limit.  This also happens when the internet
-        // connection is lost.
-        case "NetConnection.Connect.Failed":
-          this.failed = true;
-          writeDebug("NetConnection: Connection failed! Lost internet connection? Try again... Description: " + event.info.description);
-          ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Connection failed!', event.info.level, event.info.code);
-          break;
-
-        // A change has occurred to the network status. This could mean that the network
-        // connection is back, or it could mean that it has been lost...just try to resume
-        // playback.
-
-        // KJV: Can't use this yet because by the time you get your connection back the
-        // song has reached it's maximum retries, so it doesn't retry again.  We need
-        // a new _ondisconnect handler.
-        //case "NetConnection.Connect.NetworkChange":
-        //  this.failed = true;
-        //  writeDebug("NetConnection: Network connection status changed");
-        //  ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Reconnecting...');
-        //  break;
-
-        // Consider everything else a failure...
-        default:
-          this.failed = true;
-          writeDebug("NetConnection: got unhandled code '" + event.info.code + "'! Description: " + event.info.description);
-          ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", '', event.info.level, event.info.code);
-          break;
-      }
-
-    }
-
-    // Set the buffer size on the current NetSream instance to <tt>buffer</tt> secs
-    // Only set the buffer if it's different to the current buffer.
-    public function setBuffer(buffer: int) : void {
-      if (buffer != this.ns.bufferTime) {
-        this.ns.bufferTime = buffer;
-        writeDebug('set buffer to '+this.ns.bufferTime+' secs');
-      }
-    }
-
-    // Return the size of the starting buffer.
-    public function getStartBuffer() : int {
-      return this.bufferTimes[0];
-    }
-
-    // Return the size of the next buffer, given the size of the current buffer.
-    // If there are no more buffers, returns the current buffer size.
-    public function getNextBuffer(current_buffer: int) : int {
-      var i: int = bufferTimes.indexOf(current_buffer);
-      if (i == -1) {
-        // Couldn't find the buffer, start from the start buffer size
-        return getStartBuffer();
-      } else if (i + 1 >= bufferTimes.length) {
-        // Last (or only) buffer, keep the current buffer
-        return current_buffer;
-      } else {
-        return this.bufferTimes[i+1];
-      }
-   }
-
-    public function resizeHandler(e: Event) : void {
-      // scale video to stage dimensions
-      // probably less performant than using native flash scaling, but that doesn't quite seem to work. I'm probably missing something simple.
-      this.oVideo.width = this.sm.stage.stageWidth;
-      this.oVideo.height = this.sm.stage.stageHeight;
-    }
-
-    public function writeDebug (s: String, bTimestamp: Boolean = false) : Boolean {
-      return this.sm.writeDebug (s, bTimestamp); // defined in main SM object
-    }
-
-    public function metaDataHandler(infoObject: Object) : void {
-      /*
-	  var data:String = new String();
-	  for (var prop:* in infoObject) {
-		data += prop+': '+infoObject[prop]+' ';
-	  }
-	  ExternalInterface.call('soundManager._writeDebug','Metadata: '+data);
-	  */
-      if (this.oVideo) {
-        // set dimensions accordingly
-        if (!infoObject.width && !infoObject.height) {
-          writeDebug('No width/height specified, using stage dimensions');
-          infoObject.width = this.sm.stage.width;
-          infoObject.height = this.sm.stage.height;
-        }
-        writeDebug('video dimensions: ' + infoObject.width + 'x' + infoObject.height + ' (w/h)');
-        this.videoWidth = infoObject.width;
-        this.videoHeight = infoObject.height;
-        // implement a subset of metadata to pass over EI bridge
-        // some formats have extra stuff, eg. "aacaot", "avcprofile"
-        // http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000267.html
-        var oMeta: Object = new Object();
-        var item: Object = null;
-        for (item in infoObject) {
-          // exclude seekpoints for now, presumed not useful and overly large.
-          if (item != 'seekpoints') {
-            oMeta[item] = infoObject[item];
-          }
-        }
-        ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onmetadata", oMeta);
-        writeDebug('showing video for ' + this.sID);
-        this.oVideo.visible = true; // show ze video!
-      }
-      if (!this.loaded) {
-        // writeDebug('not loaded yet: '+this.ns.bytesLoaded+', '+this.ns.bytesTotal+', '+infoObject.duration*1000);
-        // TODO: investigate loaded/total values
-        // ExternalInterface.call(baseJSObject + "['" + this.sID + "']._whileloading", this.ns.bytesLoaded, this.ns.bytesTotal, infoObject.duration*1000);
-        ExternalInterface.call(baseJSObject + "['" + this.sID + "']._whileloading", this.bytesLoaded, (this.bytesTotal || this.totalBytes), (infoObject.duration || this.duration))
-      }
-      this.duration = infoObject.duration * 1000;
-      // null this out for the duration of this object's existence.
-      // it may be called multiple times.
-      this.cc.onMetaData = function(infoObject: Object) : void {}
-
-    }
-
-    public function getWaveformData() : void {
-      // http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundMixer.html#computeSpectrum()
-      SoundMixer.computeSpectrum(this.waveformData, false, 0); // sample wave data at 44.1 KHz
-      this.waveformDataArray = [];
-      for (var i: int = 0, j: int = this.waveformData.length / 4; i < j; i++) { // get all 512 values (256 per channel)
-        this.waveformDataArray.push(int(this.waveformData.readFloat() * 1000) / 1000);
-      }
-    }
-
-    public function getEQData() : void {
-      // http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundMixer.html#computeSpectrum()
-      SoundMixer.computeSpectrum(this.eqData, true, 0); // sample EQ data at 44.1 KHz
-      this.eqDataArray = [];
-      for (var i: int = 0, j: int = this.eqData.length / 4; i < j; i++) { // get all 512 values (256 per channel)
-        this.eqDataArray.push(int(this.eqData.readFloat() * 1000) / 1000);
-      }
-    }
-
-    public function start(nMsecOffset: int, nLoops: int) : void {
-      this.sm.currentObject = this; // reference for video, full-screen
-      this.useEvents = true;
-      if (this.useNetstream) {
-
-        writeDebug("SMSound::start nMsecOffset "+ nMsecOffset+ ' nLoops '+nLoops + ' current bufferTime '+this.ns.bufferTime+' current bufferLength '+this.ns.bufferLength+ ' this.lastValues.position '+this.lastValues.position);
-
-        this.cc.onMetaData = this.metaDataHandler;
-
-        // Don't seek if we don't have to because it destroys the buffer
-        if (this.lastValues.position != null && this.lastValues.position != nMsecOffset) {
-          // Minimize the buffer so playback starts ASAP
-          this.setBuffer(this.getStartBuffer());
-          // writeDebug('setting buffer to '+this.bufferTime+' secs');
-          this.ns.seek(nMsecOffset);
-          this.lastValues.position = nMsecOffset; // https://gist.github.com/1de8a3113cf33d0cff67
-        }
-
-        if (this.paused) {
-          writeDebug('start: resuming from paused state');
-          this.ns.resume(); // get the sound going again
-          if (!this.didLoad) {
-            this.didLoad = true;
-          }
-          this.paused = false;
-        } else if (!this.didLoad) {
-          writeDebug('start: !didLoad - playing '+this.sURL);
-          this.ns.play(this.sURL);
-          this.didLoad = true;
-          this.paused = false;
-        } else {
-          // previously loaded, perhaps stopped/finished. play again?
-          writeDebug('playing again (not paused, didLoad = true)');
-          this.ns.play(this.sURL);
-        }
-        // this.ns.addEventListener(Event.SOUND_COMPLETE, _onfinish);
-        this.applyTransform();
-
-      } else {
-        // writeDebug('start: seeking to '+nMsecOffset+', '+nLoops+(nLoops==1?' loop':' loops'));
-        this.soundChannel = this.play(nMsecOffset, nLoops);
-        this.addEventListener(Event.SOUND_COMPLETE, _onfinish);
-        this.applyTransform();
-      }
-
-    }
-
-    private function _onfinish() : void {
-      this.removeEventListener(Event.SOUND_COMPLETE, _onfinish);
-    }
-
-    public function loadSound(sURL: String, bStream: Boolean) : void {
-      if (this.useNetstream) {
-        this.useEvents = true;
-        if (this.didLoad != true) {
-          ExternalInterface.call('loadSound(): loading ' + this.sURL);
-          this.ns.play(this.sURL);
-          this.didLoad = true;
-        }
-        // this.addEventListener(Event.SOUND_COMPLETE, _onfinish);
-        this.applyTransform();
-      } else {
-        try {
-          this.didLoad = true;
-          this.urlRequest = new URLRequest(sURL);
-          this.soundLoaderContext = new SoundLoaderContext(1000, true); // check for policy (crossdomain.xml) file on remote domains - http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundLoaderContext.html
-          this.load(this.urlRequest, this.soundLoaderContext);
-        } catch(e: Error) {
-          writeDebug('error during loadSound(): ' + e.toString());
-        }
-      }
-    }
-
-    public function setAutoPlay(autoPlay: Boolean) : void {
-      if (!this.serverUrl) {
-        // don't apply to non-RTMP, netstream stuff.
-        this.autoPlay = true;
-        this.pauseOnBufferFull = false;
-      } else {
-        this.autoPlay = autoPlay;
-        if (this.autoPlay) {
-          this.pauseOnBufferFull = false;
-          // writeDebug('ignoring pauseOnBufferFull because autoPlay is on');
-        } else if (!this.autoPlay) {
-          this.pauseOnBufferFull = true;
-          // writeDebug('pausing on buffer full because autoPlay is off');
-        }
-      }
-    }
-
-    public function setVolume(nVolume: Number) : void {
-      this.lastValues.volume = nVolume / 100;
-      this.applyTransform();
-    }
-
-    public function setPan(nPan: Number) : void {
-      this.lastValues.pan = nPan / 100;
-      this.applyTransform();
-    }
-
-    public function applyTransform() : void {
-      var st: SoundTransform = new SoundTransform(this.lastValues.volume, this.lastValues.pan);
-      if (this.useNetstream) {
-        if (this.ns) {
-          this.ns.soundTransform = st;
-        } else {
-          // writeDebug('applyTransform(): Note: No active netStream');
-        }
-      } else if (this.soundChannel) {
-        this.soundChannel.soundTransform = st; // new SoundTransform(this.lastValues.volume, this.lastValues.pan);
-      }
-    }
-
-    public function recordPlayTime() : void {
-      this.play_time = Math.round(getTimer() - (this.start_time + this.connect_time));
-      writeDebug('Play took '+ this.play_time + ' ms');
-      // We must now have both stats, call the onstats callback
-      ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onstats", {
-        play_time:    this.play_time,
-        connect_time: this.connect_time
-      });
-      // Stop tracking any stats for this object
-      this.recordStats = false;
-    }
-
-    public function recordConnectTime() : void {
-      this.connect_time = Math.round(getTimer() - this.start_time);
-      writeDebug('Connect took '+ this.connect_time + ' ms');
-    }
-
-    // Handle FMS bandwidth check callback.
-    // @see http://www.adobe.com/devnet/flashmediaserver/articles/dynamic_stream_switching_04.html
-    // @see http://www.johncblandii.com/index.php/2007/12/fms-a-quick-fix-for-missing-onbwdone-onfcsubscribe-etc.html
-    public function onBWDone() : void {
-      // writeDebug('onBWDone: called and ignored');
-    }
-
-    // NetStream client callback. Invoked when the song is complete.
-    public function onPlayStatus(info:Object):void {
-      writeDebug('onPlayStatus called with '+info);
-      switch(info.code) {
-        case "NetStream.Play.Complete":
-          writeDebug('Song has finished!');
-          break;
-      }
-    }
-
-    public function doIOError(e: IOErrorEvent) : void {
-      ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onload", 0); // call onload, assume it failed.
-      // there was a connection drop, a loss of internet connection, or something else wrong. 404 error too.
-    }
-
-    public function doAsyncError(e: AsyncErrorEvent) : void {
-      writeDebug('asyncError: ' + e.text);
-    }
-
-    public function doNetStatus(e: NetStatusEvent) : void {
-
-      // Handle failures
-      if (e.info.code == "NetStream.Failed"
-          || e.info.code == "NetStream.Play.FileStructureInvalid"
-          || e.info.code == "NetStream.Play.StreamNotFound") {
-
-        this.lastNetStatus = e.info.code;
-        writeDebug('netStatusEvent: ' + e.info.code);
-        this.failed = true;
-        ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", '', e.info.level, e.info.code);
-        return;
-      }
-
-      writeDebug('netStatusEvent: ' + e.info.code);  // KJV we like to see all events
-
-      // When streaming, Stop is called when buffering stops, not when the stream is actually finished.
-      // @see http://www.actionscript.org/forums/archive/index.php3/t-159194.html
-      if (e.info.code == "NetStream.Play.Stop") {
-
-        if (!this.useNetstream) {
-          // finished playing
-          // this.didFinish = true; // will be reset via JS callback
-          this.didJustBeforeFinish = false; // reset
-          writeDebug('calling onfinish for a sound');
-          // reset the sound? Move back to position 0?
-          this.sm.checkProgress();
-          ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfinish");
-          // and exit full-screen mode, too?
-          this.sm.stage.displayState = StageDisplayState.NORMAL;
-        }
-
-      } else if (e.info.code == "NetStream.Play.Start" || e.info.code == "NetStream.Buffer.Empty" || e.info.code == "NetStream.Buffer.Full") {
-
-        // First time buffer has filled. Print debugging output.
-        if (this.recordStats && !this.play_time) {
-          this.recordPlayTime();
-        }
-
-        // RTMP case..
-        // We wait for the buffer to fill up before pausing the just-loaded song because only if the
-        // buffer is full will the song continue to buffer until the user hits play.
-        if (this.serverUrl && e.info.code == "NetStream.Buffer.Full" && this.pauseOnBufferFull) {
-          this.ns.pause();
-          this.paused = true;
-          this.pauseOnBufferFull = false;
-          // Call pause in JS.  This will call back to us to pause again, but
-          // that should be harmless.
-          writeDebug('Pausing song because buffer is full');
-          ExternalInterface.call(baseJSObject + "['" + this.sID + "'].pause", false);
-        }
-
-        // The buffer is full.  Increase its size if possible.
-        // Double buffering has not been shown to cause false starts, so this is safe.
-        if (e.info.code == "NetStream.Buffer.Full") {
-          var next_buffer: int = this.getNextBuffer(this.ns.bufferTime);
-          if (next_buffer != this.ns.bufferTime) {
-            this.setBuffer(next_buffer);
-          }
-        }
-
-        var isNetstreamBuffering: Boolean = (e.info.code == "NetStream.Buffer.Empty" || e.info.code == "NetStream.Play.Start");
-        // assume buffering when we start playing, eg. initial load.
-        if (isNetstreamBuffering != this.lastValues.isBuffering) {
-          this.lastValues.isBuffering = isNetstreamBuffering;
-          ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onbufferchange", this.lastValues.isBuffering ? 1 : 0);
-        }
-
-        // We can detect the end of the stream when Play.Stop is called followed by Buffer.Empty.
-        // However, if you pause and let the whole song buffer, Buffer.Flush is called followed by
-        // Buffer.Empty, so handle that case too.
-        //
-        // Ignore this event if we are more than 5 seconds from the end of the song.
-        if (e.info.code == "NetStream.Buffer.Empty" && (this.lastNetStatus == 'NetStream.Play.Stop' || this.lastNetStatus == 'NetStream.Buffer.Flush')) {
-          if (this.duration && (this.ns.time * 1000) < (this.duration - 5000)) {
-            writeDebug('Ignoring Buffer.Empty because this is too early to be the end of the stream! (sID: '+this.sID+', time: '+(this.ns.time*1000)+', duration: '+this.duration+')');
-          } else {
-            this.didJustBeforeFinish = false; // reset
-            this.finished = true;
-            writeDebug('calling onfinish for sound '+this.sID);
-            this.sm.checkProgress();
-            ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfinish");
-          }
-
-        } else if (e.info.code == "NetStream.Buffer.Empty") {
-
-          // The buffer is empty.  Start from the smallest buffer again.
-          this.setBuffer(this.getStartBuffer());
-        }
-      }
-
-      // Remember the last NetStatus event
-      this.lastNetStatus = e.info.code;
-    }
-
-    // KJV The sound adds some of its own netstatus handlers so we don't need to do it here.
-    public function addNetstreamEvents() : void {
-      ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, doAsyncError);
-      ns.addEventListener(NetStatusEvent.NET_STATUS, doNetStatus);
-      ns.addEventListener(IOErrorEvent.IO_ERROR, doIOError);
-    }
-
-    public function removeNetstreamEvents() : void {
-      ns.removeEventListener(AsyncErrorEvent.ASYNC_ERROR, doAsyncError);
-      ns.removeEventListener(NetStatusEvent.NET_STATUS, doNetStatus);
-      ns.addEventListener(NetStatusEvent.NET_STATUS, dummyNetStatusHandler);
-      ns.removeEventListener(IOErrorEvent.IO_ERROR, doIOError);
-      // KJV Stop listening for NetConnection events on the sound
-      nc.removeEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
-    }
-
-    // Prevents possible 'Unhandled NetStatusEvent' condition if a sound is being
-    // destroyed and interacted with at the same time.
-    public function dummyNetStatusHandler(e: NetStatusEvent) : void {
-      // Don't do anything
-    }
-
-  }
-
-}+/*
+   SoundManager 2: Javascript Sound for the Web
+   ----------------------------------------------
+   http://schillmania.com/projects/soundmanager2/
+
+   Copyright (c) 2007, Scott Schiller. All rights reserved.
+   Code licensed under the BSD License:
+   http://www.schillmania.com/projects/soundmanager2/license.txt
+
+   Flash 9 / ActionScript 3 version
+*/
+
+package {
+
+  import flash.external.*;
+  import flash.events.*;
+  import flash.display.Sprite;
+  import flash.display.StageDisplayState;
+  import flash.display.StageScaleMode;
+  import flash.display.StageAlign;
+  import flash.geom.Rectangle;
+  import flash.media.Sound;
+  import flash.media.SoundChannel;
+  import flash.media.SoundLoaderContext;
+  import flash.media.SoundTransform;
+  import flash.media.SoundMixer;
+  import flash.media.Video;
+  import flash.net.URLRequest;
+  import flash.utils.ByteArray;
+  import flash.utils.getTimer;
+  import flash.net.NetConnection;
+  import flash.net.NetStream;
+
+  public class SoundManager2_SMSound_AS3 extends Sound {
+
+    public var sm: SoundManager2_AS3 = null;
+    // externalInterface references (for Javascript callbacks)
+    public var baseJSController: String = "soundManager";
+    public var baseJSObject: String = baseJSController + ".sounds";
+    public var soundChannel: SoundChannel = new SoundChannel();
+    public var urlRequest: URLRequest;
+    public var soundLoaderContext: SoundLoaderContext;
+    public var waveformData: ByteArray = new ByteArray();
+    public var waveformDataArray: Array = [];
+    public var eqData: ByteArray = new ByteArray();
+    public var eqDataArray: Array = [];
+    public var usePeakData: Boolean = false;
+    public var useWaveformData: Boolean = false;
+    public var useEQData: Boolean = false;
+    public var sID: String;
+    public var sURL: String;
+    public var justBeforeFinishOffset: int;
+    public var didJustBeforeFinish: Boolean;
+    public var didFinish: Boolean;
+    public var loaded: Boolean;
+    public var connected: Boolean;
+    public var failed: Boolean;
+    public var paused: Boolean;
+    public var finished: Boolean;
+    public var duration: Number;
+    public var handledDataError: Boolean = false;
+    public var ignoreDataError: Boolean = false;
+    public var autoPlay: Boolean = false;
+    public var autoLoad: Boolean = false;
+    public var pauseOnBufferFull: Boolean = true;
+    public var loops: Number = 1;
+    public var lastValues: Object = {
+      bytes: 0,
+      position: 0,
+      volume: 100,
+      pan: 0,
+      loops: 1,
+      leftPeak: 0,
+      rightPeak: 0,
+      waveformDataArray: null,
+      eqDataArray: null,
+      isBuffering: null,
+      bufferLength: 0
+    };
+    public var didLoad: Boolean = false;
+    public var useEvents: Boolean = false;
+    public var sound: Sound = new Sound();
+
+    public var cc: Object;
+    public var nc: NetConnection;
+    public var ns: NetStream = null;
+    public var st: SoundTransform;
+    public var useNetstream: Boolean;
+    public var useVideo: Boolean = false;
+    public var bufferTime: Number = 3; // previously 0.1
+    public var bufferTimes: Array;     // an array of integers (for specifying multiple buffers)
+    public var lastNetStatus: String = null;
+    public var serverUrl: String = null;
+
+    public var oVideo: Video = null;
+    public var videoWidth: Number = 0;
+    public var videoHeight: Number = 0;
+
+    public var start_time: Number;
+    public var connect_time: Number;
+    public var play_time: Number;
+    public var recordStats: Boolean = false;
+
+    public function SoundManager2_SMSound_AS3(oSoundManager: SoundManager2_AS3, sIDArg: String = null, sURLArg: String = null, usePeakData: Boolean = false, useWaveformData: Boolean = false, useEQData: Boolean = false, useNetstreamArg: Boolean = false, useVideoArg: Boolean = false, netStreamBufferTime: Number = 1, serverUrl: String = null, duration: Number = 0, autoPlay: Boolean = false, useEvents: Boolean = false, bufferTimes: Array = null, recordStats: Boolean = false, autoLoad: Boolean = false) {
+      this.sm = oSoundManager;
+      this.sID = sIDArg;
+      this.sURL = sURLArg;
+      this.usePeakData = usePeakData;
+      this.useWaveformData = useWaveformData;
+      this.useEQData = useEQData;
+      this.urlRequest = new URLRequest(sURLArg);
+      this.justBeforeFinishOffset = 0;
+      this.didJustBeforeFinish = false;
+      this.didFinish = false; // non-MP3 formats only
+      this.loaded = false;
+      this.connected = false;
+      this.failed = false;
+      this.finished = false;
+      this.soundChannel = null;
+      this.lastNetStatus = null;
+      this.useNetstream = useNetstreamArg;
+      this.serverUrl = serverUrl;
+      this.duration = duration;
+      this.recordStats = recordStats;
+      this.useEvents = useEvents;
+      this.useVideo = useVideoArg;
+      this.autoLoad = autoLoad;
+      if (netStreamBufferTime) {
+        this.bufferTime = netStreamBufferTime;
+      }
+      // Use bufferTimes instead of bufferTime
+      if (bufferTimes !== null) {
+        this.bufferTimes = bufferTimes;
+      } else {
+        this.bufferTimes = [this.bufferTime];
+      }
+      setAutoPlay(autoPlay);
+
+      if (recordStats) {
+        this.start_time = getTimer();
+      }
+
+      writeDebug('SoundManager2_SMSound_AS3: Got duration: '+duration+', autoPlay: '+autoPlay);
+
+      if (this.useNetstream) {
+
+        this.cc = new Object();
+        this.nc = new NetConnection();
+
+        // Handle FMS bandwidth check callback.
+        // @see onBWDone
+        // @see http://www.adobe.com/devnet/flashmediaserver/articles/dynamic_stream_switching_04.html
+        // @see http://www.johncblandii.com/index.php/2007/12/fms-a-quick-fix-for-missing-onbwdone-onfcsubscribe-etc.html
+        this.nc.client = this;
+
+        // TODO: security/IO error handling
+        // this.nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, doSecurityError);
+        nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
+
+        if (this.serverUrl != null) {
+          writeDebug('SoundManager2_SMSound_AS3: NetConnection: connecting to server ' + this.serverUrl + '...');
+        }
+        this.nc.connect(serverUrl);
+      } else {
+        this.connect_time = this.start_time;
+        this.connected = true;
+      }
+
+    }
+
+    public function netStatusHandler(event:NetStatusEvent):void {
+
+      if (this.useEvents) {
+        writeDebug('netStatusHandler: '+event.info.code);
+      }
+
+      switch (event.info.code) {
+
+        case "NetConnection.Connect.Success":
+          writeDebug('NetConnection: connected');
+          try {
+            this.ns = new NetStream(this.nc);
+            this.ns.checkPolicyFile = true;
+            // bufferTime reference: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/net/NetStream.html#bufferTime
+            this.ns.bufferTime = getStartBuffer(); // set to 0.1 or higher. 0 is reported to cause playback issues with static files.
+            this.st = new SoundTransform();
+            this.cc.onMetaData = this.metaDataHandler;
+            this.ns.client = this.cc;
+            this.ns.receiveAudio(true);
+            this.addNetstreamEvents();
+
+            if (this.useVideo) {
+              this.oVideo = new Video();
+              this.ns.receiveVideo(true);
+              this.sm.stage.addEventListener(Event.RESIZE, this.resizeHandler);
+              this.oVideo.smoothing = true; // http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/Video.html#smoothing
+              this.oVideo.visible = false; // hide until metadata received
+              this.sm.addChild(this.oVideo);
+              this.oVideo.attachNetStream(this.ns);
+              writeDebug('setting video w/h to stage: ' + this.sm.stage.stageWidth + 'x' + this.sm.stage.stageHeight);
+              this.oVideo.width = this.sm.stage.stageWidth;
+              this.oVideo.height = this.sm.stage.stageHeight;
+            }
+            this.connected = true;
+            if (recordStats) {
+              this.recordConnectTime();
+            }
+            if (this.useEvents) {
+              writeDebug('firing _onconnect for '+this.sID);
+              ExternalInterface.call(this.sm.baseJSObject + "['" + this.sID + "']._onconnect", 1);
+            }
+          } catch(e: Error) {
+            this.failed = true;
+            writeDebug('netStream error: ' + e.toString());
+            ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Connection failed!', event.info.level, event.info.code);
+          }
+          break;
+
+        case "NetStream.Play.StreamNotFound":
+          this.failed = true;
+          writeDebug("NetConnection: Stream not found!");
+          ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Stream not found!', event.info.level, event.info.code);
+          break;
+
+        // This is triggered when the sound loses the connection with the server.
+        // In some cases one could just try to reconnect to the server and resume playback.
+        // However for streams protected by expiring tokens, I don't think that will work.
+        //
+        // Flash says that this is not an error code, but a status code...
+        // should this call the onFailure handler?
+        case "NetConnection.Connect.Closed":
+          this.failed = true;
+          ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Connection closed!', event.info.level, event.info.code);
+          writeDebug("NetConnection: Connection closed!");
+          break;
+
+        // Couldn't establish a connection with the server. Attempts to connect to the server
+        // can also fail if the permissible number of socket connections on either the client
+        // or the server computer is at its limit.  This also happens when the internet
+        // connection is lost.
+        case "NetConnection.Connect.Failed":
+          this.failed = true;
+          writeDebug("NetConnection: Connection failed! Lost internet connection? Try again... Description: " + event.info.description);
+          ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Connection failed!', event.info.level, event.info.code);
+          break;
+
+        // A change has occurred to the network status. This could mean that the network
+        // connection is back, or it could mean that it has been lost...just try to resume
+        // playback.
+
+        // KJV: Can't use this yet because by the time you get your connection back the
+        // song has reached it's maximum retries, so it doesn't retry again.  We need
+        // a new _ondisconnect handler.
+        //case "NetConnection.Connect.NetworkChange":
+        //  this.failed = true;
+        //  writeDebug("NetConnection: Network connection status changed");
+        //  ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", 'Reconnecting...');
+        //  break;
+
+        // Consider everything else a failure...
+        default:
+          this.failed = true;
+          writeDebug("NetConnection: got unhandled code '" + event.info.code + "'! Description: " + event.info.description);
+          ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", '', event.info.level, event.info.code);
+          break;
+      }
+
+    }
+
+    // Set the buffer size on the current NetSream instance to <tt>buffer</tt> secs
+    // Only set the buffer if it's different to the current buffer.
+    public function setBuffer(buffer: int) : void {
+      if (buffer != this.ns.bufferTime) {
+        this.ns.bufferTime = buffer;
+        writeDebug('set buffer to '+this.ns.bufferTime+' secs');
+      }
+    }
+
+    // Return the size of the starting buffer.
+    public function getStartBuffer() : int {
+      return this.bufferTimes[0];
+    }
+
+    // Return the size of the next buffer, given the size of the current buffer.
+    // If there are no more buffers, returns the current buffer size.
+    public function getNextBuffer(current_buffer: int) : int {
+      var i: int = bufferTimes.indexOf(current_buffer);
+      if (i == -1) {
+        // Couldn't find the buffer, start from the start buffer size
+        return getStartBuffer();
+      } else if (i + 1 >= bufferTimes.length) {
+        // Last (or only) buffer, keep the current buffer
+        return current_buffer;
+      } else {
+        return this.bufferTimes[i+1];
+      }
+   }
+
+    public function resizeHandler(e: Event) : void {
+      // scale video to stage dimensions
+      // probably less performant than using native flash scaling, but that doesn't quite seem to work. I'm probably missing something simple.
+      this.oVideo.width = this.sm.stage.stageWidth;
+      this.oVideo.height = this.sm.stage.stageHeight;
+    }
+
+    public function writeDebug (s: String, bTimestamp: Boolean = false) : Boolean {
+      return this.sm.writeDebug (s, bTimestamp); // defined in main SM object
+    }
+
+    public function metaDataHandler(infoObject: Object) : void {
+      /*
+	  var data:String = new String();
+	  for (var prop:* in infoObject) {
+		data += prop+': '+infoObject[prop]+' ';
+	  }
+	  ExternalInterface.call('soundManager._writeDebug','Metadata: '+data);
+	  */
+      if (this.oVideo) {
+        // set dimensions accordingly
+        if (!infoObject.width && !infoObject.height) {
+          writeDebug('No width/height specified, using stage dimensions');
+          infoObject.width = this.sm.stage.width;
+          infoObject.height = this.sm.stage.height;
+        }
+        writeDebug('video dimensions: ' + infoObject.width + 'x' + infoObject.height + ' (w/h)');
+        this.videoWidth = infoObject.width;
+        this.videoHeight = infoObject.height;
+        // implement a subset of metadata to pass over EI bridge
+        // some formats have extra stuff, eg. "aacaot", "avcprofile"
+        // http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000267.html
+        var oMeta: Object = new Object();
+        var item: Object = null;
+        for (item in infoObject) {
+          // exclude seekpoints for now, presumed not useful and overly large.
+          if (item != 'seekpoints') {
+            oMeta[item] = infoObject[item];
+          }
+        }
+        ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onmetadata", oMeta);
+        writeDebug('showing video for ' + this.sID);
+        this.oVideo.visible = true; // show ze video!
+      }
+      if (!this.loaded) {
+        // writeDebug('not loaded yet: '+this.ns.bytesLoaded+', '+this.ns.bytesTotal+', '+infoObject.duration*1000);
+        // TODO: investigate loaded/total values
+        // ExternalInterface.call(baseJSObject + "['" + this.sID + "']._whileloading", this.ns.bytesLoaded, this.ns.bytesTotal, infoObject.duration*1000);
+        ExternalInterface.call(baseJSObject + "['" + this.sID + "']._whileloading", this.bytesLoaded, this.bytesTotal, (infoObject.duration || this.duration))
+      }
+      this.duration = infoObject.duration * 1000;
+      // null this out for the duration of this object's existence.
+      // it may be called multiple times.
+      this.cc.onMetaData = function(infoObject: Object) : void {}
+
+    }
+
+    public function getWaveformData() : void {
+      // http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundMixer.html#computeSpectrum()
+      SoundMixer.computeSpectrum(this.waveformData, false, 0); // sample wave data at 44.1 KHz
+      this.waveformDataArray = [];
+      for (var i: int = 0, j: int = this.waveformData.length / 4; i < j; i++) { // get all 512 values (256 per channel)
+        this.waveformDataArray.push(int(this.waveformData.readFloat() * 1000) / 1000);
+      }
+    }
+
+    public function getEQData() : void {
+      // http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundMixer.html#computeSpectrum()
+      SoundMixer.computeSpectrum(this.eqData, true, 0); // sample EQ data at 44.1 KHz
+      this.eqDataArray = [];
+      for (var i: int = 0, j: int = this.eqData.length / 4; i < j; i++) { // get all 512 values (256 per channel)
+        this.eqDataArray.push(int(this.eqData.readFloat() * 1000) / 1000);
+      }
+    }
+
+    public function start(nMsecOffset: int, nLoops: int) : void {
+      this.sm.currentObject = this; // reference for video, full-screen
+      this.useEvents = true;
+      if (this.useNetstream) {
+
+        writeDebug("SMSound::start nMsecOffset "+ nMsecOffset+ ' nLoops '+nLoops + ' current bufferTime '+this.ns.bufferTime+' current bufferLength '+this.ns.bufferLength+ ' this.lastValues.position '+this.lastValues.position);
+
+        this.cc.onMetaData = this.metaDataHandler;
+
+        // Don't seek if we don't have to because it destroys the buffer
+        if (this.lastValues.position != null && this.lastValues.position != nMsecOffset) {
+          // Minimize the buffer so playback starts ASAP
+          this.setBuffer(this.getStartBuffer());
+          // writeDebug('setting buffer to '+this.bufferTime+' secs');
+          this.ns.seek(nMsecOffset);
+          this.lastValues.position = nMsecOffset; // https://gist.github.com/1de8a3113cf33d0cff67
+        }
+
+        if (this.paused) {
+          writeDebug('start: resuming from paused state');
+          this.ns.resume(); // get the sound going again
+          if (!this.didLoad) {
+            this.didLoad = true;
+          }
+          this.paused = false;
+        } else if (!this.didLoad) {
+          writeDebug('start: !didLoad - playing '+this.sURL);
+          this.ns.play(this.sURL);
+          this.didLoad = true;
+          this.paused = false;
+        } else {
+          // previously loaded, perhaps stopped/finished. play again?
+          writeDebug('playing again (not paused, didLoad = true)');
+          this.ns.play(this.sURL);
+        }
+        // this.ns.addEventListener(Event.SOUND_COMPLETE, _onfinish);
+        this.applyTransform();
+
+      } else {
+        // writeDebug('start: seeking to '+nMsecOffset+', '+nLoops+(nLoops==1?' loop':' loops'));
+        this.soundChannel = this.play(nMsecOffset, nLoops);
+        this.addEventListener(Event.SOUND_COMPLETE, _onfinish);
+        this.applyTransform();
+      }
+
+    }
+
+    private function _onfinish() : void {
+      this.removeEventListener(Event.SOUND_COMPLETE, _onfinish);
+    }
+
+    public function loadSound(sURL: String, bStream: Boolean) : void {
+      if (this.useNetstream) {
+        this.useEvents = true;
+        if (this.didLoad != true) {
+          ExternalInterface.call('loadSound(): loading ' + this.sURL);
+          this.ns.play(this.sURL);
+          this.didLoad = true;
+        }
+        // this.addEventListener(Event.SOUND_COMPLETE, _onfinish);
+        this.applyTransform();
+      } else {
+        try {
+          this.didLoad = true;
+          this.urlRequest = new URLRequest(sURL);
+          this.soundLoaderContext = new SoundLoaderContext(1000, true); // check for policy (crossdomain.xml) file on remote domains - http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/media/SoundLoaderContext.html
+          this.load(this.urlRequest, this.soundLoaderContext);
+        } catch(e: Error) {
+          writeDebug('error during loadSound(): ' + e.toString());
+        }
+      }
+    }
+
+    public function setAutoPlay(autoPlay: Boolean) : void {
+      if (!this.serverUrl) {
+        // don't apply to non-RTMP, netstream stuff.
+        this.autoPlay = true;
+        this.pauseOnBufferFull = false;
+      } else {
+        this.autoPlay = autoPlay;
+        if (this.autoPlay) {
+          this.pauseOnBufferFull = false;
+          // writeDebug('ignoring pauseOnBufferFull because autoPlay is on');
+        } else if (!this.autoPlay) {
+          this.pauseOnBufferFull = true;
+          // writeDebug('pausing on buffer full because autoPlay is off');
+        }
+      }
+    }
+
+    public function setVolume(nVolume: Number) : void {
+      this.lastValues.volume = nVolume / 100;
+      this.applyTransform();
+    }
+
+    public function setPan(nPan: Number) : void {
+      this.lastValues.pan = nPan / 100;
+      this.applyTransform();
+    }
+
+    public function applyTransform() : void {
+      var st: SoundTransform = new SoundTransform(this.lastValues.volume, this.lastValues.pan);
+      if (this.useNetstream) {
+        if (this.ns) {
+          this.ns.soundTransform = st;
+        } else {
+          // writeDebug('applyTransform(): Note: No active netStream');
+        }
+      } else if (this.soundChannel) {
+        this.soundChannel.soundTransform = st; // new SoundTransform(this.lastValues.volume, this.lastValues.pan);
+      }
+    }
+
+    public function recordPlayTime() : void {
+      this.play_time = Math.round(getTimer() - (this.start_time + this.connect_time));
+      writeDebug('Play took '+ this.play_time + ' ms');
+      // We must now have both stats, call the onstats callback
+      ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onstats", {
+        play_time:    this.play_time,
+        connect_time: this.connect_time
+      });
+      // Stop tracking any stats for this object
+      this.recordStats = false;
+    }
+
+    public function recordConnectTime() : void {
+      this.connect_time = Math.round(getTimer() - this.start_time);
+      writeDebug('Connect took '+ this.connect_time + ' ms');
+    }
+
+    // Handle FMS bandwidth check callback.
+    // @see http://www.adobe.com/devnet/flashmediaserver/articles/dynamic_stream_switching_04.html
+    // @see http://www.johncblandii.com/index.php/2007/12/fms-a-quick-fix-for-missing-onbwdone-onfcsubscribe-etc.html
+    public function onBWDone() : void {
+      // writeDebug('onBWDone: called and ignored');
+    }
+
+    // NetStream client callback. Invoked when the song is complete.
+    public function onPlayStatus(info:Object):void {
+      writeDebug('onPlayStatus called with '+info);
+      switch(info.code) {
+        case "NetStream.Play.Complete":
+          writeDebug('Song has finished!');
+          break;
+      }
+    }
+
+    public function doIOError(e: IOErrorEvent) : void {
+      ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onload", 0); // call onload, assume it failed.
+      // there was a connection drop, a loss of internet connection, or something else wrong. 404 error too.
+    }
+
+    public function doAsyncError(e: AsyncErrorEvent) : void {
+      writeDebug('asyncError: ' + e.text);
+    }
+
+    public function doNetStatus(e: NetStatusEvent) : void {
+
+      // Handle failures
+      if (e.info.code == "NetStream.Failed"
+          || e.info.code == "NetStream.Play.FileStructureInvalid"
+          || e.info.code == "NetStream.Play.StreamNotFound") {
+
+        this.lastNetStatus = e.info.code;
+        writeDebug('netStatusEvent: ' + e.info.code);
+        this.failed = true;
+        ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfailure", '', e.info.level, e.info.code);
+        return;
+      }
+
+      writeDebug('netStatusEvent: ' + e.info.code);  // KJV we like to see all events
+
+      // When streaming, Stop is called when buffering stops, not when the stream is actually finished.
+      // @see http://www.actionscript.org/forums/archive/index.php3/t-159194.html
+      if (e.info.code == "NetStream.Play.Stop") {
+
+        if (!this.useNetstream) {
+          // finished playing
+          // this.didFinish = true; // will be reset via JS callback
+          this.didJustBeforeFinish = false; // reset
+          writeDebug('calling onfinish for a sound');
+          // reset the sound? Move back to position 0?
+          this.sm.checkProgress();
+          ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfinish");
+          // and exit full-screen mode, too?
+          this.sm.stage.displayState = StageDisplayState.NORMAL;
+        }
+
+      } else if (e.info.code == "NetStream.Play.Start" || e.info.code == "NetStream.Buffer.Empty" || e.info.code == "NetStream.Buffer.Full") {
+
+        // First time buffer has filled. Print debugging output.
+        if (this.recordStats && !this.play_time) {
+          this.recordPlayTime();
+        }
+
+        // RTMP case..
+        // We wait for the buffer to fill up before pausing the just-loaded song because only if the
+        // buffer is full will the song continue to buffer until the user hits play.
+        if (this.serverUrl && e.info.code == "NetStream.Buffer.Full" && this.pauseOnBufferFull) {
+          this.ns.pause();
+          this.paused = true;
+          this.pauseOnBufferFull = false;
+          // Call pause in JS.  This will call back to us to pause again, but
+          // that should be harmless.
+          writeDebug('Pausing song because buffer is full');
+          ExternalInterface.call(baseJSObject + "['" + this.sID + "'].pause", false);
+        }
+
+        // The buffer is full.  Increase its size if possible.
+        // Double buffering has not been shown to cause false starts, so this is safe.
+        if (e.info.code == "NetStream.Buffer.Full") {
+          var next_buffer: int = this.getNextBuffer(this.ns.bufferTime);
+          if (next_buffer != this.ns.bufferTime) {
+            this.setBuffer(next_buffer);
+          }
+        }
+
+        var isNetstreamBuffering: Boolean = (e.info.code == "NetStream.Buffer.Empty" || e.info.code == "NetStream.Play.Start");
+        // assume buffering when we start playing, eg. initial load.
+        if (isNetstreamBuffering != this.lastValues.isBuffering) {
+          this.lastValues.isBuffering = isNetstreamBuffering;
+          ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onbufferchange", this.lastValues.isBuffering ? 1 : 0);
+        }
+
+        // We can detect the end of the stream when Play.Stop is called followed by Buffer.Empty.
+        // However, if you pause and let the whole song buffer, Buffer.Flush is called followed by
+        // Buffer.Empty, so handle that case too.
+        //
+        // Ignore this event if we are more than 5 seconds from the end of the song.
+        if (e.info.code == "NetStream.Buffer.Empty" && (this.lastNetStatus == 'NetStream.Play.Stop' || this.lastNetStatus == 'NetStream.Buffer.Flush')) {
+          if (this.duration && (this.ns.time * 1000) < (this.duration - 5000)) {
+            writeDebug('Ignoring Buffer.Empty because this is too early to be the end of the stream! (sID: '+this.sID+', time: '+(this.ns.time*1000)+', duration: '+this.duration+')');
+          } else {
+            this.didJustBeforeFinish = false; // reset
+            this.finished = true;
+            writeDebug('calling onfinish for sound '+this.sID);
+            this.sm.checkProgress();
+            ExternalInterface.call(baseJSObject + "['" + this.sID + "']._onfinish");
+          }
+
+        } else if (e.info.code == "NetStream.Buffer.Empty") {
+
+          // The buffer is empty.  Start from the smallest buffer again.
+          this.setBuffer(this.getStartBuffer());
+        }
+      }
+
+      // Remember the last NetStatus event
+      this.lastNetStatus = e.info.code;
+    }
+
+    // KJV The sound adds some of its own netstatus handlers so we don't need to do it here.
+    public function addNetstreamEvents() : void {
+      ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, doAsyncError);
+      ns.addEventListener(NetStatusEvent.NET_STATUS, doNetStatus);
+      ns.addEventListener(IOErrorEvent.IO_ERROR, doIOError);
+    }
+
+    public function removeNetstreamEvents() : void {
+      ns.removeEventListener(AsyncErrorEvent.ASYNC_ERROR, doAsyncError);
+      ns.removeEventListener(NetStatusEvent.NET_STATUS, doNetStatus);
+      ns.addEventListener(NetStatusEvent.NET_STATUS, dummyNetStatusHandler);
+      ns.removeEventListener(IOErrorEvent.IO_ERROR, doIOError);
+      // KJV Stop listening for NetConnection events on the sound
+      nc.removeEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
+    }
+
+    // Prevents possible 'Unhandled NetStatusEvent' condition if a sound is being
+    // destroyed and interacted with at the same time.
+    public function dummyNetStatusHandler(e: NetStatusEvent) : void {
+      // Don't do anything
+    }
+
+  }
+
+}


adjusted player position in minecrat.

adjusted player position in minecrat.


Transferred from the Adobe Open Source Subversion Repository

Revision: 10464
Author:   rfrishbe@adobe.com
Date:     2009-09-21T17:40:30.663638Z

Log Message:
-----------
Removing support in Flex framework for compatibility version < 3.  We won't support compatibility-version 2 or 2.01 anymore.  We only keep compatibility-version for one full release, so for Flex 4, we only support compatibility-version = 3.x.

This should reduce our code-size some as we no longer need this old code.  I didn't clean up the compiler's support for compatibility-versioning as it didn't seem worth the effort.

QE notes: -
Doc notes: -
Bugs: SDK-15360
Reviewer: Kevin
Tests run: checkintests, Joan ran all mustella tests
Is noteworthy for integration: Yes

Modified Paths:
--------------
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/listClasses/TileListItemRenderer.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/skins/halo/HaloBorder.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/ProgressBar.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/RadioButton.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/containers/accordionClasses/AccordionHeader.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/containers/utilityClasses/CanvasLayout.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/DateChooser.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/mx/core/UITLFTextField.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/NumericStepper.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/skins/halo/ScrollArrowSkin.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/skins/halo/AccordionHeaderSkin.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/Alert.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/Container.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/NavBar.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/Button.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/UITextField.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/ColorPicker.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/TextArea.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/dataGridClasses/DataGridHeaderBase.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/DateField.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/styles/StyleProxy.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/treeClasses/TreeItemRenderer.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/containers/TabNavigator.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/containers/FormItem.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/UIComponent.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/dataGridClasses/DataGridHeader.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/CheckBox.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/SWFLoader.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/skins/halo/DateChooserYearArrowSkin.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/LinkButton.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/MenuBar.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/ComboBase.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/menuClasses/MenuBarItem.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/skins/halo/PanelSkin.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/menuClasses/MenuItemRenderer.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/styles/StyleManagerImpl.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/PopUpButton.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/listClasses/ListBase.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/scrollClasses/ScrollBar.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/containers/Panel.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/colorPickerClasses/SwatchPanel.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/containers/Accordion.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/TextInput.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/styles/StyleProtoChain.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/ComboBox.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/listClasses/ListItemRenderer.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/List.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/Label.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/DataGrid.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/skins/halo/ScrollTrackSkin.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/containers/utilityClasses/Flex.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/LinkBar.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/controls/sliderClasses/Slider.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1267797 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mx/src/mx/containers/accordionClasses/AccordionHeader.as
+++ frameworks/projects/mx/src/mx/containers/accordionClasses/AccordionHeader.as
@@ -18,7 +18,6 @@
 import mx.containers.Accordion;
 import mx.controls.Button;
 import mx.core.Container;
-import mx.core.FlexVersion;
 import mx.core.EdgeMetrics;
 import mx.core.IDataRenderer;
 import mx.core.IFlexDisplayObject;
@@ -160,34 +159,6 @@
 	//  Overridden methods: UIComponent
 	//
 	//--------------------------------------------------------------------------
-
-	/**
-	 *  @private
-	 */
-	override protected function createChildren():void
-	{
-		super.createChildren();
-
-		if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_3_0)
-		{
-			// AccordionHeader has a bit of a conflict here. Our styleName points to
-			// our parent Accordion, which has padding values defined. We also have
-			// padding values defined on our type selector, but since class selectors
-			// take precedence over type selectors, the type selector padding values
-			// are ignored. Force them in here.
-			var styleDecl:CSSStyleDeclaration = StyleManager.getStyleDeclaration(className);
-
-			if (styleDecl)
-			{
-				var value:Number = styleDecl.getStyle("paddingLeft");
-				if (!isNaN(value))
-					setStyle("paddingLeft", value);
-				value = styleDecl.getStyle("paddingRight");
-				if (!isNaN(value))
-					setStyle("paddingRight", value);
-			}
-		}
-	}

 	/**
 	 *  @private


Transferred from the Adobe Open Source Subversion Repository

Revision: 23247
Author:   cframpto@adobe.com
Date:     2011-12-20T19:21:13.134833Z

Log Message:
-----------
Remove ADOBE SYSTEMS license and replace with Apache license in headers - frameworks.  A 2nd pass will be needed to get the files not handled up by the scripts.

Modified Paths:
--------------
4959 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1267823 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mx/src/mx/containers/utilityClasses/ApplicationLayout.as
+++ frameworks/projects/mx/src/mx/containers/utilityClasses/ApplicationLayout.as
@@ -1,11 +1,19 @@
 ////////////////////////////////////////////////////////////////////////////////
 //
-//  ADOBE SYSTEMS INCORPORATED
-//  Copyright 2005-2006 Adobe Systems Incorporated
-//  All Rights Reserved.
+//  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
 //
-//  NOTICE: Adobe permits you to use, modify, and distribute this file
-//  in accordance with the terms of the license agreement accompanying it.
+//      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.
 //
 ////////////////////////////////////////////////////////////////////////////////


Transferred from the Adobe Open Source Subversion Repository

Revision: 21792
Author:   klin@adobe.com
Date:     2011-08-03T17:04:31.076541Z

Log Message:
-----------
Fix RTE when changing column visiblity via states. In GridDimensions, we should only handle update events from columns that have a valid columnIndex.

QE notes: No
Doc notes: No
Bugs: SDK-29918
Reviewer: Hans
Tests run: cyclone server, checkintests
Is noteworthy for integration: No

Modified Paths:
--------------
/private/flex/sdk/branches/4.y/frameworks/projects/spark/src/spark/components/gridClasses/GridDimensions.as

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1281529 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/gridClasses/GridDimensions.as
+++ frameworks/projects/spark/src/spark/components/gridClasses/GridDimensions.as
@@ -1819,7 +1819,7 @@
     {
         const column:GridColumn = pcEvent.source as GridColumn;
         const columnIndex:int = column.columnIndex;
-        if (!column || columnIndex == -1)
+        if (!column || columnIndex < 0 || columnIndex >= _columnCount)
             return;

         clearColumns(columnIndex, 1);


Transferred from the Adobe Open Source Subversion Repository

Revision: 17918
Author:   deeptika@adobe.com
Date:     2010-09-29T09:10:43.362516Z

Log Message:
-----------
Automation support for spark DG - 1
Only selection event is supported by automation. Header related events, column resize / sort, item edit and drag-drop are not yet supported by the component.

QE notes:
Doc notes:
Bugs:
Reviewer:
Tests run:
Is noteworthy for integration:

Modified Paths:
--------------
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/automation_spark/src/spark/automation/tabularData/SparkDataGridTabularData.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/automation_spark/manifest_automation_spark.xml</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/automation_spark/src/AutomationSparkClasses.as</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/automation_spark/src/spark/automation/delegates/components/SparkDataGridAutomationImpl.as</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/automation_spark/src/spark/automation/events/SparkDataGridItemSelectEvent.as</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/automation_spark/src/spark/automation/delegates/skins/spark/SparkDefaultGridItemRendererAutomationImpl.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1252341 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/automation_spark/src/spark/automation/events/SparkDataGridItemSelectEvent.as
+++ frameworks/projects/automation_spark/src/spark/automation/events/SparkDataGridItemSelectEvent.as
@@ -0,0 +1,305 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2009 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.automation.events
+{
+
+	import flash.events.Event;
+
+	import spark.components.IGridItemRenderer;
+
+	/**
+	 *  The SparkDataGridItemSelectEvent class represents event objects that are dispatched
+	 *  when an item in a datagrid control is selected or deselected.
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	public class SparkDataGridItemSelectEvent extends Event
+	{
+		include "../../core/Version.as";
+
+		//--------------------------------------------------------------------------
+		//
+		//  Class constants
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  The SparkDataGridItemSelectEvent.SELECT constant defines the value of the
+		 *  type property of the event object for an event that is
+		 *  dispatched when a single item is selected.
+		 *
+		 *
The properties of the event object have the following values.
+		 *  Not all properties are meaningful for all kinds of events.
+		 *  See the detailed property descriptions for more information.

+		 *

+		 *
Property	Value

+		 *
altKey	Boolean value indicating whether
+		 *              the Alt key was pressed at the time of the event.

+		 *
bubbles	false

+		 *
cancelable	false

+		 *
ctrlKey	Boolean value indicating whether
+		 *              the Ctrl key was pressed at the time of the event.

+		 *
currentTarget	The Object that defines the
+		 *       event listener that handles the event. For example, if you use
+		 *       myButton.addEventListener() to register an event listener,
+		 *       myButton is the value of the currentTarget.

+		 *
itemRenderer	The item renderer object
+		 *              for the item.

+		 *
shiftKey	Boolean value indicating whether
+		 *              the Shift key was pressed at the time of the event.

+		 *
target	The Object that dispatched the event;
+		 *       it is not always the Object listening for the event.
+		 *       Use the currentTarget property to always access the
+		 *       Object listening for the event.

+		 *
triggerEvent	The event, such as a
+		 *             mouse or keyboard event, that triggered the action.

+		 *
type	SparkListItemSelectEvent.SELECT

+		 *

+		 *
+		 *  @eventType select
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public static const SELECT:String = "select";
+
+		/**
+		 *  The SparkDataGridItemSelectEvent.SELECT_INDEX constant defines the value of the
+		 *  type property of the event object for an event that is
+		 *  dispatched when an item's index is selected.
+		 *
+		 *
The properties of the event object have the following values.
+		 *  Not all properties are meaningful for all kinds of events.
+		 *  See the detailed property descriptions for more information.

+		 *

+		 *
Property	Value

+		 *
altKey	Boolean value indicating whether
+		 *              the Alt key was pressed at the time of the event.

+		 *
bubbles	false

+		 *
cancelable	false

+		 *
ctrlKey	Boolean value indicating whether
+		 *              the Ctrl key was pressed at the time of the event.

+		 *
currentTarget	The Object that defines the
+		 *       event listener that handles the event. For example, if you use
+		 *       myButton.addEventListener() to register an event listener,
+		 *       myButton is the value of the currentTarget.

+		 *
itemIndex	The data provider index of
+		 *              the item to be selected.

+		 *
shiftKey	Boolean value indicating whether
+		 *              the Shift key was pressed at the time of the event.

+		 *
target	The Object that dispatched the event;
+		 *       it is not always the Object listening for the event.
+		 *       Use the currentTarget property to always access the
+		 *       Object listening for the event.

+		 *
triggerEvent	The event, such as a
+		 *             mouse or keyboard event, that triggered the action.

+		 *
type	SparkListItemSelectEvent.SELECT_INDEX

+		 *

+		 *
+		 *  @eventType select
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public static const SELECT_INDEX:String = "selectIndex";
+
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Constructor.
+		 *  Normally called by the Flex control and not used in application code.
+		 *
+		 *  @param type The event type; indicates the action that caused the event.
+		 *
+		 *  @param bubbles Specifies whether the event can bubble
+		 *  up the display list hierarchy.
+		 *
+		 *  @param cancelable Specifies whether the behavior
+		 *  associated with the event can be prevented.
+		 *
+		 *  @param itemRenderer The item renderer object for the item.
+		 *
+		 *  @param triggerEvent The event, such as a mouse or keyboard event, that
+		 *              triggered the selection action.
+		 *
+		 *  @param altKey Whether the Alt key was pressed at the time of the event.
+		 *
+		 *  @param ctrlKey Whether the Ctrl key was pressed at the time of the event.
+		 *
+		 *  @param shiftKey Whether the Shift key was pressed at the time of the event.
+		 *
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function SparkDataGridItemSelectEvent(type:String, bubbles:Boolean = false,
+												 cancelable:Boolean = false,
+												 itemRenderer:IGridItemRenderer = null,
+												 triggerEvent:Event = null,
+												 ctrlKey:Boolean = false,
+												 altKey:Boolean = false,
+												 shiftKey:Boolean = false)
+		{
+			super(type, bubbles, cancelable);
+
+			this.itemRenderer = itemRenderer;
+			this.triggerEvent = triggerEvent;
+			this.ctrlKey = ctrlKey;
+			this.altKey = altKey;
+			this.shiftKey = shiftKey;
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  altKey
+		//----------------------------------
+
+		/**
+		 *  Indicates whether the Alt key was pressed at the time of the event, true,
+		 *  or not, false.
+		 *
+		 *  @default false
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public var altKey:Boolean;
+
+		//----------------------------------
+		//  ctrlKey
+		//----------------------------------
+
+		/**
+		 *  Indicates whether the Ctrl key was pressed at the time of the event, true,
+		 *  or not, false.
+		 *
+		 *  @default false
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public var ctrlKey:Boolean;
+
+		//----------------------------------
+		//  triggerEvent
+		//----------------------------------
+
+		/**
+		 *  Event that triggered the item selection event,
+		 *  such as a keyboard or mouse event.
+		 *
+		 *  @default null
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public var triggerEvent:Event;
+
+		//----------------------------------
+		//  itemRenderer
+		//----------------------------------
+
+		/**
+		 *  Item renderer object for the item being selected or deselected.
+		 *  You can access the cell data using this property.
+		 *
+		 *  @default null
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public var itemRenderer:IGridItemRenderer;
+
+		//----------------------------------
+		//  shiftKey
+		//----------------------------------
+
+		/**
+		 *  Indicates whether the Shift key was pressed at the time of the event, true,
+		 *  or not, false.
+		 *
+		 *  @default false
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public var shiftKey:Boolean;
+
+
+		/**
+		 *  The automationValue string of the item to be selected.
+		 *  This is used when the item to be selected is not visible in the control.
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public var itemAutomationValue:String;
+
+
+		/**
+		 *  The data provider index of the item to be selected.
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public var itemIndex:uint;
+
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods: Event
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  @private
+		 */
+		override public function clone():Event
+		{
+			return new SparkDataGridItemSelectEvent(type, bubbles, cancelable,
+				itemRenderer,  triggerEvent,
+				ctrlKey, altKey, shiftKey);
+		}
+	}
+
+}


UIButtonBase supports width and height change events.

--- frameworks/projects/Core/src/main/flex/org/apache/flex/core/UIButtonBase.as
+++ frameworks/projects/Core/src/main/flex/org/apache/flex/core/UIButtonBase.as
@@ -277,6 +277,7 @@

 		private var _width:Number;

+		[Bindable("widthChanged")]
         [PercentProxy("percentWidth")]
         /**
          *  @copy org.apache.flex.core.UIBase#width
@@ -327,6 +328,7 @@

 		private var _height:Number;

+		[Bindable("heightChanged")]
         [PercentProxy("percentHeight")]
         /**
          *  @copy org.apache.flex.core.UIBase#width


FLEX-33259 Removed semi colon after metadata

git-svn-id: 7d913817b0a978d84de757191e4bce372605a781@1409209 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/framework/src/mx/managers/ISystemManagerChildManager.as
+++ frameworks/projects/framework/src/mx/managers/ISystemManagerChildManager.as
@@ -22,7 +22,7 @@

 import flash.display.DisplayObject;

-[ExcludeClass];
+[ExcludeClass]

 /**
  */


fix typo

fix typo

--- actionscript/src/com/freshplanet/nativeExtensions/PushNotification.as
+++ actionscript/src/com/freshplanet/nativeExtensions/PushNotification.as
@@ -77,7 +77,7 @@
 			return extCtx.call("getCanSendUserToSettings");
 		}

-		public function openDeviceNotificationSettions():void
+		public function openDeviceNotificationSettings():void
 		{
 			if(isPushNotificationSupported) {
 				extCtx.call("openDeviceNotificationSettings");


Transferred from the Adobe Open Source Subversion Repository

Revision: 12850
Author:   jimurphy@adobe.com
Date:     2009-12-11T14:57:14.623098Z

Log Message:
-----------
add 6 new DMV projects to the SDK:
automation
automation_air
automation_dmv
automation_flashflexkit
automation_spark
datavisualization

These projects are setup to build in an ant main call.  There are currently several warnings in the datavisualization project that will be cleaned up.  No checkintests exist for these projects as of yet.

I also modified the exisitng projects build files for easier management of the localization targets, bundle and fat-swc. If the projects that I updated:airframework,airspark,framework,playerglobal,rpc,and spark.  All the new projects have been implemented this same way.

QE notes: DMV folks should run through their tests
Doc notes: probably
Bugs: nope
Reviewer:
Tests run: ran the following targets: compile,checkintests,other.locales and doc
Is noteworthy for integration: no

Modified Paths:
--------------
1404 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1251430 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/automation/src/mx/automation/delegates/controls/ListItemRendererAutomationImpl.as
+++ frameworks/projects/automation/src/mx/automation/delegates/controls/ListItemRendererAutomationImpl.as
@@ -0,0 +1,131 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2009 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.automation.delegates.controls
+{
+	import flash.display.DisplayObject;
+	import flash.events.Event;
+	import mx.automation.Automation;
+	import mx.automation.IAutomationObjectHelper;
+	import mx.automation.delegates.core.UIComponentAutomationImpl;
+	import mx.controls.listClasses.ListItemRenderer;
+	import mx.core.mx_internal;
+	import mx.core.IUITextField;
+
+	use namespace mx_internal;
+
+	[Mixin]
+	/**
+	 *
+	 *  Defines methods and properties required to perform instrumentation for the
+	 *  ListItemRenderer class.
+	 *
+	 *  @see mx.controls.listClasses.ListItemRenderer
+	 *
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	public class ListItemRendererAutomationImpl extends UIComponentAutomationImpl
+	{
+		include "../../../core/Version.as";
+
+		//--------------------------------------------------------------------------
+		//
+		//  Class methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Registers the delegate class for a component class with automation manager.
+		 *
+		 *  @param root The SystemManger of the application.
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static function init(root:DisplayObject):void
+		{
+			Automation.registerDelegateClass(ListItemRenderer, ListItemRendererAutomationImpl);
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Constructor.
+		 * @param obj ListItemRenderer object to be automated.
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function ListItemRendererAutomationImpl(obj:ListItemRenderer)
+		{
+			super(obj);
+		}
+
+		//--------------------------------------------------------------------------
+		//
+		//  Variables
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  @private
+		 *  storage for the owner component
+		 */
+		protected function get listItem():ListItemRenderer
+		{
+			return uiComponent as ListItemRenderer;
+		}
+
+
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden properties
+		//
+		//--------------------------------------------------------------------------
+
+		//----------------------------------
+		//  automationName
+		//----------------------------------
+
+		/**
+		 *  @private
+		 */
+		override public function get automationName():String
+		{
+			return listItem.getLabel().text || super.automationName;
+		}
+
+		//----------------------------------
+		//  automationValue
+		//----------------------------------
+
+		/**
+		 *  @private
+		 */
+		override public function get automationValue():Array
+		{
+			return [automationName];
+		}
+
+	}
+}


disable video hardware acceleration by default causing too much trouble :-(

--- src/org/mangui/hls/HLSSettings.as
+++ src/org/mangui/hls/HLSSettings.as
@@ -135,7 +135,7 @@
          *  it will set NetStream.useHardwareDecoder
          *  refer to http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#useHardwareDecoder
          */
-        public static var useHardwareVideoDecoder : Boolean = true;
+        public static var useHardwareVideoDecoder : Boolean = false;

         /**
          * Defines whether INFO level log messages will will appear in the console


Transferred from the Adobe Open Source Subversion Repository

Revision: 19635
Author:   aharui@adobe.com
Date:     2011-01-07T00:25:18.039632Z

Log Message:
-----------
revert the layout changes from svn 18635.  Management feels that there isn't enough time to thoroughly test the changes.

Modified Paths:
--------------
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/layouts/TileLayout.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/TextBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/managers/layoutClasses/PriorityQueue.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/ScrollerLayout.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mx/src/mx/core/Application.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ViewNavigatorApplicationSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/SkinnableContainerSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/SkinnableComponent.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/RichEditableText.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/core/UIComponent.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/controls/SWFLoader.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/primitives/BitmapImage.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/DataGroup.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/primitives/supportClasses/GraphicElement.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/layouts/BasicLayout.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/components/IconItemRenderer.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/Group.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ViewNavigatorSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/PopUpAnchor.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/flash-integration/src/mx/flash/UIMovieClip.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/layouts/supportClasses/LinearLayoutVector.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/events/FlexEvent.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/airspark/src/spark/components/Window.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/styles/StyleProtoChain.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/core/SpriteVisualElement.as</path>
<path kind="file" action="D">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/core/IContainerInvalidating.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/skins/spark/DefaultItemRenderer.as</path>
<path kind="file" action="D">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/managers/ILayoutManagerContainerClient.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/layouts/supportClasses/LayoutBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/DataGrid.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/GroupBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/layouts/VerticalLayout.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/TabbedViewNavigatorApplicationSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/styles/IStyleManager.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/core/ILayoutElement.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/TextAreaSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/gridClasses/GridLayout.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/airframework/src/mx/core/Window.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/skins/spark/TextFieldGridItemRendererInclude.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/styles/StyleManagerImpl.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mx/src/mx/core/Container.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/managers/LayoutManager.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/layouts/HorizontalLayout.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/Application.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1261981 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/framework/src/mx/managers/layoutClasses/PriorityQueue.as
+++ frameworks/projects/framework/src/mx/managers/layoutClasses/PriorityQueue.as
@@ -358,61 +358,6 @@
         return parent == child;
     }

-    /**
-     *  @private
-     */
-    public function clone(client:ILayoutManagerClient = null):PriorityQueue
-    {
-        var level:int = client ? client.nestLevel : 0;
-
-        var pq:PriorityQueue = new PriorityQueue();
-        var i:int = Math.max(minPriority, level);
-        for (; i <= maxPriority; i++)
-        {
-            var obj:PriorityBin = priorityBins[i];
-            if (obj)
-            {
-                var items:Dictionary = obj.items;
-                var d:Dictionary = new Dictionary(false);
-                for (var p:* in items)
-                {
-                    if (client)
-                    {
-                        if (!contains(DisplayObject(client), DisplayObject(p)))
-                            continue;
-                    }
-                    d[p] = true;
-                }
-                pq.addDictionary(d, obj.length, i);
-            }
-        }
-        return pq;
-    }
-
-    /**
-     *  @private
-     *  used by clone() to clone dictionaries
-     */
-    private function addDictionary(d:Dictionary, length:int, priority:int):void
-    {
-        var bin:PriorityBin = new PriorityBin();
-        bin.length = length;
-        bin.items = d;
-        priorityBins[priority] = bin;
-
-        // Update our min and max priorities.
-        if (maxPriority < minPriority)
-        {
-            minPriority = maxPriority = priority;
-        }
-        else
-        {
-            if (priority < minPriority)
-                minPriority = priority;
-            if (priority > maxPriority)
-                maxPriority = priority;
-        }
-    }
 }

 }


Transferred from the Adobe Open Source Subversion Repository

Revision: 5101
Author:   gauravj@adobe.com
Date:     2009-02-27T05:22:45.887116Z

Log Message:
-----------
Update action script files with asdoc version tags.

QE Notes: None.
Doc Notes: Please review and update as necessary.
tests: checkintests

Modified Paths:
--------------
663 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1267795 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mx/src/mx/containers/accordionClasses/AccordionHeader.as
+++ frameworks/projects/mx/src/mx/containers/accordionClasses/AccordionHeader.as
@@ -38,6 +38,11 @@
  *  to an individual AccordionHeader object.
  *
  *  @see mx.containers.Accordion
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
  */
 public class AccordionHeader extends Button implements IDataRenderer
 {
@@ -63,6 +68,11 @@

 	/**
 	 *  Constructor.
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
 	 */
 	public function AccordionHeader()
 	{
@@ -111,6 +121,11 @@

 	/**
 	 *  Stores a reference to the content associated with the header.
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
 	 */
 	override public function get data():Object
 	{