/*CSS Browser Selector v0.3.5 (Feb 05, 2010)Rafael Lima (http://rafael.adm.br)http://rafael.adm.br/css_browser_selectorLicense: http://creativecommons.org/licenses/by/2.5/Contributors: http://rafael.adm.br/css_browser_selector#contributors*/function css_browser_selector(u){var ua = u.toLowerCase(),is=function(t){return ua.indexOf(t)>-1;},g='gecko',w='webkit',s='safari',o='opera',h=document.documentElement,b=[(!(/opera|webtv/i.test(ua))&&/msie\s(\d)/.test(ua))?('ie ie'+RegExp.$1):is('firefox/2')?g+' ff2':is('firefox/3.5')?g+' ff3 ff3_5':is('firefox/3')?g+' ff3':is('gecko/')?g:is('opera')?o+(/version\/(\d+)/.test(ua)?' '+o+RegExp.$1:(/opera(\s|\/)(\d+)/.test(ua)?' '+o+RegExp.$2:'')):is('konqueror')?'konqueror':is('chrome')?w+' chrome':is('iron')?w+' iron':is('applewebkit/')?w+' '+s+(/version\/(\d+)/.test(ua)?' '+s+RegExp.$1:''):is('mozilla/')?g:'',is('j2me')?'mobile':is('iphone')?'iphone':is('ipod')?'ipod':is('mac')?'mac':is('darwin')?'mac':is('webtv')?'webtv':is('win')?'win':is('freebsd')?'freebsd':(is('x11')||is('linux'))?'linux':'','js']; c = b.join(' '); h.className += ' '+c; return c;}; css_browser_selector(navigator.userAgent);/*SUPERNOTE v1.0beta (c) 2005-2006 Angus Turnbull, http://www.twinhelix.comAltering this notice or redistributing this file is prohibited.*/// Common event handler API code.if (typeof addEvent != 'function'){ var addEvent = function(o, t, f, l) {  var d = 'addEventListener', n = 'on' + t, rO = o, rT = t, rF = f, rL = l;  if (o[d] && !l) return o[d](t, f, false);  if (!o._evts) o._evts = {};  if (!o._evts[t])  {   o._evts[t] = o[n] ? { b: o[n] } : {};   o[n] = new Function('e',    'var r = true, o = this, a = o._evts["' + t + '"], i; for (i in a) {' +     'o._f = a[i]; r = o._f(e||window.event) != false && r; o._f = null;' +     '} return r');   if (t != 'unload') addEvent(window, 'unload', function() {    removeEvent(rO, rT, rF, rL);   });  }  if (!f._i) f._i = addEvent._i++;  o._evts[t][f._i] = f; }; addEvent._i = 1; var removeEvent = function(o, t, f, l) {  var d = 'removeEventListener';  if (o[d] && !l) return o[d](t, f, false);  if (o._evts && o._evts[t] && f._i) delete o._evts[t][f._i]; };}function cancelEvent(e, c){ e.returnValue = false; if (e.preventDefault) e.preventDefault(); if (c) {  e.cancelBubble = true;  if (e.stopPropagation) e.stopPropagation(); }};// *** MAIN OBJECT CLASS ***function SuperNote(myName, config){ var defaults = {  myName: myName,        // Names used for notes of this class.  allowNesting: false,   // Whether to allow triggers within triggers.  cssProp: 'visibility', // CSS property used to show/hide notes and values.  cssVis: 'inherit',  cssHid: 'hidden',  IESelectBoxFix: true,  // Enables the IFRAME select-box-covering fix.  showDelay: 0,          // Millisecond delays.  hideDelay: 0,  animInSpeed: 1.0,           // Animation speed, from 0.0 to 1.0; 1.0 disables.  animOutSpeed: 1.0,  animations: [],        // Array of animation plugins.  mouseX: 0, mouseY: 0,  // Live mouse co-ords.  notes: {},             // Store for note timers/references.  rootElm: null,         // The outermost element, handles mouse events.  onshow: null,          // Events you can capture. Passed the note ID.  onhide: null }; for (var p in defaults)  this[p] = (typeof config[p] == 'undefined') ? defaults[p] : config[p]; // Capture mouse events on the entire document. var obj = this; addEvent(document, 'mouseover', function(evt) { obj.mouseHandler(evt, 1) } ); addEvent(document, 'click', function(evt) { obj.mouseHandler(evt, 2) } ); addEvent(document, 'mousemove', function(evt) { obj.mouseTrack(evt) } ); addEvent(document, 'mouseout', function(evt) { obj.mouseHandler(evt, 0) } ); // Record this instance in our 'instances' array (for setTimeouts). this.instance = SuperNote.instances.length; SuperNote.instances[this.instance] = this;}// Collection of all objects created.SuperNote.instances = [];// A list of note behaviour and positioning type handlers.SuperNote.prototype.bTypes = {};SuperNote.prototype.pTypes = {};// *** DEFAULT TYPE HANDLERS ***// Handlers are called as the note's state changes. They are passed:// 1) An object reference to this SuperNote object.// 2) The ID of the note in question.// 3) The proposed next 'visible' flag of the note.// 4) The proposed next 'animating' flag of the note ("positional" only).//// There are two types: "pTypes" are positional handlers, "bTypes" behavioural.// Use positional handlers to perform actions when notes show/hide.// Use behavioural handlers to cancel default actions; they're called when// notes are about to animate, and can "return false" to cancel it.//// Your might find it handy to set notes[noteID].ref.style.left and .top to// position the note. Also, checkWinX/Y() are functions accepting a note// reference and proposed position that modify the position so the note will// display within the borders of the current browser window.SuperNote.prototype.pTypes.mouseoffset = function(obj, noteID, nextVis, nextAnim) { with (obj){ // Position on first show, and respect both shows and hides. var note = notes[noteID]; if (nextVis && !note.animating && !note.visible) {  note.ref.style.left = checkWinX(mouseX, note) + 'px';  note.ref.style.top = checkWinY(mouseY, note) + 'px'; }}};SuperNote.prototype.pTypes.mousetrack = function(obj, noteID, nextVis, nextAnim) { with (obj){ // Position every few milliseconds the entire time it's visible. var note = notes[noteID]; if (nextVis && !note.animating && !note.visible) {  var posString = 'with (' + myName + ') {' +   'var note = notes["' + noteID + '"];' +   'note.ref.style.left = checkWinX(mouseX, note) + "px";' +   'note.ref.style.top = checkWinY(mouseY, note) + "px" }';  eval(posString);  obj.IEFrameFix(noteID, 1);  if (!note.trackTimer) note.trackTimer = setInterval(posString, 50); } else if (!nextVis && !nextAnim) {  clearInterval(note.trackTimer);  note.trackTimer = null; }}};SuperNote.prototype.pTypes.triggeroffset = function(obj, noteID, nextVis, nextAnim) { with (obj){ // Find the trigger position and offset the note from that. var note = notes[noteID]; if (nextVis && !note.animating && !note.visible) {  var x = 0, y = 0, elm = note.trigRef;  while (elm)  {   x += elm.offsetLeft;   y += elm.offsetTop;   elm = elm.offsetParent;  }  note.ref.style.left = checkWinX(x, note) + 'px';  note.ref.style.top = checkWinY(y, note) + 'px'; }}};SuperNote.prototype.bTypes.pinned = function(obj, noteID, nextVis) { with (obj){ // Ignore hide requests. return (!nextVis) ? false : true;}};// *** OBJECT METHODS ***SuperNote.prototype.docBody = function(){ return document[(document.compatMode &&  document.compatMode.indexOf('CSS') > -1) ? 'documentElement' : 'body'];};SuperNote.prototype.getWinW = function(){ return this.docBody().clientWidth || window.innerWidth || 0;};SuperNote.prototype.getWinH = function(){ return this.docBody().clientHeight || window.innerHeight || 0;};SuperNote.prototype.getScrX = function(){ return this.docBody().scrollLeft || window.scrollX || 0;};SuperNote.prototype.getScrY = function(){ return this.docBody().scrollTop || window.scrollY || 0;};SuperNote.prototype.checkWinX = function(newX, note) { with (this){ // Takes a note and a proposed X position, and modifies the position so that // the note will fit within the border of the visible browser window. return Math.max(getScrX(), Math.min(newX, getScrX() + getWinW() - note.ref.offsetWidth - 8));}};SuperNote.prototype.checkWinY = function(newY, note) { with (this){ return Math.max(getScrY(), Math.min(newY, getScrY() + getWinH() - note.ref.offsetHeight - 8));}};SuperNote.prototype.mouseTrack = function(evt) { with (this){ // Stores the mouse coordinates as it moves. mouseX = evt.pageX || evt.clientX + getScrX() || 0; mouseY = evt.pageY || evt.clientY + getScrY() || 0;}};SuperNote.prototype.mouseHandler = function(evt, show) { with (this){ // This is called from an onmouseover/click/mouseout handler in the document. // show: 0 = mouseout, 1 = mouseover, 2 = click. // It loops up the DOM from the event source, initialises element references, // and forwards the event to display() for processing. if (!document.documentElement) return true; var srcElm = evt.target || evt.srcElement,  // Match CLASS="objectname-hover-foobar" or "objectname-click-foobar".  trigRE = new RegExp(myName + '-(hover|click)-([a-z0-9]+)', 'i'),  // Match ID="objectname-target-foobar"  targRE = new RegExp(myName + '-(note)-([a-z0-9]+)', 'i'),  // Whether to repsect a found trigger or not (for nesting triggers).  trigFind = 1,  // A list of found notes in the current DOM tree.  foundNotes = {}; if (srcElm.nodeType != 1) srcElm = srcElm.parentNode; var elm = srcElm; while (elm && elm != rootElm) {  // Match our regexes, and keep going upwards to detect nested notes!  if (targRE.test(elm.id) || (trigFind && trigRE.test(elm.className)))  {   if (!allowNesting) trigFind = 0;   var click = RegExp.$1 == 'click' ? 1 : 0,    noteID = RegExp.$2,    ref = document.getElementById(myName + '-note-' + noteID),    trigRef = trigRE.test(elm.className) ? elm : null;   // If the target exists...   if (ref)   {    // Init data store, keyed on the last part of the tag class/id.    if (!notes[noteID])    {     notes[noteID] = {      click: click,      ref: ref,      trigRef : null,      visible: 0,      animating: 0,      timer: null     };     // Also store references in the note DOM object.     ref._sn_obj = this;     ref._sn_id = noteID;    }    var note = notes[noteID];    // Add to our list of found notes on this loop up the DOM.    // Don't "find" clicks on triggers; they're 'outside' clicks, hiding note.    if (!note.click || (trigRef != srcElm)) foundNotes[noteID] = true;    // Show/hide hover notes, and show onclick notes.    if (!note.click || (show == 2))    {     // If this is a trigger, record this as the note's current trigger.     // Also record the trigger reference on the note DOM object for looping.     if (trigRef)      notes[noteID].trigRef = notes[noteID].ref._sn_trig = elm;     // Now call display() to show/record it, if its visibility has changed.     display(noteID, show);     // Click notes: avoid navigating the entire document :).     if (note.click && (srcElm == trigRef)) cancelEvent(evt);    }   }  }  // Otherwise check the next element up the DOM.  if (elm._sn_trig)  {   // If this is a note target, recurse to its original trigger and allow   // further triggers to be found and activated.   trigFind = 1;   elm = elm._sn_trig;  }  else  {   elm = elm.parentNode;  } } // Now we've finished looping up the DOM, do a final loop through our list // of notes, checking to see if any onclick notes need hiding. if (show == 2) for (var n in notes) {  if (notes[n].click && notes[n].visible && !foundNotes[n]) display(n, 0); }}};SuperNote.prototype.display = function(noteID, show) { with (this){ // Called to manage show/hide timers for a specified target. with (notes[noteID]) {  // Clear any existing timeout.  clearTimeout(timer);  // Check that this note isn't already performing the desired action.  if (!animating || (show ? !visible : visible))  {   // If we're currently animating, use a short timeout.   // Otherwise revert to the standard show/hide timeout.   var tmt = animating ? 1 : (show ? showDelay||1 : hideDelay||1);   timer = setTimeout('SuperNote.instances[' + instance + '].setVis("' +    noteID + '", ' + show + ', false)', tmt);  } }}};SuperNote.prototype.checkType = function(noteID, nextVis, nextAnim) { with (this){ // Processes the two 'types' for each note and returns the results. // The behavioural type is called when about to animate; it can "return false" // to cancel the pending action. // The positioning type is always called whenever an action succeeds. var note = notes[noteID], bType, pType; if ((/snp-([a-z]+)/).test(note.ref.className)) pType = RegExp.$1; if ((/snb-([a-z]+)/).test(note.ref.className)) bType = RegExp.$1; if (nextAnim && bType && bTypes[bType] &&  (bTypes[bType](this, noteID, nextVis) == false)) return false; if (pType && pTypes[pType]) pTypes[pType](this, noteID, nextVis, nextAnim); return true;}};SuperNote.prototype.setVis = function(noteID, show, now) { with (this){ // Called from display() above; sets the note visibility, // calls the type handler function, and calls animate() below. // Pass 'now' in order to show/hide immediately (skips animation). var note = notes[noteID]; if (note && checkType(noteID, show, 1) || now) {  note.visible = show;  note.animating = 1;  animate(noteID, show, now); }}};SuperNote.prototype.animate = function(noteID, show, now) { with (this){ // Repeatedly called to animate a note in and out (if applicable). var note = notes[noteID]; if (!note.animTimer) note.animTimer = 0; if (!note.animC) note.animC = 0; with (note) {  clearTimeout(animTimer);  var speed = (animations.length && !now) ? (show ? animInSpeed : animOutSpeed) : 1;  if (show && !animC)  {   if (onshow) this.onshow(noteID);   IEFrameFix(noteID, 1);   ref.style[cssProp] = cssVis;  }  animC = Math.max(0, Math.min(1, animC + speed * (show ? 1 : -1)));  if (document.getElementById && speed < 1)   for (var a = 0; a < animations.length; a++) animations[a](ref, animC);  if (!show && !animC)  {   if (onhide) this.onhide(noteID);   IEFrameFix(noteID, 0);   ref.style[cssProp] = cssHid;  }  if (animC != parseInt(animC))  {   animTimer = setTimeout(myName + '.animate("' +    noteID + '", ' + show + ')', 50);  }  else  {   checkType(noteID, animC ? 1 : 0, 0);   note.animating = 0;  } }}};SuperNote.prototype.IEFrameFix = function(noteID, show) { with (this){ // Positions a hidden IFRAME under a note to allow it to cross over <select> // boxes in MSIE.  if (!window.createPopup || !IESelectBoxFix) return;  var note = notes[noteID], ifr = note.iframe;  if (!ifr)  {   ifr = notes[noteID].iframe = document.createElement('iframe');   ifr.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)';   ifr.style.position = 'absolute';   ifr.style.borderWidth = '0';   note.ref.parentNode.insertBefore(ifr, note.ref.parentNode.firstChild);  }  if (show)  {   ifr.style.left = note.ref.offsetLeft + 'px';   ifr.style.top = note.ref.offsetTop + 'px';   ifr.style.width = note.ref.offsetWidth + 'px';   ifr.style.height = note.ref.offsetHeight + 'px';   ifr.style.visibility = 'inherit';  }  else  {   ifr.style.visibility = 'hidden';  }}};function sprite(div_id, height){var div_el = document.getElementById(div_id);div_el.style.backgroundPosition = '0 ' + height;}
