diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..7fb690e6fd
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,23 @@
+IE/Debug/*
+IE/Release/*
+Chrome.pem
+XPI/reddit_res.xpi
+
+/Chrome/*.js
+/Chrome/*.css
+!/Chrome/background.js
+/RES.safariextension/*.js
+/RES.safariextension/*.css
+/Opera/includes/*.js
+/Opera/includes/*.css
+/Opera/modules/*.js
+/XPI/data/*.js
+/XPI/data/*.css
+!/XPI/lib/main.js
+!/lib/*
+/commentBoxes.css
+/nightmode.css
+/res.css
+
+
+.DS_Store
diff --git a/BUILD.md b/BUILD.md
new file mode 100644
index 0000000000..0587ddbc8f
--- /dev/null
+++ b/BUILD.md
@@ -0,0 +1,17 @@
+### Building release versions of the extension ###
+
+This document is here for RES developer reference/testing. Please do not distribute your own binaries unofficially - see README.md for an explanation as to why. Thanks!
+
+**Chrome**
+ 1. Go to ``Settings->Extensions`` and choose ``Pack extension``. Choose the ``Chrome`` folder for RES. You can also choose to sign the extension with a private key.
+ 2. This will generate a ``.crx`` and ``.pem`` file for your extension that you can install by dropping the ``.crx`` file in ``Chrome``.
+
+**Firefox**
+ 1. Make sure you have the addons SDK installed as described in the development section.
+ 2. In your terminal, ``cd`` to the ``XPI`` folder and run ``cfx xpi``. This should build an ``.xpi`` file that you can use to install RES.
+
+**Opera**
+ 1. Opera extensions are simply zip files. So all you need to do is zip up the contents of the ``Opera`` folder, but not the folder itself. So the zip should contain everything inside the ``Opera`` folder. Rename the ``.zip`` file to have the extension ``.oex`` instead. See [here](http://dev.opera.com/articles/view/opera-extensions-hello-world/#packaging) for more information.
+
+**Safari**
+ 1. Navigate to the ``Extension Builder`` panel as described in the development instructions. Assuming you have followed those instructions and installed RES, you can now choose ``build`` in the top right. This will generate a ``.safariextz`` file (signed by your certificate) that you can use to install RES.
diff --git a/Chrome/background.html b/Chrome/background.html
deleted file mode 100644
index 7111fefd93..0000000000
--- a/Chrome/background.html
+++ /dev/null
@@ -1,177 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Chrome/background.js b/Chrome/background.js
new file mode 100644
index 0000000000..dd37fbb8f6
--- /dev/null
+++ b/Chrome/background.js
@@ -0,0 +1,245 @@
+/*
+
+ RES is released under the GPL. However, I do ask a favor (obviously I don't/can't require it, I ask out of courtesy):
+
+ Because RES auto updates and is hosted from a central server, I humbly request that if you intend to distribute your own
+ modified Reddit Enhancement Suite, you name it something else and make it very clear to your users that it's your own
+ branch and isn't related to mine.
+
+ RES is updated very frequently, and I get lots of tech support questions/requests from people on outdated versions. If
+ you're distributing RES via your own means, those recipients won't always be on the latest and greatest, which makes
+ it harder for me to debug things and understand (at least with browsers that auto-update) whether or not people are on
+ a current version of RES.
+
+ I can't legally hold you to any of this - I'm just asking out of courtesy.
+
+ Thanks, I appreciate your consideration. Without further ado, the all-important GPL Statement:
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+*/
+
+XHRCache = {
+ forceCache: false,
+ capacity: 250,
+ entries: {},
+ count: 0,
+ check: function(key) {
+ if (key in this.entries) {
+// console.count("hit");
+ this.entries[key].hits++;
+ return this.entries[key].data;
+ } else {
+// console.count("miss");
+ return null;
+ }
+ },
+ add: function(key, value) {
+ if (key in this.entries) {
+ return;
+ } else {
+// console.count("add");
+ this.entries[key] = {data: value, timestamp: new Date(), hits: 1};
+ this.count++;
+ }
+ if (this.count > this.capacity) {
+ this.prune();
+ }
+ },
+ prune: function() {
+ var now = new Date();
+ var bottom = [];
+ for (var key in this.entries) {
+// if (this.entries[key].hits == 1) {
+// delete this.entries[key];
+// this.count--;
+// continue;
+// }
+
+ //Weight by hits/age which is similar to reddit's hit/controversial sort orders
+ bottom.push({
+ key: key,
+ weight: this.entries[key].hits/(now - this.entries[key].timestamp)
+ });
+ }
+ bottom.sort(function(a,b){return a.weight-b.weight;});
+ var count = this.count - Math.floor(this.capacity / 2);
+ for (var i = 0; i < count; i++) {
+ delete this.entries[bottom[i].key];
+ this.count--;
+ }
+// console.count("prune");
+ },
+ clear: function() {
+ this.entries = {};
+ this.count = 0;
+ }
+};
+
+chrome.extension.onMessage.addListener(
+ function(request, sender, sendResponse) {
+ switch(request.requestType) {
+ case 'deleteCookie':
+ // Get chrome cookie handler
+ if (!chrome.cookies) {
+ chrome.cookies = chrome.experimental.cookies;
+ }
+ chrome.cookies.remove({'url': 'http://reddit.com', 'name': request.cname});
+ break;
+ case 'GM_xmlhttpRequest':
+ if (request.aggressiveCache || XHRCache.forceCache) {
+ var cachedResult = XHRCache.check(request.url);
+ if (cachedResult) {
+ sendResponse(cachedResult);
+ return;
+ }
+ }
+ var xhr = new XMLHttpRequest();
+ xhr.open(request.method, request.url, true);
+ if (request.method == "POST") {
+ xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ }
+ xhr.onreadystatechange = function(a) {
+ if (xhr.readyState == 4) {
+ //Only store `status` and `responseText` fields
+ var response = {status: xhr.status, responseText: xhr.responseText};
+ sendResponse(response);
+ //Only cache on HTTP OK and non empty body
+ if ((request.aggressiveCache || XHRCache.forceCache) && (xhr.status == 200 && xhr.responseText)) {
+ XHRCache.add(request.url, response);
+ }
+ }
+ };
+ xhr.send(request.data);
+ return true;
+ break;
+ case 'singleClick':
+ var button = !((request.button == 1) || (request.ctrl == 1));
+ // Get the selected tab so we can get the index of it. This allows us to open our new tab as the "next" tab.
+ var newIndex = sender.tab.index+1;
+ // handle requests from singleClick module
+ if (request.openOrder == 'commentsfirst') {
+ // only open a second tab if the link is different...
+ if (request.linkURL != request.commentsURL) {
+ chrome.tabs.create({url: request.commentsURL, selected: button, index: newIndex, openerTabId: sender.tab.id});
+ }
+ chrome.tabs.create({url: request.linkURL, selected: button, index: newIndex+1, openerTabId: sender.tab.id});
+ } else {
+ chrome.tabs.create({url: request.linkURL, selected: button, index: newIndex, openerTabId: sender.tab.id});
+ // only open a second tab if the link is different...
+ if (request.linkURL != request.commentsURL) {
+ chrome.tabs.create({url: request.commentsURL, selected: button, index: newIndex+1, openerTabId: sender.tab.id});
+ }
+ }
+ sendResponse({status: "success"});
+ break;
+ case 'keyboardNav':
+ var button = !(request.button == 1);
+ // handle requests from keyboardNav module
+ thisLinkURL = request.linkURL;
+ if (thisLinkURL.toLowerCase().substring(0,4) != 'http') {
+ (thisLinkURL.substring(0,1) == '/') ? thisLinkURL = 'http://www.reddit.com' + thisLinkURL : thisLinkURL = location.href + thisLinkURL;
+ }
+ // Get the selected tab so we can get the index of it. This allows us to open our new tab as the "next" tab.
+ var newIndex = sender.tab.index+1;
+ chrome.tabs.create({url: thisLinkURL, selected: button, index: newIndex, openerTabId: sender.tab.id});
+ sendResponse({status: "success"});
+ break;
+ case 'openLinkInNewTab':
+ var focus = (request.focus === true);
+ // handle requests from keyboardNav module
+ thisLinkURL = request.linkURL;
+ if (thisLinkURL.toLowerCase().substring(0,4) != 'http') {
+ (thisLinkURL.substring(0,1) == '/') ? thisLinkURL = 'http://www.reddit.com' + thisLinkURL : thisLinkURL = location.href + thisLinkURL;
+ }
+ // Get the selected tab so we can get the index of it. This allows us to open our new tab as the "next" tab.
+ var newIndex = sender.tab.index+1;
+ chrome.tabs.create({url: thisLinkURL, selected: focus, index: newIndex, openerTabId: sender.tab.id});
+ sendResponse({status: "success"});
+ break;
+ case 'compareVersion':
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", request.url, true);
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ // JSON.parse does not evaluate the attacker's scripts.
+ var resp = JSON.parse(xhr.responseText);
+ sendResponse(resp);
+ }
+ };
+ xhr.send();
+ return true;
+ break;
+ case 'loadTweet':
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", request.url, true);
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ // JSON.parse does not evaluate the attacker's scripts.
+ var resp = JSON.parse(xhr.responseText);
+ sendResponse(resp);
+ }
+ };
+ xhr.send();
+ return true;
+ break;
+ case 'getLocalStorage':
+ sendResponse(localStorage);
+ break;
+ case 'saveLocalStorage':
+ for (var key in request.data) {
+ localStorage.setItem(key,request.data[key]);
+ }
+ localStorage.setItem('importedFromForeground',true);
+ sendResponse(localStorage);
+ break;
+ case 'localStorage':
+ switch (request.operation) {
+ case 'getItem':
+ sendResponse({status: true, value: localStorage.getItem(request.itemName)});
+ break;
+ case 'removeItem':
+ localStorage.removeItem(request.itemName);
+ sendResponse({status: true, value: null});
+ break;
+ case 'setItem':
+ localStorage.setItem(request.itemName, request.itemValue);
+ sendResponse({status: true, value: null});
+ var thisTabID = sender.tab.id;
+ chrome.tabs.query({}, function(tabs){
+ for (var i = 0; i < tabs.length; i++) {
+ if (thisTabID != tabs[i].id) {
+ chrome.tabs.sendMessage(tabs[i].id, { requestType: "localStorage", itemName: request.itemName, itemValue: request.itemValue });
+ }
+ }
+ });
+ break;
+ }
+ break;
+ case 'addURLToHistory':
+ chrome.history.addUrl({url: request.url});
+ break;
+ case 'XHRCache':
+ switch (request.operation) {
+ case 'clear':
+ XHRCache.clear();
+ break;
+ }
+ break;
+ default:
+ sendResponse({status: "unrecognized request type"});
+ break;
+ }
+ }
+);
diff --git a/Chrome/icon128.png b/Chrome/icon128.png
index 11a223d02a..ce1db3b43b 100644
Binary files a/Chrome/icon128.png and b/Chrome/icon128.png differ
diff --git a/Chrome/icon48.png b/Chrome/icon48.png
index d51a6c0b5f..c9cb7661ff 100644
Binary files a/Chrome/icon48.png and b/Chrome/icon48.png differ
diff --git a/Chrome/jquery-1.6.4.min.js b/Chrome/jquery-1.6.4.min.js
deleted file mode 100644
index 628ed9b316..0000000000
--- a/Chrome/jquery-1.6.4.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery v1.6.4 http://jquery.com/ | http://jquery.org/license */
-(function(a,b){function cu(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cr(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cq(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cp(){cn=b}function co(){setTimeout(cp,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bv(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bd,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function U(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function M(a,b){return(a&&a!=="*"?a+".":"")+b.replace(y,"`").replace(z,"&")}function L(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function J(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function D(){return!0}function C(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function K(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(K,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.4",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;B.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-1000px",top:"-1000px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bn.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bm,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bm.test(g)?g.replace(bm,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bv(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bw=function(a,c){var d,e,g;c=c.replace(bo,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bx=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bp.test(d)&&bq.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bv=bw||bx,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bz=/%20/g,bA=/\[\]$/,bB=/\r?\n/g,bC=/#.*$/,bD=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bE=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bF=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bG=/^(?:GET|HEAD)$/,bH=/^\/\//,bI=/\?/,bJ=/
\ No newline at end of file
+
diff --git a/README b/README
deleted file mode 100644
index 32ea0fe0c6..0000000000
--- a/README
+++ /dev/null
@@ -1,76 +0,0 @@
-Reddit Enhancement Suite - github README
-
-/// FIRST, a note:
-
-Hi there! Thanks for checking out RES on github. A few important notes:
-
-1) RES is GPLed, which means you're technically free to do whatever you wish in terms
-of redistribution. However, I ask out of courtesy that should you choose to release
-your own, separate distribution of RES, you please name it something else completely.
-Unfortunately, I have run into problems in the past with people redistributing under
-the same name, and causing me tech support headaches.
-
-2) Related: RES is not submitted to browser extension pages like the Chrome Extension
-Gallery, AMO, etc, because the hope/intent is to provide simultaneous releases for all
-four browsers at once - which is not possible given the variable approval times in each
-gallery. I ask that you please do not submit your own RES that isn't renamed there
-just to get browser syncing of extensions going - because like in #1, it has caused me
-issues in the past. Someone decided to submit to Chrome's gallery, then I was getting
-tech support requests from people who were on an old (his) version and weren't getting
-auto updated through my distribution channel.
-
-I can't stop you from doing any of this. I'm just asking out of courtesy because I already
-spend a great deal of time providing tech support and chasing down bugs, and it's much harder
-when people think I'm the support guy for a separate branch of code.
-
-Thanks!
-
-Steve Sobel
-steve@honestbleeps.com
-
-/// OKAY! On to what you came to the readme for - how is this project structured?
-
-- README - (YOU ARE HERE)
-
-- changelog.txt - self explanatory
-
-- lib/reddit_enhancement_suite.user.js
- This is the core userscript. There are hard links (which I hope github translates
- properly, we'll see!) from each browser's own directory to this file. Note that
- because Safari's extension builder barfs on symlinks, I had to use hard links instead.
-
-- Chrome/
- This directory contains the following:
- - background.html - the "background page" for RES, necessary for chrome extensions
- - manifest.json - the project manifest
- - icon.png, icon48.png, icon128.png - icons!
- - jquery-1.6.4.min.js - jquery 1.6.4!
- - reddit_enhancement_suite.user.js - a hard link to ../lib, not the "actual file"...
-
-- Opera/
- This directory contains the following:
- - index.html - the "background page" for RES, necessary for opera extensions
- - config.xml - Opera's equivalent of Chrome's manifest.json
- - logo.gif - a logo gif!
- - includes/reddit_enhancement_suite.user.js - a hard link to ../lib, not the "actual file"...
-
-
-- RES.safariextension/
- NOTE: This directory must have .safariextension in the name, or Safari's extension builder pukes.
- This directory contains the following:
- - background-safari.html - the "background page" for RES, necessary for safari extensions
- - Info.plist - the project manifest
- - icon.png, icon48.png, icon128.png - icons!
- - jquery-1.6.4.min.js - jquery 1.6.4!
- - reddit_enhancement_suite.user.js - a hard link to ../lib, not the "actual file"...
-
-
-- XPI/
- NOTE: An XPI is a Firefox addon... This is compiled using the Addon SDK.
- This directory contains the following:
- - lib/main.js - this is firefox's sort of "background page" for RES, like what chrome has, but just a JS file
- - data/jquery-1.6.4.min.js - jquery 1.6.4!
- - data/reddit_enhancement_suite.user.js - a hard link to ../lib, not the "actual file"...
- - doc/main.md - "documentation" file that's not currently being used.
- - README.md - "documentation" file that's not currently being used.
- - package.json - the project manifest for the Firefox addon
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000..fb71542ad6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,91 @@
+For general documentation, see the RES Wiki (http://redditenhancementsuite.com:8080/wiki/index.php?title=Main\_Page), at least until the new documentation is finished.
+
+### FIRST, a note ###
+
+Hi there! Thanks for checking out RES on GitHub. A few important notes:
+
+1. RES is licensed under GPLv3, which means you're technically free to do whatever you wish in terms of redistribution. However, I ask out of courtesy that should you choose to release your own, separate distribution of RES, you please name it something else entirely. Unfortunately, I have run into problems in the past with people redistributing under the same name, and causing me tech support headaches.
+
+2. I ask that you please do not distribute your own binaries of RES (e.g. with bugfixes, etc). The version numbers in RES are important references for tech support so that we can replicate bugs that users report using the same version they are, and when you distribute your own - you run the risk of polluting/confusing that. In addition, if a user overwrites his/her extension with your distributed copy, it may not properly retain their RES settings/data depending on the developer ID used, etc.
+
+I can't stop you from doing any of this. I'm just asking out of courtesy because I already spend a great deal of time providing tech support and chasing down bugs, and it's much harder when people think I'm the support guy for a separate branch of code.
+
+Thanks!
+
+Steve Sobel
+steve@honestbleeps.com
+
+### OKAY! On to what you came to the readme for - how is this project structured? ###
+
+- README - (YOU ARE HERE - unless you're on GitHub browsing)
+
+- changelog.txt - self explanatory
+
+- lib/reddit\_enhancement\_suite.user.js
+ This is the core userscript. You will need to create a set of hard links from this script under each browser specific folder. Unfortunately, Github does not maintain these hard links on committing. Note that because Safari's extension builder barfs on symlinks, you must use hard links instead.
+
+- Chrome/ This directory contains the following:
+ - background.html - the "background page" for RES, necessary for chrome extensions
+ - manifest.json - the project manifest
+ - icon.png, icon48.png, icon128.png - icons!
+ - jquery-1.6.4.min.js - jquery 1.6.4!
+ - reddit_enhancement_suite.user.js - a hard link to ../lib
+
+
+- Opera/ This directory contains the following:
+ - index.html - the "background page" for RES, necessary for opera extensions
+ - config.xml - Opera's equivalent of Chrome's manifest.json
+ - logo.gif - a logo gif!
+ - includes/reddit_enhancement_suite.user.js - a hard link to ../lib
+
+
+- RES.safariextension/ NOTE: This directory must have .safariextension in the name, or Safari's extension builder pukes.
+ This directory contains the following:
+ - background-safari.html - the "background page" for RES, necessary for safari extensions
+ - Info.plist - the project manifest
+ - icon.png, icon48.png, icon128.png - icons!
+ - jquery-1.6.4.min.js - jquery 1.6.4!
+ - reddit_enhancement_suite.user.js - a hard link to ../lib
+
+
+- XPI/ NOTE: An XPI is a Firefox addon... This is compiled using the Addon SDK.
+ This directory contains the following:
+
+ - lib/main.js - this is firefox's sort of "background page" for RES, like what chrome has, but just a JS file
+
+ - data/jquery-1.6.4.min.js - jquery 1.6.4!
+
+ - data/reddit_enhancement_suite.user.js - a hard link to ../lib
+
+ - doc/main.md - "documentation" file that's not currently being used.
+
+ - README.md - "documentation" file that's not currently being used.
+
+ - package.json - the project manifest for the Firefox addon
+
+### Building development versions of the extension ###
+
+One thing to note is that if you switch branches this will break you hard links. Therefore, you must create them when checking out new pieces of code.
+
+**Chrome**
+ 1. Go to ``Settings->Extensions`` and tick the ``Developer Mode`` checkbox
+ 2. Choose ``Load unpacked extension`` and point it to the ``Chrome`` folder. Make sure you have created the hard link to ``lib/reddit_enhancement_suite.js`` before doing this. Make sure you only have one RES version running at a time.
+ 3. Any time you make changes to the script you must go back to the ``Settings->Extensions`` page and ``Reload`` the extension.
+
+**Firefox**
+ 1. Download the addon SDK from [here](https://ftp.mozilla.org/pub/mozilla.org/labs/jetpack/jetpack-sdk-latest.zip).
+ 2. Start a terminal and source the python script so that you can run the ``cfx`` commands. In Unix this is usually ``. bin/activate`` or ``source bin/activate`` and in Windows this usually involves running ``Scripts/activate.bat``.
+ 3. In the terminal, ``cd`` to the ``XPI`` folder and run the command ``cfx run``, which should launch a new Firefox browser using a temporary profile with only RES installed. Make sure you have create the hard link to ``lib/reddit_enhancement_suite.js`` before doing this.
+
+**Safari (assumes Mac)**
+ 1. Open the ``Preferences`` by going to ``Safari->Preferences`` or pressing ``⌘,``, then go to ``Advanced`` and check the checkbox for ``Show develop menu in menu bar``.
+ 2. Navigate to ``Develop->Show Extension Builder`` to open the extensions menu. Add a new extension by pressing the ``+`` in the bottom left and choosing ``Add extension``.
+ 3. Navigate to the ``RES.safariextension`` folder for RES and select it. Make sure you have created the hard link to ``lib/reddit_enhancement_suite.js`` before doing this.
+ 4. It will likely say you cannot install it becase no Safari development certificate exists. You will need to visit the [Safari Dev Center](https://developer.apple.com/devcenter/safari/index.action) and create an account (right hand side).
+ 5. You then need to visit the [Safari Developer Program](https://developer.apple.com/programs/safari/) site and sign up for a FREE account.
+ 6. You can then visit your member page and use the certificate utility to create a new Safari Developer Certificate. Follow the instructions to install the certificate. If you have an error involving it being signed by an unknown authority, then doubleclick the certificate and under the ``Trust`` setting choose ``Always Trust``. You should then be able to install the extension from the ``Extension Builder`` menu.
+
+**Opera**
+ 1. Click ``Tools->Extensions->Manage Extensions``
+ 2. Drag the ``config.xml`` file in the ``Opera`` directory in to the extensions window and release. You should now have installed the extension. Make sure you have created the hard link to ``lib/reddit_enhancement_suite.js`` before doing this.
+
diff --git a/RES.safariextension/Info.plist b/RES.safariextension/Info.plist
index 407a2040f6..e3696247c1 100644
--- a/RES.safariextension/Info.plist
+++ b/RES.safariextension/Info.plist
@@ -5,7 +5,7 @@
AuthorSteve SobelBuilder Version
- 534.50
+ 8536.29.13CFBundleDisplayNameReddit Enhancement SuiteCFBundleIdentifier
@@ -13,9 +13,9 @@
CFBundleInfoDictionaryVersion6.0CFBundleShortVersionString
- 4.0.2
+ 4.2.0.2CFBundleVersion
- 4.0.2
+ 4.2.0.2ChromeDatabase Quota
@@ -27,10 +27,16 @@
Scripts
- End
+ Start
+ jquery-1.9.1.min.js
+ guiders-1.2.8.js
+ jquery.dragsort-0.4.3.min.js
+ jquery-fieldselection.min.js
+ tinycon.js
+ jquery.tokeninput.js
+ snuownd.jsreddit_enhancement_suite.user.js
- jquery-1.6.4.min.js
@@ -52,9 +58,12 @@
api.imgur.commin.us*.flickr.com
+ imgclean.comimg.photobucket.comgdata.youtube.comredditenhancementsuite.com
+ backend.deviantart.com
+ api.tumblr.comInclude Secure Pages
diff --git a/RES.safariextension/background-safari.html b/RES.safariextension/background-safari.html
index 85aeba1917..37263c3399 100644
--- a/RES.safariextension/background-safari.html
+++ b/RES.safariextension/background-safari.html
@@ -34,12 +34,76 @@
-
\ No newline at end of file
+
diff --git a/RES.safariextension/jquery-1.6.4.min.js b/RES.safariextension/jquery-1.6.4.min.js
deleted file mode 100644
index 628ed9b316..0000000000
--- a/RES.safariextension/jquery-1.6.4.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery v1.6.4 http://jquery.com/ | http://jquery.org/license */
-(function(a,b){function cu(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cr(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cq(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cp(){cn=b}function co(){setTimeout(cp,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bv(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bd,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function U(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function M(a,b){return(a&&a!=="*"?a+".":"")+b.replace(y,"`").replace(z,"&")}function L(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function J(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function D(){return!0}function C(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function K(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(K,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.4",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;B.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-1000px",top:"-1000px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="