Index: gs3-extensions/overlay-notes/trunk/src/BrowserDetect.js
===================================================================
--- gs3-extensions/overlay-notes/trunk/src/BrowserDetect.js	(revision 26826)
+++ gs3-extensions/overlay-notes/trunk/src/BrowserDetect.js	(revision 26826)
@@ -0,0 +1,116 @@
+var BrowserDetect = {
+	init: function () {
+		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
+		this.version = this.searchVersion(navigator.userAgent)
+			|| this.searchVersion(navigator.appVersion)
+			|| "an unknown version";
+		this.OS = this.searchString(this.dataOS) || "an unknown OS";
+	},
+	searchString: function (data) {
+		for (var i=0;i<data.length;i++)	{
+			var dataString = data[i].string;
+			var dataProp = data[i].prop;
+			this.versionSearchString = data[i].versionSearch || data[i].identity;
+			if (dataString) {
+				if (dataString.indexOf(data[i].subString) != -1)
+					return data[i].identity;
+			}
+			else if (dataProp)
+				return data[i].identity;
+		}
+	},
+	searchVersion: function (dataString) {
+		var index = dataString.indexOf(this.versionSearchString);
+		if (index == -1) return;
+		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
+	},
+	dataBrowser: [
+		{
+			string: navigator.userAgent,
+			subString: "Chrome",
+			identity: "Chrome"
+		},
+		{ 	string: navigator.userAgent,
+			subString: "OmniWeb",
+			versionSearch: "OmniWeb/",
+			identity: "OmniWeb"
+		},
+		{
+			string: navigator.vendor,
+			subString: "Apple",
+			identity: "Safari",
+			versionSearch: "Version"
+		},
+		{
+			prop: window.opera,
+			identity: "Opera"
+		},
+		{
+			string: navigator.vendor,
+			subString: "iCab",
+			identity: "iCab"
+		},
+		{
+			string: navigator.vendor,
+			subString: "KDE",
+			identity: "Konqueror"
+		},
+		{
+			string: navigator.userAgent,
+			subString: "Firefox",
+			identity: "Firefox"
+		},
+		{
+			string: navigator.vendor,
+			subString: "Camino",
+			identity: "Camino"
+		},
+		{		// for newer Netscapes (6+)
+			string: navigator.userAgent,
+			subString: "Netscape",
+			identity: "Netscape"
+		},
+		{
+			string: navigator.userAgent,
+			subString: "MSIE",
+			identity: "Explorer",
+			versionSearch: "MSIE"
+		},
+		{
+			string: navigator.userAgent,
+			subString: "Gecko",
+			identity: "Mozilla",
+			versionSearch: "rv"
+		},
+		{ 		// for older Netscapes (4-)
+			string: navigator.userAgent,
+			subString: "Mozilla",
+			identity: "Netscape",
+			versionSearch: "Mozilla"
+		}
+	],
+	dataOS : [
+		{
+			string: navigator.platform,
+			subString: "Win",
+			identity: "Windows"
+		},
+		{
+			string: navigator.platform,
+			subString: "Mac",
+			identity: "Mac"
+		},
+		{
+			   string: navigator.userAgent,
+			   subString: "iPhone",
+			   identity: "iPhone/iPod"
+	    },
+		{
+			string: navigator.platform,
+			subString: "Linux",
+			identity: "Linux"
+		}
+	]
+
+};
+BrowserDetect.init();
Index: gs3-extensions/overlay-notes/trunk/src/PhotoNotes-1.5.css
===================================================================
--- gs3-extensions/overlay-notes/trunk/src/PhotoNotes-1.5.css	(revision 26826)
+++ gs3-extensions/overlay-notes/trunk/src/PhotoNotes-1.5.css	(revision 26826)
@@ -0,0 +1,193 @@
+
+body {
+}
+
+/*
+The overall container: always has class="fn-container", and also one of:
+container-inactive container-active
+*/
+
+.fn-container {
+ position: relative;
+}
+
+.fn-container img {
+ border-width: 0;
+}
+
+.fn-area 
+{
+	position: absolute;
+	border:none;
+	border: 0px solid #D4D82D;
+	margin:1px;
+}
+
+.fn-area-blackborder
+{
+	border: 1px solid #000;
+	opacity: 0.40;
+	filter:alpha(opacity=40);
+}
+
+.fn-area-whiteborder
+{
+	border: 1px solid #FFF;	
+	opacity: 0.40;
+	filter:alpha(opacity=40);
+}
+
+
+
+.fn-area-inner
+{
+	border: 1px solid #000000;
+	background-color:#FFF;
+	filter:alpha(opacity=0);
+	opacity:0;
+	cursor: pointer;
+}
+
+.fn-note 
+{
+	position: absolute;
+	//max-width: 200px;
+	padding: 3px;
+	display:none;
+	cursor:default;
+	z-index:5000;
+}
+
+.fn-note-text
+{
+	font: 12px Arial,Helvetica,sans-serif;
+	background-color: rgba(243,243,243,0.5);
+	border: 1px solid #000000;
+	padding: 3px;
+	-moz-border-radius: 3px; /* Non-standard */
+}
+
+.fn-note-edit-text
+{
+	background-color: rgba(243,243,243,0.5);
+	border: 1px solid #000000;
+	padding: 5px;
+	-moz-border-radius: 3px; /* Non-standard */
+}
+.fn-note-edit
+{
+	display:none;
+}
+
+.fn-note-edit TEXTAREA
+{
+	background-color: rgba(243,243,243,0.5);
+	border:0;
+	overflow:visible;
+	margin-bottom:10px;
+	padding:0;
+	width:100%;
+	font-size: 10pt;
+	margin:0;
+}
+
+
+
+
+
+.Butt 
+{
+background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAEiCAYAAAD0w4JOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTgzMTc5QkE0NEQ0MTFFMDg0NThDMTEyQTJBNDEwMkUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTgzMTc5QkI0NEQ0MTFFMDg0NThDMTEyQTJBNDEwMkUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0QTgyRjZDRDQ0RDMxMUUwODQ1OEMxMTJBMkE0MTAyRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0QTgyRjZDRTQ0RDMxMUUwODQ1OEMxMTJBMkE0MTAyRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvMEaMUAAA9eSURBVHja7JsJVBRX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');
+	background-repeat:no-repeat;
+	background-position: 0 -120px;
+	background-color:#3865F9;
+	background-image:-moz-linear-gradient(-90deg, #7691FB, #5075FB 50%, #3865F9 50%, #3665FA);
+	font: 14px Georgia,Serif; 
+	color: #363636;
+	height: 15px;
+	margin-top:-7px;
+	padding-left:20px;
+}
+.CancelButt 
+{ 
+	color: #000000; 
+	background: #d9d9d5; 
+	border-top-width: 1px; 
+	border-right-width: 1px; 
+	border-bottom-width: 1px; 
+	border-left-width: 1px; 
+	border-top-style: solid; 
+	border-right-style: solid; 
+	border-bottom-style: solid; 
+	border-left-style: solid; 
+	border-top-color: #fff; 
+	border-right-color: #b6aeb3; 
+	border-bottom-color: #b6aeb3; 
+	border-left-color: #fff; 
+	font: 12px Arial, Helvetica, sans-serif; 
+
+	margin-right:4px;	
+}
+.DeleteButt { color: #000000; background: #DCE0E6; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #F5F6F7; border-right-color: #BFB7BC; border-bottom-color: #BFB7BC; border-left-color: #F5F6F7; font: 12px Arial, Helvetica, sans-serif; }
+
+
+
+/* Note drag/resize UI */
+
+.dragresize {
+ position: absolute;
+ width: 5px;
+ height: 5px;
+ font-size: 1px;
+ background: white;
+ border: 1px solid black;
+}
+
+.dragresize-tl {
+ top: -8px;
+ left: -8px;
+ cursor: nw-resize;
+}
+.dragresize-tm {
+ top: -8px;
+ left: 50%;
+ margin-left: -4px;
+ cursor: n-resize;
+}
+.dragresize-tr {
+ top: -8px;
+ right: -8px;
+ cursor: ne-resize;
+}
+
+.dragresize-ml {
+ top: 50%;
+ margin-top: -4px;
+ left: -8px;
+ cursor: w-resize;
+}
+.dragresize-mr {
+ top: 50%;
+ margin-top: -4px;
+ right: -8px;
+ cursor: e-resize;
+}
+
+.dragresize-bl {
+ bottom: -8px;
+ left: -8px;
+ cursor: sw-resize;
+}
+.dragresize-bm {
+ bottom: -8px;
+ left: 50%;
+ margin-left: -4px;
+ cursor: s-resize;
+}
+.dragresize-br {
+ bottom: -8px;
+ right: -8px;
+ cursor: se-resize;
+}
+
+
Index: gs3-extensions/overlay-notes/trunk/src/PhotoNotes-1.5.js
===================================================================
--- gs3-extensions/overlay-notes/trunk/src/PhotoNotes-1.5.js	(revision 26826)
+++ gs3-extensions/overlay-notes/trunk/src/PhotoNotes-1.5.js	(revision 26826)
@@ -0,0 +1,944 @@
+/*
+Copyright (c) 2006 Dusty Davidson - http://www.dustyd.net
+(portions Copyright (c) 2005 Angus Turnbull http://www.twinhelix.come)
+
+Permission is hereby granted, free of charge, to any person obtaining 
+a copy of this software and associated documentation files (the "Software"), 
+to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+and/or sell copies of the Software, and to permit persons to whom the Software 
+is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in 
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+
+
+/*********************************************************/
+/*** Photo Notes Container *******************************/
+/*********************************************************/
+
+// Modified version derived from:
+//  http://www.takaitra.com/files/photonotes-1.5.zip
+//
+
+function PhotoNoteContainer(id, config)
+{
+    var element = document.getElementById(id);
+
+    var props = {
+	id: id,
+        element: element,
+        dragresize: null,
+        notes: new Array(),
+        editing: false
+    };
+
+    for (var p in props)
+    {
+        this[p] = (!config || typeof config[p] == 'undefined') ? props[p] : config[p];
+    }
+        
+};
+
+PhotoNoteContainer.prototype.DeleteNote = function(note)
+{
+    note.UnSelect();
+
+    /* remove from the DOM */
+    this.element.removeChild(note.gui.ElementRect);
+    this.element.removeChild(note.gui.ElementNote);
+    
+    /* remove from the array... */
+    //this.notes.remove2(note);
+    removeFromArray(this.notes,note);
+}
+
+PhotoNoteContainer.prototype.AddNote = function(note)
+{
+    if(!this.editing)
+    {
+        /* add the note to the array of notes, and set its container */
+        this.notes[this.notes.length] = note;
+        note.container = this;
+
+        /* add the note to the DOM */
+        this.element.appendChild(note.gui.ElementRect);
+        this.element.appendChild(note.gui.ElementNote);    
+    }
+};
+
+/* hide all of the "text" parts of the notes. Primarily called when hovering a note, at which
+    point we want to hide all of the other note texts */
+PhotoNoteContainer.prototype.HideAllNoteTexts = function()
+{
+    for (var i = 0;i<this.notes.length;i++)
+        this.notes[i].HideNoteText();
+};
+
+
+PhotoNoteContainer.prototype.DisableAllNotes = function()
+{
+    for (var i = 0;i<this.notes.length;i++)
+        this.notes[i].DisableNote();
+};
+
+PhotoNoteContainer.prototype.HideAllNotes = function()
+{
+    for (var i = 0;i<this.notes.length;i++)
+        this.notes[i].HideNote();
+};
+
+PhotoNoteContainer.prototype.ShowAllNotes = function()
+{
+    for (var i = 0;i<this.notes.length;i++)
+        this.notes[i].ShowNote();
+};
+
+PhotoNoteContainer.prototype.EnableAllNotes = function()
+{
+    for (var i = 0;i<this.notes.length;i++)
+        this.notes[i].EnableNote();
+};
+
+/*** Photo Note ******************************************/
+
+function PhotoNote(text,containerId,id,rect)
+{
+    var props = {
+        text: text,                 
+	containerId: containerId,
+        id: id,
+        rect: rect,                    
+        selected: false,
+        container: null,
+        dragresize: null,
+        oldRect: null,
+        YOffset: 10,
+        XOffset: 0,
+        onsave: null,
+        ondelete: null,
+        gui: null                  
+        
+    };
+
+    for (var p in props)
+    {
+        this[p] = props[p];
+    }
+    
+    this.CreateElements();
+}
+
+PhotoNote.prototype.Select = function()
+{
+    //window.status = 'container: ' + this.container;
+    if(!this.container.editing)
+    {
+        this.ShowNoteText();
+        this.dragresize.select(this.gui.ElementRect);
+        this.selected = true;
+        this.SetEditable(true);
+    }    
+}
+
+PhotoNote.prototype.UnSelect = function()
+{
+    this.dragresize.deselect(false);
+    this.selected = false;
+    this.SetEditable(false);
+    this.HideNoteText();
+}
+
+PhotoNote.prototype.Save = function()
+{
+    this.oldRect = null;
+    this.gui.TextTitle.innerHTML = this.gui.TextBox.value;
+    this.text = this.gui.TextBox.value
+    this.UnSelect();
+}
+
+PhotoNote.prototype.Cancel = function()
+{
+    //if the note is still new, then we actually want to delete it, not cancel it..
+    if(this.id < 0)
+    {
+        this.container.DeleteNote(this)
+    }
+    else
+    {
+       //reset the node to it's old position 
+        if(this.oldRect != null)
+        {
+            this.rect = this.oldRect;                
+        }
+        this.oldRect = null;               
+        this.gui.TextBox.value = this.text;                
+        this.PositionNote();
+        this.UnSelect();
+    }
+}
+
+PhotoNote.prototype.ShowNoteText = function()
+{
+    if(!this.container.editing)
+    {
+        this.container.HideAllNoteTexts();
+        this.container.DisableAllNotes();
+        this.EnableNote();
+
+        this.gui.ElementNote.style.display='block';
+		if(BrowserDetect.browser == 'Explorer')
+		{
+		    this.gui.ElementRect.firstChild.filters.alpha.opacity = '85';
+		    this.gui.ElementRect.firstChild.firstChild.filters.alpha.opacity = '85';
+		} else {
+		    this.gui.ElementRect.firstChild.firstChild.style.opacity = '.85';
+		    this.gui.ElementRect.firstChild.style.opacity = '.85';
+		}
+
+    }
+}
+
+PhotoNote.prototype.DisableNote = function ()
+{
+    this.dragresize.enabled=false;
+}
+
+PhotoNote.prototype.EnableNote = function ()
+{
+    this.dragresize.enabled=true;
+}
+
+PhotoNote.prototype.HideNoteText = function ()
+{
+    this.gui.ElementNote.style.display='none';
+	if(BrowserDetect.browser == 'Explorer')
+	{
+        this.gui.ElementRect.firstChild.firstChild.filters.alpha.opacity = '40';
+        this.gui.ElementRect.firstChild.filters.alpha.opacity = '40';
+	} else {
+    	this.gui.ElementRect.firstChild.style.opacity = '0.4';
+        this.gui.ElementRect.firstChild.firstChild.style.opacity = '0.4';
+	}
+}
+
+PhotoNote.prototype.HideNote = function ()
+{
+    this.gui.ElementRect.style.display='none';
+    this.gui.ElementNote.style.display='none';
+}
+
+PhotoNote.prototype.ShowNote = function ()
+{
+    this.gui.ElementRect.style.display='block';
+    this.gui.ElementNote.style.display='none';
+}
+
+PhotoNote.prototype.SetEditable = function(editable)
+{
+    this.container.editing = editable;
+    
+    if(editable)
+    {
+        //the first child of the note is the text
+        this.gui.TextTitle.style.display = 'none';
+        
+        //the second child is the edit area...
+        this.gui.EditArea.style.display = 'block';
+        
+        //if this is a "new" note, then hide the delete button
+        if(this.id <= 0)
+            this.gui.DeleteButton.style.display = 'none';
+        else
+            this.gui.DeleteButton.style.display = '';
+        
+        // get the textarea and select the text...
+        this.HighlightTextbox();
+   }
+    else
+    {
+        //the first child of the note is the text
+        this.gui.TextTitle.style.display = 'block';
+        
+        //the second child is the edit area...
+        this.gui.EditArea.style.display = 'none';
+    }
+}
+
+PhotoNote.prototype.HighlightTextbox = function ()
+{
+    // get the textarea and select the text...
+    if(this.gui.EditArea.style.display=='block')
+    {
+        var textfield = this.gui.TextBox;
+        setTimeout(function() {
+                try
+                {
+                    textfield.focus();
+                    //textfield.select();
+                }
+                catch(e) {}
+            }, 200);
+    }
+
+}
+
+PhotoNote.prototype.CreateElements = function()
+{
+    this.gui = new PhotoNoteGUI();
+
+    var newArea = document.createElement('div');
+    this.dragresize = new DragResize(this.containerId,'dragresize', { allowBlur: false });
+    newArea.className = 'fn-area';
+    newArea.id = 'fn-area-new';
+
+    var newAreaBlack = document.createElement('div');
+    newAreaBlack.className = 'fn-area-blackborder';
+    var newAreaWhite = document.createElement('div');
+    newAreaWhite.className = 'fn-area-whiteborder';
+    
+    var currentNote = this;
+
+    var newAreaInner = document.createElement('div');
+    newAreaInner.className = 'fn-area-inner';
+    newAreaWhite.appendChild(newAreaInner);
+
+    //attach mouse events to this element...
+    _PN_addEvent(newAreaInner, 'mouseover', function() {
+            currentNote.ShowNoteText();
+        });
+    _PN_addEvent(newAreaInner, 'mouseout', function() {
+
+            if(!currentNote.selected)
+            {
+                setTimeout(function () {
+                    currentNote.HideNoteText();
+                    }, 250);
+                    
+            }
+        });
+        
+    _PN_addEvent(newAreaInner, 'mousedown', function() {
+            if(!currentNote.selected)
+            {
+                //window.status = 'mouseDown2!';
+                currentNote.Select();
+            }
+        });
+    
+    newAreaBlack.appendChild(newAreaWhite);
+    newArea.appendChild(newAreaBlack);
+    
+    // add the notes area
+    var noteArea = document.createElement('div');
+    noteArea.className = 'fn-note';
+	noteArea.onmouseover = function(){_zoomEnabled = false;};
+	noteArea.onmouseout = function(){_zoomEnabled = true;};
+    var titleArea = document.createElement('div');
+    titleArea.className = 'fn-note-text';
+    var t = document.createTextNode(this.text);
+    titleArea.appendChild(t);
+    noteArea.appendChild(titleArea);
+    
+    var editArea = document.createElement('div');
+    editArea.className = 'fn-note-edit';
+    
+    var editAreaText = document.createElement('div');
+    editAreaText.className = 'fn-note-edit-text';
+    
+    var newTextbox = document.createElement('textarea');
+    newTextbox.value = this.text;
+    editAreaText.appendChild(newTextbox);
+    editArea.appendChild(editAreaText);
+    
+    var buttonsDiv = document.createElement('div');
+    buttonsDiv.setAttribute("class", "annotator-editor");
+
+    var newButtonOK = document.createElement('a');
+    newButtonOK.setAttribute("class", "annotator-save annotator-inline");
+    newButtonOK.innerHTML='Save';
+    newButtonOK.onmouseover = function(){_zoomEnabled = false;};
+    newButtonOK.onmouseout = function(){_zoomEnabled = true;};
+    newButtonOK.onclick = function() {
+            if(currentNote.onsave) 
+            {
+				currentNote.text = newTextbox.value;
+                var res = currentNote.onsave(currentNote);
+                if(res > 0)
+                {
+                    //window.status = '';
+                    currentNote.id = res;
+                    currentNote.Save();
+                }
+                else
+                {
+                    alert("error saving note");
+                    currentNote.Cancel();                        
+                }
+            }
+            else
+            {
+                alert("onsave must be implemented in order to *actually* save");
+                currentNote.Cancel();                        
+            }
+        };
+    buttonsDiv.appendChild(newButtonOK);
+    
+    var newButtonCancel = document.createElement('a');
+    newButtonCancel.setAttribute("class", "annotator-cancel  annotator-inline");
+    newButtonCancel.innerHTML='Cancel';
+    newButtonCancel.onmouseover = function(){_zoomEnabled = false;};
+    newButtonCancel.onmouseout = function(){_zoomEnabled = true;};
+    newButtonCancel.onclick = function() {
+            currentNote.Cancel();            
+        };
+    buttonsDiv.appendChild(newButtonCancel);
+
+    var newButtonDelete = document.createElement('a');
+    newButtonDelete.setAttribute("class", "annotator-cancel annotator-inline");
+    newButtonDelete.innerHTML='Delete';
+    newButtonDelete.onmouseover = function(){_zoomEnabled = false;};
+    newButtonDelete.onmouseout = function(){_zoomEnabled = true;};
+    newButtonDelete.onclick = function() {
+            
+            if(currentNote.ondelete) 
+            {
+                var res = currentNote.ondelete(currentNote);
+                if(res)
+                {
+                    currentNote.container.DeleteNote(currentNote);
+                }
+                else
+                {
+                    alert("error deleting note");
+                }
+            }
+            else
+            {
+                alert("ondelete must be implemented in order to *actually* delete");
+            }
+			setTimeout(function(){_zoomEnabled = true;}, 100);
+        };
+    buttonsDiv.appendChild(newButtonDelete);
+
+    editArea.appendChild(buttonsDiv);
+    noteArea.appendChild(editArea);
+    
+    this.buttonsDiv = buttonsDiv;
+    this.editArea = editArea;
+    this.noteArea = noteArea;
+
+    /********* DRAG & RESIZE EVENTS **********************/
+    this.dragresize.isElement = function(elm)
+        {
+            if(elm.className == 'fn-area')
+            {
+                this.maxRight = currentNote.container.element.offsetWidth;
+                this.maxBottom = currentNote.container.element.offsetHeight + $("#"+this.containerId).position().top - 3;
+                return true;
+            }
+        };
+    this.dragresize.isHandle = function(elm)
+        {
+            if(elm.className == 'fn-area')
+                return true;
+        };
+    this.dragresize.ondragfocus = function()
+        {
+            currentNote.gui.ElementRect.style.cursor = 'move';
+        };
+    this.dragresize.ondragblur = function()
+        {
+            currentNote.gui.ElementRect.style.cursor = 'pointer';
+        };
+    this.dragresize.ondragstart = function()
+        {
+            if(currentNote.oldRect == null)
+            {
+                var r = currentNote.rect;
+                currentNote.oldRect = new PhotoNoteRect(r.left,r.top,r.width,r.height);
+            }
+        };
+    this.dragresize.ondragend = function()
+        {
+            //window.status = 'LKSFDLKJDFSLKJFDLKJ';
+            currentNote.HighlightTextbox();
+        };
+    this.dragresize.ondragmove = function()
+        {
+            currentNote.rect.left = parseInt(this.element.style.left);
+            currentNote.rect.top = parseInt(this.element.style.top) - $("#"+this.containerId).position().top;
+            currentNote.rect.width = parseInt(this.element.style.width);
+            currentNote.rect.height = parseInt(this.element.style.height);
+            currentNote.PositionNote();
+        };
+
+    this.dragresize.apply(document);
+    
+    /* setup the GUI object */
+    this.gui.ElementRect = newArea;
+    this.gui.ElementNote = noteArea;
+    this.gui.EditArea = editArea;
+    this.gui.TextBox = newTextbox;
+    this.gui.TextTitle = titleArea;
+    this.gui.DeleteButton = newButtonDelete;
+    
+    /* position the note text below the note area */
+    this.PositionNote();
+}
+
+PhotoNote.prototype.PositionNote = function()
+{
+    /* outer most box */
+    this.gui.ElementRect.style.left  = this.rect.left + 'px';
+    this.gui.ElementRect.style.top  = this.rect.top + $("#"+this.containerId).position().top + 'px';
+    this.gui.ElementRect.style.width  = this.rect.width + 'px';
+    this.gui.ElementRect.style.height  = this.rect.height + 'px';
+    
+    // black border
+    this.gui.ElementRect.firstChild.style.width  = parseInt(this.gui.ElementRect.style.width) - 2 + 'px';
+    this.gui.ElementRect.firstChild.style.height  = parseInt(this.gui.ElementRect.style.height) - 2 + 'px';        
+    
+    // white border
+    this.gui.ElementRect.firstChild.firstChild.style.width  = parseInt(this.gui.ElementRect.style.width) - 4 + 'px';
+    this.gui.ElementRect.firstChild.firstChild.style.height  = parseInt(this.gui.ElementRect.style.height) - 4 + 'px';        
+
+    // inner box
+    this.gui.ElementRect.firstChild.firstChild.firstChild.style.width  = parseInt(this.gui.ElementRect.style.width) - 6 + 'px';
+    this.gui.ElementRect.firstChild.firstChild.firstChild.style.height  = parseInt(this.gui.ElementRect.style.height) - 6 + 'px';        
+ 
+    this.gui.ElementNote.style.left  = this.rect.left + this.XOffset + 'px';
+    this.gui.ElementNote.style.top  = this.rect.top + this.YOffset + this.rect.height + $("#"+this.containerId).position().top + 'px';
+   
+}
+
+/*********************************************************/
+/*** Photo Note GUI Object *******************************/
+/*********************************************************/
+function PhotoNoteGUI()
+{
+    this.ElementRect = null;
+    
+    // the note text area...
+    this.ElementNote = null;
+    this.TextTitle = null;
+    this.EditArea = null;
+    this.TextBox = null;
+    
+    // buttons
+    this.DeleteButton = null;
+}
+
+
+
+/*********************************************************/
+/*** Rectangle *******************************************/
+/*********************************************************/
+function PhotoNoteRect(left,top,width,height)
+{
+    this.left = left;
+    this.top = top;
+    this.width = width;
+    this.height = height;
+}
+
+/* for debugging purposes */
+PhotoNoteRect.prototype.toString = function()
+{
+    return 'left: ' + this.left + ', top: ' + this.top + ', width: ' + this.width + ', height: ' + this.height;
+}
+
+
+// *** Common API Code ***
+// (c) 2005 Angus Turnbull http://www.twinhelix.com
+
+var aeOL = [];
+function _PN_addEvent(o, n, f, l)
+{
+ var a = 'addEventListener', h = 'on'+n, b = '', s = '';
+ if (o[a] && !l) return o[a](n, f, false);
+ o._c |= 0;
+ if (o[h])
+ {
+  b = '_f' + o._c++;
+  o[b] = o[h];
+ }
+ s = '_f' + o._c++;
+ o[s] = f;
+ o[h] = function(e)
+ {
+  e = e || window.event;
+  var r = true;
+  if (b) r = o[b](e) != false && r;
+  r = o[s](e) != false && r;
+  return r;
+ };
+ aeOL[aeOL.length] = { o: o, h: h };
+};
+_PN_addEvent(window, 'unload', function() {
+ for (var i = 0; i < aeOL.length; i++) with (aeOL[i])
+ {
+  o[h] = null;
+  for (var c = 0; o['_f' + c]; c++) o['_f' + c] = null;
+ }
+});
+
+function cancelEvent2(e, c)
+{
+ e.returnValue = false;
+ if (e.preventDefault) e.preventDefault();
+ if (c)
+ {
+  e.cancelBubble = true;
+  if (e.stopPropagation) e.stopPropagation();
+ }
+};
+
+function addLoadEvent2(func) {
+  var oldonload = window.onload;
+  if (typeof window.onload != 'function') {
+    window.onload = func;
+  } else {
+    window.onload = function() {
+      oldonload();
+      func();
+    }
+  }
+}
+
+
+/* Extend the Array object with some useful features 
+   http://www.ditchnet.org/wp/?p=8
+*/
+
+/*
+
+Causes problem with Seaweed/Direct Edit's dynamic loader
+
+Array.prototype.clear2 = function () {
+    this.length = 0;
+};
+
+
+
+Array.prototype.remove2 = function (element) {
+	var result = false;
+	var array = [];
+	for (var i = 0; i < this.length; i++) {
+		if (this[i] == element) {
+			result = true;
+		} else {
+			array.push(this[i]);
+		}
+	}
+	this.clear2();
+	for (var i = 0; i < array.length; i++) {
+		this.push(array[i]);
+	}
+	array = null;
+	return result;
+};
+*/
+
+function removeFromArray(that,element) {
+	var result = false;
+	var array = [];
+	for (var i = 0; i < that.length; i++) {
+		if (that[i] == element) {
+			result = true;
+		} else {
+			array.push(that[i]);
+		}
+	}
+	that.length = 0;
+
+	for (var i = 0; i < array.length; i++) {
+		that.push(array[i]);
+	}
+	array = null;
+	return result;
+}
+
+
+// *** Drag and Resize Library Code ***
+// (c) 2005 Angus Turnbull http://www.twinhelix.come
+
+function DragResize(containerId, myName, config)
+{
+    var props = {
+	containerId: containerId,
+        myName: myName,                  // Name of the object.
+        enabled: true,                   // Global toggle of drag/resize.
+        handles: ['tl', 'tm', 'tr',
+        'ml', 'mr', 'bl', 'bm', 'br'], // Array of drag handles: top/mid/.
+        isElement: null,                 // Function ref to test for an element.
+        isHandle: null,                  // Function ref to test for move handle.
+        element: null,                   // The currently selected element.
+        dragging: null,                  // Active handle reference of the element.
+        minWidth: 10, minHeight: 10,     // Minimum pixel size of elements.
+        minLeft: 0, maxRight: 9999,      // Bounding box area.
+        minTop: $("#"+containerId).position().top, maxBottom: 9999,
+        zIndex: 1,                       // The highest Z-Index yet allocated.
+        mouseX: 0, mouseY: 0,            // Current mouse position, recorded live.
+        lastMouseX: 0, lastMouseY: 0,    // Last processed mouse positions.
+        mOffX: 0, mOffY: 0,              // A known offset between position & mouse.
+        elmX: 0, elmY: 0,                // Element position.
+        elmW: 0, elmH: 0,                // Element size.
+        allowBlur: true,                 // Whether to allow automatic blur onclick.
+        ondragfocus: null,               // Event handler functions.
+        ondragstart: null,
+        ondragmove: null,
+        ondragend: null,
+        ondragblur: null
+    };
+
+    for (var p in props)
+    {
+        this[p] = (typeof config[p] == 'undefined') ? props[p] : config[p];
+    }
+};
+
+DragResize.prototype.apply = function(node)
+{
+    // Adds object event handlers to the specified DOM node.
+
+    var obj = this;
+    _PN_addEvent(node, 'mousedown', function(e) { obj.mouseDown(e) } );
+    _PN_addEvent(node, 'mousemove', function(e) { obj.mouseMove(e) } );
+    _PN_addEvent(node, 'mouseup', function(e) { obj.mouseUp(e) } );
+};
+
+DragResize.prototype.handleSet = function(elm, show) { with (this)
+{
+    // Either creates, shows or hides the resize handles within an element.
+
+    // If we're showing them, and no handles have been created, create 4 new ones.
+    if (!elm._handle_tr)
+    {
+        for (var h = 0; h < handles.length; h++)
+        {
+            // Create 4 news divs, assign each a generic + specific class.
+            var hDiv = document.createElement('div');
+            hDiv.className = myName + ' ' +  myName + '-' + handles[h];
+            elm['_handle_' + handles[h]] = elm.appendChild(hDiv);
+        }
+    }
+
+    // We now have handles. Find them all and show/hide.
+    for (var h = 0; h < handles.length; h++)
+    {
+        elm['_handle_' + handles[h]].style.visibility = show ? 'inherit' : 'hidden';
+    }
+}};
+
+
+DragResize.prototype.select = function(newElement) { with (this)
+{
+    // Selects an element for dragging.
+
+    if (!document.getElementById || !enabled) return;
+
+    // Activate and record our new dragging element.
+    if (newElement && (newElement != element) && enabled)
+    {
+        element = newElement;
+        // Elevate it and give it resize handles.
+        element.style.zIndex = ++zIndex;
+        handleSet(element, true);
+        // Record element attributes for mouseMove().
+        elmX = parseInt(element.style.left);
+        elmY = parseInt(element.style.top + $("#"+this.containerId).position().top);
+        elmW = element.offsetWidth;
+        elmH = element.offsetHeight;
+        if (ondragfocus) this.ondragfocus();
+    //window.status = 'start elmX=' + element.className;
+        
+    }
+}};
+
+
+DragResize.prototype.deselect = function(keepHandles) { with (this)
+{
+    // Immediately stops dragging an element. If 'keepHandles' is false, this
+    // remove the handles from the element and clears the element flag,
+    // completely resetting the .
+
+    if (!document.getElementById || !enabled) return;
+
+    if (!keepHandles)
+    {
+        if (ondragblur) this.ondragblur();
+        handleSet(element, false);
+        element = null;
+    }
+
+    dragging = null;
+    mOffX = 0;
+    mOffY = 0;
+}};
+
+
+DragResize.prototype.mouseDown = function(e) { with (this)
+{
+    //window.status = 'mouseDown!';
+    // Suitable elements are selected for drag/resize on mousedown.
+    // We also initialise the resize boxes, and drag parameters like mouse position etc.
+    if (!document.getElementById || !enabled) return true;
+
+    var elm = e.target || e.srcElement,
+    newElement = null,
+    newHandle = null,
+    hRE = new RegExp(myName + '-([trmbl]{2})', '');
+
+    while (elm)
+    {
+        // Loop up the DOM looking for matching elements. Remember one if found.
+        if (elm.className)
+        {
+        if (!newHandle && (hRE.test(elm.className) || isHandle(elm))) newHandle = elm;
+        if (isElement(elm)) { newElement = elm; break }
+        }
+        elm = elm.parentNode;
+    }
+
+    // If this isn't on the last dragged element, call deselect(false),
+    // which will hide its handles and clear element.
+    if (element && (element != newElement) && allowBlur) deselect(false);
+
+    // If we have a new matching element, call select().
+    if (newElement && (!element || (newElement == element)))
+    {
+        // Stop mouse selections.
+        cancelEvent2(e);
+        select(newElement, newHandle);
+        dragging = newHandle;
+        if (dragging && ondragstart) this.ondragstart();
+    }
+}};
+
+
+DragResize.prototype.mouseMove = function(e) { with (this)
+{
+    // This continually offsets the dragged element by the difference between the
+    // last recorded mouse position (mouseX/Y) and the current mouse position.
+    if (!document.getElementById || !enabled) return true;
+
+    // We always record the current mouse position.
+    mouseX = e.pageX || e.clientX + document.documentElement.scrollLeft;
+    mouseY = e.pageY || e.clientY + document.documentElement.scrollTop;
+    // Record the relative mouse movement, in case we're dragging.
+    // Add any previously stored&ignored offset to the calculations.
+    var diffX = mouseX - lastMouseX + mOffX;
+    var diffY = mouseY - lastMouseY + mOffY;
+    mOffX = mOffY = 0;
+    // Update last processed mouse positions.
+    lastMouseX = mouseX;
+    lastMouseY = mouseY;
+
+    // That's all we do if we're not dragging anything.
+    if (!dragging) return true;
+
+    // Establish which handle is being dragged -- retrieve handle name from className.
+    var hClass = dragging && dragging.className &&
+    dragging.className.match(new RegExp(myName + '-([tmblr]{2})')) ? RegExp.$1 : '';
+
+    // If the hClass is one of the resize handles, resize one or two dimensions.
+    // Bounds checking is the hard bit -- basically for each edge, check that the
+    // element doesn't go under minimum size, and doesn't go beyond its boundary.
+    var rs = 0, dY = diffY, dX = diffX;
+    if (hClass.indexOf('t') >= 0)
+    {
+        rs = 1;
+        if (elmH - dY < minHeight) mOffY = (dY - (diffY = elmH - minHeight));
+        else if (elmY + dY < minTop) mOffY = (dY - (diffY = minTop - elmY));
+        elmY += diffY;
+        elmH -= diffY;
+    }
+    if (hClass.indexOf('b') >= 0)
+    {
+        rs = 1;
+        if (elmH + dY < minHeight) mOffY = (dY - (diffY = minHeight - elmH));
+        else if (elmY + elmH + dY > maxBottom) mOffY = (dY - (diffY = maxBottom - elmY - elmH));
+        elmH += diffY;
+    }
+    if (hClass.indexOf('l') >= 0)
+    {
+        rs = 1;
+        if (elmW - dX < minWidth) mOffX = (dX - (diffX = elmW - minWidth));
+        else if (elmX + dX < minLeft) mOffX = (dX - (diffX = minLeft - elmX));
+        elmX += diffX;
+        elmW -= diffX;
+    }
+    if (hClass.indexOf('r') >= 0)
+    {
+        rs = 1;
+        if (elmW + dX < minWidth) mOffX = (dX - (diffX = minWidth - elmW));
+        else if (elmX + elmW + dX > maxRight) mOffX = (dX - (diffX = maxRight - elmX - elmW));
+        elmW += diffX;
+        window.status = 'diffX:' + diffX;
+    }
+    // If 'rs' isn't set, we must be dragging the whole element, so move that.
+    if (dragging && !rs)
+    {
+        // Bounds check left-right...
+        if (elmX + dX < minLeft) mOffX = (dX - (diffX = minLeft - elmX));
+        else if (elmX + elmW + dX > maxRight) mOffX = (dX - (diffX = maxRight - elmX - elmW));
+        // ...and up-down.
+        if (elmY + dY < minTop) mOffY = (dY - (diffY = minTop - elmY));
+        else if (elmY + elmH + dY > maxBottom) mOffY = (dY - (diffY = maxBottom - elmY - elmH));
+        //window.status = 'diffX-' + diffX + ' , elmX-' + elmX;
+        elmX += diffX;
+        elmY += diffY;
+    }
+    
+    //window.status = 'elmX=' + elmX;
+    // Assign new info back to the element, with minimum dimensions.
+    with (element.style)
+    {
+        left =   elmX + 'px';
+        width =  elmW + 'px';
+        top =    elmY + 'px';
+        height = elmH + 'px';
+    }
+
+    // Evil, dirty, hackish Opera select-as-you-drag fix.
+    if (window.opera && document.documentElement)
+    {
+        var oDF = document.getElementById('op-drag-fix');
+        if (!oDF)
+        {
+            var oDF = document.createElement('input');
+            oDF.id = 'op-drag-fix';
+            oDF.style.display = 'none';
+            document.body.appendChild(oDF);
+        }
+        oDF.focus();
+    }
+
+    if (ondragmove) this.ondragmove();
+
+    // Stop a normal drag event.
+    cancelEvent2(e);
+}};
+
+
+DragResize.prototype.mouseUp = function(e) { with (this)
+{
+    // On mouseup, stop dragging, but don't reset handler visibility.
+    if (!document.getElementById || !enabled) return;
+
+    if (ondragend) this.ondragend();
+    deselect(true);
+}};
+
+
+
Index: gs3-extensions/overlay-notes/trunk/src/PhotoNotes-1.5.js.orig
===================================================================
--- gs3-extensions/overlay-notes/trunk/src/PhotoNotes-1.5.js.orig	(revision 26826)
+++ gs3-extensions/overlay-notes/trunk/src/PhotoNotes-1.5.js.orig	(revision 26826)
@@ -0,0 +1,899 @@
+/*
+Copyright (c) 2006 Dusty Davidson - http://www.dustyd.net
+(portions Copyright (c) 2005 Angus Turnbull http://www.twinhelix.come)
+
+Permission is hereby granted, free of charge, to any person obtaining 
+a copy of this software and associated documentation files (the "Software"), 
+to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+and/or sell copies of the Software, and to permit persons to whom the Software 
+is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in 
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+
+
+/*********************************************************/
+/*** Photo Notes Container *******************************/
+/*********************************************************/
+function PhotoNoteContainer(element, config)
+{
+    var props = {
+        element: element,
+        dragresize: null,
+        notes: new Array(),
+        editing: false
+    };
+
+    for (var p in props)
+    {
+        this[p] = (!config || typeof config[p] == 'undefined') ? props[p] : config[p];
+    }
+        
+};
+
+PhotoNoteContainer.prototype.DeleteNote = function(note)
+{
+    note.UnSelect();
+
+    /* remove from the DOM */
+    this.element.removeChild(note.gui.ElementRect);
+    this.element.removeChild(note.gui.ElementNote);
+    
+    /* remove from the array... */
+    this.notes.remove(note);
+}
+
+PhotoNoteContainer.prototype.AddNote = function(note)
+{
+    if(!this.editing)
+    {
+        /* add the note to the array of notes, and set its container */
+        this.notes[this.notes.length] = note;
+        note.container = this;
+
+        /* add the note to the DOM */
+        this.element.appendChild(note.gui.ElementRect);
+        this.element.appendChild(note.gui.ElementNote);    
+    }
+};
+
+/* hide all of the "text" parts of the notes. Primarily called when hovering a note, at which
+    point we want to hide all of the other note texts */
+PhotoNoteContainer.prototype.HideAllNoteTexts = function()
+{
+    for (var i = 0;i<this.notes.length;i++)
+        this.notes[i].HideNoteText();
+};
+
+
+PhotoNoteContainer.prototype.DisableAllNotes = function()
+{
+    for (var i = 0;i<this.notes.length;i++)
+        this.notes[i].DisableNote();
+};
+
+PhotoNoteContainer.prototype.HideAllNotes = function()
+{
+    for (var i = 0;i<this.notes.length;i++)
+        this.notes[i].HideNote();
+};
+
+PhotoNoteContainer.prototype.ShowAllNotes = function()
+{
+    for (var i = 0;i<this.notes.length;i++)
+        this.notes[i].ShowNote();
+};
+
+PhotoNoteContainer.prototype.EnableAllNotes = function()
+{
+    for (var i = 0;i<this.notes.length;i++)
+        this.notes[i].EnableNote();
+};
+
+
+
+/*********************************************************/
+/*** Photo Note ******************************************/
+/*********************************************************/
+function PhotoNote(text,id,rect)
+{
+    var props = {
+        text: text,                   
+        id: id,
+        rect: rect,                    
+        selected: false,
+        container: null,
+        dragresize: null,
+        oldRect: null,
+        YOffset: 10,
+        XOffset: 0,
+        onsave: null,
+        ondelete: null,
+        gui: null                  
+        
+    };
+
+    for (var p in props)
+    {
+        this[p] = props[p];
+    }
+    
+    this.CreateElements();
+}
+
+PhotoNote.prototype.Select = function()
+{
+    //window.status = 'container: ' + this.container;
+    if(!this.container.editing)
+    {
+        this.ShowNoteText();
+        this.dragresize.select(this.gui.ElementRect);
+        this.selected = true;
+        this.SetEditable(true);
+    }    
+}
+
+PhotoNote.prototype.UnSelect = function()
+{
+    this.dragresize.deselect(false);
+    this.selected = false;
+    this.SetEditable(false);
+    this.HideNoteText();
+}
+
+PhotoNote.prototype.Save = function()
+{
+    this.oldRect = null;
+    this.gui.TextTitle.innerHTML = this.gui.TextBox.value;
+    this.text = this.gui.TextBox.value
+    this.UnSelect();
+}
+
+PhotoNote.prototype.Cancel = function()
+{
+    //if the note is still new, then we actually want to delete it, not cancel it..
+    if(this.id < 0)
+    {
+        this.container.DeleteNote(this)
+    }
+    else
+    {
+       //reset the node to it's old position 
+        if(this.oldRect != null)
+        {
+            this.rect = this.oldRect;                
+        }
+        this.oldRect = null;               
+        this.gui.TextBox.value = this.text;                
+        this.PositionNote();
+        this.UnSelect();
+    }
+}
+
+PhotoNote.prototype.ShowNoteText = function()
+{
+    if(!this.container.editing)
+    {
+        this.container.HideAllNoteTexts();
+        this.container.DisableAllNotes();
+        this.EnableNote();
+
+        this.gui.ElementNote.style.display='block';
+		if(BrowserDetect.browser == 'Explorer')
+		{
+		    this.gui.ElementRect.firstChild.filters.alpha.opacity = '85';
+		    this.gui.ElementRect.firstChild.firstChild.filters.alpha.opacity = '85';
+		} else {
+		    this.gui.ElementRect.firstChild.firstChild.style.opacity = '.85';
+		    this.gui.ElementRect.firstChild.style.opacity = '.85';
+		}
+
+    }
+}
+
+PhotoNote.prototype.DisableNote = function ()
+{
+    this.dragresize.enabled=false;
+}
+
+PhotoNote.prototype.EnableNote = function ()
+{
+    this.dragresize.enabled=true;
+}
+
+PhotoNote.prototype.HideNoteText = function ()
+{
+    this.gui.ElementNote.style.display='none';
+	if(BrowserDetect.browser == 'Explorer')
+	{
+        this.gui.ElementRect.firstChild.firstChild.filters.alpha.opacity = '40';
+        this.gui.ElementRect.firstChild.filters.alpha.opacity = '40';
+	} else {
+    	this.gui.ElementRect.firstChild.style.opacity = '0.4';
+        this.gui.ElementRect.firstChild.firstChild.style.opacity = '0.4';
+	}
+}
+
+PhotoNote.prototype.HideNote = function ()
+{
+    this.gui.ElementRect.style.display='none';
+    this.gui.ElementNote.style.display='none';
+}
+
+PhotoNote.prototype.ShowNote = function ()
+{
+    this.gui.ElementRect.style.display='block';
+    this.gui.ElementNote.style.display='none';
+}
+
+PhotoNote.prototype.SetEditable = function(editable)
+{
+    this.container.editing = editable;
+    
+    if(editable)
+    {
+        //the first child of the note is the text
+        this.gui.TextTitle.style.display = 'none';
+        
+        //the second child is the edit area...
+        this.gui.EditArea.style.display = 'block';
+        
+        //if this is a "new" note, then hide the delete button
+        if(this.id <= 0)
+            this.gui.DeleteButton.style.display = 'none';
+        else
+            this.gui.DeleteButton.style.display = 'inline';
+        
+        // get the textarea and select the text...
+        this.HighlightTextbox();
+   }
+    else
+    {
+        //the first child of the note is the text
+        this.gui.TextTitle.style.display = 'block';
+        
+        //the second child is the edit area...
+        this.gui.EditArea.style.display = 'none';
+    }
+}
+
+PhotoNote.prototype.HighlightTextbox = function ()
+{
+    // get the textarea and select the text...
+    if(this.gui.EditArea.style.display=='block')
+    {
+        var textfield = this.gui.TextBox;
+        setTimeout(function() {
+                try
+                {
+                    textfield.focus();
+                    textfield.select();
+                }
+                catch(e) {}
+            }, 200);
+    }
+
+}
+
+PhotoNote.prototype.CreateElements = function()
+{
+    this.gui = new PhotoNoteGUI();
+
+    var newArea = document.createElement('div');
+    this.dragresize = new DragResize('dragresize', { allowBlur: false });
+    newArea.className = 'fn-area';
+    newArea.id = 'fn-area-new';
+
+    var newAreaBlack = document.createElement('div');
+    newAreaBlack.className = 'fn-area-blackborder';
+    var newAreaWhite = document.createElement('div');
+    newAreaWhite.className = 'fn-area-whiteborder';
+    
+    var currentNote = this;
+
+    var newAreaInner = document.createElement('div');
+    newAreaInner.className = 'fn-area-inner';
+    newAreaWhite.appendChild(newAreaInner);
+
+    //attach mouse events to this element...
+    addEvent(newAreaInner, 'mouseover', function() {
+            currentNote.ShowNoteText();
+        });
+    addEvent(newAreaInner, 'mouseout', function() {
+
+            if(!currentNote.selected)
+            {
+                setTimeout(function () {
+                    currentNote.HideNoteText();
+                    }, 250);
+                    
+            }
+        });
+        
+    addEvent(newAreaInner, 'mousedown', function() {
+            if(!currentNote.selected)
+            {
+                //window.status = 'mouseDown2!';
+                currentNote.Select();
+            }
+        });
+    
+    newAreaBlack.appendChild(newAreaWhite);
+    newArea.appendChild(newAreaBlack);
+    
+    // add the notes area
+    var noteArea = document.createElement('div');
+    noteArea.className = 'fn-note';
+    
+    var titleArea = document.createElement('div');
+    titleArea.className = 'fn-note-text';
+    var t = document.createTextNode(this.text);
+    titleArea.appendChild(t);
+    noteArea.appendChild(titleArea);
+    
+    var editArea = document.createElement('div');
+    editArea.className = 'fn-note-edit';
+    
+    var editAreaText = document.createElement('div');
+    editAreaText.className = 'fn-note-edit-text';
+    
+    var newTextbox = document.createElement('textarea');
+    newTextbox.value = this.text;
+    editAreaText.appendChild(newTextbox);
+    editArea.appendChild(editAreaText);
+    
+    var buttonsDiv = document.createElement('div');
+    var newButtonOK = document.createElement('input');
+    newButtonOK.type='button';
+    newButtonOK.className = 'Butt';
+    newButtonOK.value='SAVE';
+    newButtonOK.onclick = function() {
+            if(currentNote.onsave) 
+            {
+                var res = currentNote.onsave(currentNote);
+                if(res > 0)
+                {
+                    //window.status = '';
+                    currentNote.id = res;
+                    currentNote.Save();
+                }
+                else
+                {
+                    alert("error saving note");
+                    currentNote.Cancel();                        
+                }
+            }
+            else
+            {
+                alert("onsave must be implemented in order to *actually* save");
+                currentNote.Cancel();                        
+            }
+        };
+    buttonsDiv.appendChild(newButtonOK);
+    
+    var newButtonCancel = document.createElement('input');
+    newButtonCancel.type='button';
+    newButtonCancel.className = 'CancelButt';
+    newButtonCancel.value='CANCEL';
+    newButtonCancel.onclick = function() {
+            currentNote.Cancel();            
+            
+        };
+    buttonsDiv.appendChild(newButtonCancel);
+
+    var newButtonDelete = document.createElement('input');
+    newButtonDelete.type='button';
+    newButtonDelete.className = 'CancelButt';
+    newButtonDelete.value='DELETE';
+    newButtonDelete.onclick = function() {
+            
+            if(currentNote.ondelete) 
+            {
+                var res = currentNote.ondelete(currentNote);
+                if(res)
+                {
+                    currentNote.container.DeleteNote(currentNote);
+                }
+                else
+                {
+                    alert("error deleting note");
+                }
+            }
+            else
+            {
+                alert("ondelete must be implemented in order to *actually* delete");
+            }
+        };
+    buttonsDiv.appendChild(newButtonDelete);
+
+    editArea.appendChild(buttonsDiv);
+    noteArea.appendChild(editArea);
+    
+    /********* DRAG & RESIZE EVENTS **********************/
+    this.dragresize.isElement = function(elm)
+        {
+            if(elm.className == 'fn-area')
+            {
+                this.maxRight = currentNote.container.element.offsetWidth;
+                this.maxBottom = currentNote.container.element.offsetHeight - 3;
+                return true;
+            }
+        };
+    this.dragresize.isHandle = function(elm)
+        {
+            if(elm.className == 'fn-area')
+                return true;
+        };
+    this.dragresize.ondragfocus = function()
+        {
+            currentNote.gui.ElementRect.style.cursor = 'move';
+        };
+    this.dragresize.ondragblur = function()
+        {
+            currentNote.gui.ElementRect.style.cursor = 'pointer';
+        };
+    this.dragresize.ondragstart = function()
+        {
+            if(currentNote.oldRect == null)
+            {
+                var r = currentNote.rect;
+                currentNote.oldRect = new PhotoNoteRect(r.left,r.top,r.width,r.height);
+            }
+        };
+    this.dragresize.ondragend = function()
+        {
+            //window.status = 'LKSFDLKJDFSLKJFDLKJ';
+            currentNote.HighlightTextbox();
+        };
+    this.dragresize.ondragmove = function()
+        {
+            currentNote.rect.left = parseInt(this.element.style.left);
+            currentNote.rect.top = parseInt(this.element.style.top);
+            currentNote.rect.width = parseInt(this.element.style.width);
+            currentNote.rect.height = parseInt(this.element.style.height);
+            currentNote.PositionNote();
+        };
+
+    this.dragresize.apply(document);
+    
+    /* setup the GUI object */
+    this.gui.ElementRect = newArea;
+    this.gui.ElementNote = noteArea;
+    this.gui.EditArea = editArea;
+    this.gui.TextBox = newTextbox;
+    this.gui.TextTitle = titleArea;
+    this.gui.DeleteButton = newButtonDelete;
+    
+    /* position the note text below the note area */
+    this.PositionNote();
+}
+
+PhotoNote.prototype.PositionNote = function()
+{
+    /* outer most box */
+    this.gui.ElementRect.style.left  = this.rect.left + 'px';
+    this.gui.ElementRect.style.top  = this.rect.top + 'px';
+    this.gui.ElementRect.style.width  = this.rect.width + 'px';
+    this.gui.ElementRect.style.height  = this.rect.height + 'px';
+    
+    // black border
+    this.gui.ElementRect.firstChild.style.width  = parseInt(this.gui.ElementRect.style.width) - 2 + 'px';
+    this.gui.ElementRect.firstChild.style.height  = parseInt(this.gui.ElementRect.style.height) - 2 + 'px';        
+    
+    // white border
+    this.gui.ElementRect.firstChild.firstChild.style.width  = parseInt(this.gui.ElementRect.style.width) - 4 + 'px';
+    this.gui.ElementRect.firstChild.firstChild.style.height  = parseInt(this.gui.ElementRect.style.height) - 4 + 'px';        
+
+    // inner box
+    this.gui.ElementRect.firstChild.firstChild.firstChild.style.width  = parseInt(this.gui.ElementRect.style.width) - 6 + 'px';
+    this.gui.ElementRect.firstChild.firstChild.firstChild.style.height  = parseInt(this.gui.ElementRect.style.height) - 6 + 'px';        
+ 
+    this.gui.ElementNote.style.left  = this.rect.left + this.XOffset + 'px';
+    this.gui.ElementNote.style.top  = this.rect.top + this.YOffset + this.rect.height + 'px';
+   
+}
+
+/*********************************************************/
+/*** Photo Note GUI Object *******************************/
+/*********************************************************/
+function PhotoNoteGUI()
+{
+    this.ElementRect = null;
+    
+    // the note text area...
+    this.ElementNote = null;
+    this.TextTitle = null;
+    this.EditArea = null;
+    this.TextBox = null;
+    
+    // buttons
+    this.DeleteButton = null;
+}
+
+
+
+/*********************************************************/
+/*** Rectangle *******************************************/
+/*********************************************************/
+function PhotoNoteRect(left,top,width,height)
+{
+    this.left = left;
+    this.top = top;
+    this.width = width;
+    this.height = height;
+}
+
+/* for debugging purposes */
+PhotoNoteRect.prototype.toString = function()
+{
+    return 'left: ' + this.left + ', top: ' + this.top + ', width: ' + this.width + ', height: ' + this.height;
+}
+
+
+// *** Common API Code ***
+// (c) 2005 Angus Turnbull http://www.twinhelix.com
+
+var aeOL = [];
+function addEvent(o, n, f, l)
+{
+ var a = 'addEventListener', h = 'on'+n, b = '', s = '';
+ if (o[a] && !l) return o[a](n, f, false);
+ o._c |= 0;
+ if (o[h])
+ {
+  b = '_f' + o._c++;
+  o[b] = o[h];
+ }
+ s = '_f' + o._c++;
+ o[s] = f;
+ o[h] = function(e)
+ {
+  e = e || window.event;
+  var r = true;
+  if (b) r = o[b](e) != false && r;
+  r = o[s](e) != false && r;
+  return r;
+ };
+ aeOL[aeOL.length] = { o: o, h: h };
+};
+addEvent(window, 'unload', function() {
+ for (var i = 0; i < aeOL.length; i++) with (aeOL[i])
+ {
+  o[h] = null;
+  for (var c = 0; o['_f' + c]; c++) o['_f' + c] = null;
+ }
+});
+
+function cancelEvent(e, c)
+{
+ e.returnValue = false;
+ if (e.preventDefault) e.preventDefault();
+ if (c)
+ {
+  e.cancelBubble = true;
+  if (e.stopPropagation) e.stopPropagation();
+ }
+};
+
+function addLoadEvent(func) {
+  var oldonload = window.onload;
+  if (typeof window.onload != 'function') {
+    window.onload = func;
+  } else {
+    window.onload = function() {
+      oldonload();
+      func();
+    }
+  }
+}
+
+
+/* Extend the Array object with some useful features 
+   http://www.ditchnet.org/wp/?p=8
+*/
+
+Array.prototype.clear = function () {
+    this.length = 0;
+};
+
+Array.prototype.remove = function (element) {
+	var result = false;
+	var array = [];
+	for (var i = 0; i < this.length; i++) {
+		if (this[i] == element) {
+			result = true;
+		} else {
+			array.push(this[i]);
+		}
+	}
+	this.clear();
+	for (var i = 0; i < array.length; i++) {
+		this.push(array[i]);
+	}
+	array = null;
+	return result;
+};
+
+
+// *** Drag and Resize Library Code ***
+// (c) 2005 Angus Turnbull http://www.twinhelix.come
+
+function DragResize(myName, config)
+{
+    var props = {
+        myName: myName,                  // Name of the object.
+        enabled: true,                   // Global toggle of drag/resize.
+        handles: ['tl', 'tm', 'tr',
+        'ml', 'mr', 'bl', 'bm', 'br'], // Array of drag handles: top/mid/.
+        isElement: null,                 // Function ref to test for an element.
+        isHandle: null,                  // Function ref to test for move handle.
+        element: null,                   // The currently selected element.
+        dragging: null,                  // Active handle reference of the element.
+        minWidth: 10, minHeight: 10,     // Minimum pixel size of elements.
+        minLeft: 0, maxRight: 9999,      // Bounding box area.
+        minTop: 0, maxBottom: 9999,
+        zIndex: 1,                       // The highest Z-Index yet allocated.
+        mouseX: 0, mouseY: 0,            // Current mouse position, recorded live.
+        lastMouseX: 0, lastMouseY: 0,    // Last processed mouse positions.
+        mOffX: 0, mOffY: 0,              // A known offset between position & mouse.
+        elmX: 0, elmY: 0,                // Element position.
+        elmW: 0, elmH: 0,                // Element size.
+        allowBlur: true,                 // Whether to allow automatic blur onclick.
+        ondragfocus: null,               // Event handler functions.
+        ondragstart: null,
+        ondragmove: null,
+        ondragend: null,
+        ondragblur: null
+    };
+
+    for (var p in props)
+    {
+        this[p] = (typeof config[p] == 'undefined') ? props[p] : config[p];
+    }
+};
+
+DragResize.prototype.apply = function(node)
+{
+    // Adds object event handlers to the specified DOM node.
+
+    var obj = this;
+    addEvent(node, 'mousedown', function(e) { obj.mouseDown(e) } );
+    addEvent(node, 'mousemove', function(e) { obj.mouseMove(e) } );
+    addEvent(node, 'mouseup', function(e) { obj.mouseUp(e) } );
+};
+
+DragResize.prototype.handleSet = function(elm, show) { with (this)
+{
+    // Either creates, shows or hides the resize handles within an element.
+
+    // If we're showing them, and no handles have been created, create 4 new ones.
+    if (!elm._handle_tr)
+    {
+        for (var h = 0; h < handles.length; h++)
+        {
+            // Create 4 news divs, assign each a generic + specific class.
+            var hDiv = document.createElement('div');
+            hDiv.className = myName + ' ' +  myName + '-' + handles[h];
+            elm['_handle_' + handles[h]] = elm.appendChild(hDiv);
+        }
+    }
+
+    // We now have handles. Find them all and show/hide.
+    for (var h = 0; h < handles.length; h++)
+    {
+        elm['_handle_' + handles[h]].style.visibility = show ? 'inherit' : 'hidden';
+    }
+}};
+
+
+DragResize.prototype.select = function(newElement) { with (this)
+{
+    // Selects an element for dragging.
+
+    if (!document.getElementById || !enabled) return;
+
+    // Activate and record our new dragging element.
+    if (newElement && (newElement != element) && enabled)
+    {
+        element = newElement;
+        // Elevate it and give it resize handles.
+        element.style.zIndex = ++zIndex;
+        handleSet(element, true);
+        // Record element attributes for mouseMove().
+        elmX = parseInt(element.style.left);
+        elmY = parseInt(element.style.top);
+        elmW = element.offsetWidth;
+        elmH = element.offsetHeight;
+        if (ondragfocus) this.ondragfocus();
+    //window.status = 'start elmX=' + element.className;
+        
+    }
+}};
+
+
+DragResize.prototype.deselect = function(keepHandles) { with (this)
+{
+    // Immediately stops dragging an element. If 'keepHandles' is false, this
+    // remove the handles from the element and clears the element flag,
+    // completely resetting the .
+
+    if (!document.getElementById || !enabled) return;
+
+    if (!keepHandles)
+    {
+        if (ondragblur) this.ondragblur();
+        handleSet(element, false);
+        element = null;
+    }
+
+    dragging = null;
+    mOffX = 0;
+    mOffY = 0;
+}};
+
+
+DragResize.prototype.mouseDown = function(e) { with (this)
+{
+    //window.status = 'mouseDown!';
+    // Suitable elements are selected for drag/resize on mousedown.
+    // We also initialise the resize boxes, and drag parameters like mouse position etc.
+    if (!document.getElementById || !enabled) return true;
+
+    var elm = e.target || e.srcElement,
+    newElement = null,
+    newHandle = null,
+    hRE = new RegExp(myName + '-([trmbl]{2})', '');
+
+    while (elm)
+    {
+        // Loop up the DOM looking for matching elements. Remember one if found.
+        if (elm.className)
+        {
+        if (!newHandle && (hRE.test(elm.className) || isHandle(elm))) newHandle = elm;
+        if (isElement(elm)) { newElement = elm; break }
+        }
+        elm = elm.parentNode;
+    }
+
+    // If this isn't on the last dragged element, call deselect(false),
+    // which will hide its handles and clear element.
+    if (element && (element != newElement) && allowBlur) deselect(false);
+
+    // If we have a new matching element, call select().
+    if (newElement && (!element || (newElement == element)))
+    {
+        // Stop mouse selections.
+        cancelEvent(e);
+        select(newElement, newHandle);
+        dragging = newHandle;
+        if (dragging && ondragstart) this.ondragstart();
+    }
+}};
+
+
+DragResize.prototype.mouseMove = function(e) { with (this)
+{
+    // This continually offsets the dragged element by the difference between the
+    // last recorded mouse position (mouseX/Y) and the current mouse position.
+    if (!document.getElementById || !enabled) return true;
+
+    // We always record the current mouse position.
+    mouseX = e.pageX || e.clientX + document.documentElement.scrollLeft;
+    mouseY = e.pageY || e.clientY + document.documentElement.scrollTop;
+    // Record the relative mouse movement, in case we're dragging.
+    // Add any previously stored&ignored offset to the calculations.
+    var diffX = mouseX - lastMouseX + mOffX;
+    var diffY = mouseY - lastMouseY + mOffY;
+    mOffX = mOffY = 0;
+    // Update last processed mouse positions.
+    lastMouseX = mouseX;
+    lastMouseY = mouseY;
+
+    // That's all we do if we're not dragging anything.
+    if (!dragging) return true;
+
+    // Establish which handle is being dragged -- retrieve handle name from className.
+    var hClass = dragging && dragging.className &&
+    dragging.className.match(new RegExp(myName + '-([tmblr]{2})')) ? RegExp.$1 : '';
+
+    // If the hClass is one of the resize handles, resize one or two dimensions.
+    // Bounds checking is the hard bit -- basically for each edge, check that the
+    // element doesn't go under minimum size, and doesn't go beyond its boundary.
+    var rs = 0, dY = diffY, dX = diffX;
+    if (hClass.indexOf('t') >= 0)
+    {
+        rs = 1;
+        if (elmH - dY < minHeight) mOffY = (dY - (diffY = elmH - minHeight));
+        else if (elmY + dY < minTop) mOffY = (dY - (diffY = minTop - elmY));
+        elmY += diffY;
+        elmH -= diffY;
+    }
+    if (hClass.indexOf('b') >= 0)
+    {
+        rs = 1;
+        if (elmH + dY < minHeight) mOffY = (dY - (diffY = minHeight - elmH));
+        else if (elmY + elmH + dY > maxBottom) mOffY = (dY - (diffY = maxBottom - elmY - elmH));
+        elmH += diffY;
+    }
+    if (hClass.indexOf('l') >= 0)
+    {
+        rs = 1;
+        if (elmW - dX < minWidth) mOffX = (dX - (diffX = elmW - minWidth));
+        else if (elmX + dX < minLeft) mOffX = (dX - (diffX = minLeft - elmX));
+        elmX += diffX;
+        elmW -= diffX;
+    }
+    if (hClass.indexOf('r') >= 0)
+    {
+        rs = 1;
+        if (elmW + dX < minWidth) mOffX = (dX - (diffX = minWidth - elmW));
+        else if (elmX + elmW + dX > maxRight) mOffX = (dX - (diffX = maxRight - elmX - elmW));
+        elmW += diffX;
+        window.status = 'diffX:' + diffX;
+    }
+    // If 'rs' isn't set, we must be dragging the whole element, so move that.
+    if (dragging && !rs)
+    {
+        // Bounds check left-right...
+        if (elmX + dX < minLeft) mOffX = (dX - (diffX = minLeft - elmX));
+        else if (elmX + elmW + dX > maxRight) mOffX = (dX - (diffX = maxRight - elmX - elmW));
+        // ...and up-down.
+        if (elmY + dY < minTop) mOffY = (dY - (diffY = minTop - elmY));
+        else if (elmY + elmH + dY > maxBottom) mOffY = (dY - (diffY = maxBottom - elmY - elmH));
+        //window.status = 'diffX-' + diffX + ' , elmX-' + elmX;
+        elmX += diffX;
+        elmY += diffY;
+    }
+    
+    //window.status = 'elmX=' + elmX;
+    // Assign new info back to the element, with minimum dimensions.
+    with (element.style)
+    {
+        left =   elmX + 'px';
+        width =  elmW + 'px';
+        top =    elmY + 'px';
+        height = elmH + 'px';
+    }
+
+    // Evil, dirty, hackish Opera select-as-you-drag fix.
+    if (window.opera && document.documentElement)
+    {
+        var oDF = document.getElementById('op-drag-fix');
+        if (!oDF)
+        {
+            var oDF = document.createElement('input');
+            oDF.id = 'op-drag-fix';
+            oDF.style.display = 'none';
+            document.body.appendChild(oDF);
+        }
+        oDF.focus();
+    }
+
+    if (ondragmove) this.ondragmove();
+
+    // Stop a normal drag event.
+    cancelEvent(e);
+}};
+
+
+DragResize.prototype.mouseUp = function(e) { with (this)
+{
+    // On mouseup, stop dragging, but don't reset handler visibility.
+    if (!document.getElementById || !enabled) return;
+
+    if (ondragend) this.ondragend();
+    deselect(true);
+}};
+
+
+
Index: gs3-extensions/overlay-notes/trunk/src/annotator.min.css
===================================================================
--- gs3-extensions/overlay-notes/trunk/src/annotator.min.css	(revision 26826)
+++ gs3-extensions/overlay-notes/trunk/src/annotator.min.css	(revision 26826)
@@ -0,0 +1,618 @@
+.annotator-notice, .annotator-filter *, .annotator-widget * {
+	font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;
+	font-weight:normal;
+	text-align:left;
+	margin:0;
+	padding:0;
+	background:none;
+	-webkit-transition:none;
+	-moz-transition:none;
+	-o-transition:none;
+	transition:none;
+	-moz-box-shadow:none;
+	-webkit-box-shadow:none;
+	-o-box-shadow:none;
+	box-shadow:none;
+	color:#909090;
+}
+.annotator-adder {
+	background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAA3CAYAAADuQbOpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEVGMDAzMUQzOEYxMTFFMDlEMzBEQjFGNjc4QjA5NjAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEVGMDAzMUUzOEYxMTFFMDlEMzBEQjFGNjc4QjA5NjAiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowRUYwMDMxQjM4RjExMUUwOUQzMERCMUY2NzhCMDk2MCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowRUYwMDMxQzM4RjExMUUwOUQzMERCMUY2NzhCMDk2MCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqTirkQAABk0SURBVHja7FwJdBTH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');
+	background-repeat:no-repeat;
+}
+.annotator-resize, .annotator-widget::after, .annotator-editor a::after, .annotator-viewer .annotator-controls button, .annotator-filter .annotator-filter-navigation button::after, .annotator-filter .annotator-filter-property .annotator-filter-clear {
+	background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAEiCAYAAAD0w4JOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTgzMTc5QkE0NEQ0MTFFMDg0NThDMTEyQTJBNDEwMkUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTgzMTc5QkI0NEQ0MTFFMDg0NThDMTEyQTJBNDEwMkUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0QTgyRjZDRDQ0RDMxMUUwODQ1OEMxMTJBMkE0MTAyRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0QTgyRjZDRTQ0RDMxMUUwODQ1OEMxMTJBMkE0MTAyRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvMEaMUAAA9eSURBVHja7JsJVBRX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');
+	background-repeat:no-repeat;
+}
+.annotator-hl {
+	background:rgba(255,255,10,0.3);
+}
+.annotator-wrapper {
+	position:relative;
+}
+.annotator-adder, .annotator-outer, .annotator-notice {
+	z-index:9999;
+}
+.annotator-adder, .annotator-outer, .annotator-widget, .annotator-notice {
+	position:absolute;
+	font-size:10px;
+	line-height:1;
+}
+.annotator-hide {
+	display:none;
+	visibility:hidden;
+}
+.annotator-adder {
+	margin-top:-41px;
+	margin-left:-25px;
+	width:50px;
+	height:55px;
+	background-position:left top;
+}
+.annotator-adder:hover {
+	background-position:center top;
+}
+.annotator-adder:active {
+	background-position:center right;
+}
+.annotator-adder button {
+	display:block;
+	width:36px;
+	height:41px;
+	margin:0 auto;
+	border:none;
+	background:none;
+	text-indent:-999em;
+	cursor:pointer;
+}
+.annotator-outer {
+	width:0;
+	height:0;
+}
+.annotator-widget {
+	margin:0;
+	padding:0;
+	bottom:8px;
+	left:-18px;
+	min-width:265px;
+	background-color:rgba(251,251,251,0.98);
+	border:1px solid rgba(122,122,122,0.6);
+	-webkit-border-radius:5px;
+	-moz-border-radius:5px;
+	border-radius:5px;
+	-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.2);
+	-moz-box-shadow:0 5px 15px rgba(0,0,0,0.2);
+	-o-box-shadow:0 5px 15px rgba(0,0,0,0.2);
+	box-shadow:0 5px 15px rgba(0,0,0,0.2);
+}
+.annotator-invert-x .annotator-widget {
+	left:auto;
+	right:-18px;
+}
+.annotator-invert-y .annotator-widget {
+	bottom:auto;
+	top:8px;
+}
+.annotator-widget strong {
+	font-weight:bold;
+}
+.annotator-widget .annotator-listing, .annotator-widget .annotator-item {
+	padding:0;
+	margin:0;
+	list-style:none;
+}
+.annotator-widget::after {
+	content:"";
+	display:block;
+	width:18px;
+	height:10px;
+	background-position:0 0;
+	position:absolute;
+	bottom:-10px;
+	left:8px;
+}
+.annotator-invert-x .annotator-widget::after {
+	left:auto;
+	right:8px;
+}
+.annotator-invert-y .annotator-widget::after {
+	background-position:0 -15px;
+	bottom:auto;
+	top:-9px;
+}
+.annotator-widget .annotator-item, .annotator-editor .annotator-item input, .annotator-editor .annotator-item textarea {
+	position:relative;
+	font-size:12px;
+}
+.annotator-viewer .annotator-item {
+	border-top:2px solid rgba(122,122,122,0.2);
+}
+.annotator-widget .annotator-item:first-child {
+	border-top:none;
+}
+.annotator-editor .annotator-item, .annotator-viewer div {
+	border-top:1px solid rgba(133,133,133,0.11);
+}
+.annotator-viewer div {
+	padding:6px 6px;
+}
+.annotator-viewer .annotator-item ol, .annotator-viewer .annotator-item ul {
+	padding:4px 16px;
+}
+.annotator-viewer div:first-of-type, .annotator-editor .annotator-item:first-child textarea {
+	padding-top:12px;
+	padding-bottom:12px;
+	color:#3c3c3c;
+	font-size:13px;
+	font-style:italic;
+	line-height:1.3;
+	border-top:none;
+}
+.annotator-viewer .annotator-controls {
+	position:relative;
+	top:5px;
+	right:5px;
+	padding-left:5px;
+	opacity:0;
+	-webkit-transition:opacity .2s ease-in;
+	-moz-transition:opacity .2s ease-in;
+	-o-transition:opacity .2s ease-in;
+	transition:opacity .2s ease-in;
+	float:right;
+}
+.annotator-viewer li:hover .annotator-controls, .annotator-viewer li .annotator-controls.annotator-visible {
+	opacity:1;
+}
+.annotator-viewer .annotator-controls button {
+	cursor:pointer;
+	display:inline-block;
+	width:13px;
+	height:13px;
+	margin-left:2px;
+	border:none;
+	opacity:.2;
+	text-indent:-900em;
+	background-color:transparent;
+	outline:none;
+}
+.annotator-viewer .annotator-controls button:hover, .annotator-viewer .annotator-controls button:focus {
+	opacity:.9;
+}
+.annotator-viewer .annotator-controls button:active {
+	opacity:1;
+}
+.annotator-viewer .annotator-controls button[disabled] {
+	display:none;
+}
+.annotator-viewer .annotator-controls .annotator-edit {
+	background-position:0 -60px;
+}
+.annotator-viewer .annotator-controls .annotator-delete {
+	background-position:0 -75px;
+}
+.annotator-editor .annotator-item {
+	position:relative;
+}
+.annotator-editor .annotator-item label {
+	top:0;
+	display:inline;
+	cursor:pointer;
+}
+.annotator-editor .annotator-item input, .annotator-editor .annotator-item textarea {
+	display:block;
+	min-width:100%;
+	padding:10px 8px;
+	border:none;
+	margin:0;
+	color:#3c3c3c;
+	background:none;
+	border-radius:0;
+	height:auto;
+	width:auto;
+	line-height:auto;
+	-webkit-box-sizing:border-box;
+	-moz-box-sizing:border-box;
+	-o-box-sizing:border-box;
+	box-sizing:border-box;
+	resize:none;
+}
+.annotator-editor .annotator-item textarea::-webkit-scrollbar {
+height:8px;
+width:8px;
+}
+.annotator-editor .annotator-item textarea::-webkit-scrollbar-track-piece {
+margin:13px 0 3px;
+background-color:#e5e5e5;
+-webkit-border-radius:4px;
+}
+.annotator-editor .annotator-item textarea::-webkit-scrollbar-thumb:vertical {
+height:25px;
+background-color:#ccc;
+-webkit-border-radius:4px;
+-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);
+}
+.annotator-editor .annotator-item textarea::-webkit-scrollbar-thumb:horizontal {
+width:25px;
+background-color:#ccc;
+-webkit-border-radius:4px;
+}
+.annotator-editor .annotator-item:first-child textarea {
+	min-height:5.5em;
+	-webkit-border-radius:5px 5px 0 0;
+	-moz-border-radius:5px 5px 0 0;
+	-o-border-radius:5px 5px 0 0;
+	border-radius:5px 5px 0 0;
+}
+.annotator-editor .annotator-item input:focus, .annotator-editor .annotator-item textarea:focus {
+	background-color:#f3f3f3;
+	outline:none;
+}
+.annotator-editor .annotator-item input[type=radio], .annotator-editor .annotator-item input[type=checkbox] {
+	width:auto;
+	min-width:0;
+	padding:0;
+	display:inline;
+	margin:0 4px 0 0;
+	cursor:pointer;
+}
+.annotator-editor .annotator-checkbox {
+	padding:8px 6px;
+}
+.annotator-filter, .annotator-filter .annotator-filter-navigation button, .annotator-editor .annotator-controls {
+	text-align:right;
+	padding:3px;
+	border-top:1px solid #d4d4d4;
+	background-color:rgba(212,212,212,0.5);
+	background-image:-webkit-gradient(linear, left top, left bottom, from(#f5f5f5), color-stop(0.6, #dcdcdc), to(#d2d2d2));
+	background-image:-moz-linear-gradient(-90deg, #f5f5f5, #dcdcdc 60%, #d2d2d2);
+	background-image:-webkit-linear-gradient(-90deg, #f5f5f5, #dcdcdc 60%, #d2d2d2);
+	background-image:linear-gradient(-90deg, #f5f5f5, #dcdcdc 60%, #d2d2d2);
+	-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.7), inset -1px 0 0 rgba(255,255,255,0.7), inset 0 1px 0 rgba(255,255,255,0.7);
+	-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.7), inset -1px 0 0 rgba(255,255,255,0.7), inset 0 1px 0 rgba(255,255,255,0.7);
+	-o-box-shadow:inset 1px 0 0 rgba(255,255,255,0.7), inset -1px 0 0 rgba(255,255,255,0.7), inset 0 1px 0 rgba(255,255,255,0.7);
+	box-shadow:inset 1px 0 0 rgba(255,255,255,0.7), inset -1px 0 0 rgba(255,255,255,0.7), inset 0 1px 0 rgba(255,255,255,0.7);
+	-webkit-border-radius:0 0 5px 5px;
+	-moz-border-radius:0 0 5px 5px;
+	-o-border-radius:0 0 5px 5px;
+	border-radius:0 0 5px 5px;
+}
+.annotator-invert-y .annotator-controls {
+	border-top:none;
+	border-bottom:1px solid #b4b4b4;
+	-webkit-border-radius:5px 5px 0 0;
+	-moz-border-radius:5px 5px 0 0;
+	-o-border-radius:5px 5px 0 0;
+	border-radius:5px 5px 0 0;
+}
+.annotator-editor a, .annotator-filter .annotator-filter-property label {
+	position:relative;
+	display:inline-block;
+	padding:0 6px 0 22px;
+	color:#363636;
+	text-shadow:0 1px 0 rgba(255,255,255,0.75);
+	text-decoration:none;
+	line-height:24px;
+	font-size:12px;
+	font-weight:bold;
+	border:1px solid #a2a2a2;
+	background-color:rgba(212,212,212,0.5);
+	background-image:-webkit-gradient(linear, left top, left bottom, from(#f5f5f5), color-stop(0.5, #d2d2d2), color-stop(0.5, #bebebe), to(#d2d2d2));
+	background-image:-moz-linear-gradient(-90deg, #f5f5f5, #d2d2d2 50%, #bebebe 50%, #d2d2d2);
+	background-image:-webkit-linear-gradient(-90deg, #f5f5f5, #d2d2d2 50%, #bebebe 50%, #d2d2d2);
+	background-image:linear-gradient(-90deg, #f5f5f5, #d2d2d2 50%, #bebebe 50%, #d2d2d2);
+	-webkit-box-shadow:inset 0 0 5px rgba(255,255,255,0.2), inset 0 0 1px rgba(255,255,255,0.8);
+	-moz-box-shadow:inset 0 0 5px rgba(255,255,255,0.2), inset 0 0 1px rgba(255,255,255,0.8);
+	-o-box-shadow:inset 0 0 5px rgba(255,255,255,0.2), inset 0 0 1px rgba(255,255,255,0.8);
+	box-shadow:inset 0 0 5px rgba(255,255,255,0.2), inset 0 0 1px rgba(255,255,255,0.8);
+	-webkit-border-radius:5px;
+	-moz-border-radius:5px;
+	-o-border-radius:5px;
+	border-radius:5px;
+}
+.annotator-editor a::after {
+	position:absolute;
+	top:50%;
+	left:5px;
+	display:block;
+	content:"";
+	width:15px;
+	height:15px;
+	margin-top:-7px;
+	background-position:0 -90px;
+}
+
+
+.annotator-editor a:hover, .annotator-editor a:focus, .annotator-editor a.annotator-focus, .annotator-filter .annotator-filter-active label, .annotator-filter .annotator-filter-navigation button:hover {
+	outline:none;
+	border-color:#435aa0;
+	background-color:#3865f9;
+	background-image:-webkit-gradient(linear, left top, left bottom, from(#7691fb), color-stop(0.5, #5075fb), color-stop(0.5, #3865f9), to(#3665fa));
+	background-image:-moz-linear-gradient(-90deg, #7691fb, #5075fb 50%, #3865f9 50%, #3665fa);
+	background-image:-webkit-linear-gradient(-90deg, #7691fb, #5075fb 50%, #3865f9 50%, #3665fa);
+	background-image:linear-gradient(-90deg, #7691fb, #5075fb 50%, #3865f9 50%, #3665fa);
+	color:#fff;
+	text-shadow:0 -1px 0 rgba(0,0,0,0.42);
+}
+.annotator-editor a:hover::after, .annotator-editor a:focus::after {
+	margin-top:-8px;
+	background-position:0 -105px;
+}
+.annotator-editor a:active, .annotator-filter .annotator-filter-navigation button:active {
+	border-color:#700c49;
+	background-color:#d12e8e;
+	background-image:-webkit-gradient(linear, left top, left bottom, from(#fc7cca), color-stop(0.5, #e85db2), color-stop(0.5, #d12e8e), to(#ff009c));
+	background-image:-moz-linear-gradient(-90deg, #fc7cca, #e85db2 50%, #d12e8e 50%, #ff009c);
+	background-image:-webkit-linear-gradient(-90deg, #fc7cca, #e85db2 50%, #d12e8e 50%, #ff009c);
+	background-image:linear-gradient(-90deg, #fc7cca, #e85db2 50%, #d12e8e 50%, #ff009c);
+}
+.annotator-editor a.annotator-save::after {
+	background-position:0 -120px;
+}
+.annotator-editor a.annotator-save:hover::after, .annotator-editor a.annotator-save:focus::after, .annotator-editor a.annotator-save.annotator-focus::after {
+	margin-top:-8px;
+	background-position:0 -135px;
+}
+.annotator-editor .annotator-widget::after {
+	background-position:0 -30px;
+}
+.annotator-editor.annotator-invert-y .annotator-widget .annotator-controls {
+	background-color:#f2f2f2;
+}
+.annotator-editor.annotator-invert-y .annotator-widget::after {
+	background-position:0 -45px;
+	height:11px;
+}
+.annotator-resize {
+	position:absolute;
+	top:0;
+	right:0;
+	width:12px;
+	height:12px;
+	background-position:2px -150px;
+}
+.annotator-invert-x .annotator-resize {
+	right:auto;
+	left:0;
+	background-position:0 -195px;
+}
+.annotator-invert-y .annotator-resize {
+	top:auto;
+	bottom:0;
+	background-position:2px -165px;
+}
+.annotator-invert-y.annotator-invert-x .annotator-resize {
+	background-position:0 -180px;
+}
+.annotator-notice {
+	color:#fff;
+	position:absolute;
+	position:fixed;
+	top:-54px;
+	left:0;
+	width:100%;
+	font-size:14px;
+	line-height:50px;
+	text-align:center;
+	background:black;
+	background:rgba(0,0,0,0.9);
+	border-bottom:4px solid #d4d4d4;
+	-webkit-transition:top .4s ease-out;
+	-moz-transition:top .4s ease-out;
+	-o-transition:top .4s ease-out;
+	transition:top .4s ease-out;
+}
+.ie6 .annotator-notice {
+	position:absolute;
+}
+.annotator-notice-success {
+	border-color:#3665f9;
+}
+.annotator-notice-error {
+	border-color:#ff7e00;
+}
+.annotator-notice p {
+	margin:0;
+}
+.annotator-notice a {
+	color:#fff;
+}
+.annotator-notice-show {
+	top:0;
+}
+.annotator-tags {
+	margin-bottom:-2px;
+}
+.annotator-tags .annotator-tag {
+	display:inline-block;
+	padding:0 8px;
+	margin-bottom:2px;
+	line-height:1.6;
+	font-weight:bold;
+	background-color:#e6e6e6;
+	-webkit-border-radius:8px;
+	-moz-border-radius:8px;
+	-o-border-radius:8px;
+	border-radius:8px;
+}
+.annotator-filter {
+	z-index:10000;
+	position:fixed;
+	top:0;
+	right:0;
+	left:0;
+	text-align:left;
+	line-height:0;
+	border:none;
+	border-bottom:1px solid #878787;
+	padding-left:10px;
+	padding-right:10px;
+	-webkit-border-radius:0;
+	-moz-border-radius:0;
+	-o-border-radius:0;
+	border-radius:0;
+	-webkit-box-shadow:inset 0 -1px 0 rgba(255,255,255,0.3);
+	-moz-box-shadow:inset 0 -1px 0 rgba(255,255,255,0.3);
+	-o-box-shadow:inset 0 -1px 0 rgba(255,255,255,0.3);
+	box-shadow:inset 0 -1px 0 rgba(255,255,255,0.3);
+}
+.annotator-filter strong {
+	font-size:12px;
+	font-weight:bold;
+	color:#3c3c3c;
+	text-shadow:0 1px 0 rgba(255,255,255,0.7);
+	position:relative;
+	top:-9px;
+}
+.annotator-filter .annotator-filter-property, .annotator-filter .annotator-filter-navigation {
+	position:relative;
+	display:inline-block;
+	overflow:hidden;
+	line-height:10px;
+	padding:2px 0;
+	margin-right:8px;
+}
+.annotator-filter .annotator-filter-property label, .annotator-filter .annotator-filter-navigation button {
+	text-align:left;
+	display:block;
+	float:left;
+	line-height:20px;
+	-webkit-border-radius:10px 0 0 10px;
+	-moz-border-radius:10px 0 0 10px;
+	-o-border-radius:10px 0 0 10px;
+	border-radius:10px 0 0 10px;
+}
+.annotator-filter .annotator-filter-property label {
+	padding-left:8px;
+}
+.annotator-filter .annotator-filter-property input {
+	display:block;
+	float:right;
+	-webkit-appearance:none;
+	background-color:#fff;
+	border:1px solid #878787;
+	border-left:none;
+	padding:2px 4px;
+	line-height:16px;
+	min-height:16px;
+	font-size:12px;
+	width:150px;
+	color:#333;
+	background-color:#f8f8f8;
+	-webkit-border-radius:0 10px 10px 0;
+	-moz-border-radius:0 10px 10px 0;
+	-o-border-radius:0 10px 10px 0;
+	border-radius:0 10px 10px 0;
+	-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.2);
+	-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.2);
+	-o-box-shadow:inset 0 1px 1px rgba(0,0,0,0.2);
+	box-shadow:inset 0 1px 1px rgba(0,0,0,0.2);
+}
+.annotator-filter .annotator-filter-property input:focus {
+	outline:none;
+	background-color:#fff;
+}
+.annotator-filter .annotator-filter-clear {
+	position:absolute;
+	right:3px;
+	top:6px;
+	border:none;
+	text-indent:-900em;
+	width:15px;
+	height:15px;
+	background-position:0 -90px;
+	opacity:.4;
+}
+.annotator-filter .annotator-filter-clear:hover, .annotator-filter .annotator-filter-clear:focus {
+	opacity:.8;
+}
+.annotator-filter .annotator-filter-clear:active {
+	opacity:1;
+}
+.annotator-filter .annotator-filter-navigation button {
+	border:1px solid #a2a2a2;
+	padding:0;
+	text-indent:-900px;
+	width:20px;
+	min-height:22px;
+	-webkit-box-shadow:inset 0 0 5px rgba(255,255,255,0.2), inset 0 0 1px rgba(255,255,255,0.8);
+	-moz-box-shadow:inset 0 0 5px rgba(255,255,255,0.2), inset 0 0 1px rgba(255,255,255,0.8);
+	-o-box-shadow:inset 0 0 5px rgba(255,255,255,0.2), inset 0 0 1px rgba(255,255,255,0.8);
+	box-shadow:inset 0 0 5px rgba(255,255,255,0.2), inset 0 0 1px rgba(255,255,255,0.8);
+}
+.annotator-filter .annotator-filter-navigation button, .annotator-filter .annotator-filter-navigation button:hover, .annotator-filter .annotator-filter-navigation button:focus {
+	color:transparent;
+}
+.annotator-filter .annotator-filter-navigation button::after {
+	position:absolute;
+	top:9px;
+	left:8px;
+	content:"";
+	display:block;
+	width:7px;
+	height:7px;
+	background-position:0 -210px;
+}
+.annotator-filter .annotator-filter-navigation button:hover::after {
+	background-position:0 -225px;
+}
+.annotator-filter .annotator-filter-navigation .annotator-filter-next {
+	-webkit-border-radius:0 10px 10px 0;
+	-moz-border-radius:0 10px 10px 0;
+	-o-border-radius:0 10px 10px 0;
+	border-radius:0 10px 10px 0;
+	border-left:none;
+}
+.annotator-filter .annotator-filter-navigation .annotator-filter-next::after {
+	left:auto;
+	right:9px;
+	background-position:0 -240px;
+}
+.annotator-filter .annotator-filter-navigation .annotator-filter-next:hover::after {
+	background-position:0 -256px;
+}
+.annotator-hl-active {
+	background:rgba(255,255,10,0.8);
+}
+.annotator-hl-filtered {
+	background-color:transparent;
+}
+
+/* an entry that helps the annotator CSS play nicely when embedded within a SoundManager <ul> playlist */
+
+ul.playlist a.annotator-inline {
+	display: inline;
+	color: black;
+}
+
+ul.playlist a.annotator-inline:hover {
+	color: black;
+}
+
+ul.playlist a.annotator-inline:focus {
+	color: black;
+}
+
+ul.playlist li:hover a.annotator-inline {
+ color:black;
+}
+
+
+.annotator-editor a, .annotator-filter .annotator-filter-property label {
+	background-image: none;
+}
+
+
+.annotator-editor a:hover, .annotator-editor a:focus, .annotator-editor a.annotator-focus, .annotator-filter .annotator-filter-active label, .annotator-filter .annotator-filter-navigation button:hover {
+	border-color:#008000;
+	background-color:#00AA00;
+	background-image: none;
+	/* background-image:linear-gradient(-90deg, #CCDDCC, #A0CCA0 50%, #80AA80 50%, #00AA00 ); */
+}
+.annotator-editor a:hover::after, .annotator-editor a:focus::after {
+	margin-top:-8px;
+	background-position:0 -105px;
+}
+.annotator-editor a:active, .annotator-filter .annotator-filter-navigation button:active {
+	border-color:#49700c;
+	background-color:#8ed12e;
+	background-image: none;
+}
Index: gs3-extensions/overlay-notes/trunk/src/main-ingest.js
===================================================================
--- gs3-extensions/overlay-notes/trunk/src/main-ingest.js	(revision 26826)
+++ gs3-extensions/overlay-notes/trunk/src/main-ingest.js	(revision 26826)
@@ -0,0 +1,241 @@
+function checkLoop(pid, serverFunction, callback)
+{
+    var startLoop = function()
+    {
+	var loopCallback = 
+	    {
+		success:function(response)
+		{
+		    var checkText = response.responseText;
+		    if(checkText == null || checkText == "")
+		    {
+			console.log("There was an error getting the XML to check the status of " + serverFunction);
+		    }
+		    else
+		    {
+			var checkCodeStart = checkText.indexOf("code=\"") + 6;
+			var checkCodeEnd = checkText.indexOf("\"", checkCodeStart);
+			var code = checkText.substring(checkCodeStart, checkCodeEnd);
+			
+			if(code == 11 || code == 1) //11 is COMPLETED, 1 is success
+			{
+			    callback();
+			}
+			else if(code == 12 || code == 3) //12 is HALTED, 3 is ERROR 
+			{
+			    console.log("There was an error on the server, could not check status of " + serverFunction);
+			}
+			else
+			{
+			    setTimeout(startLoop, 1000);
+			}
+		    }
+		},
+		failed:function()
+		{
+		    console.log("There was a problem checking the status of " + serverFunction)
+		}
+	    }
+	YAHOO.util.Connect.asyncRequest("GET", gs.xsltParams.library_name + "?a=g&rt=s&ro=1&s=" + serverFunction + "&s1.pid=" + pid, loopCallback);
+    }
+    startLoop();
+}
+
+function buildFunction(collection)
+{
+    var buildCallback = 
+	{
+	    success:function(response)
+	    {
+		var buildText = response.responseText;
+		if(buildText == null || buildText == "")
+		{
+		    console.log("There was an error getting the xml response from the building request");
+		}
+		else
+		{
+		    var buildPIDStart = buildText.indexOf("pid=\"") + 5;
+		    var buildPIDEnd = buildText.indexOf("\"", buildPIDStart);
+		    var buildPID = buildText.substring(buildPIDStart, buildPIDEnd);
+		    
+		    checkLoop(buildPID, "BuildCollection", function()
+			      {
+				  var activateCallback = 
+				      {
+					  success: function(response)
+					  {
+					      var activateText = response.responseText;
+					      if(activateText == null || activateText == "")
+					      {
+						  console.log("There was an error getting the xml response from the activating request");
+					      }
+					      else
+					      {
+						  var activatePIDStart = activateText.indexOf("pid=\"") + 5;
+						  var activatePIDEnd = activateText.indexOf("\"", activatePIDStart);
+						  var activatePID = activateText.substring(activatePIDStart, activatePIDEnd);
+						  
+						  checkLoop(activatePID, "ActivateCollection", function()
+							    {
+								var updateCallback = 
+								    {
+									success: function(response){document.getElementById("buildStatusBar").style.visibility = "hidden";},
+									failed: function(reponse){ alert("Failed in saveFunction() to re-read config files"); document.getElementById("buildStatusBar").style.visibility = "hidden";}
+								    };
+								YAHOO.util.Connect.asyncRequest("GET", gs.xsltParams.library_name + "?a=s&sa=c", updateCallback);
+							    });
+					      }
+					  },
+					  failed: function(response)
+					  {
+					      document.getElementById("buildStatusBar").style.visibility = "hidden";
+					      console.log("Failed to get response from activate collection request");
+					  }
+				      }
+				  YAHOO.util.Connect.asyncRequest("GET", gs.xsltParams.library_name + "?a=g&rt=r&ro=1&s=ActivateCollection&s1.collection=" + collection, activateCallback);
+			      });
+		}
+	    },
+	    failed: function(){console.log("Failed to get build collection response"); document.getElementById("buildStatusBar").style.visibility = "hidden";}
+	}
+    
+    YAHOO.util.Connect.asyncRequest("GET", gs.xsltParams.library_name + "?a=g&rt=r&ro=1&s=BuildCollection&s1.collection=" + collection, buildCallback);
+    showBuildingMessage();
+}
+
+function saveAndBuildCollection(col)
+{			
+    for(var j = 0; j < gs.toDeleteArray.keys.length; j++)
+    {
+	var current = gs.toDeleteArray[gs.toDeleteArray.keys[j]];
+	if(current == null){continue;}
+	var metaToDelete = ["user", "text", "tags"];
+	for(var l = 0; l < metaToDelete.length; l++)
+	{
+	    var deleteArchivesURL = "cgi-bin/metadata-server.pl?\
+a=remove-archives-metadata&\
+c=" + gs.cgiParams.c + "&\
+site="+gs.xsltParams.site_name+"&\
+d=" + gs.cgiParams.d + "&\
+metaname=gstext." + metaToDelete[l] + "&\
+metavalue=" + ((l == 0) ? (current.user.name) : (current[metaToDelete[l]])); 
+	    
+	    var deleteIndexURL = "cgi-bin/metadata-server.pl?\
+a=remove-metadata&\
+c=" + gs.cgiParams.c + "&\
+site="+gs.xsltParams.site_name+"&\
+d=" + gs.cgiParams.d + "&\
+metaname=gstext." + metaToDelete[l] + "&\
+metavalue=" + ((l == 0) ? (current.user.name) : (current[metaToDelete[l]])); 
+	    
+	    var deleteImportURL = "cgi-bin/metadata-server.pl?\
+a=remove-import-metadata&\
+c=" + gs.cgiParams.c + "&\
+site="+gs.xsltParams.site_name+"&\
+d=" + gs.cgiParams.d + "&\
+metaname=gstext." + metaToDelete[l] + "&\
+metavalue=" + ((l == 0) ? (current.user.name) : (current[metaToDelete[l]]));
+	    var deleteArchivesCallback = 
+		{
+		    success:function(){},
+		    failed: function(){alert("Failed to save text annotations archives metadata");}
+		}
+	    YAHOO.util.Connect.asyncRequest("GET", deleteArchivesURL, deleteArchivesCallback);
+
+	    var deleteIndexCallback =
+		{
+		    success:function(){},
+		    failed: function(){alert("Failed to save text annotations index metadata");}
+		}
+	    YAHOO.util.Connect.asyncRequest("GET", deleteIndexURL, deleteIndexCallback);
+
+	    var deleteImportCallback =
+		{
+		    success:function(){},
+		    failed: function(){alert("Failed to save text annotations import metadata");}
+		}
+	    YAHOO.util.Connect.asyncRequest("GET", deleteImportURL, deleteImportCallback);
+	}
+    }
+    gs.toDeleteArray = new Array();
+    gs.toDeleteArray.keys = new Array();
+    
+    if(gs.annotationArray.keys.length > 0)
+    {
+	var json = "[";
+	for(var i = 0; i < gs.annotationArray.keys.length; i++)
+	{
+	    var current = gs.annotationArray[gs.annotationArray.keys[i]];
+	    if(current == null){continue;}					
+	    var metaToAdd = ["user", "text", "tags"];
+	    
+	    for(var j = 0; j < metaToAdd.length; j++)
+	    {
+		if(metaToAdd[j] == "user")
+		{
+		    json += '{"docid":"' + gs.cgiParams.d + '", "metaname":"gstext.' + metaToAdd[j] + '", "metavalue":"' + current.user.name + '"}';
+		}
+		else
+		{
+		    json += '{"docid":"' + gs.cgiParams.d + '", "metaname":"gstext.' + metaToAdd[j] + '", "metavalue":"' + current[metaToAdd[j]] + '"}';
+		}
+
+		if(j != (metaToAdd.length - 1) || i != (gs.annotationArray.keys.length - 1))
+		{
+		    json += ',';
+		}
+	    }
+	}
+	json += "]";
+
+	var saveArchivesURL = "cgi-bin/metadata-server.pl?a=set-archives-metadata-array&c=" + gs.cgiParams.c + "&site="+gs.xsltParams.site_name+"&collect=" + gs.cgiParams.c + "&json=" + json;
+	var saveIndexURL = "cgi-bin/metadata-server.pl?a=set-metadata-array&c=" + gs.cgiParams.c + "&site="+gs.xsltParams.site_name+"&collect=" + gs.cgiParams.c + "&json=" + json;
+	var saveImportURL = "cgi-bin/metadata-server.pl?a=set-import-metadata-array&c=" + gs.cgiParams.c + "&site="+gs.xsltParams.site_name+"&collect=" + gs.cgiParams.c + "&json=" + json;
+
+	var saveArchivesCallback = 
+	    {
+		success:function(){console.log("Away to build"); buildFunction(gs.cgiParams.c);},
+		failed: function(){alert("Failed to save text annotations index metadata");}
+	    }
+	YAHOO.util.Connect.asyncRequest("GET", saveArchivesURL, saveArchivesCallback);
+
+	var saveIndexCallback =
+	    {
+		success:function(){},
+		failed: function(){alert("Failed to save text annotations import metadata");}
+	    }
+	YAHOO.util.Connect.asyncRequest("GET", saveIndexURL, saveIndexCallback);
+
+	var saveImportCallback =
+	    {
+		success:function(){},
+		failed: function(){alert("Failed to save text annotations import metadata");}
+	    }
+	YAHOO.util.Connect.asyncRequest("GET", saveImportURL, saveImportCallback);
+    }
+    
+    gs.annotationArray = new Array();
+    gs.annotationArray.keys = new Array();
+}
+
+function showRebuildOption()
+{
+    var buildStatusBar = document.getElementById("buildStatusBar");
+    buildStatusBar.style.visibility = "visible";
+    
+    var buildMessage = document.getElementById("buildMessage");
+    buildMessage.innerHTML = 'Please rebuild to index annotations (make annotations searchable): <span id="rebuildButton" style="cursor:pointer; padding:2px;" class="ui-state-default ui-corner-all">Rebuild</span>';
+    
+    var rebuildButton = document.getElementById("rebuildButton");
+    rebuildButton.onclick = function(){saveAndBuildCollection("pj-flat");}
+}
+
+function showBuildingMessage()
+{
+    var buildStatusBar = document.getElementById("buildStatusBar");
+    buildStatusBar.style.visibility = "visible";
+    
+    var buildMessage = document.getElementById("buildMessage");
+    buildMessage.innerHTML = '<img src="' + gs.imageURLs.loading + '"/> Reindexing ...';
+}
+
Index: gs3-extensions/overlay-notes/trunk/src/main-notes.js
===================================================================
--- gs3-extensions/overlay-notes/trunk/src/main-notes.js	(revision 26826)
+++ gs3-extensions/overlay-notes/trunk/src/main-notes.js	(revision 26826)
@@ -0,0 +1,342 @@
+
+function OverlayNotes(divID,metaname)
+{
+    this.divID = divID;
+    this.metaname = metaname;
+
+    this.posCount = 0;
+
+    /* create the Photo Note Container */
+    this.notes = new PhotoNoteContainer(divID);
+
+    this.getNotes(divID,metaname);
+}
+
+OverlayNotes.prototype.deleteFunction = function(note)
+{
+    var status = true;
+    
+    if (note && note.id && note.id > 0) {
+	var metaposStr =  note.id - 1;
+	
+	var jsonVal = '{"caption":"' + note.text + '", "area":{"x":' + note.rect.left + ', "y":' + note.rect.top + ', "width":' + note.rect.width + ', "height":' + note.rect.height + '}}';
+	
+	var removeFromIndexURL = "cgi-bin/metadata-server.pl?a=remove-metadata&site="+gs.xsltParams.site_name+"&c=" + gs.cgiParams.c + "&d=" + gs.cgiParams.d + "&metaname="+this.metaname+"&metapos=" + metaposStr;
+	var removeFromArchivesURL = "cgi-bin/metadata-server.pl?a=remove-archives-metadata&site="+gs.xsltParams.site_name+"&c=" + gs.cgiParams.c + "&d=" + gs.cgiParams.d + "&metaname="+this.metaname+"&metapos=" + metaposStr;
+	var removeFromImportURL = "cgi-bin/metadata-server.pl?a=remove-import-metadata&site="+gs.xsltParams.site_name+"&c=" + gs.cgiParams.c + "&d=" + gs.cgiParams.d + "&metaname="+this.metaname+"&metavalue=" + jsonVal;
+	
+	var indexCallback =
+	    {
+		success: function(response)
+		{
+		    for(var i = 0; i < this.notes.length; i++)
+		    {
+			var currentNote = this.notes[i];
+			if(currentNote.id > note.id)
+			{
+			    currentNote.id--;
+			}
+		    }
+		    this.posCount--;
+		},
+		failed: function(){alert("Failed to delete index metadata of note with id: " + note.id);},
+	    };
+	
+	var archiveCallback = 
+	    {
+		success: function(){buildFunction(gs.cgiParams.c);},
+		failed: function(){alert("Failed to delete archive metadata of note with id: " + note.id);}
+	    }
+	
+	var importCallback =
+	    {
+		success: function(){},
+		failed: function(){alert("Failed to delete import metadata of note with id: " + note.id);}
+	    }
+	
+	YAHOO.util.Connect.asyncRequest("GET", removeFromIndexURL, indexCallback);
+	YAHOO.util.Connect.asyncRequest("GET", removeFromArchivesURL, archiveCallback);
+	YAHOO.util.Connect.asyncRequest("GET", removeFromImportURL, importCallback);
+    }
+    else {
+	alert("Failed to find valid note data to delete");
+	status = false;
+    }
+    
+    return status;
+}
+
+OverlayNotes.prototype.saveFunction = function(note)
+{
+    var saveIndexCallback = 
+	{
+	    success: function(response){},
+	    failed: function(reponse){ alert("Failed to save index metadata of note with id: " + note.id)},
+	};
+    
+    var saveArchivesCallback = 
+	{
+	    success: function(response){buildFunction(gs.cgiParams.c);},
+	    failed: function(response){ alert("Failed in save import metadata of note with id: " + note.id) }
+	};
+    
+    var saveImportCallback = 
+	{
+	    success: function(response){},
+	    failed: function(response){ alert("Failed in save import metadata of note with id: " + note.id) }
+	};
+    
+    var jsonVal = '{"caption":"' + note.text + '", "area":{"x":' + note.rect.left + ', "y":' + note.rect.top + ', "width":' + note.rect.width + ', "height":' + note.rect.height + '}}';
+    var metaposStr = (note && note.id && note.id > 0) ? note.id - 1 : this.posCount;
+    
+    var saveIndexURL = "cgi-bin/metadata-server.pl?a=set-metadata&site="+gs.xsltParams.site_name+"&c=" + gs.cgiParams.c + "&d=" + gs.cgiParams.d + "&metaname="+this.metaname+"&metamode=override&metavalue=" + jsonVal + "&metapos=" + metaposStr;
+    var saveArchivesURL = "cgi-bin/metadata-server.pl?a=set-archives-metadata&site="+gs.xsltParams.site_name+"&c=" + gs.cgiParams.c + "&d=" + gs.cgiParams.d + "&metaname="+this.metaname+"&metamode=override&metavalue=" + jsonVal + "&metapos=" + metaposStr;
+    var saveImportURL = "cgi-bin/metadata-server.pl?a=set-import-metadata&site="+gs.xsltParams.site_name+"&c=" + gs.cgiParams.c + "&d=" + gs.cgiParams.d + "&metaname="+this.metaname+"&metamode=override&metavalue=" + jsonVal + "&metapos=" + metaposStr;
+    YAHOO.util.Connect.asyncRequest("GET", saveIndexURL, saveIndexCallback);
+    YAHOO.util.Connect.asyncRequest("GET", saveArchivesURL, saveArchivesCallback);
+    YAHOO.util.Connect.asyncRequest("GET", saveImportURL, saveImportCallback);
+    
+    return 1;
+}				
+
+OverlayNotes.prototype.getNotes = function(divID,metaname)
+{
+    if(gs.variables[metaname] == null || gs.variables[metaname] == undefined)
+    {
+	console.log("No photo notes");
+	return;
+    }
+    
+    for(var i = 0; i < gs.variables[metaname].length; i++)
+    {
+	var metavals = gs.variables[metaname];
+	var note = metavals[i];
+	if(!note)
+	{
+	    continue;
+	}
+
+	var newNote = new PhotoNote(note.caption, divID, i+1, new PhotoNoteRect(note.area.x,note.area.y,note.area.width,note.area.height));
+
+	var that = this;
+	newNote.onsave = function(note) { return that.saveFunction(note) };
+	newNote.ondelete = function(note) { return that.deleteFunction(note) };
+
+	this.notes.AddNote(newNote);
+	this.posCount++;
+    }
+    
+    this.addNoteOverAndOutHandlers();
+}
+
+OverlayNotes.prototype.AddNote = function()
+{
+    this.posCount++;
+
+    var photoPos = $("#"+this.divID).offset();
+    
+    var newNote = new PhotoNote('Add note text here...',this.divID,this.posCount,new PhotoNoteRect(20,20,50,50));
+
+    var that = this;
+    newNote.onsave = function(note) { return that.saveFunction(note) };
+    newNote.ondelete = function(note) { return that.deleteFunction(note) };
+    this.notes.AddNote(newNote);
+    
+    this.addNoteOverAndOutHandlers();
+    newNote.Select();
+}
+
+OverlayNotes.prototype.addNoteOverAndOutHandlers = function()
+{
+    var divs = document.getElementsByTagName("DIV");
+    for(var i = 0; i < divs.length; i++)
+    {
+	if(divs[i].getAttribute("class") && divs[i].getAttribute("class").search("fn-area") != -1)
+	{
+	    divs[i].onmouseover = function(){_zoomEnabled = false;}
+	    divs[i].onmouseout = function(){_zoomEnabled = true;}
+	}
+    }
+}
+
+function addStatusBar()
+{
+    if (document.getElementById("buildStatusBar") != null) {
+	// already been added
+	return;
+    }
+
+    var textDiv = document.getElementById("gs-document");
+    var buildStatusBar = document.createElement("div");
+    buildStatusBar.setAttribute("id", "buildStatusBar");
+    buildStatusBar.setAttribute("class", "ui-state-default ui-corner-all");
+    buildStatusBar.setAttribute("style", "visibility:hidden; width:100%; margin-bottom: 10px;");
+    var buildingMessage = document.createElement("div");
+    buildingMessage.setAttribute("id", "buildMessage");
+    buildingMessage.setAttribute("style", "width:50%; padding:3px; margin:5px auto; text-align:center;");
+    buildStatusBar.appendChild(buildingMessage);
+
+    textDiv.insertBefore(buildStatusBar, textDiv.firstChild);
+}
+
+function prepopulateAnnotatorSearchBar()
+{
+    if(gs.cgiParams.s1_query && gs.cgiParams.s1_index == "GE")
+    {
+	$("#annotator-filter-text").val(gs.cgiParams.s1_query).keyup().blur(); 
+	console.log("AAA");
+    }
+    
+    if(gs.cgiParams.s1_query && gs.cgiParams.s1_index == "GT")
+    {
+	$("#annotator-filter-tags").val(gs.cgiParams.s1_query).keyup().blur(); 
+	console.log("BBB");
+    }
+    
+    if(gs.cgiParams.s1_query && gs.cgiParams.s1_index == "GX")
+    {
+	$("#annotator-filter-user").val(gs.cgiParams.s1_query).keyup().blur(); 
+	console.log("CCC");
+    }
+}
+
+function addPrevNextPageButtons()
+{
+    var buttonDiv = document.createElement("DIV");
+    var buttonTable = document.createElement("TABLE");
+    var buttonRow = document.createElement("TR");
+    var buttonPrevCell = document.createElement("TD");
+    var buttonNextCell = document.createElement("TD");
+    buttonRow.appendChild(buttonPrevCell);
+    buttonRow.appendChild(buttonNextCell);
+    buttonTable.appendChild(buttonRow);
+    buttonDiv.appendChild(buttonTable);
+
+    buttonDiv.setAttribute("style", "width:100%");
+    buttonTable.setAttribute("style", "margin:auto;");
+    buttonPrevCell.setAttribute("style", "padding:10px;");
+    buttonNextCell.setAttribute("style", "padding:10px;");
+
+    document.getElementById("gs-document-text").appendChild(buttonDiv);
+    
+    gs.functions.getArchivesMetadata(gs.cgiParams.c, gs.xsltParams.site_name, gs.cgiParams.d, "SourceFile", null, function(meta)
+				     {
+					 var sourceFilename = meta.getValue();
+					 var fileNameSegments = sourceFilename.split("-");
+					 var finalSegment = fileNameSegments[fileNameSegments.length-1];
+
+					 var extIndex = finalSegment.indexOf(".");
+					 var ext = "";
+					 if(extIndex != -1)
+					 {
+					     ext = finalSegment.substring(extIndex);
+					     finalSegment = finalSegment.substring(0, extIndex);
+					 }
+					 var finalNumber = parseInt(finalSegment);
+
+					 var prevFilename = "";
+					 var nextFilename = "";
+					 for(var i = 0; i < fileNameSegments.length - 1; i++)
+					 {
+					     prevFilename += fileNameSegments[i] + "-";
+					     nextFilename += fileNameSegments[i] + "-";
+					 }
+					 
+					 if(finalNumber - 1 >= 0)
+					 {
+					     var prevFinalNumber = "" + (finalNumber - 1);
+					     while(prevFinalNumber.length < finalSegment.length)
+					     {
+						 prevFinalNumber = "0" + prevFinalNumber;
+					     }
+					     prevFilename += prevFinalNumber + ext;
+					     
+					     prevButtonCallback = 
+						 {
+						     success:function(response)
+						     {
+							 var text = response.responseText;
+							 var startIndex = text.indexOf("nodeID=\"");
+							 if(startIndex == -1)
+							 {
+							     return;
+							 }
+							 startIndex += 8;
+							 endIndex = text.indexOf("\"", startIndex + 1);
+							 
+							 var id = text.substring(startIndex, endIndex);
+							 
+							 var prevLink = document.createElement("A");
+							 prevLink.innerHTML = "Previous Page";
+							 prevLink.setAttribute("href", gs.xsltParams.library_name + "?a=d&d=" + id + "&c=" + gs.cgiParams.c + "&dt=hierarchy&ed=1");
+							 buttonPrevCell.appendChild(prevLink);
+						     },
+						     failed:function(response){console.log("Search for previous document failed");}
+						 }
+					     YAHOO.util.Connect.asyncRequest("GET", gs.xsltParams.library_name + "?a=q&sa=&rt=rd&s=TextQuery&c=pj-flat&startPage=1&s1.query=" + prevFilename.replace(/-/g, " ") + "&s1.index=SO&o=xml", prevButtonCallback);
+					 }
+					 
+					 var nextFinalNumber = "" + (finalNumber + 1);
+					 while(nextFinalNumber.length < finalSegment.length)
+					 {
+					     nextFinalNumber = "0" + nextFinalNumber;
+					 }
+					 nextFilename += nextFinalNumber + ext;
+					 
+					 nextButtonCallback = 
+					     {
+						 success:function(response)
+						 {
+						     var text = response.responseText;
+						     var startIndex = text.indexOf("nodeID=\"");
+						     if(startIndex == -1)
+						     {
+							 return;
+						     }
+						     startIndex += 8;
+						     endIndex = text.indexOf("\"", startIndex + 1);
+						     
+						     var id = text.substring(startIndex, endIndex);
+						     
+						     var nextLink = document.createElement("A");
+						     nextLink.innerHTML = "Next Page";
+						     nextLink.setAttribute("href", gs.xsltParams.library_name + "?a=d&d=" + id + "&c=" + gs.cgiParams.c + "&dt=hierarchy&ed=1");
+						     buttonNextCell.appendChild(nextLink);
+						 },
+						 failed:function(response){console.log("Search for next document failed");}
+					     }
+					 
+					 YAHOO.util.Connect.asyncRequest("GET", gs.xsltParams.library_name + "?a=q&sa=&rt=rd&s=TextQuery&c=pj-flat&startPage=1&s1.query=" + nextFilename.replace(/-/g, " ") + "&s1.index=SO&o=xml", nextButtonCallback);
+				     });
+}
+
+function addSocialLinks()
+{
+    var socialLinksDiv = document.createElement("DIV");
+    socialLinksDiv.setAttribute("class", "addthis_toolbox addthis_default_style");
+    
+    var facebookLink = document.createElement("A");
+    facebookLink.setAttribute("class", "addthis_button_facebook_like");
+    facebookLink.setAttribute("fb:like:layout", "button_count");
+    socialLinksDiv.appendChild(facebookLink);
+    
+    var twitterLink = document.createElement("A");
+    twitterLink.setAttribute("class", "addthis_button_tweet");
+    socialLinksDiv.appendChild(twitterLink);
+    
+    var gplusLink = document.createElement("A");
+    gplusLink.setAttribute("class", "addthis_button_google_plusone");
+    gplusLink.setAttribute("g:plusone:size", "medium");
+    socialLinksDiv.appendChild(gplusLink);
+    
+    var addThisLink = document.createElement("A");
+    addThisLink.setAttribute("class", "addthis_counter addthis_pill_style");
+    socialLinksDiv.appendChild(addThisLink);
+    
+    var script = document.createElement("SCRIPT");
+    script.setAttribute("type", "text/javascript");
+    script.setAttribute("src", "http://s7.addthis.com/js/250/addthis_widget.js#pubid=xa-4f5fe0cf41940d54");
+    socialLinksDiv.appendChild(script);
+
+    document.getElementById("gs-document-text").appendChild(socialLinksDiv);
+}
