Source for "OiNKPlus music torrent site enhancer"

By Indieana
Has no other scripts.


the source is over 100KB, syntax highlighting in the browser is too slow

// ==UserScript==
// @name          OiNKPlus
// @author        Indieana AKA interonaut, indieana@mailpuppy.com  
// @namespace     http://www.myspace.com/interonaut
// @description   Enables easy artist discovery by adding similar artists, tags, short bio and last.fm & Myspace player to torrent details pages.
// @include       http*://www.waffles.fm/details.php*
// @include       http*://waffles.fm/details.php*
// @include       http*://88.80.6.249/details.php*
// @include       http*://www.what.cd/torrents.php?id*
// @include       http*://what.cd/torrents.php?id*
// @include       http*://www.what.cd/artist.php?id*
// @include       http*://what.cd/artist.php?id*
// @include       http://stmusic.org/details.php*
// @include       http://www.stmusic.org/details.php*
// @include       http://85.17.105.5/details.php*
// @include       http://www.libble.com/details.php*
// @include       http://libble.com/details.php*
// @include       http://67.211.200.76/details.php*
// @include       http://www.funkytorrents.com/details.php*
// @include       http://funkytorrents.com/details.php*
// @include       http://213.248.54.223/details.php*
// @include       http://www.mininova.org/tor/*
// @include       http://mininova.org/tor/*
// @include       http://87.233.147.140/tor/*
// @include       http://thepiratebay.org/tor/*
// @include       http://83.140.176.146/tor/*
// @include       http*://scenetorrents.org/details.php*
// @include       http*://www.scenetorrents.org/details.php*
// @include       http*://85.17.40.165/details.php*
// @include       http://www.softmp3.org/details.php*
// @include       http://softmp3.org/details.php*
// @include       http://85.24.152.69/details.php*
// @include       http*://kraytracker.com/?cls=5&id=*
// @include       http*://64.34.39.105/?cls=5&id=*
// @include       http://arenabg.com/details.php?id=*
// @include       http://www.arenabg.com/details.php?id=*
// @include       http://85.14.6.83/details.php?id=*
// @include       http://metal.iplay.ro/details.php?id=*
// @include       http://84.247.80.243/details.php?id=*
// @include       http*://themusik.org/details.php*
// @include       http*://www.themusik.org/details.php*
// @include       http*://85.17.164.57/details.php*
// @include       http://www.welovemusique.com/musicreviews/*
// @include       http://christiantorrents.com/details.php*
// @include       http://www.christiantorrents.com/details.php*
// @include       http://85.11.33.12/details.php*
// @include       http*://tracker.vipv2.org/details.php*
// @include       http*://194.145.250.133/details.php*
// @include       http*://www.exodusmusic.org/details.php*
// @include       http*://111.111.111.111/details.php*
// @include       http*://*indietorrents*/details.php*
// @include       http*://66.129.1.42/details.php*
// @include       http*://*metalbits*/details.php*
// @include       http*://83.227.1.135/details.php*
// @include	  http://www.torrentz.com/*
// @include	  http://213.239.140.13/*

// @date          2008/06/13
// @version       8
// @subversion		8
// @since         2007/04/25
// ==/UserScript==
// 
// ------------------------------------------------------------------------
// Copyright (c) 2007-2008, indieana  AKA interonaut, indieana@mailpuppy.com
// Released under the GPL license
// http://www.gnu.org/copyleft/gpl.html
//
//			- TODO fix: better artist recognition on TPB,Mininova and Torrentz
//			- TODO add: DeepBassNine, MetaCritic support
// CHANGELOG
//
// 8 	  2008/06/13  	- fix: indietorrents.com domain recognition
//			- add: OiNKPlus shown on artist pages on What.cd
//			- add: what.cd https browsing
//			- add: support for torrentz
//			- fix: OiNKPlus shown above comments on What
//			- fix: OiNKPlus shown above artist info on TPB
// 7 	  2008/04/16	- fix: phrase quotes on The Pirate Bay 
//			- add: Gazelle support
//			- fix: fixed Google search since MySpace player wouldn't show in rare cases 
// 6	  2008/03/21
//			- add: support for indietorrents, metalbits finally
//			- fix: ct support
//			- fix: MySpace player working again
//			- change: read more abstract is now shown inline instead of external page
//			- fix: load similar will now not reload present artist information
// 4	  2008/02/06
//			Same as 3.02, considered stabe now
// 3.0.2  2008/01/21 New site support
//			- add: support for SceneTorrents, SoftMp3.org, KrayTracker, arenabg.com, MetalTorrents, TheMusik.org, WLM, vipv2.org
//			- fix: Improved MySpace google search query
//			- fix: oinkplus not showing up on unrcognzied artists
//			- change: update ip addresses of several trackers, welcome to sweden!
//			- change: TPB allows phrase search
//			- change: new categories on waffles
//			- fix: extreme lag caused by caching, caching disabled now
//			- change: More on these sites
//			- add: external link to PureVolume
//			- change: shorten external links names
//			- fix: search query on waffles changed
//			- fix: what.cd suppport, what.cd details page structure changed
//			- change: removed prototype framework at cost of ugly code
// 3.0.1  2007/11/20 small bugfix
//			- fix: what.cd site layout changed			
// 3  2007/11/08 	Second beta, the HyDrA Release
//			- add: support for various sites including Waffles.fm, What.cd, Stmusic.org, Libble.com, ThePirateBay.org, Mininova.org and FunkyTorrents.com
//			- add: search bar to lookup artist with Oinkplus
//			- add: new browsing capabilities by navigating deep into similar artists (browsing history)
//			- add: new external links to Hypemachine, SeeqPod, RIAA Radar and Pandora
// 			- fix: avoid sending referer for flash content and artist logo
// 							Thanks and credits to Drew McLellan for Flash Satay and Marcus Granado for binary XHR [http://mgran.blogspot.com]
//			- fix: speed up by not loading unneccessary images and objects in fetched html,intepret code as plain text instead	
//			- fix: remove script tags or embedded stuff in abstracts, less ressource consuming and better security
//			- fix: small toggle icons are now hard-coded base64 encoded data streams
//			- fix: abstracts now showing up again
//			- fix: don't show Oinkplus in Apps etc.
//			- fix: smaller bugfixes and code improvements	
// 2	2007/06/03	Beta test ended, first stable version
//				minor bugfixes, added display toggle
//				added more external links
// 1	2007/04/25	Original version - beta
//
// This script is for use with several torrent trackers
// It adds information to torrent details pages.
// ------------------------------------------------------------------------
//
// FEATURES
// - data from last.fm
// 	similar artists, 
// 	tags, 
// 	short bio, 
// 	preview player
// 
// - data from Myspace.com
// 	preview player 
// 
// - links to external ressources
// 	last.fm, myspace, imeem, foxytunes, allmusic, wikipedia, discogs, google, amazon and others
// 	
// ------------------------------------------------------------------------
// 
// IMPORTANT NOTICE
// The script does not and will not do automatic searches on the site it runs on, 
// because it is very harmful to the site's performance. If you had the 
// great idea of implementing such a feature you are STRONGLY advised not to do so.
// OiNKPlus is not related to the supported sites in any way. Use at own risk.
// Some functions were created by the Platypus extension.
// The script may frequently break, therefore it will automatically check for updated 
// versions every now and then.
// The author does not claim the code to be elegant. 
// Ok? Fine.
// Suggestions, feedback and contributions welcome.
//
//
// FUTURE DEVELOPMENT
// If you would like to see this script to work with another site not supported yet,
// like another public or private tracker, get in contact with me (indieana@mailpuppy.com), 
// I will gladly port it to that site. Please remind, that I need to be invited, if 
// the site is private, though.
// Please refrain from simple tinkering to make it work with other sites, in case you 
// don't want to seriously maintain the script. This rushing ahead attitude has shown to 
// result in a lot of confusion among users and unsupported or even buggy code in the past.
// On the other hand, the GPL license gives you all the freedom, for example if you seriously want
// to improve the script. Please let me know, I would love that and I'm curious!
//
//
// CREDITS
// * My greatest respect goes to oinkylicious Alan, for selflessly driving the amazing
// community that OiNK was. His excellent vision and talent of leadership have impressed
// and motivated me eversince I have been a proud member of the site. It was for his
// generous front paging to get the word about Oinkplus spread and opening it up to
// a broader audience.
// * Many thanks go also out to the fellow OiNKers, that provided suggestions, bug fixes,
// spread the word or even went as far as porting the script to other browsers. Thanks go to
// Eighty, ar33ome3, )deckstream(, evilman, lhnz, the_e_male among all the other dedicated users
// that found very nice words and placed themselves in a 1000 replies O+ thread :)
// * Thanks to the codemonkeys, that open up their code, especially those,
// that code/libraries the script makes use of. The is remarked in the code. 
// * Love is sent out to the wonderful people over at Last.fm that provide the excellent, reliable
// webservice, this script relies on. Sign up for their great subscription service!
// * At last lovely greetings to everyone supporting the hydra!
//
// Enough pathos,
// have fun!
//
// ------------------------------------------------------------------------
// Developed under Kubuntu Linux, Kate
// ------------------------------------------------------------------------
(function () {

// -- [Main] --------------------------------------------------------------------------------------

function main() {

  EventNotifier = {
    observers: new Array(),
    
    /*
      Function: addObserver
        Registers a new object as observer
        
      Parameters:
        observer - Observer (should implement message function to be notified)
        sender   - Sender object (default:null) If not null, observer will only received message from this object
    */
    addObserver: function(observer, sender) {
      sender = sender || null;
      this.removeObserver(observer);
      this.observers.push({observer:observer, sender:sender});
    },
    
    /*
      Function: removeObserver
        Unregisters an observer
        
      Parameters:
        observer - Observer 
    */
    removeObserver: function(observer) {  
      //this.observers = this.observers.reject( function(o) { return o.observer == observer });
      var results = [];
      this.observers.forEach(
	function(o) {
		if (o.observer != observer) {
		 results.push(o);
		}
	});
       this.observers = results;
    },
    
    /*
      Function: send
        Send a new message to all registered observers
        
      Parameters:
        sender    - Sender object (can be null)
        eventName - Event name (observers have to implement this method)
        options   - Object or Hash table (for multiple options) of sending event  (default null)
    */
    send: function(sender, eventName, options) {  
      options = options || null;
      this.observers.forEach( function(o) {
        if ((o.sender == null || o.sender == sender) && o.observer[eventName]) 
          o.observer[eventName](sender, options);
      });
    }
  }
  
  function deserialize(name, def) {
    return eval(GM_getValue(name, (def || '({})')));
  }

  function serialize(name, val) {
    GM_setValue(name, uneval(val));
  }
  
	var VERSION = 8;
	var CACHE_NAME = "OINKPLUS_CACHE";
	GM_setValue(CACHE_NAME,0);
	var CACHE_SIZE = 75;
	var M_RE = 0;
	var R_STRING = 1;
	var TYPE_HTML = 0;
	var TYPE_XML = 1;
	var TYPE_BINARY=2;
	var UPDATE_INTERVAL_HOURS = 2;
	var MAX_TAGS = 5;
	var MAX_SIMILAR_ARTISTS = 25;
	var MAX_BIO_LENGTH = 450;

	var UNLOADED = 0;
	var LOADING = 1;
	var LOADED = 2;
	var CACHED = 3;
	var FAILED = 4;

	var TOGGLEABLE = true;
	var NON_TOGGLEABLE = false;

	var RESOURCE_LOAD_TIMEOUT = 10000;
	
	var CSS_CODE =		".OinkPlus { position:relative; max-width:700px}\
				 .explore  { text-decoration:none; } \
				.floatright { border: solid #000000 0px;float:right;margin:0pt 0pt 10px 10px;padding:2px;text-align: right;} 	\
				.floatleft { border: solid #000000 0px;float:left;text-align: left; width:140px; } \
				.floatmiddle { border: solid #000000 0px;text-align: left; margin-left:140px;} ";	

	var BASIC_LAYOUT = 	"<div id=\"Oinkplus\" class=\"OinkPlus\">\
												<div class=\"floatleft\"> \
													<h2><div id=\"ArtistName\"></div></h2><br>		\
													<div id=\"toggleLastFMSimilar\"></div>&nbsp;<b>Similar artists:</b><br>				\
													<div id=\"LastFMSimilar\"></div> 		\
													<br> \
													<div id=\"toggleHistory\"></div>&nbsp;<b>Browsing History:</b><br>				\
													<div id=\"History\"></div> 		\
												</div><br>										\
												<div id=\"artistinfo\" class=\"floatmiddle\">					\
													<div class=\"floatright\">	\
														<div id=\"ArtistSearchField\"></div><br>					\
														<div id=\"ArtistImage\"></div>			\
													</div>															\
													<div id=\"ArtistTitle\"></div><br>				\
													<b>Tags:</b>						\
													<div id=\"LastFMTags\"></div><br>				\
													<div id=\"toggleLastFMBio\"></div>&nbsp;<b>Abstract:</b><br>							\
													<div id=\"LastFMBio\"></div><br>				\		\
													<div id=\"toggleLastFMPlayer\"></div>&nbsp;<b>Last.fm Player:</b><br>				\
													<div id=\"LastFMPlayer\"></div><br>					\
													<div id=\"toggleMySpacePlayer\"></div>&nbsp;<b>Myspace Player:</b><br>				\
													<div id=\"MySpacePlayer\"></div><br>					\
													<!--<div id=\"toggleLastFMAlbum\"></div>&nbsp;<b>Albums:</b><br>				\
													<div id=\"LastFMAlbums\"></div><br>--!>					\
													<b>External links:</b><br>						\
													<div id=\"ExternalLinks\"></div><br>\
													<div id=\"HydraLinks\"></div><br>\
												</div>							\
												<div id=\"UpdateNotify\" class=\"leftinfo\"></div>			\
											</div>";
	
	var NAME			= "OiNKPlus";
	var UPDATE_MESSAGE 		= "<a href=\"%s\">A <font color=\"red\">new version</font> of " + NAME + " is available.</a>";
	var RELEASE_INFORMATION_URL 	= "http://www.naptoon.com/oinkplus/oinkplus.xml";
	var LASTFM_ARTIST_URL 		= "http://www.last.fm/music/%s";
	var REDIR 					=	"http://anonym.to/?";
	var LASTFM_LINK 		= "<a href=\""+ REDIR + "http://www.last.fm/music/%s\">Last.fm</a>";
	var LASTFM_BIO_URL  =	"http://www.last.fm/music/%s/%2bwiki";
	var LASTFM_BIO_LINK = "<a href=\""+ REDIR + "http://www.last.fm/music/%s/%2bwiki\">read more</a>";
	var MYSPACE_URL			= "http://www.google.com/search?&q=site:www.myspace.com+-intitle:MySpaceTV+%22%s%22";
	var MYSPACE_LINK		= "<a href=\""+ REDIR + MYSPACE_URL + "&btnI\">Myspace</a>";
	var LASTFM_TAGS_URL 		= "http://ws.audioscrobbler.com/1.0/artist/%s/toptags.xml";
	var LASTFM_SIMILAR_URL 		= "http://ws.audioscrobbler.com/1.0/artist/%s/similar.xml";
	var LASTFM_ALBUMS_URL  = "http://ws.audioscrobbler.com/1.0/artist/%s/topalbums.xml";
	var WIKIPEDIA_URL		= REDIR + "http://www.google.com/search?&q=site:en.wikipedia.org+intitle:%22%s - %22&btnI";
	var WIKIPEDIA_LINK		= "<a href=\""+ WIKIPEDIA_URL + "\">Wikipedia</a>";
	var ALLMUSIC_URL		= REDIR + "http://www.google.com/search?&q=site:www.allmusic.com+intitle:%22%s > %22+intitle:%22Overview%22&btnI";
	var ALLMUSIC_LINK		= "<a href=\""+ ALLMUSIC_URL + "\">Allmusic</a>";
	var FOXYTUNES_URL		= REDIR + "http://www.foxytunes.com/artist/%s";
	var FOXYTUNES_LINK		= "<a href=\""+ FOXYTUNES_URL + "\">Foxytunes</a>";
	var IMEEM_URL			= REDIR + "http://www.imeem.com/tag/?q=%s&f=music";
	var IMEEM_LINK			= "<a href=\""+ IMEEM_URL + "\">Imeem</a>";
	var DISCOGS_URL			= REDIR + "http://www.discogs.com/artist/%s";
	var DISCOGS_LINK		= "<a href=\""+ DISCOGS_URL + "\">Discogs</a>";
	var GOOGLE_URL			= REDIR + "http://www.google.com/search?&q=%22%s%22";
	var GOOGLE_LINK			= "<a href=\""+ GOOGLE_URL + "\">Google</a>";
	var AMAZON_URL			= "http://www.amazon.com/gp/search?ie=UTF8&keywords=%22%s%22&index=music&linkCode=ur2&camp=1789&creative=9325";
	var AMAZON_LINK			= "<a href=\""+ AMAZON_URL + "\">Amazon</a>";
	var HYPEMACHINE_URL = REDIR + "http://hypem.com/search/%s/1/";
	var HYPEMACHINE_LINK = "<a href=\""+ HYPEMACHINE_URL + "\">HypeMachine</a>";
	var SEEQPOD_URL 		= REDIR + "http://www.seeqpod.com/music/?query=%s&query_unused=&command=q";
	var SEEQPOD_LINK    = "<a href=\""+ SEEQPOD_URL + "\">SeeqPod</a>";
	var PANDORA_URL 		= REDIR + "http://www.pandora.com/music/artist/%s";
	var PANDORA_LINK 		= "<a href=\""+ PANDORA_URL + "\">Pandora</a>";
	var RIAARADAR_URL		= REDIR + "http://www.riaaradar.com/search.asp?searchtype=ArtistSearch&keyword=%s";
	var RIAARADAR_LINK  = "<a href=\""+ RIAARADAR_URL + "\">RIAA Radar</a>";
	var PUREVOLUME_URL  = REDIR + "http://www.google.com/search?&q=site:purevolume.com+intitle:%22%s%22+-inurl:videos+-inurl:photos+-inurl:shows&btnI";
	var PUREVOLUME_LINK = "<a href=\""+ PUREVOLUME_URL + "\">purevolume</a>";

	
	// base64 encoded pics
	var TOGGLE_IMG_PLUS		= "data:image/gif;base64,R0lGODlhCQAJAIAAAOLn7UtjfCwAAAAACQAJAAACEYyPoAu28aCSDSJLc44s3lMAADs%3D";
	var TOGGLE_IMG_MINUS		= "data:image/gif;base64,R0lGODlhCQAJAIAAAOLn7UtjfCwAAAAACQAJAAACEIyPoAvG614L80x5ZXyohwIAOw%3D%3D";
	var SPINNER_IMG       = "data:image/gif;base64,R0lGODlhEAAQAPMAAP%2F%2F%2FwAAAAAAAIKCgnJycqioqLy8vM7Ozt7e3pSUlOjo6GhoaAAAAAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAEAAQAAAEKxDISau9OE%2FBu%2F%2FcQBTGgWDhWJ5XSpqoIL6s5a7xjLeyCvOgIEdDLBqPlAgAIfkECQoAAAAsAAAAABAAEAAABCsQyEmrvThPwbv%2FXJEMxIFg4VieV0qaqCC%2BrOWu8Yy3sgrzoCBHQywaj5QIACH5BAkKAAAALAAAAAAQABAAAAQrEMhJq704T8G7%2F9xhFMlAYOFYnldKmqggvqzlrvGMt7IK86AgR0MsGo%2BUCAAh%2BQQJCgAAACwAAAAAEAAQAAAEMRDISau9OE%2FBu%2F%2BcghxGkQyEFY7lmVYraaKqIMpufbc0bLOzFyXGE25AyI5myWw6KREAIfkECQoAAAAsAAAAABAAEAAABDYQyEmrvThPwbv%2FnKQgh1EkA0GFwFie6SqIpImq29zWMC6xLlssR3vdZEWhDwBqejTQqHRKiQAAIfkECQoAAAAsAAAAABAAEAAABDYQyEmrvThPwbv%2FHKUgh1EkAyGF01ie6SqIpImqACu5dpzPrRoMpwPwhjLa6yYDOYuaqHRKjQAAIfkECQoAAAAsAAAAABAAEAAABDEQyEmrvThPwbv%2FnKUgh1EkAxFWY3mmK9WaqCqIJA3fbP7aOFctNpn9QEiPZslsOikRACH5BAkKAAAALAAAAAAQABAAAAQrEMhJq704T8G7%2FxymIIexEOE1lmdqrSYqiGTsVnA7q7VOszKQ8KYpGo%2FICAAh%2BQQJCgAAACwAAAAAEAAQAAAEJhDISau9OE%2FBu%2F%2BcthBDEmZjeWKpKYikC6svGq9XC%2B6e5v%2FAICUCACH5BAkKAAAALAAAAAAQABAAAAQrEMhJq704T8G7%2Fxy2EENSGOE1lmdqrSYqiGTsVnA7q7VOszKQ8KYpGo%2FICAAh%2BQQJCgAAACwAAAAAEAAQAAAEMRDISau9OE%2FBu%2F%2BctRBDUhgHElZjeaYr1ZqoKogkDd9s%2Fto4Vy02mf1ASI9myWw6KREAIfkECQoAAAAsAAAAABAAEAAABDYQyEmrvThPwbv%2FHLUQQ1IYByKF01ie6SqIpImqACu5dpzPrRoMpwPwhjLa6yYDOYuaqHRKjQAAIfkECQoAAAAsAAAAABAAEAAABDYQyEmrvThPwbv%2FnLQQQ1IYB0KFwFie6SqIpImq29zWMC6xLlssR3vdZEWhDwBqejTQqHRKiQAAIfkECQoAAAAsAAAAABAAEAAABDEQyEmrvThPwbv%2F3EIMSWEciBWO5ZlWK2miqiDKbn23NGyzsxclxhNuQMiOZslsOikRADsAAAAAAAAAAAA%3D";

	var SEARCH_IMG = "data:image/gif;base64,R0lGODlhDgAOANUAAPr6%2Bri4uPLy8vz8%2FMbGxtjY2Pf3997e3vv7%2B9bW1rq6utPT07u7u7S0tLKystzc3NDQ0MPDw7CwsO%2Fv783NzczMzNTU1PT09NXV1ezs7LW1tc%2FPz7Ozs%2FPz86mpqevr6%2Fb29v39%2Fbm5uf7%2B%2Fqampv%2F%2F%2FwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAAOAA4AAAZvwJJwSCwOB6GRcmm0MDwMzMVYIpCuV0KnuCCJEp9EgLQoikgFA8BQ8I6IHlInVAp1SB768PwYPrwDRBAkCgcABwokFHpCGRFYWA4gRAgfGwEeARUOJA2TQiMIIAITAh0fDSQanyVvRAAfHBICVFRBADs%3D";

	var EXPLORE_SIMILAR_IMG = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAABGdBTUEAAK%2FINwWK6QAAAAZiS0dEAP8A%2FwD%2FoL2nkwAAAAlwSFlzAAAASAAAAEgARslrPgAAAOFJREFUOMvVUqFuw1AMvE7VpHxAQHDA0Da4gf5DUL4kLN%2FzWFDQAwNT2camRQMJHA0NsC9O3lCrri3oFtSTLFuWfD75vAohYAluFk1fH0FZli9FUdz%2Bm0BVNyLyddhbhRDgnAsAYGYwM5AESagqVBUiAlVFHMcgia7rPp1zjwCw3jGlaYp5njFN068ws5M8DMNDlmXvdV0%2FrQ837wiOh47rcRxBctwrMDM0TXNWtohARBBFEZIkQd%2F3aNv2w3u%2F2d%2FgEuR5%2FkzyleS39%2F7uzy5UVfVGcmtm9ycuLMGVvfI5%2FADcE8BIG7ekhwAAACJ6VFh0U29mdHdhcmUAAHjac0zJT0pV8MxNTE8NSk1MqQQAL5wF1K4MqU0AAAAASUVORK5CYII%3D";
	// Array(match_re, replace_string)
	var ARTIST_RE 			= new Array(/http:\/\/oink\.me\.uk\/search\.php\?artist=(.*)/, 	'$1');
	var ARTIST_BIO_RE 		= new Array(/\/music\/(.*)\/\+wiki/, 				'http://www.last.fm/music/$1/+wiki');
	var LASTFM_LINK_RE 		= new Array(/\/music\/(.*)/, 					'http://www.last.fm/music/$1');
	var artist;
	
	var FLASH_CONTAINER_URL = "http://www.naptoon.com/oinkplus/c.swf";
	
	var FLASH_CONTAINER = "<object type=\"application/x-shockwave-flash\" data=\"" + FLASH_CONTAINER_URL + "\"  width=\"%WIDTH\" height=\"%HEIGHT\" ><param name=\"movie\" value=\"" + FLASH_CONTAINER_URL + "\"  quality=\"high\"/><param name=FlashVars value=\"path=%MOVIE\" /></object>";
	
	//var cache = new Cache(CACHE_SIZE);


var site_functions =({ 
what:	{	
				name:	"What", 
				url:	{		0:"https:\/\/what.cd\/torrents.php\\?id*", 
									1:"http:\/\/what.cd\/torrents.php\\?id*",
									2:"https:\/\/www.what.cd\/torrents.php\\?id*",
									3:"http:\/\/www.what.cd\/torrents.php\\?id*",
									4:"http:\/\/88.80.6.238\/torrents.php\\?id*",
									5:"https:\/\/88.80.6.238\/torrents.php\\?id*",
									6:"https:\/\/what.cd\/artist.php\\?id*", 
									7:"http:\/\/what.cd\/artist.php\\?id*",
									8:"https:\/\/www.what.cd\/artist.php\\?id*",
									9:"http:\/\/www.what.cd\/artist.php\\?id*",
									10:"http:\/\/88.80.6.238\/artist.php\\?id*",
									11:"https:\/\/88.80.6.238\/artist.php\\?id*"
							},
				searchurl: "http://what.cd/torrents.php?searchstr=%s",
				css: ".artistHeadline {font-size: 10pt;} \
				     font-size: 10pt !important;}",
				version:"1",
				isAudioRelease: "var tds = document.getElementsByTagName(\"td\");\
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"heading\" && tds[i].textContent.match(new RegExp(\"Type\"))) {\
												typeFieldContent = tds[i].nextSibling.textContent; \
												if (typeFieldContent.match(new RegExp(\"(Apps|Comics|E-books|E-learning videos)\"))) \
													return false; \
												break; \
											}	\
										} \
										return true",
				hook: "var divs = document.getElementsByTagName(\"div\");\
										var centertable; \
										for (var i = 0; i < divs.length; i++){ \
											if (divs[i].className == \"main_column\") {\
												centertable =  divs[i]; \
												break; \
											}	\
										} \
										hook = centertable.firstChild.nextSibling.nextSibling.nextSibling;\
										myDiv = document.createElement(\"div\"); \
										myDiv.className = 'box'; \
										myHeadline = document.createElement(\"div\");\
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										myHeadline.appendChild(toggleDiv);\
										myHeadline.appendChild(document.createTextNode(' '));\
										myBoldText = document.createElement('b'); \
										myBoldText.textContent = 'OiNKPlus'; \
										myHeadline.appendChild(myBoldText);\
										myHeadline.className='head'; \
										myDiv.appendChild(myHeadline);\
										myNode = document.createElement(\"div\"); \
										myNode.className = 'OiNK'; \
										myNode.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										myDiv.appendChild(myNode); \
										hook.parentNode.insertBefore(myDiv, hook.nextSibling); \
										seperator = document.createElement(\"div\"); \
										seperator.setAttribute('style','clear: both');\
										hook.parentNode.insertBefore(seperator, myDiv.nextSibling);",
				findArtist: "var h2s = document.getElementsByTagName(\"h2\");   \
											if (h2s.length > 0) {   \
												var str = h2s[0].textContent;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
												} \
												else return str.replace(/^\\s+|\\s+$/g,\"\"); \
											} \
											return '';",
				morelink: "More from <b><a href=\"/torrents.php?searchstr=%s\">%s</a></b> on What.CD"
	},
	wafflesfm:	{	
				name:	"Waffles", 
				url:	{		0: "http:\/\/www.waffles.fm\/details.php*",
									1: "http:\/\/88.80.6.249\/details.php*",
									2: "http:\/\/waffles.fm\/details.php*",
									3: "https:\/\/www.waffles.fm\/details.php*",
									4: "https:\/\/88.80.6.249\/details.php*",
									5: "https:\/\/waffles.fm\/details.php*"
							},
				searchurl: "http://waffles.fm/browse.php?q=%s",
				css: "",
				version:"1",
				isAudioRelease: "var tds = document.getElementsByTagName(\"td\");\
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"heading\" && tds[i].textContent.match(new RegExp(\"Type\"))) {\
												typeFieldContent = tds[i].nextSibling.textContent; \
												if (typeFieldContent.match(new RegExp(\"(Apps|Components|eBook)\"))) \
													return false; \
												break; \
											}	\
										} \
										return true",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"rowhead\") {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var h1s = document.getElementsByTagName(\"h1\");   \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
												} \
											} \
											return '';",
				morelink: "More from <b><a href=\"/browse.php?q=%s\">%s</a></b> on Waffles"
	},
	stmusic:	{	
				name:	"STM", 
				url:	{		0: "http:\/\/www.stmusic.org\/details.php*",
									1: "http:\/\/85.17.105.5\/details.php*",
									2: "http:\/\/stmusic.org\/details.php*"
							},
				searchurl: "http://stmusic.org/browse.php?search=%s",
				css: "",
				version:"1",
				isAudioRelease: "var tds = document.getElementsByTagName(\"td\");\
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"heading\" && tds[i].textContent.match(new RegExp(\"Type\"))) {\
												typeFieldContent = tds[i].nextSibling.textContent; \
												if (typeFieldContent.match(new RegExp(\"(Videos)\"))) \
													return false; \
												break; \
											}	\
										} \
										return true",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"rowhead\") {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var h1s = document.getElementsByTagName(\"h1\");   \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
												} \
											} \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split('-').length > 1) {  \
													return str.split('-')[0].replace(/^\\s+|\\s+$/g,\"\").replace(/_/g,\" \"); \
												} \
											} \
											return '';",
				morelink: "More from <b><a href=\"/browse.php?search=%s\">%s</a></b> on STMusic"
	},
	funkytorrents:	{	
				name:	"FTn", 
				url:	{		0: "http:\/\/www.funkytorrents.com\/details.php*",
									1: "http:\/\/213.248.54.223\/details.php*",
									2: "http:\/\/funkytorrents.com\/details.php*"
							},
				searchurl: "http://funkytorrents.com/browse.php?search=%s",
				css: "",
				version:"1",
				isAudioRelease: "var tds = document.getElementsByTagName(\"td\");\
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"heading\" && tds[i].textContent.match(new RegExp(\"Type\"))) {\
												typeFieldContent = tds[i].nextSibling.textContent; \
												if (typeFieldContent.match(new RegExp(\"(Apps|Movie|eBooks|Music Vids)\"))) \
													return false; \
												break; \
											}	\
										} \
										return true",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"rowhead\") {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var h1s = document.getElementsByTagName(\"h1\");   \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
												} \
											} \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split('-').length > 1) {  \
													return str.split('-')[0].replace(/^\\s+|\\s+$/g,\"\").replace(/_/g,\" \"); \
												} \
											} \
											return '';",
				morelink: "More from <b><a href=\"/browse.php?search=%s\">%s</a></b> on FunkyTorrents"
	},
	libble:	{	
				name:	"Lbl", 
				url:	{		0: "http:\/\/www.libble.com\/details.php*",
									1: "http:\/\/67.211.200.76\/details.php*",
									2: "http:\/\/libble.com\/details.php*"
							},
				searchurl: "http://libble.com/browse.php?qs=%s&cat=0",
				css: "",
				version:"1",
				isAudioRelease: "return true;",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"rowhead\") {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var h1s = document.getElementsByTagName(\"h1\");   \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
												} \
											} \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split('-').length > 1) {  \
													return str.split('-')[0].replace(/^\\s+|\\s+$/g,\"\").replace(/_/g,\" \"); \
												} \
											} \
											return '';",
				morelink: "More from <b><a href=\"/browse.php?qs=%s&cat=0\">%s</a></b> on Libble"
	},
  mininova:	{	
				name:	"Mnv", 
				url:	{		0: "http:\/\/www.mininova.org\/tor\/*",
									1: "http:\/\/mininova.org\/tor\/*",
									2: "http:\/\/87.233.147.140\/tor\/*"
							},
				searchurl: "http://mininova.org/search/%22%s%22/5/seeds",
				css: "",
				version:"1",
				isAudioRelease: "var hints = [\': Music &gt;\']; \
												 for (var i= 0; i< hints.length; i++)   \
													if (document.getElementsByTagName(\'title\')[0].innerHTML.indexOf(hints[i]) > 0) { \
															return true; \
													} \
													return false;",
				hook: "			myDiv = document.createElement(\"div\"); \
										myHeadline = document.createElement(\"h2\");\
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										myHeadline.appendChild(toggleDiv);\
										myHeadline.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										myDiv.appendChild(myHeadline);\
										myDiv.appendChild(document.createElement('br')); \
										myNode = document.createElement(\"div\"); \
										myNode.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										myDiv.appendChild(myNode); \
										document.getElementById(\"content\").appendChild(document.createElement('br')); \
										document.getElementById(\"content\").appendChild(myDiv);",
				findArtist: "var title = document.getElementsByTagName(\'title\')[0].innerHTML; \
											title = title.replace(' - Mininova', ''); \
											if (title.indexOf(\"-\") < 0 ) return null; \
											var myartist = title.replace(/\\[.*?\\]/g,\"\").replace(/_/g,' ').split(\"-\")[0]; \
											return myartist.replace(/(^( )*)|(( )*$)/g,\"\").replace(/[ ]{2,}/gi,\" \");",
				morelink:   "More from <b><a href=\"/search/%22%s%22/5/seeds\">%s</a></b> on Mininova"
			},
  thepiratebay:	{	
				name:	"TPB", 
				url:	{		0: "http:\/\/thepiratebay.org\/tor\/*",
									1: "http:\/\/83.140.176.146\/tor\/*"
							},
				searchurl: "http://thepiratebay.org/search/%s/0/7/100",
				css: ".artistHeadline {font-size: 12pt;}",
				version:"1",
				isAudioRelease: "var hints = [\'/browse/101\']; \
												 for (var i= 0; i< hints.length; i++)   \
													if (document.getElementById(\"details\").innerHTML.indexOf(hints[i]) > 0) { \
															return true; \
													} \
													return false;",
				hook: "			myDiv = document.createElement(\"div\"); \
										myHeadline = document.createElement(\"h4\");\
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										myHeadline.appendChild(toggleDiv);\
										myHeadline.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										myDiv.appendChild(myHeadline);\
										myDiv.appendChild(document.createElement('br')); \
										myNode = document.createElement(\"div\"); \
										myNode.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										myDiv.appendChild(myNode); \
										var divs = document.getElementsByTagName(\"div\");\
										var nfoDiv; \
										for (var i = 0; i < divs.length; i++){ \
											if (divs[i].className == \"nfo\") {\
												nfoDiv =  divs[i]; \
												break; \
											}	\
										} \
										nfoDiv.parentNode.insertBefore(myDiv, nfoDiv.nextSibling);",
				findArtist: "var title = document.getElementById(\"title\").innerHTML; \
											if (title.indexOf(\"-\") < 0 ) return null; \
											var myartist = title.replace(/\\[.*?\\]/g,\"\").replace(/_/g,' ').split(\"-\")[0]; \
											return myartist.replace(/(^( )*)|(( )*$)/g,\"\").replace(/[ ]{2,}/gi,\" \");",
				morelink:   "More from <b><a href=\"/search/%s/0/7/100\">%s</a></b> on ThePirateBay"
			},
	scenetorrents:	{	
				name:	"ScT", 
				url:	{		0: "http:\/\/www.scenetorrents.org\/details.php*",
									1: "http:\/\/scenetorrents.org\/details.php*",
									2: "http:\/\/85.17.40.165\/details.php*",
									3: "https:\/\/www.scenetorrents.org\/details.php*",
									4: "https:\/\/85.17.40.165\/details.php*",
									5: "https:\/\/scenetorrents.org\/details.php*",
									
							},
				searchurl: "http://scenetorrents.org/browse.php?c%5B%5D=8&search=%s&titleonly=1&all=0&incldead=0",
				css: "",
				version:"1",
				isAudioRelease: "var tds = document.getElementsByTagName(\"td\");\
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"heading\" && tds[i].textContent.match(new RegExp(\"Type\"))) {\
												typeFieldContent = tds[i].nextSibling.textContent; \
												if (typeFieldContent.match(new RegExp(\"(Music/MP3)\"))) \
													return true; \
												break; \
											}	\
										} \
										return false",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"rowhead\") {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var h1s = document.getElementsByTagName(\"h1\");   \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
												} \
											} \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split('-').length > 1) {  \
													return str.split('-')[0].replace(/^\\s+|\\s+$/g,\"\").replace(/_/g,\" \"); \
												} \
											} \
											return '';",
				morelink: "More from <b><a href=\"/browse.php?c%5B%5D=8&search=%s&titleonly=1&all=0&incldead=0\">%s</a></b> on SceneTorrents"
	},
	softmp3:	{	
				name:	"Smp3", 
				url:	{		0: "http:\/\/www.softmp3.org\/details.php*",
									1: "http:\/\/softmp3.org\/details.php*",
									2: "http:\/\/85.24.152.69\/details.php*"
							},
				searchurl: "http://softmp3.org/browse.php?search=%s",
				css: "",
				version:"1",
				isAudioRelease: "return true;",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"rowhead\") {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var as = document.getElementsByTagName(\"a\");   \
											for (var i = 0; i < as.length; i++){ \
												if (as[i].className == \"index\") { \
													str =  as[i].firstChild.innerHTML; \
													break; \
												}	\
											} \
											str = str.replace(/\\[[^\\]]*\\]/g, '');  \
											if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
											} \
											if (str.split('-').length > 1) {  \
													return str.split('-')[0].replace(/^\\s+|\\s+$/g,\"\").replace(/_/g,\" \"); \
												} \
											return '';",
				morelink: "More from <b><a href=\"/browse.php?search=%s\">%s</a></b> on softmp3"
	},
  kraytracker:	{	
				name:	"KTc", 
				url:	{		0: "http:\/\/kraytracker.com\/\\?cls=5\&id=*",
									1: "http:\/\/64.34.39.105\/\\?cls=5\&id=*",
									2: "https:\/\/kraytracker.com\/\\?cls=5\&id=*",
									3: "https:\/\/64.34.39.105\/\\?cls=5\&id=*"
							},
				searchurl: "http://kraytracker.com/?cls=2&act=audio&orderby=added&sortby=desc&artist=%s",
				css: ".artistHeadline {font-size: 12pt;} \
							.OiNKPlusHeadline {text-align:left }",
				version:"1",
				isAudioRelease: "var tds = document.getElementsByTagName(\"td\");\
													for (var i = 0; i < tds.length; i++){ \
														if (tds[i].className == \"td_dark\" && tds[i].innerHTML.indexOf(\"Artist\") > -1) { \
															return true; \
															break; \
														}	\
													} \
													return false;",
				hook: "			myDiv = document.createElement(\"div\"); \
										myHeadline = document.createElement(\"h4\");\
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										myHeadline.appendChild(toggleDiv);\
										myHeadline.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										myHeadline.className = \"OiNKPlusHeadline\"; \
										myDiv.appendChild(myHeadline);\
										myDiv.appendChild(document.createElement('br')); \
										myNode = document.createElement(\"div\"); \
										myNode.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										myDiv.appendChild(myNode); \
										var tds = document.getElementsByTagName(\"table\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"main\") {\
												centertable =  tds[i].parentNode.parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(myDiv);\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var title = document.getElementsByTagName(\'title\')[0].innerHTML; \
											title = title.replace('Kraytracker / ', ''); \
											if (title.indexOf(\"-\") < 0 ) return null; \
											var myartist = title.replace(/\\[.*?\\]/g,\"\").replace(/_/g,' ').split(\" - \")[0]; \
											return myartist.replace(/(^( )*)|(( )*$)/g,\"\").replace(/[ ]{2,}/gi,\" \");",
				morelink:   "More from <b><a href=\"/?cls=2&act=audio&orderby=added&sortby=desc&artist=%s\">%s</a></b> on KrayTracker"
			},
	arenabg:	{	
				name:	"ABG", 
				url:	{		0: "http:\/\/arenabg.com\/details.php\\?id=*",
									1: "http:\/\/www.arenabg.com\/details.php\\?id=*",
									2: "http:\/\/85.14.6.83\/details.php\\?id=*"
							},
				searchurl: null,
				css: "",
				version:"1",
				isAudioRelease: "var tds = document.getElementsByTagName(\"td\");\
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"lista\" && tds[i].textContent.match(new RegExp(\"Category\"))) {\
												typeFieldContent = tds[i].nextSibling.textContent; \
												if (typeFieldContent.match(new RegExp(\"(Music/)\"))) \
													return true; \
												break; \
											}	\
										} \
										return false",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										var tds = document.getElementsByTagName(\"td\");\
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"lista\" && tds[i].textContent.match(new RegExp(\"Category\"))) {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var title = document.getElementsByTagName(\'title\')[0].innerHTML; \
											title = title.replace('ArenaBG.com - ', ''); \
											title = title.replace(' - Torrent Details', ''); \
											if (title.indexOf(\"-\") < 0 ) return null; \
											str = title; \
											str = str.replace(/\\[[^\\]]*\\]/g, '');  \
											if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
											} \
											if (str.split('-').length > 1) {  \
													return str.split('-')[0].replace(/^\\s+|\\s+$/g,\"\").replace(/_/g,\" \"); \
												} \
											return '';",
				morelink: "More from <b><a href=\"/torrents.php?search=%s&category=23&active=1\">%s</a></b> on ArenaBG"
	},
 	metaltorrents:	{	
				name:	"RMT", 
				url:	{		0:"http:\/\/metal.iplay.ro\/details.php\\?id=*", 
									1:"http:\/\/84.247.80.243\/details.php\\?id=*"
							},
				searchurl: null,
				css: "",
				version:"1",
				isAudioRelease: "var tds = document.getElementsByTagName(\"td\");\
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"heading\" && tds[i].textContent.match(new RegExp(\"Type\"))) {\
												typeFieldContent = tds[i].nextSibling.textContent; \
												if (typeFieldContent.match(new RegExp(\"(VA|rmtva|elearn|dvdr|discgrr)\"))) \
													return false; \
												break; \
											}	\
										} \
										return true",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"rowhead\") {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										new_row.firstChild.innerHTML = \"\"; \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var h1s = document.getElementsByTagName(\"h1\");   \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(' - RMT', ''); \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
											if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
											} \
											if (str.split('-').length > 1) {  \
													return str.split('-')[0].replace(/^\\s+|\\s+$/g,\"\").replace(/_/g,\" \"); \
												} \
											return ''; \
											} \
											return '';",
				morelink: "More from <b><a href=\"/browse.php?search=%s&cat=0\">%s</a></b> on MetalTorrents"
	},
	themusik:	{	
				name:	"TMo", 
				url:	{		0: "http:\/\/www.themusik.org\/details.php*",
									1: "http:\/\/themusik.org\/details.php*",
									2: "http:\/\/85.17.164.57\/details.php*",
									3: "https:\/\/www.themusik.org\/details.php*",
									4: "https:\/\/themusik.org\/details.php*",
									5: "https:\/\/85.17.164.57\/details.php*"
							},
				searchurl: "http://themusik.org/browse.php?search=%s",
				css: "",
				version:"1",
				isAudioRelease: "var tds = document.getElementsByTagName(\"td\");\
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"heading\" && tds[i].textContent.match(new RegExp(\"Type\"))) {\
												typeFieldContent = tds[i].nextSibling.textContent; \
												if (typeFieldContent.match(new RegExp(\"(DVD|CD Packs|E-learning|Top 40|Music Apps)\"))) \
													return false; \
												break; \
											}	\
										} \
										return true",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"rowhead\") {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var h1s = document.getElementsByTagName(\"h1\");   \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
												} \
											} \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split('-').length > 1) {  \
													return str.split('-')[0].replace(/^\\s+|\\s+$/g,\"\").replace(/_/g,\" \"); \
												} \
											} \
											return '';",
				morelink: "More from <b><a href=\"/browse.php?search=%s\">%s</a></b> on TheMusik"
	},
  welovemusique:	{	
				name:	"WLM", 
				url:	{		0: "http:\/\/www.welovemusique.com\/musicreviews\/*"
							},
				searchurl: null,
				css: ".artistHeadline {font-size: 12pt;}",
				version:"1",
				isAudioRelease: "return true;",
				hook: "			myDiv = document.createElement(\"div\"); \
										myHeadline = document.createElement(\"h4\");\
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										myHeadline.appendChild(toggleDiv);\
										myHeadline.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										myDiv.appendChild(myHeadline);\
										myDiv.appendChild(document.createElement('br')); \
										myNode = document.createElement(\"div\"); \
										myNode.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										myDiv.appendChild(myNode); \
										var results = new Array(); \
										var elems = document.getElementsByTagName(\"h2\"); \
										for (var i=0; i<elems.length; i++) { \
											if (elems[i].className.indexOf(\"comments-header\") != -1) {\
												results[results.length] = elems[i];\
											}\
										}\
										results[0].parentNode.insertBefore(myDiv, results[0]);",
				findArtist: "var title = document.getElementsByTagName('title')[0].innerHTML; \
											if (title.indexOf(\"-\") < 0 ) return null; \
											var myartist = title.split(\"-\")[0].replace('_',' '); \
											return myartist.replace(/(^( )*)|(( )*$)/g,\"\").replace(/[ ]{2,}/gi,\" \");",
				morelink:   "More from <b><a href=\"/index.php?s=%s&cat=1%2C11%2C24%2C41%2C44%2C45%2C46\">%s</a></b> on We Love Musique"
			},
	ct:	{	
				name:	"CT", 
				url:	{				0: "http:\/\/www.christiantorrents.com\/details.php*",
									1: "http:\/\/85.11.33.12\/details.php*",
									2: "http:\/\/christiantorrents.com\/details.php*"
							},
				searchurl: null,
				css: ".artistHeadline {font-size: 10pt;}",
				version:"1",
				isAudioRelease: "var tds = document.getElementsByTagName(\"td\");\
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"heading\" && tds[i].textContent.match(new RegExp(\"Type\"))) {\
												typeFieldContent = tds[i].nextSibling.textContent; \
												if (typeFieldContent.match(new RegExp(\"(Appz|Debates|e-Books|Gaither|Lectures|Misc|Movies|Scores|Sermons)\"))) \
													return false; \
												break; \
											}	\
										} \
										return true",
				hook: "var tds = document.getElementsByTagName(\"table\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"coltable\" && tds[i].textContent.match(new RegExp(\"Type\"))) {\
												centertable =  tds[i].firstChild; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var h1s = document.getElementsByTagName(\"h1\");   \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
												} \
											} \
											return '';",
				morelink: "More from <b><a href=\"/browse.php?search=%22%s%22&nameonly=true\">%s</a></b> on CT"
	},
	vipv2:	{	
				name:	"ViP", 
				url:	{				0: "http:\/\/tracker.vipv2.org\/details.php*",
									1: "http:\/\/194.145.250.133\/details.php*",
									2: "https:\/\/tracker.vipv2.org\/details.php*",
									3: "https:\/\/194.145.250.133\/details.php*"
							},
				searchurl: "http://tracker.vipv2.org/browse.php?search=%s",
				css: ".artistHeadline {font-size: 10pt;}",
				version:"1",
				isAudioRelease: "var tds = document.getElementsByTagName(\"td\");\
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"heading\" && tds[i].textContent.match(new RegExp(\"Type\"))) {\
												typeFieldContent = tds[i].nextSibling.textContent; \
												if (typeFieldContent.match(new RegExp(\"(Collections|Video)\"))) \
													return false; \
												break; \
											}	\
										} \
										return true",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"rowhead\") {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var h1s = document.getElementsByTagName(\"h1\");   \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
												} \
											} \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split('-').length > 1) {  \
													return str.split('-')[0].replace(/^\\s+|\\s+$/g,\"\").replace(/_/g,\" \"); \
												} \
											} \
											return '';",
				morelink: "More from <b><a href=\"/browse.php?search=%s\">%s</a></b> on ViPv2"
	},
	ex:	{	
				name:	"Ex", 
				url:	{				0: "http:\/\/www.exodusmusic.org\/details.php*",
									1: "http:\/\/111.111.111.111\/details.php*",
									2: "https:\/\/www.exodusmusic.org\/details.php*",
									3: "https:\/\/111.111.111.111\/details.php*"
							},
				searchurl: null,
				css: ".artistHeadline {font-size: 10pt;}",
				version:"1",
				isAudioRelease: "return true",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"colhead\") {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"colhead\") {\
												var str = tds[i].textContent.replace(/Details for: /,'');     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
												} \
											} \
										}\
											return '';",
				morelink: "More from <b><a href=\"/browse.php?search=%s\">%s</a></b> on Exigo"
	},
	indietorrents:	{	
				name:	"#i.t", 
					url:	{		0: "http:\/\/www.indietorrents.com\/details.php*",
									1: "http:\/\/66.129.1.42\/details.php*",
									2: "https:\/\/www.indietorrents.com\/details.php*",
									4: "https:\/\/66.129.1.42\/details.php*",
									5: "http:\/\/indietorrents.com\/details.php*",
									6: "https:\/\/indietorrents.com\/details.php*"
							},
				searchurl: "http://www.indietorrents.com/browse.php?search=%s",
				css: "",
				version:"1",
				isAudioRelease: "return true;",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"rowhead\") {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var h1s = document.getElementsByTagName(\"h1\");   \
											if (h1s.length > 0) {   \
												var str = h1s[0].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
												} \
											} \
											return '';",
				morelink: "More from <b><a href=\"browse.php?search=%s\">%s</a></b> on #i.t"
	},
	metalbits:	{	
				name:	"MetalBits", 
					url:	{		0: "http:\/\/www.metalbits.org\/details.php*",
									1: "http:\/\/83.227.1.135\/details.php*",
									2: "https:\/\/www.metalbits.org\/details.php*",
									4: "https:\/\/83.227.1.135\/details.php*",
									5: "https:\/\/metalbits.org\/details.php*",
									6: "http:\/\/metalbits.org\/details.php*"
							},
				searchurl: "http://www.metalbits.org/browse.php?search=%s&dead=incl&scene=both",
				css: "",
				version:"1",
				isAudioRelease: "return true;",
				hook: "var tds = document.getElementsByTagName(\"td\");\
										var centertable; \
										for (var i = 0; i < tds.length; i++){ \
											if (tds[i].className == \"rowhead\") {\
												centertable =  tds[i].parentNode.parentNode; \
												break; \
											}	\
										} \
										var new_row = centertable.lastChild.previousSibling.cloneNode(true); \
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										if (new_row.firstChild.hasChildNodes()){ \
												new_row.firstChild.innerHTML = '';\
										} \
										new_row.firstChild.appendChild(toggleDiv);\
										new_row.firstChild.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										new_row.firstChild.nextSibling.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										var parent = centertable.lastChild.previousSibling.parentNode; \
										parent.appendChild(new_row);",
				findArtist: "var h1s = document.getElementsByTagName(\"h1\");   \
											if (h1s.length > 0) {   \
												var str = h1s[1].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split(' - ').length > 1) {  \
													return str.split(' - ')[0].replace(/^\\s+|\\s+$/g,\"\"); \
												} \
											} \
											if (h1s.length > 0) {   \
												var str = h1s[1].innerHTML;     \
												str = str.replace(/\\[[^\\]]*\\]/g, '');  \
												if (str.split('-').length > 1) {  \
													return str.split('-')[0].replace(/^\\s+|\\s+$/g,\"\").replace(/_/g,\" \"); \
												} \
											} \
											return '';",
				morelink: "More from <b><a href=\"/browse.php?search=%s&dead=incl&scene=both\">%s</a></b> on MetalBits"
	},
  torrentz:	{	
				name:	"Torrentz", 
				url:	{		0: "http:\/\/www.torrentz.com\/*",
									1: "http:\/\/213.239.140.13\/*"
							},
				searchurl: "http://www.torrentz.com/search?q=%s+music",
				css: ".OiNK {float: left !important;} \
				      .OinkPlus {float: left !important;} \
				     .artistHeadline {font-size: 10pt;}",
				version:"1",
				isAudioRelease: "var divs = document.getElementsByTagName(\"div\");\
										for (var i = 0; i < divs.length; i++){ \
											if (divs[i].className == \"download\") {\
												if (divs[i].textContent.match(new RegExp(\"(audio|music)\"))) \
													return true; \
												break; \
											}	\
										} \
										return false;",
				hook: "			myDiv = document.createElement(\"div\"); \
										myDiv.className = 'results'; \
										myDiv.setAttribute('style','position: relative'); \
										myHeadline = document.createElement(\"h2\");\
										toggleDiv = document.createElement(\"div\"); \
										toggleDiv.id = \"toggleOiNKPlus\"; \
										myHeadline.appendChild(toggleDiv);\
										myHeadline.appendChild(document.createTextNode(' ' + 'OiNKPlus'));\
										myDiv.appendChild(myHeadline);\
										myNode = document.createElement(\"div\"); \
										myNode.className = 'OiNK'; \
										myNode.innerHTML = '<div id=\"OiNKPlus\"></div>';\
										myDiv.appendChild(myNode); \
										var divs = document.getElementsByTagName(\"div\");\
										var filesDiv; \
										for (var i = 0; i < divs.length; i++){ \
											if (divs[i].className == \"download\") {\
												filesDiv = divs[i]; \
												break;\
											} \
										} \
										filesDiv.parentNode.insertBefore(myDiv, filesDiv.nextSibling);\
										seperator = document.createElement(\"div\"); \
										seperator.setAttribute('style','clear: both');\
										filesDiv.parentNode.insertBefore(seperator, myDiv.nextSibling);\
										",
				findArtist: "var title = document.getElementsByTagName('title')[0].innerHTML; \
											title = title.replace(/Torrent Download/,'');\
											if (title.indexOf(\"-\") < 0 ) return null; \
											var myartist = title.replace(/\\[.*?\\]/g,\"\").replace(/_/g,' ').split(\"-\")[0]; \
											return myartist.replace(/(^( )*)|(( )*$)/g,\"\").replace(/[ ]{2,}/gi,\" \");",
				morelink:   "More from <b><a href=\"/search?q=%s+music\">%s</a></b> on Torrentz"
			}
});




var RessourceLoader = {
	ressources: new Array(),
	index: 0,
	callback: "",
	addRessource: function(res, save) {
		save = save==false?false:true;
		this.ressources.push(res);
		window.setTimeout( function () {EventNotifier.send(null, "removeOnTimeout", {ressource: res })}, RESOURCE_LOAD_TIMEOUT, false);
	},
	isRessourceLoading: function(res) {
    for(var i = 0, length = this.ressources.length; i < length; i++){
      if (res.url == this.ressources[i].url) {
        return true;  
      }
    } 
    return false;
	},
	load: function(callback) {
		this.callback = callback;
		this.loadRessource(this.ressources[this.index++]);	
	},
	loadNext: function() {
		if(this.index < this.ressources.length) this.loadRessource(this.ressources[this.index++]);
		else this.callback();
	},
	loadRessource: function(res, res_type) {
    if (!this.isRessourceLoading(res)){
      	this.addRessource(res, true);
      
	if(!GM_getValue("ressource_"+res.url, "")) {
        	GM_xmlhttpRequest({
			method:	'GET',
			overrideMimeType: "text/plain;" + ((res_type == TYPE_BINARY)?" charset=x-user-defined":""),
			url:	res.url,
			headers: {'Accept-Language': 'en-us,en;q=0.5' },
			onload:	function(data) {
			if(res.save) GM_setValue("ressource_"+res.url,  data.responseText );
				RessourceLoader.announceLoad(res, data.responseText );
			}
		});
      	} else {
		//console.('Error: ' + res.url + ' is cached?!');
		RessourceLoader.announceLoad(res, GM_getValue("ressource_"+res.url));
      }
    } 
	else {
		//console.(res.url + ' is already loading');
	}
	},
	announceLoad: function(res, data) {
		//console.(res.url + ' announcing load');
		//this.ressources = this.ressources.reject( function(o) { return (o.url == res.url); });
		var results = [];
		this.ressources.forEach(
			function(o) {
				if (o.url == res.url) {
				results.push(o);
				}
			});
		this.ressources = results;

		EventNotifier.send(null, "onRessourceLoaded", {ressource: res, content: data  });	
		//this.loadNext();
	},
	removeOnTimeout: function (sender, e){
		//this.ressources = this.ressources.reject( function(o) {  return (o.url == e.ressource.url)});
		var results = [];
		this.ressources.forEach(
			function(o) {
				if (o.url == e.ressource.url) {
				results.push(o);
				}
			});
		this.ressources = results;
	}
}
EventNotifier.addObserver(RessourceLoader);
	// class Widget
	function Widget(name, res, toggleable){
		this._name = name;
		this._ressource = res;
		this._toggleable = toggleable;
		this._state = UNLOADED;	
		this._content = '';
		this._scrapedObject;
		this._currentArtist = '';
		this._contentNode;
		if (toggleable) {
			var togglelink = document.createElement('a');
			if (this.isVisible()) 
				togglelink.innerHTML = "<img src=\""+TOGGLE_IMG_MINUS	+"\" border=0>";
			else	{
				togglelink.innerHTML = "<img src=\""+TOGGLE_IMG_PLUS	+"\" border=0>";
				this.hide();
			}
			togglelink.href= '#';
			togglelink.id = "toggle"+this._name;
			togglelink.addEventListener("click", function (e) {EventNotifier.send(null, "onToggle", {toggleId: this.id }); e.preventDefault();}, false);
			$("toggle"+this._name).parentNode.replaceChild(togglelink, $("toggle"+this._name));
		}	
		EventNotifier.addObserver(this);
		

		this.load();
	};
	
	Widget.prototype.getName = function() {
		return this._name;
	};
	
	Widget.prototype.onToggle =  function(sender, e) {
		if (e.toggleId == "toggle"+this._name ){
			this.toggle();
		}
	};

	Widget.prototype.prepareRessourceUrl = function (artistname) {
					// should be implemented by the Widget
	};

	Widget.prototype.isVisible = function() {
		return (GM_getValue('visible'+this._name+'', 1) == 1);
	};
	
	Widget.prototype.isEnabled = function() {
		return (GM_getValue('enable'+this._name+'', 1) == 1);
	};
	
	Widget.prototype.Enable = function() {
		GM_setValue('enable'+this._name+'', 1);
	};
	
	Widget.prototype.Disable = function() {
		GM_setValue('enable'+this._name+'', 0);
	};
	
	Widget.prototype.toggle = function() {
		if (this.isVisible()){
			this.hide();
			$("toggle"+this._name).innerHTML = "<img src=\""+TOGGLE_IMG_PLUS	+"\" border=0>";
		} else {
			this.show();
			$("toggle"+this._name).innerHTML = "<img src=\""+TOGGLE_IMG_MINUS	+"\" border=0>";
		}
	};
	
	Widget.prototype.hide = function (){
		$(this._name).style.display = 'none';
		GM_setValue('visible'+this._name+'', 0);
	};
	
	Widget.prototype.show = function (){
		$(this._name).style.display = 'block';
		GM_setValue('visible'+this._name+'', 1);
		this.render();
	};
	
	Widget.prototype.load = function (){
		this._state = LOADING;
		// implement data request here
	};
	
	Widget.prototype.onArtistChange = function(sender, e) {
		if(sender != this._name && this._currentArtist != e.artistname) {
			this._state = LOADING;
			this.render();
			this._currentArtist = e.artistname;
			if (this._ressource != null) {
				var tempRessource = {key: this._ressource.key, url: this._ressource.url, save: this._ressource.save, artistname: e.artistname};
				tempRessource.url = this.prepareRessourceUrl(e.artistname);
				//var cachedContent = cache.getItem("cache_widget_" + this._name + "_" + this._currentArtist);
				var cachedContent = null;
				if (cachedContent == null){
					//console.(this._name + " contentUnCached for " + this._currentArtist); 
					RessourceLoader.loadRessource(tempRessource);
				}
				else {
					//console.(this._name + " contentCached for " + this._currentArtist); 
					this._state = CACHED;
					this._scrapedObject = cachedContent;
					this.createNodeFromScrapedContent();
					this.render();
				}
			}
			else {
				this._state = LOADED;
				this._scrapedObject = cachedContent;
				this.createNodeFromScrapedContent();
				this.render();
			}
		}
	};

	Widget.prototype.onRessourceLoaded = function (sender, e){
		if (this._ressource != null && this._ressource.key == e.ressource.key && this._currentArtist == e.ressource.artistname) {
			//alert(this._name + " contentLoaded for " + this._currentArtist); 
			this._state = LOADED;
			this._content = e.content;
			this._scrapedObject = this.scraperImpl();
			//cache.setItem("cache_widget_" + this._name + "_" + this._currentArtist, this._scrapedObject);
			this.createNodeFromScrapedContent();
			this.render();
		}
	};
	

	Widget.prototype.render = function (){
		if (this._state == CACHED || this._state == LOADED) {
			if ($(this._name).hasChildNodes()){
				//console.(this._name  + 'has Child node, state' + this._state);
				$(this._name).replaceChild(this._contentNode, $(this._name).firstChild);	
			}
			else $(this._name).appendChild(this._contentNode);
		}
		if (this._state == LOADING) {
				$(this._name).innerHTML = "<img src=\""+ SPINNER_IMG	+"\" border=0>";
		}
		if (this._state == FAILED) {
				$(this._name).innerHTML = "n/a";
		}
	};

	Widget.prototype.createNodeFromScrapedContent = function (){
		var node = document.createElement("div");
		node.innerHTML = this._scrapedObject;
		this._contentNode = node;
	};
  
	// end of class Widget
	
	function a(artist){
		EventNotifier.send("global", "onArtistChange", {artistname: artist, albumname: null  });
	}

		
	function addWidgets(artist){
      
 			/* 
			* Widget for OiNKPlus container 
			*/
			OiNKPlusRessource = null;
			wOiNKPlus =  new Widget("OiNKPlus", OiNKPlusRessource, TOGGLEABLE );
			wOiNKPlus.createNodeFromScrapedContent = function () {
					tempContent = BASIC_LAYOUT;
					var node = document.createElement("div");
					node.innerHTML = tempContent;
					this._contentNode = node;
			};
			wOiNKPlus.onArtistChange = function () {
					// overwritten to do nothing
			};
			wOiNKPlus.createNodeFromScrapedContent();
			wOiNKPlus._state = LOADED;
			wOiNKPlus.render();
			// Widget for OiNKPlus container 
      
		 /* 
			* Widget for Artist Name 
			*/
			ArtistNameRessource = null;
			wArtistName =  new Widget("ArtistName", ArtistNameRessource, NON_TOGGLEABLE );
			wArtistName.createNodeFromScrapedContent = function () {
					var myLink = document.createElement('a');
					myLink.innerHTML = this._currentArtist;
					myLink.id = this._currentArtist;
					myLink.href = '#';
					myLink.addEventListener("click", function (e) {EventNotifier.send("LastFMSimilar", "onArtistChange", {artistname: this.id, albumname: null  }); e.preventDefault();} , false);
					this._contentNode = myLink;
			};
			wArtistName.onArtistChange = function (sender, e) {
					if(sender == "global") {
						this._currentArtist = e.artistname;	
						this.createNodeFromScrapedContent();
						this._state = LOADED;
						this.render();
					}
			};
			wArtistName._currentArtist = artist;
			wArtistName.createNodeFromScrapedContent();
			wArtistName._state = LOADED;
			wArtistName.render();
			
			// Widget for Artist Name

			/* 
			* Widget for Artist Title and More Link 
			*/
			ArtistTitleRessource = null;
			wArtistTitle =  new Widget("ArtistTitle", ArtistTitleRessource, NON_TOGGLEABLE );
			wArtistTitle.createNodeFromScrapedContent = function () {
					// TODO encodeURIComponent 
					//var tempContent = '<h1>' + this._currentArtist + '</h1>';
					artistHeadline = document.createElement("h1");
					artistHeadline.className = "artistHeadline";
					artistHeadline.appendChild(document.createTextNode(this._currentArtist + " "));
					var myLink = document.createElement('a');
					myLink.innerHTML = "<font size=-2>[ load similar ]</font>";
					myLink.id = this._currentArtist;
					myLink.href = '#';
					myLink.className = "explore";
					myLink.addEventListener("click", function (e) {EventNotifier.send("global", "onArtistChange", {artistname: this.id, albumname: null  }); e.preventDefault();} , false);
					artistHeadline.appendChild(myLink);
					tempContent = MORE_LINK.replace(/%s/, this._currentArtist.replace(/&/g, '%26')).replace(/%s/, this._currentArtist).replace(/%s/,this._currentArtist.replace(/&/g, '%26')) + '<br>';
					var moreNode = document.createElement("div");
					moreNode.innerHTML = tempContent;
					var node = document.createElement("div");
					node.appendChild(artistHeadline);
					node.appendChild(moreNode);
					this._contentNode = node;
			};
			// Widget for Artist Title and More Link
		
			/*
			* Widget for artist search field
			*/
			ArtistSearchFieldRessource = null;
			wArtistSearchField =  new Widget("ArtistSearchField", ArtistSearchFieldRessource, NON_TOGGLEABLE);
			wArtistSearchField.createNodeFromScrapedContent = function () {
					logmsg('ArtistSearchField');
					var searchField = document.createElement("input");
					searchField.value = 'type artist name here';
					var baseStyle = 'background:#FFFFFF url('+SEARCH_IMG+') no-repeat scroll left center; border:1px solid #7E1325; font-size:11px;padding:1px 4px 2px 16px;width:162px;';
					searchField.setAttribute('style', baseStyle + 'color:grey');
					searchField.addEventListener("click", function (e) { if (this.value == 'type artist name here') {this.value = ''; searchField.setAttribute('style',baseStyle);}}, false);
					searchField.addEventListener("keypress", function (e) { if (e.keyCode == 13) EventNotifier.send("global", "onArtistChange", {artistname: this.value.replace(/^\s+|\s+$/g,""), albumname: null  })}, false);
					var node = document.createElement("div");
					node.style.textAlign = "right";
					node.appendChild(searchField);
					this._contentNode = node;
					
			};
			wArtistSearchField.onArtistChange(null, {artistname: null, albumname: null  });
			// Widget for artist search field
			/* 
			* Widget for Last.fm Artist Image 
			*/
			LFMArtistPageRessource = {key: "LastFMArtistPage", url: LASTFM_ARTIST_URL, save: false};
			wLFMArtistImage =  new Widget("ArtistImage", LFMArtistPageRessource, NON_TOGGLEABLE);
					  wLFMArtistImage.prepareRessourceUrl = function (artistname) {
							  return this._ressource.url.replace(/%s/, artistname.replace(/&/g, '%2526').replace(/\//g, '%252F').replace(/\?/,"%3F"));
					  };
					  wLFMArtistImage.scraperImpl = function () {
									  return "<img src=\"" + buildDataScheme(this._content, 'data:image/jpeg;base64,')  + "\" border=1>";
					  };
			wLFMArtistImage.onRessourceLoaded = function (sender, e){
			    if (this._ressource != null && e.ressource.key == 'LastFMArtistPage' && this._currentArtist == e.ressource.artistname) {
				  var imgUrl = e.content.extract("<div class=\"imgHolder\">","</div>").replace(/.*src=\"(.*)\" alt=.*/,'$1');
				// Subsequent Ressource
									  if (imgUrl.search(/^http/) >= 0) {
										  LFMArtistImageRessource = {key: "LastFMArtistImage", url: imgUrl, save: false, artistname: e.ressource.artistname};
				  RessourceLoader.loadRessource(LFMArtistImageRessource, TYPE_BINARY);
									  } else {
										  this._state = FAILED;
				  this.render();
									  }
			    }
			    if (this._ressource != null &&  e.ressource.key == 'LastFMArtistImage' && this._currentArtist == e.ressource.artistname) {
										  this._state = LOADED;
										  this._content = e.content;
										  this._scrapedObject = this.scraperImpl();
										  //cache.setItem("cache_widget_" + this._name + "_" + this._currentArtist, this._scrapedObject);
										  this.createNodeFromScrapedContent();
										  this.render();
			    }
			};
			// Widget for Last.fm Artist Image
 
			/* 
			* Widget for Last.fm Abstracts 
			*/
			wLFMBio =  new Widget("LastFMBio", LFMArtistPageRessource, TOGGLEABLE);
			wLFMBio.prepareRessourceUrl = function (artistname) {
					return this._ressource.url.replace(/%s/, artistname.replace(/&/g, '%2526').replace(/\//g, '%252F').replace(/\?/,"%3F"));
			};
			wLFMBio.scraperImpl = function () {
					cleanedBio = basicClean(this._content.extract("<div id=\"wikiAbstract\">", "</div>"));
					return cleanedBio;
			};
			wLFMBio.createNodeFromScrapedContent = function (){
					var node = document.createElement("div");
					node.innerHTML = this._scrapedObject;
					encodedArtistName = this._currentArtist.replace(/&/g, '%252526').replace(/\//g, '%25252F').replace(/\?/,"%25253F");
					textContent = node.textContent;
					var maxLength = 450;
					if (textContent.length > MAX_BIO_LENGTH){	
						logmsg('bio longer than maximum length');
						textContent = textContent.replace(/\(read more\)/, "");
						sentences = textContent.split(".");
						var out = "";
						logmsg('got ' + sentences.length + ' sentences');
						for (i = 0; out.length < MAX_BIO_LENGTH && i < sentences.length; i++){
							out += sentences[i] + ".";
						}
						//textContent = out + new String(" (read more)");
						textContent = out;	
					}
					//textContent = textContent.replace(/read more/, LASTFM_BIO_LINK.replace(/%s/, encodedArtistName));
					node.innerHTML = textContent;
					if (textContent.length > MAX_BIO_LENGTH) {
						var readmorelink = document.createElement('a');
						readmorelink.innerHTML = "read more";
						readmorelink.href= '#';
						readmorelink.id = this._currentArtist;
						readmorelink.addEventListener("click", function (e) { EventNotifier.send("LastFMBio", "onReadMore", {artistname: this.id, albumname: null  }); e.preventDefault();}, false);
						node.appendChild(document.createTextNode(" ("));
						node.appendChild(readmorelink);
						node.appendChild(document.createTextNode(")"));
						node.appendChild(document.createElement("br"));	
					}
					this._contentNode = node;
			};
			wLFMBio.scraperImplBio = function () {
					cleanedBio = basicClean(this._content.extract("<div id=\"tabbody\">", "<div style=\"margin-top:20px; border-top:1px solid #CCC").extract("</div></div>", "<div style=\"margin-top:20px; border-top:1px solid #CCC"));
					return cleanedBio;
			};
			wLFMBio.onRessourceLoaded = function (sender, e){
				if (this._ressource != null && this._ressource.key == e.ressource.key && this._currentArtist == e.ressource.artistname) {
					this._state = LOADED;
					this._content = e.content;
					this._scrapedObject = this.scraperImpl();
					this.createNodeFromScrapedContent();
					this.render();
				}
				if (this._ressource != null && e.ressource.key == "LastFMArtistBio" ) {
					this._state = LOADED;
					this._content = e.content;
					this._scrapedObject = this.scraperImplBio();
					//this.createNodeFromScrapedContent();
					var node = document.createElement("div");
					node.innerHTML = this._scrapedObject.replace(/<br \/>/g, "%%br%%");
					logmsg(node.textContent);
					textContent = node.textContent;
					node.innerHTML = textContent.replace(/%%br%%/g, "<br />");
					this._contentNode = node;
					this.render();
				}
			};
			wLFMBio.onReadMore =  function (sender, e){
				encodedArtistName = this._currentArtist.replace(/&/g, '%252526').replace(/\//g, '%25252F').replace(/\?/,"%25253F");
			    	LFMArtistBioRessource = {key: "LastFMArtistBio", url: LASTFM_BIO_URL.replace(/%s/, encodedArtistName), save: false};
				RessourceLoader.loadRessource(LFMArtistBioRessource, TYPE_HTML);
			};


			// Widget for Last.fm Abstracts

			/* 
			* Widget for Last.fm Player 
			*/
			wLFMPlayer =  new Widget("LastFMPlayer", LFMArtistPageRessource, TOGGLEABLE);
			wLFMPlayer.prepareRessourceUrl = function (artistname) {
					return this._ressource.url.replace(/%s/, artistname.replace(/&/g, '%2526').replace(/\//g, '%252F').replace(/\?/,"%3F"));
			};
			wLFMPlayer.scraperImpl = function () {
						var lfmPlayerCode = this._content.extract("<div id=\"flashContainer\">", "</div>").extract("<object", "</object>");
						if (lfmPlayerCode !='') {
							var movieUrl = lfmPlayerCode.extractInner("src=\"", "\"\n ");
							var flashVars = lfmPlayerCode.extractInner("FlashVars = \"", "\"\n ");
							return getFlashContainerCode(340, 103, movieUrl + '?flashvars=' + encodeURIComponent(flashVars));
						}
						else return 'n/a';
			};
			// Widget for Last.fm Player

			/* 
			* Widget for Last.fm Tags 
			*/
			LFMTagsWebserviceRessource = {key: "LastFMTagsWebservice", url: LASTFM_TAGS_URL, save: false};
			wLFMTags =  new Widget("LastFMTags", LFMTagsWebserviceRessource, NON_TOGGLEABLE);
			wLFMTags.prepareRessourceUrl = function (artistname) {
					return this._ressource.url.replace(/%s/, artistname.replace(/&/g, '%2526').replace(/\//g, '%252F').replace(/\?/,"%3F"));
			};
			wLFMTags.scraperImpl = function () {
					var parser = new DOMParser();
					result = parser.parseFromString(this._content, "application/xml");
					var entries = result.getElementsByTagName('tag');
					var arr = [];
					for (var i = 0;i < MAX_TAGS && i < entries.length; i++)
						arr.push(entries[i].getElementsByTagName('name')[0].textContent);
					 var text = arr.join(', ') + '';
					 return text;
			};
			// Widget for Last.fm Tags
		
			/* 
			* Widget for Last.fm Similar Artists 
			*/
		
			LFMSimilarWebserviceRessource = {key: "LastFMSimilarWebservice", url: LASTFM_SIMILAR_URL, save: false};
			wLFMSimilar =  new Widget("LastFMSimilar", LFMSimilarWebserviceRessource, TOGGLEABLE);
			wLFMSimilar.prepareRessourceUrl = function (artistname) {
					return this._ressource.url.replace(/%s/, artistname.replace(/&/g, '%2526').replace(/\//g, '%252F').replace(/\?/,"%3F"));
			};
			wLFMSimilar.scraperImpl = function () {
					var parser = new DOMParser();
					result = parser.parseFromString(this._content, "application/xml");
					var entries = result.getElementsByTagName('artist');
					var arr = [];
					for (var i = 0; i < MAX_SIMILAR_ARTISTS && i < entries.length; i++) {
						arr.push(entries[i].getElementsByTagName('name')[0].textContent);
					}
					return arr;
			};
			wLFMSimilar.createNodeFromScrapedContent = function () {
				var node = document.createElement("div");
				for (var i = 0; i < this._scrapedObject.length; i++) {
						var artistname = this._scrapedObject[i];
						var artistlink = document.createElement('a');
						artistlink.innerHTML = artistname;
						artistlink.href= '#';
						artistlink.id = artistname;
						artistlink.addEventListener("click", function (e) { EventNotifier.send("LastFMSimilar", "onArtistChange", {artistname: this.id, albumname: null  }); e.preventDefault();}, false);
						node.appendChild(artistlink);
						node.appendChild(document.createElement("br"));	
					}
				this._contentNode = node;	
			};
			
			// Widget for Last.fm Similar

			/* 
			* Widget for (simple) Browsing History 
			*/
		
			BrowsingHistoryRessource = null;
			wBrowsingHistory =  new Widget("History", BrowsingHistoryRessource, TOGGLEABLE);
			wBrowsingHistory.onArtistChange = function(sender, e) {
				if(sender == "global") {
						this._currentArtist = e.artistname;
						this._state = LOADED;
						this.createNodeFromScrapedContent();
						this.render();
				}
			};
			wBrowsingHistory.createNodeFromScrapedContent = function () {
				// init
				if(this._scrapedObject == null) {
					logmsg('scraped Object null');
					this._scrapedObject = new Array();	
				}
				logmsg('got artist: ' + this._currentArtist);	
				var found = false;
				this._scrapedObject.forEach(function (o) { if (o == this._currentArtist) {found = true;}}, this);
				if (!found)
					this._scrapedObject.push(this._currentArtist);
				var node = document.createElement("div");
				for (var i = 0; i < this._scrapedObject.length; i++) {
						var artistname = this._scrapedObject[i];
						var artistlink = document.createElement('a');
						artistlink.innerHTML = artistname;
						artistlink.href= '#';
						artistlink.id = artistname;
						artistlink.addEventListener("click", function (e) { EventNotifier.send("global", "onArtistChange", {artistname: this.id, albumname: null  }); e.preventDefault();}, false);
						node.appendChild(artistlink);
						node.appendChild(document.createElement("br"));	
					}
				this._contentNode = node;
				this._cachedContent = this._scrapedObject;	
			};
			
			// Widget for Browsing History
			
			/* 
			* Widget for Last.fm Albums
			*/
			/*
			LFMAlbumsWebserviceRessource = {key: "LastFMAlbumsWebservice", url: LASTFM_ALBUMS_URL, save: false};
			wLFMAlbums =  new Widget("LastFMAlbums", LFMAlbumsWebserviceRessource, true);
			wLFMAlbums.prepareRessourceUrl = function (artistname) {
					return this._ressource.url.replace(/%s/, artistname.replace(/&/g, '%2526'));
			};
			wLFMAlbums.scraperImpl = function () {
					var parser = new DOMParser();
					result = parser.parseFromString(this._content, "application/xml");
					var entries = result.getElementsByTagName('album');
					var arr = [];
					for (var i = 0; i < entries.length; i++)
						if (entries[i].getElementsByTagName('mbid')[0].textContent.length > 0)
              arr.push(entries[i].getElementsByTagName('name')[0].textContent);
					 var text = arr.join('<br> ') + '';
					 return text;
			};
			*/
			// Widget for Last.fm Albums
			
			
			/* 
			* Widget for MySpace Player 
			*/
			MSPArtistPageRessource = {key: "MySpaceArtistPage", url: MYSPACE_URL, save: false};
			wMSPPlayer =  new Widget("MySpacePlayer", MSPArtistPageRessource, TOGGLEABLE);
			wMSPPlayer.prepareRessourceUrl = function (artistname) {
					return this._ressource.url.replace(/%s/, artistname.replace(/&/g, '%26').replace(/\?/,"%3F"));
			};
			wMSPPlayer.scraperImpl = function () {
					var mspPlayerCode = this._content.extract("<OBJECT id=\"mp3player", "</OBJECT>").extract("<embed", "</embed>");
					if (mspPlayerCode != ''){
						//disableAutoplay
						mspPlayerCode = mspPlayerCode.replace(/&a=0/g, "&a=1");
						var movieUrl = mspPlayerCode.extractInner("src=\"", "?n=");
						var flashVars = mspPlayerCode.extractInner("?n=", "\"");
						return getFlashContainerCode(450, 345, movieUrl + '?n=' + encodeURIComponent(flashVars));
					}
					else return 'n/a';
			};
			
			wMSPPlayer.onRessourceLoaded = function (sender, e){
			    if (this._ressource != null && e.ressource.key == 'MySpaceArtistPage' && this._currentArtist == e.ressource.artistname) {
				  googleResultPage = e.content.replace(/ target=_blank/,"");
				  var mspUrl = googleResultPage.match(/http\:\/\/(www\.)?myspace.com\/\w+/)[0];
				// Subsequent Ressource
									  if (mspUrl.search(/^http/) >= 0) {
										  MSPPageRessource = {key: "MySpacePage", url: mspUrl, save: false, artistname: e.ressource.artistname};
				  RessourceLoader.loadRessource(MSPPageRessource, TYPE_HTML);
									  } else {
										  this._state = FAILED;
				  this.render();
									  }
			    }
			    if (this._ressource != null &&  e.ressource.key == 'MySpacePage' && this._currentArtist == e.ressource.artistname) {
										  this._state = LOADED;
										  this._content = e.content;
										  this._scrapedObject = this.scraperImpl();
										  //cache.setItem("cache_widget_" + this._name + "_" + this._currentArtist, this._scrapedObject);
										  this.createNodeFromScrapedContent();
										  this.render();
			    }

			};
			// Widget for MySpace Player
		
			/* 
			* Widget for External Links 
			*/
			ExternalLinksRessource = null;
			wExternalLinks =  new Widget("ExternalLinks", ExternalLinksRessource, NON_TOGGLEABLE);
			wExternalLinks.prepareRessourceUrl = function (artistname) {
					// nothing to do
			};
			wExternalLinks.createNodeFromScrapedContent = function () {
					var arr = [];
					var artist = this._currentArtist;
					arr.push(this.getExternalLink(artist, LASTFM_LINK).replace(/%26/g, '%252526').replace(/%2F/g, '%25252F'));
					arr.push(this.getExternalLink(artist, WIKIPEDIA_LINK).replace(/%26/g, '%2526'));
					arr.push(this.getExternalLink(artist, ALLMUSIC_LINK).replace(/%26/g, '%2526'));
					arr.push(this.getExternalLink(artist, FOXYTUNES_LINK).replace(/%2F/g, '%252F').replace(/%26/g, '%2526'));
					arr.push(this.getExternalLink(artist, IMEEM_LINK).replace(/%26/g, '%2526'));
					arr.push(this.getExternalLink(artist.replace(/^(The) (.*)/,'$2, $1'), DISCOGS_LINK).replace(/%26/g, '%2526'));
					arr.push(this.getExternalLink(artist, GOOGLE_LINK).replace(/%26/g, '%2526'));
					arr.push(this.getExternalLink(artist, AMAZON_LINK));
					arr.push(this.getExternalLink(artist, MYSPACE_LINK).replace(/%26/g, '%2526'));
					arr.push(this.getExternalLink(artist, HYPEMACHINE_LINK).replace(/%26/g, '%252526'));
					arr.push(this.getExternalLink(artist, SEEQPOD_LINK).replace(/%26/g, '%252526').replace(/%2F/g, '%252F'));
					arr.push(this.getExternalLink(artist, PANDORA_LINK).replace(/%26/g, '%252526').replace(/%2F/g, '%252F'));
					arr.push(this.getExternalLink(artist, RIAARADAR_LINK).replace(/%26/g, '%252526').replace(/%2F/g, '%252F'));
					arr.push(this.getExternalLink(artist, PUREVOLUME_LINK).replace(/%26/g, '%2526'));
					var node = document.createElement("div");
					node.innerHTML = arr.join(' | ') + '';
					this._contentNode = node;
			};
			
			wExternalLinks.getExternalLink = function (artist, mylink) {
        return mylink.replace(/%s/, encodeURIComponent(artist.replace(/\?/,"%3F")));
      };
			// Widget for External Links

			/* 
			* Widget for Hydra Links 
			*/
			HydraLinksRessource = null;
			wHydraLinks =  new Widget("HydraLinks", HydraLinksRessource, NON_TOGGLEABLE);
			wHydraLinks.prepareRessourceUrl = function (artistname) {
					// nothing to do
			};
			wHydraLinks.createNodeFromScrapedContent = function () {
					var arr = [];
					var artist = this._currentArtist;
					SITES = site_functions;
					for (var sitename in SITES){
						mySITE = SITES[sitename];
						searchurl = mySITE["searchurl"];
						name = mySITE["name"];
						if (searchurl != null) arr.push(this.getExternalLink(artist, searchurl, name));
					}

					var node = document.createElement("div");
					node.innerHTML = '<b>More from </b>' + this._currentArtist + '<b> on:</b><br>';
					node.innerHTML = node.innerHTML + arr.join(' | ') + '';
					this._contentNode = node;
			};
			
			wHydraLinks.getExternalLink = function (artist, mylink, name) {
        return '<a href="' + mylink.replace(/%s/, encodeURIComponent(artist.replace(/\?/,"%3F"))) +'" target="_blank">'+name+'</a>';
      };
			// Widget for HydraLinks

			/* 
			* Widget for Update Notfication 
			*/
			UpdateServiceRessource = {key: "UpdateService", url: RELEASE_INFORMATION_URL, save: false};
			wUpdateNotify =  new Widget("UpdateNotify", UpdateServiceRessource, NON_TOGGLEABLE);
			wUpdateNotify.prepareRessourceUrl = function (artistname) {
					  // avoid caching
						var rnd = Math.random(); 
						return this._ressource.url + "?rnd=" + rnd;
			};
			wUpdateNotify.onArtistChange = function(sender, e) {
					this._state = LOADING;
					this.render();
					this._currentArtist = null;
					var tempRessource = {key: this._ressource.key, url: this._ressource.url, save: this._ressource.save, artistname: null};
					tempRessource.url = this.prepareRessourceUrl(null);
					if ( GM_getValue('latestversion', 0) > VERSION) {
							logmsg('newer latest version available');
							this._state = LOADED;
							this._scrapedObject =  UPDATE_MESSAGE.replace(/%s/, GM_getValue('latestversionurl'));
							this.createNodeFromScrapedContent();
							this.render();
					} 
					else {
							logmsg('no newer vesion available');
							this._state = LOADED;
							this._scrapedObject =  "";
							this.createNodeFromScrapedContent();
							this.render();
					}
					var date = new Date();
					currentTime = Math.round(date.getTime() / (1000 * 60 * 60));
					lastcheckTime = GM_getValue('lastcheck', 0);
					if ((currentTime - lastcheckTime) > UPDATE_INTERVAL_HOURS){ 
						logmsg('loading UpdateNotify Ressource');
						RessourceLoader.loadRessource(tempRessource);
						GM_setValue('lastcheck',currentTime);
					}
					logmsg('cT: ' + currentTime);
					logmsg('lastcT: ' + lastcheckTime);
					logmsg((currentTime - lastcheckTime) + " > " + UPDATE_INTERVAL_HOURS);
			};
			wUpdateNotify.scraperImpl = function () {
						var parser = new DOMParser();
						result = parser.parseFromString(this._content, "application/xml");
						var date = new Date();
						currentTime = Math.round(date.getTime() / (1000 * 60 * 60));
						GM_setValue('lastcheck',currentTime);
						var releases = result.getElementsByTagName('release');
						var latest_version = releases[0].getAttribute('version');
						var latest_version_url = releases[0].getElementsByTagName('url')[0].textContent;
						GM_setValue('latestversion', latest_version);
						GM_setValue('latestversionurl', latest_version_url);
						logmsg('latesversion: ' + latest_version);
						if ( latest_version > VERSION) {
							logmsg('received information of newer version');
							return UPDATE_MESSAGE.replace(/%s/, GM_getValue('latestversionurl'));
						}
						logmsg('received information of up to date version');
						return "";
			};
			// Widget for Update Notification
			
	}
	
	// helper functions
	
	function $() {
		var elements = new Array();
		for (var i = 0; i < arguments.length; i++) {
			var element = arguments[i];
			if (typeof element == 'string')
				element = document.getElementById(element);
			if (arguments.length == 1)
				return element;
			elements.push(element);
		}
		return elements;
	}
	

  function basicClean(myString) {
       
				do {
					oldstring = myString;
					//var regexp0=new RegExp("<(object)[^>]*>.*<\/(object)>","i");
					var regexp0=new RegExp("<script[^>]*>[^<]*<\/script>","gi");
					var regexp1=new RegExp("<span class=\"wiki_continued\".*","i");
					var regexp2=new RegExp("<object[^>]*>.*<\/object>","i");
					//var regexp1=new RegExp("<(span).*?<\/(span)>","i");
					//regexp2 = new RegExp('<script.*?.*?</script>',"gi");
					//myString = myString.replace(regexp0,"");
					myString = myString.replace(regexp0,"");
					myString = myString.replace(regexp1,"");
					//myString = myString.replace(regexp1,"");
					myString = myString.replace(regexp2,"");
				} while (oldstring != myString);
        return myString;
   }
   

	function translateToBinaryString(text){
		var out='';
		for(i=0;i<text.length;i++){
			//*bugfix* by Marcus Granado 2006 [http://mgran.blogspot.com] adapted by Thomas Belot
			out+=String.fromCharCode(text.charCodeAt(i) & 0xff);
		}
		return out;
	}
	
	function buildDataScheme(responseText, dataScheme){
		//translating the text to a valid binary stream
		var stream = translateToBinaryString(responseText);
		//translating the binaryStream to Base64
		dataScheme+=window.btoa(stream);
		return dataScheme
	}
	
	// aaBBBcccDDDee.extract('BB','DD') returns BBBcccDD
	String.prototype.extract = function(startString, endString){
		var start = this.indexOf(startString);
		if (start == -1) {
			return '';
		}
		var choppedContent = this.substr(start);
		var end = choppedContent.indexOf(endString, startString.length);
		if (end == -1) {
			return '';
		}
		var extractedContent = choppedContent.substring(0, end+endString.length);	
		if (extractedContent.length > 0) return extractedContent
		else return '';
	}
	
	// aaBBBcccDDDee.extractInner('BB','DD') returns Bccc
	String.prototype.extractInner = function(startString, endString){
		var outerContent = this.extract(startString, endString);
		if (outerContent != '')
      var innerContent = outerContent.substring(startString.length, outerContent.length-endString.length);
		else return '';		
		return innerContent;
	}
	
	function getFlashContainerCode(width, height, movieUrl){
		return FLASH_CONTAINER.replace('%WIDTH', width).replace('%HEIGHT', height).replace('%MOVIE', movieUrl);
	}
	
	// Platypus functions and other html modification functions
	
	function notifyUpdate(){
		$("updatenotify").innerHTML = UPDATE_MESSAGE.replace(/%s/, GM_getValue('latestversionurl'));;
	}
	
	function modify_single_url(doc, match_re, replace_string, node) {
		if (node.href) 
			node.href = node.href.replace(match_re, replace_string);
	}
	
	function do_modify_url_it(doc, node, match_re, replace_string, global_flag) {
		match_re = new RegExp(match_re);
		if (global_flag) {
			var allurls = doc.getElementsByTagName('A');
			for(var i = 0, url; url = allurls[i]; i++)
			modify_single_url(doc, match_re, replace_string, url);
		} 
		else modify_single_url(doc, match_re, replace_string, node);
	}
	
	function insertAfter(newNode, target) {
		var parent = target.parentNode;
		var refChild = target.nextSibling;
		if(refChild != null)
			parent.insertBefore(newNode, refChild);
		else parent.appendChild(newNode);
	}
	
	function find_table(){
		var tds = document.getElementsByTagName("td");
		for (var i = 0; i < tds.length; i++)
			if (tds[i].className == "rowhead")
				return tds[i].parentNode.parentNode;
	}
	
	function find_it(doc, node, match_re, replace_string) {
		match_re = new RegExp(match_re);
		if( node != null) 
			return node.innerHTML.replace(match_re, replace_string);
		else return null;
	}
	
	function addGlobalStyle(css) {
		var head, style;
		head = document.getElementsByTagName('head')[0];
		if (!head) 
			return;
		style = document.createElement('style');
		style.type = 'text/css';
		style.innerHTML = css;
		head.appendChild(style);
	}
	

	var DEBUG = false;
	function logmsg(message) {
		if (DEBUG) {
			console.log(message);
		}
	}
	
	function findMatchingSite(){
		SITES = site_functions;
		for (var sitename in SITES){
					logmsg(sitename);
					mySITE = SITES[sitename];
					url_res = mySITE["url"];
					var found = false;
					for (var elemI in url_res){
						var site_url_re = new RegExp(url_res[elemI]);							
						if ( location.href.match(site_url_re))	{
							logmsg(mySITE["name"] + " matched.");
							find_artist_name = new Function(mySITE["findArtist"]);
							logmsg(find_artist_name());
							MORE_LINK = mySITE["morelink"];
							logmsg("More link: " + MORE_LINK); 
							hook = new Function(mySITE["hook"]);
							isAudioRelease = new Function(mySITE["isAudioRelease"]);
							if (isAudioRelease()) {
								logmsg("This is an Audio release.");
								hook();
								logmsg("Hook installed");
								addGlobalStyle(CSS_CODE);
								addGlobalStyle(mySITE["css"]);
								artist = find_artist_name();
								if (artist != null) artist = artist.replace(/&amp;/,"&");	
								if (artist == null || artist.toLowerCase().indexOf('various') > -1 || artist.match(new RegExp("^VA.*"))) {
									logmsg('no artist to process');
									artist = null;
									addWidgets(artist);
									// TODO
									$("ArtistTitle").innerHTML = "<b>Sorry, the artist name could not be parsed.<br>However, you can still use the search box to the right.</b>";
									return;
								}
								addWidgets(artist);
								a(artist);
								break;
							}
							else logmsg("This is not an audio release.");
							found = true;
							break;
						}	
					}
					if (!found) logmsg(mySITE["name"] + " didn't match.");
		}			
	}	

	// here we go
	function do_it_baby() {
		//console.log('do it baby');
		/*
		artist = find_artist_name();	
		if (artist == null || artist == "Various Artists") return;
		//console.log('found artist: ' + artist);
		addGlobalStyle(CSS_CODE);
		centertable = find_table();
		//console.log('here am i');
		appendTableRow(window.document,centertable.lastChild.previousSibling);
		
		//check_for_new_version_init();
		addWidgets(artist);
		a(artist);
		*/
		//check_for_new_version_init();
		findMatchingSite();
		
	}
	
	do_it_baby();
	

	
	
} // main()

var Library = {
	libraries: new Array(),
	index: 0,
	callback: "",
	addLibrary: function(key, url, save) {
		save = save==false?false:true;
		this.libraries.push({key: key, url: url, save: save});
	},
	load: function(callback) {
		this.callback = callback;
		this.loadLibrary(this.libraries[this.index++]);	
	},
	loadNext: function() {
		if(this.index < this.libraries.length) this.loadLibrary(this.libraries[this.index++]);
		else this.callback();
	},
	loadLibrary: function(lib) {
		if(!GM_getValue("library_"+lib.url, "")) {
			GM_xmlhttpRequest({
				method:	'GET',
				url:	lib.url,
				onload:	function(data) {
						if(lib.save) GM_setValue("library_"+lib.url,  data.responseText );
						Library.evalLibrary(lib, data.responseText );
					}
			});
		} else {
			Library.evalLibrary(lib, GM_getValue("library_"+lib.url));
		}
	},
	evalLibrary: function(lib, data) {
			var script = document.createElement('script');
			script.appendChild(document.createTextNode(data));
			document.getElementsByTagName('head')[0].appendChild(script);
		this.loadNext();
	}
}

function libraryLoad() {
	//Library.addLibrary("Prototype", "http://www.naptoon.com/oinkplus/libraries/prototype-1.4.0.oinkplus.js", false);
	//Library.addLibrary("Include", "http://www.naptoon.com/oinkplus/libraries/oinkplus.inc.ver3.js", false);
	//Library.load(main);
}

// add event for loading libraries and invoking main()
//window.addEventListener('load', function(){libraryLoad();}, false);
main();

})();

// here be monsters
//.user.js