<?xml version="1.0" encoding="UTF-8" ?>
<!-- Copyright (c) 2009 Michael Brown
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
Or go online to: http://www.gnu.org/licenses/gpl-3.0.txt 
-->


<Module>
  <ModulePrefs title="Slashdot Bot" height= "450">
    <Require feature="wave" />
    <Require feature="dynamic-height" />
    <Require feature="setprefs"/> 
  </ModulePrefs>
  <Content type="html">
    <![CDATA[     
    <!-- ++Begin Dynamic Feed Wizard Generated Code++ -->
             <!--
             // Created with a Google AJAX Search and Feed Wizard
             // http://code.google.com/apis/ajaxsearch/wizards.html
             -->
           
             <!--
             // The Following div element will end up holding the actual feed control.
             // You can place this anywhere on your page.
             -->
             <div id="feed-control">
               <span style="color:#676767;font-size:11px;margin:10px;padding:4px;">Loading...</span>
         </div>
         
          <!-- Google Ajax Api
	         -->
	       <script type="text/javascript" src="http://www.google.com/jsapi"></script>
	         
	          <!-- Dynamic Feed Control and Stylesheet -->
	          
	          <style type="text/css">
	            @import url("http://www.m1cr0sux0r.com/debug/Slashdot.css");
                  </style>
          <script type="text/javascript">
	            function LoadDynamicFeedControl() {
	              var feeds = [
	        	{title: 'Slashdot Headlines',
	        	 url: 'http://rss.slashdot.org/Slashdot/slashdot'
	        	}];
	              var options = {
	                stacked : true,
	                horizontal : false,
	                title : "Slashdot Bot"
	              }
	        
	              new GFdynamicFeedControl(feeds, 'feed-control', options);
	               
	     
	            }
	            // Load the feeds API and set the onload callback.
	            google.load('feeds', '1');
           google.setOnLoadCallback(LoadDynamicFeedControl);
           </script>
           <script type="text/javascript">
           
           
           /**
	    * Copyright (c) 2008 Google Inc.
	    *
	    * You are free to copy and use this sample.
	    * License can be found here: http://code.google.com/apis/ajaxsearch/faq/#license
	   */
	   
	   /**
	    * @fileoverview A feed gadget based on the AJAX Feed API.
	    * @author dcollison@google.com (Derek Collison)
	    */
	   
	   /**
	    * GFdynamicFeedControl
	    * @param {String} feed The feed URL.
	    * @param {String|Object} container Either the id string or the element itself.
	    * @param {Object} options Options map.
	    * @constructor
	    */
	   
	   function GFdynamicFeedControl(feedUrls, container, options) {
	     // node elements.
	     this.nodes = {};
	     this.collapseElements = [];
	     
	     // the feeds.
	     this.feeds = [];
	     this.results = [];
	   
	     if (typeof feedUrls == 'string') {
	       this.feeds.push({url:feedUrls});
	     } else if (typeof feedUrls == 'object') {
	       for (var i=0; i<feedUrls.length; i++) {
	         var entry = feedUrls[i];
	         var o = {};
	         var feedUrl;
	         if (typeof entry == 'string') {
	           o.url = feedUrls[i];
	         } else if (typeof entry == 'object') {
	           o = feedUrls[i];
	   	if (o && o.title) {
	   	  var s = o.title;
	   	  o.title = s.replace(/</g,'&lt;').replace(/>/g, '&gt;');
	   	}
	         }
	         this.feeds.push(o);
	       }
	     }
	   
	     if (typeof container == "string") {
	       container = document.getElementById(container);
	     }
	     this.parseOptions_(options);
	     this.setup_(container);
	   }
	   
	   /*
	    * Default time in milliseconds for the feed to be reloaded.
	    * @type Number
	    */
	   GFdynamicFeedControl.DEFAULT_NUM_RESULTS = 4;
	   /*
	    * Default time in milliseconds for the feed to be reloaded.
	    * @type Number
	    */
	   GFdynamicFeedControl.DEFAULT_FEED_CYCLE_TIME = 1800000;
	   /*
	    * Default display time in milliseconds for each entry.
	    * @type Number
	    */
	   GFdynamicFeedControl.DEFAULT_DISPLAY_TIME = 8000;
	   /*
	    * Default fadeout transition time in milliseconds for each entry.
	    * @type Number
	    */
	   GFdynamicFeedControl.DEFAULT_FADEOUT_TIME = 1000;
	   /*
	    * Default time between transition steps in milliseconds
	    * @type Number
	    */
	   GFdynamicFeedControl.DEFAULT_TRANSISTION_STEP = 40;
	   /*
	    * Default hover time in milliseconds for each entry.
	    * @type Number
	    */
	   GFdynamicFeedControl.DEFAULT_HOVER_TIME = 100;
	   
	   /**
	    * Setup default option map and apply overrides from constructor.
	    * @param {Object} options Options map.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.parseOptions_ = function(options) {
	     // Default Options
	     // TODO(dcollison) - implement Feed Cycle.
	   	
	     this.options = {
	       numResults : GFdynamicFeedControl.DEFAULT_NUM_RESULTS,
	       feedCycleTime : GFdynamicFeedControl.DEFAULT_FEED_CYCLE_TIME,
	       linkTarget : google.feeds.LINK_TARGET_BLANK,
	       displayTime : GFdynamicFeedControl.DEFAULT_DISPLAY_TIME,
	       transitionTime : GFdynamicFeedControl.DEFAULT_TRANSISTION_TIME,
	       transitionStep : GFdynamicFeedControl.DEFAULT_TRANSISTION_STEP,
	       fadeOutTime: GFdynamicFeedControl.DEFAULT_FADEOUT_TIME,
	       scrollOnFadeOut : true,
	       pauseOnHover : true,
	       hoverTime : GFdynamicFeedControl.DEFAULT_HOVER_TIME,
	       autoCleanup : true,
	       transitionCallback : null,
	       feedTransitionCallback : null,
	       feedLoadCallback : null,
	       collapseable : false,
	       sortByDate : false,
	       horizontal : false,
	       stacked : false,
	       title : null
	       
	       
	     };
	   
	     if (options) {
	       for (var o in this.options) {
	         if (typeof options[o] != 'undefined') {
	           this.options[o] = options[o];
	         }
	       }
	     }
	     
	     // Cant be collapseable unless stacked
	     if(!this.options.stacked) {
	       this.options.collapseable = false;
	     }
	     
	     // Override strange/bad options
	     this.options.displayTime = Math.max(200, this.options.displayTime);
	     this.options.fadeOutTime = Math.max(0, this.options.fadeOutTime);
	   
	     // Calculated
	     var ts = this.options.fadeOutTime / this.options.transitionStep;
	     this.fadeOutDelta = Math.min(1, (1.0/ts));
	   
	     // Flag to start
	     this.started = false;
	   };
	   
	   /**
	    * Basic setup.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.setup_ = function(container) {
	     if (container == null) return;
	     this.nodes.container = container;
	   
	     // Browser fun.
	     if (window.ActiveXObject) {
	       this.ie = this[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true;
	     } else if (document.childNodes && !document.all && !navigator.taintEnabled) {
	       this.safari = true;
	     } else if (document.getBoxObjectFor != null) {
	       this.gecko = true;
	     }
	     // The feedControl instance for generating entry HTML.
	     this.feedControl = new google.feeds.FeedControl();
	     this.feedControl.setLinkTarget(this.options.linkTarget);
	   
	     // The feeds
	     this.expected = this.feeds.length;
	     this.errors = 0;
	   
	     for (var i = 0; i < this.feeds.length; i++) {
	       var feed = new google.feeds.Feed(this.feeds[i].url);
	       feed.setResultFormat(google.feeds.Feed.JSON_FORMAT);
	       feed.setNumEntries(this.options.numResults);
	       feed.load(this.bind_(this.feedLoaded_, i));
	     }
	   };
	   
	   /**
	    * Helper method to bind this instance correctly.
	    * @param {Object} method function/method to bind.
	    * @return {Function}
	    * @private
	    */
	   GFdynamicFeedControl.prototype.bind_ = function(method) {
	     var self = this;
	     var opt_args = [].slice.call(arguments, 1);
	     return function() {
	       var args = opt_args.concat([].slice.call(arguments));
	       return method.apply(self, args);
	     }
	   };
	   
	   /**
	    * Callback associated with the AJAX Feed api after load.
	    * @param {Object} result Loaded result.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.feedLoaded_ = function(index, result) {
	     if (this.options.feedLoadCallback) {
	       this.options.feedLoadCallback(result);
	       
	     
	     }
	     if (result.error) {
	       // Ignore failed feeds for the most part.
	       // The user has control through the feedLoadCallback above
	       // if they choose to do something more createive.
	       // Only complain if we can't load anything.
	       if (++this.errors >= this.expected) {
	         this.nodes.container.innerHTML = 'Feed' + ((this.expected > 1)?'s ':' ') +
	                                          'could not be loaded.';
	       }
	       return;
	     }
	     // Override of title option.
	     if (this.feeds[index].title) {
	       result.feed.title = this.feeds[index].title;
	     }
	     this.results.push(result);
	   
	     if (!this.started) {
	       this.createSubContainers_();
	       this.displayResult_(0);
	     } else if (!this.options.horizontal && this.options.stacked) {
	       this.addResult_(this.results.length-1);
	     }
	   };
	   
	   /**
	    * Insert blog in correct place
	    * @private
	    */
	   GFdynamicFeedControl.prototype.sortByDate_ = function(resultIndex, newTitle,
	                                                         newList) {
	     // if sorting by date, insert it into the correct spot
	     var newEntryDate = this.results[resultIndex].feed.entries[0].publishedDate;
	     var newEntryDateMS = Date.parse(newEntryDate);
	     var insertIndex = null;
	   
	     for (var i = 0; i < this.results.length; i++) {
	       var mostRecentPost = this.results[i].feed.entries[0].publishedDate;
	       var mostRecentPostMS = Date.parse(mostRecentPost);
	       if(newEntryDateMS > mostRecentPostMS) {
	         insertIndex = i;
	         break;
	       }
	     }
	   
	     // If it's most stale blog, just append as usual
	     if(insertIndex == null) {
	       this.nodes.root.appendChild(newTitle);
	       this.nodes.root.appendChild(newList);
	       this.createListEntries_(resultIndex, newList);
	       return;
	     }
	   
	     // If it is fresher than a blog, insert to correct position
	     var insertBeforeIndex = 2 + (insertIndex * 2);
	     var swapToIndex = insertBeforeIndex + 2;
	     var tempSwap = null;
	     var myResultIndex = resultIndex + 1;
	   
	     var sectionsToChange = this.nodes.root.childNodes;
	     var nodeToInsertBefore = sectionsToChange[insertBeforeIndex];
	   
	     this.nodes.root.insertBefore(newTitle, nodeToInsertBefore);
	     this.nodes.root.insertBefore(newList, nodeToInsertBefore);
	   
	     this.results.splice(insertIndex, 0, this.results[resultIndex]);
	     this.results.splice(myResultIndex, 1);
	     
	     var nodesToChangeClick = sectionsToChange[swapToIndex].nextSibling.childNodes;
	     
	     this.createListEntries_(insertIndex, newList);
	   
	     // Keep freshest blog open first
	     if(insertIndex == 0) {
	       this.displayResult_(0);
	     }
	   
	     insertIndex += 1;
	     // Reset all of the onmousehover listeners to highlight corect index
	     for (var i = swapToIndex; i < sectionsToChange.length; i += 2) {
	       var nodesToChangeClick = sectionsToChange[i].nextSibling.childNodes;
	       for (var j=0; j < nodesToChangeClick.length; j++) {
	         nodesToChangeClick[j].onmouseover = this.bind_(this.listMouseOver_, 
	                                                        insertIndex, j);
	         nodesToChangeClick[j].onmouseout = this.bind_(this.listMouseOut_, 
	                                                       insertIndex, j);
	       }
	       insertIndex++;
	     }
	   };
	   
	   /**
	    * Setup to display the Result for stacked mode
	    * @private
	    */
	   GFdynamicFeedControl.prototype.addResult_ = function(resultIndex) {
	     var result = this.results[resultIndex];
	     var newTitle = this.createDiv_('gfg-subtitle');
	     
	     this.setTitle_(result.feed, newTitle);
	     var newList = this.createDiv_('gfg-list');
	     
	     
	   
	     // add a collapseable button
	     if(this.options.collapseable) {
	       var collapseLink = document.createElement('div');
	       newList.style.display = 'none';
	       collapseLink.className = 'gfg-collapse-closed';
	       newTitle.appendChild(collapseLink);
	       collapseLink.onclick = this.toggleCollapse(this, newList, collapseLink);
	       this.collapseElements.push({
	         list : newList,
	         collapse : collapseLink
	       });
	     }
	   
	   
	     var clearFloat = document.createElement('div');
	     clearFloat.className = 'clearFloat';
	     newTitle.appendChild(clearFloat);
	     
	    
	     // If not sorting by date, add them as usual
	     if(!this.options.sortByDate) {
	       this.nodes.root.appendChild(newTitle);
	       this.nodes.root.appendChild(newList);
	       this.createListEntries_(resultIndex, newList);
	     } else {
	       this.sortByDate_(resultIndex, newTitle,newList);
	     }
	     
	   };
	   
	   /**
	    * Setup to display the Result
	    * @private
	    */
	   GFdynamicFeedControl.prototype.displayResult_ = function(resultIndex) {
	     this.resultIndex = resultIndex;
	     var result = this.results[resultIndex];
	     if (this.options.feedTransitionCallback) {
	       this.options.feedTransitionCallback(result);
	     }
	     if (this.options.title) {
	       this.setPlainTitle_(this.options.title);
	     } else {
	       this.setTitle_(result.feed);
	     }
	     this.clearNode_(this.nodes.entry);
	   
	     if (this.started && !this.options.horizontal && this.options.stacked) {
	       this.entries = result.feed.entries;
	     } else {
	       this.createListEntries_(resultIndex, this.nodes.list);
	     }
	     this.displayEntries_();
	   }
	   
	   /**
	    * Set the Title to just plaintext
	    * @private
	    */
	   GFdynamicFeedControl.prototype.setPlainTitle_ = function(title, opt_element) {
	     var el = opt_element || this.nodes.title;
	     el.innerHTML = title;
	   }
	   
	   /**
	    * Set the Title
	    * @private
	    */
	   GFdynamicFeedControl.prototype.setTitle_ = function(resultFeed, opt_element) {
	     var el = opt_element || this.nodes.title;
	     
	     this.clearNode_(el);
	     var link = document.createElement('a');
	     
	     link.target = google.feeds.LINK_TARGET_BLANK;
	     link.href = resultFeed.link;
	     link.className = 'gfg-collapse-href';
	     link.innerHTML = resultFeed.title;
	     
	     el.appendChild(link);
	      
	    
	   }
	   
	   
	   GFdynamicFeedControl.prototype.toggleCollapse = function(feedControl, 
	                                                            listReference, 
	                                                            collapseLink) {
	     return function() {
	       var els = feedControl.collapseElements;
	       for (var i=0; i < els.length; i++) {
	         var el = els[i];
	         el.list.style.display = 'none';
	         el.collapse.className = 'gfg-collapse-closed';
	       }
	       listReference.style.display = 'block';
	       collapseLink.className = 'gfg-collapse-open';
	     }
	   }
	   
	   /**
	    * Create the list Entries
	    * @private
	    */
	   GFdynamicFeedControl.prototype.createListEntries_ = function(resultIndex, node) {
	     var entries = this.results[resultIndex].feed.entries;
	     this.clearNode_(node);
	     for (var i = 0; i < entries.length; i++) {
	       this.feedControl.createHtml(entries[i]);
	       var className = 'gfg-listentry ';
	       className += (i%2)?'gfg-listentry-even':'gfg-listentry-odd';
	       var listEntry = this.createDiv_(className);
	       var link = this.createLink_(entries[i].link,
	                                   entries[i].title,
	                                   this.options.linkTarget);
	       listEntry.appendChild(link);
	       if (this.options.pauseOnHover) {
	         listEntry.onmouseover = this.bind_(this.listMouseOver_, resultIndex, i);
	         listEntry.onmouseout = this.bind_(this.listMouseOut_, resultIndex, i);
	       }
	       entries[i].listEntry = listEntry;
	       node.appendChild(listEntry);
	     }
	     if (node == this.nodes.list) {
	       this.entries = entries;
	     }
	   }
	   
	   /**
	    * Begin to display the entries.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.displayEntries_ = function() {
	     this.entryIndex = 0;
	     this.displayCurrentEntry_();
	     this.setDisplayTimer_();
	     this.started = true;
	   }
	   
	   /**
	    * Display next entry.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.displayNextEntry_ = function() {
	     // Check to see if we have been orphaned and need to cleanup..
	     if (this.options.autoCleanup && this.isOrphaned_()) {
	         this.cleanup_();
	         return;
	     }
	   
	     if (++this.entryIndex >= this.entries.length) {
	       // End of list, see if we should rotate feeds..
	       if (this.results.length > 1) {
	         if (++this.resultIndex >= this.results.length) {
	           this.resultIndex = 0;
	         }
	         this.displayResult_(this.resultIndex);
	         return;
	       } else {
	         this.entryIndex = 0;
	       }
	     }
	   
	     if (this.options.transitionCallback) {
	       this.options.transitionCallback(this.entries[this.entryIndex]);
	     }
	     this.displayCurrentEntry_();
	     this.setDisplayTimer_();
	   }
	   
	   /**
	    * Display current entry.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.displayCurrentEntry_ = function() {
	     this.clearNode_(this.nodes.entry);
	     this.current = this.entries[this.entryIndex].html;
	     this.current.style.top = '0px';
	     this.nodes.entry.appendChild(this.current);
	     this.createOverlay_();
	     
	     // Expand the blog who's post is being displayed
	     if(this.options.collapseable) {
	       var feedTitle = null;
	       
	       for (var i=0; i < this.results.length; i++) {
	         if(this.results[i].feed.entries == this.entries) {
	           feedTitle = this.results[i].feed.title;
	         }
	       }
	   
	       var els = this.collapseElements;
	   
	       for (var i=0; i < els.length; i++) {
	         var el = els[i];
	         var divfeedTitle = el.collapse.previousSibling.innerHTML;
	         var expandClicker = el.collapse;
	         if(feedTitle == divfeedTitle) {
	           if(this.ie) {
	             expandClicker.click();
	           } else {
	             expandClicker.onclick();
	           }
	   
	         }
	       }
	     }
	     
	     if (this.currentList) {
	       var className = 'gfg-listentry ';
	       className += (this.currentListIndex%2)?
	           'gfg-listentry-even':'gfg-listentry-odd';
	       this.currentList.className = className;
	     }
	     this.currentList = this.entries[this.entryIndex].listEntry;
	     this.currentListIndex = this.entryIndex;
	     var className = 'gfg-listentry gfg-listentry-highlight ';
	     className += (this.currentListIndex%2)?
	          'gfg-listentry-even':'gfg-listentry-odd';
	     this.currentList.className = className;
	   }
	   
	   /**
	    * Simulated mouse hover events for list entries.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.listMouseHover_ = function(resultIndex,
	                                                             listIndex) {
	     var result = this.results[resultIndex];
	     var listEntry = result.feed.entries[listIndex].listEntry;
	     listEntry.selectTimer = null;
	     this.clearTransitionTimer_();
	     this.clearDisplayTimer_();
	     this.resultIndex = resultIndex;
	     this.entries = result.feed.entries;
	     this.entryIndex = listIndex;
	     this.displayCurrentEntry_();
	   }
	   
	   /**
	    * Mouse over events for list entries.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.listMouseOver_ = function(resultIndex,
	                                                            listIndex) {
	     var result = this.results[resultIndex];
	     var listEntry = result.feed.entries[listIndex].listEntry;
	     var cb = this.bind_(this.listMouseHover_, resultIndex, listIndex);
	     listEntry.selectTimer = setTimeout(cb, this.options.hoverTime);
	   }
	   
	   /**
	    * Mouse out events for list entries.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.listMouseOut_ = function(resultIndex, listIndex) {
	     var result = this.results[resultIndex];
	     var listEntry = result.feed.entries[listIndex].listEntry;
	     if (listEntry.selectTimer) {
	       clearTimeout(listEntry.selectTimer);
	       listEntry.selectTimer = null;
	     } else {
	       this.setDisplayTimer_();
	     }
	   }
	   
	   /**
	    * Mouse over events for main entry.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.entryMouseOver_ = function(e) {
	     this.clearDisplayTimer_();
	     if (this.transitionTimer) {
	       this.clearTransitionTimer_();
	       this.displayCurrentEntry_();
	     }
	   }
	   
	   /**
	    * Mouse out events for main entry.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.entryMouseOut_ = function(e) {
	     this.setDisplayTimer_();
	   }
	   
	   /**
	    * Create the overlay div. This hack is for IE and transparency effects.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.createOverlay_ = function() {
	     if (this.current == null) return;
	     // Create div lazily and hold on to it..
	     if (this.overlay == null) {
	       var overlay = this.createDiv_('gfg-entry');
	       overlay.style.position = 'absolute';
	       overlay.style.top = '0px';
	       overlay.style.left = '0px';
	       this.overlay = overlay;
	               
	     }
	     this.setOpacity_(this.overlay, 0);
	     this.nodes.entry.appendChild(this.overlay);
	     
	   }
	   
	   /**
	    * Sets the display timer.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.setDisplayTimer_ = function() {
	     if (this.displayTimer) {
	       this.clearDisplayTimer_();
	     }
	     var cb = this.bind_(this.setFadeOutTimer_);
	     this.displayTimer = setTimeout(cb, this.options.displayTime);
	   };
	   
	   /**
	    * Class helper method for the time now in milliseconds
	    * @private
	    */
	   GFdynamicFeedControl.timeNow = function() {
	     var d = new Date();
	     return d.getTime();
	   };
	   
	   /**
	    * Transition animation for fadeout. Cleanup when finished.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.fadeOutEntry_ = function() {
	     if (this.overlay) {
	       var delta = this.fadeOutDelta;
	       var ts = this.options.transitionStep;
	       var now = GFdynamicFeedControl.timeNow();
	       var tick = now - this.lastTick;
	       this.lastTick = now;
	       delta *= (tick/ts);
	   
	       var op = this.overlay.opacity + delta;
	       // Overlay opacity
	       this.setOpacity_(this.overlay, op);
	       // Scroll down
	       if (this.options.scrollOnFadeOut && (op > .5)) {
	         var r = (op-.5)*2;
	         var newTop = Math.round(this.current.offsetHeight * r);
	         this.current.style.top = newTop + 'px';
	       }
	       if (op < 1) return;
	     }
	     // Finished.
	     this.clearTransitionTimer_();
	     this.displayNextEntry_();
	   };
	   
	   /**
	    * Sets the transition timer for fadeout.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.setFadeOutTimer_ = function() {
	     this.clearTransitionTimer_();
	     this.lastTick = GFdynamicFeedControl.timeNow();
	     var cb = this.bind_(this.fadeOutEntry_);
	     this.transitionTimer = setInterval(cb, this.options.transitionStep);
	   };
	   
	   /**
	    * Clear the transition timer. Used to prevent leaks.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.clearTransitionTimer_ = function() {
	     if (this.transitionTimer) {
	       clearInterval(this.transitionTimer);
	       this.transitionTimer = null;
	     }
	   };
	   
	   /**
	    * Clear the display timer.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.clearDisplayTimer_ = function() {
	     if (this.displayTimer) {
	       clearTimeout(this.displayTimer);
	       this.displayTimer = null;
	     }
	   };
	   
	   /**
	    * Setup our own subcontainer to the user supplied container.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.createSubContainers_ = function() {
	     var nodes = this.nodes;
	     var container = this.nodes.container;
	     
	     this.clearNode_(container);
	     if (this.options.horizontal) {
	       container = this.createDiv_('gfg-horizontal-container');
	       nodes.root = this.createDiv_('gfg-horizontal-root');
	       this.nodes.container.appendChild(container);
	     } else {
	       nodes.root = this.createDiv_('gfg-root');
	     }
	     nodes.title = this.createDiv_('gfg-title');
	     nodes.entry = this.createDiv_('gfg-entry');
	     nodes.list = this.createDiv_('gfg-list');
	     var logo = this.createDiv_('gf-entry');
	     //logo.className = 'gfg-title';
	     logo.innerHTML = '<img src="http://images.slashdot.org/favicon.ico" alt="Slashdot" border="0" height="16" width="16">&nbsp;<input type = "button" onclick="show_prompt()" value="Share this Story"/>';
	     
	     nodes.root.appendChild(nodes.title);
	     nodes.root.appendChild(nodes.entry);
	     nodes.root.appendChild(logo);
	   
	     if (!this.options.horizontal && this.options.stacked) {
	       var newTitle = this.createDiv_('gfg-subtitle');
	       nodes.root.appendChild(newTitle);
	       this.setTitle_(this.results[0].feed, newTitle);
	       
	       if(this.options.collapseable) {
	         var collapseLink = document.createElement('div');
	         collapseLink.className = 'gfg-collapse-open';
	         newTitle.appendChild(collapseLink);
	         collapseLink.onclick = this.toggleCollapse(this, nodes.list, collapseLink);
	         this.collapseElements.push({
	           list : nodes.list,
	           collapse : collapseLink
	         });
	         nodes.list.style.display = 'block';
	       }
	       
	       var clearFloat = document.createElement('div');
	       clearFloat.className = 'clearFloat';
	       newTitle.appendChild(clearFloat);
	     }
	     
	     nodes.root.appendChild(nodes.list);
	     container.appendChild(nodes.root);
	   
	     if (this.options.pauseOnHover) {
	       nodes.entry.onmouseover = this.bind_(this.entryMouseOver_);
	       nodes.entry.onmouseout = this.bind_(this.entryMouseOut_);
	     }
	   
	     // Add Branding.
	     if (this.options.horizontal) {
	       nodes.branding = this.createDiv_('gfg-branding');
	       google.feeds.getBranding(nodes.branding, google.feeds.VERTICAL_BRANDING);
	       container.appendChild(nodes.branding);
	     }
	   };
	   
	   /**
	    * Helper method to properly clear a node and its children.
	    * @param {Object} node Node to clear.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.clearNode_ = function(node) {
	     if (node == null) return;
	     var child;
	     while ((child = node.firstChild)) {
	       node.removeChild(child);
	     }
	   };
	   
	   /**
	    * Helper method to create a div with optional class and text.
	    * @param {String} opt_className Optional className for the div.
	    * @param {String} opt_text Optional text for the innerHTML.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.createDiv_ = function(opt_className, opt_text) {
	     var el = document.createElement("div");
	     if (opt_text) {
	       el.innerHTML = opt_text;
	     }
	     if (opt_className) { el.className = opt_className; }
	     return el;
	   };
	   
	   /**
	    * Helper method to create a link with href and text.
	    * @param {String} href Href URL
	    * @param {String} text text for the link.
	    * @param {String} opt_target Optional link target.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.createLink_ = function(href, text, opt_target) {
	     var link = document.createElement('a');
	     link.href = href;
	     link.innerHTML = text;
	     link.style.color = "#006666";
	     if (opt_target) {
	       link.target = opt_target;
	     }
	     return link;
	   };
	   
	   /**
	    * Cleanup results on being orphaned.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.clearResults_ = function() {
	     for (var i=0; i < this.results.length; i++) {
	       var result = this.results[i];
	       var entries = result.feed.entries;
	       for (var i = 0; i < entries.length; i++) {
	         var entry = entries[i];
	         entry.html = null;
	         entry.listEntry.onmouseover = null;
	         entry.listEntry.onmouseout = null;
	         if (entry.listEntry.selectTimer) {
	           clearTimeout(entry.listEntry.selectTimer);
	           entry.listEntry.selectTimer = null;
	         }
	         entry.listEntry = null;
	       }
	     }
	   }
	   
	   /**
	    * Check for being orphaned.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.isOrphaned_ = function() {
	     var root = this.nodes.root;
	     var orphaned = false;
	     if (!root || !root.parentNode) {
	       orphaned = true;
	     } else if (this.options.horizontal && !root.parentNode.parentNode) {
	       orphaned = true;
	     }
	     return orphaned;
	   }
	   
	   /**
	    * Cleanup on being orphaned.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.cleanup_ = function() {
	     this.started = false;
	     // Timer Events.
	     this.clearDisplayTimer_();
	     this.clearTransitionTimer_();
	     // Structures
	     this.clearResults_();
	     // Nodes
	     this.clearNode_(this.nodes.root);
	     this.nodes.container = null;
	   }
	   
	   /**
	    * Helper method to set opacity for nodes.. Also takes into account
	    * visibility in general.
	    * @param {Element} node element.
	    * @param {Number} opacity alpha level.
	    * @private
	    */
	   GFdynamicFeedControl.prototype.setOpacity_ = function(node, opacity) {
	     if (node == null) return;
	     opacity = Math.max(0, Math.min(1, opacity));
	     if (opacity == 0) {
	       if (node.style.visibility != 'hidden') {
	         node.style.visibility = 'hidden';
	       }
	     } else {
	       if (node.style.visibility != 'visible') {
	         node.style.visibility = 'visible';
	       }
	     }
	     if (this.ie) {
	       var normalized = Math.round(opacity*100);
	       node.style.filter = 'alpha(opacity=' + normalized + ')';
	     }
	     node.style.opacity = node.opacity = opacity;
	   };
	   
GFgadget = GFdynamicFeedControl;
           
           </script>
           
           
           <script type ="text/javascript">
           var isInWave = wave.isInWaveContainer();
	         
	    
	   
	    function show_prompt()
	    {
	    var isInWave = wave.isInWaveContainer();
	    gadgets.window.adjustHeight();
	    var name = prompt("Enter the Wave addresses with whom you would like to share, seperated by commas");
	    <!--
	    	 // Reading state ...
	    	 if (isInWave) {
	    	 	wave.setStateCallback(function() {
	    	 	id = wave.getState().get('id');
	    		});
	     	 }
	     	 -->
	    	if (name !=null && name !=""){
	     		// Writing state ...
	     		if (isInWave) {
	     		
	     	   		wave.getState().submitDelta({'addresses': name});
	     	        }
	     	}
	    
	    
	    }
 </script> 
       <div align = "right"><img src="http://www.m1cr0sux0r.com/topicslashdot.gif"></div>
   ]]>
  </Content>
</Module>


