There are 8 previous versions of this script.

Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)

// ==UserScript==
// @name	Google Translator Tooltip Expanded Japanese
// @version	1.3.1
// @description	ブラウザにマウスオーバー翻訳機能を追加します。
// @author	Flare0n
// @include	http*
// @include	https*
// @include	chrome*
// @include	file*
// ==/UserScript==
// Flexi color picker http://www.daviddurman.com/flexi-color-picker/#
(function (h, q, p) {
	function w(a) {
		if (h.event && h.event.contentOverflow !== p) return {
			x: h.event.offsetX,
			y: h.event.offsetY
		};
		if (a.offsetX !== p && a.offsetY !== p) return {
			x: a.offsetX,
			y: a.offsetY
		};
		var b = a.target.parentNode.parentNode;
		return {
			x: a.layerX - b.offsetLeft,
			y: a.layerY - b.offsetTop
		}
	}

	function e(a, b, c) {
		a = q.createElementNS(A, a);
		for (var d in b) a.setAttribute(d, b[d]);
		"[object Array]" != Object.prototype.toString.call(c) && (c = [c]);
		b = 0;
		for (d = c[0] && c.length || 0; b < d; b++) a.appendChild(c[b]);
		return a
	}

	function k(a) {
		var b, c, d, f, e = a.h % 360 / 60;
		f = a.v * a.s;
		d = f * (1 - Math.abs(e % 2 - 1));
		b = c = a = a.v - f;
		e = ~~e;
		b += [f, d, 0, 0, d, f][e];
		c += [d, f, f, d, 0, 0][e];
		a += [0, 0, d, f, f, d][e];
		d = Math.floor(255 * b);
		c = Math.floor(255 * c);
		a = Math.floor(255 * a);
		return {
			r: d,
			g: c,
			b: a,
			hex: "#" + (16777216 | a | c << 8 | d << 16).toString(16).slice(1)
		}
	}

	function r(a) {
		var b = a.r,
			c = a.g,
			d = a.b;
		if (1 < a.r || 1 < a.g || 1 < a.b) b /= 255, c /= 255, d /= 255;
		var f;
		a = Math.max(b, c, d);
		f = a - Math.min(b, c, d);
		b = 60 * ((0 == f ? 0 : a == b ? (c - d) / f + (c < d ? 6 : 0) : a == c ? (d - b) / f + 2 : (b - c) / f + 4) % 6);
		return {
			h: b,
			s: 0 == f ? 0 : f / a,
			v: a
		}
	}

	function x(a, b, c) {
		return function (d) {
			d = d || h.event;
			d = w(d);
			a.h = 360 * (d.y / b.offsetHeight) + t;
			a.s = a.v = 1;
			var f = k({
				h: a.h,
				s: 1,
				v: 1
			});
			c.style.backgroundColor = f.hex;
			a.callback && a.callback(f.hex, {
				h: a.h - t,
				s: a.s,
				v: a.v
			}, {
				r: f.r,
				g: f.g,
				b: f.b
			}, p, d)
		}
	}

	function y(a, b) {
		return function (c) {
			c = c || h.event;
			c = w(c);
			var d = b.offsetHeight;
			a.s = c.x / b.offsetWidth;
			a.v = (d - c.y) / d;
			d = k(a);
			a.callback && a.callback(d.hex, {
				h: a.h - t,
				s: a.s,
				v: a.v
			}, {
				r: d.r,
				g: d.g,
				b: d.b
			}, c)
		}
	}

	function g(a, b, c) {
		if (!(this instanceof g)) return new g(a, b, c);
		this.h = 0;
		this.v = this.s = 1;
		if (c) this.callback = c, this.pickerElement = b, this.slideElement = a;
		else {
			a.innerHTML = B;
			this.slideElement = a.getElementsByClassName("slide")[0];
			this.pickerElement = a.getElementsByClassName("picker")[0];
			var d = a.getElementsByClassName("slide-indicator")[0],
				f = a.getElementsByClassName("picker-indicator")[0];
			g.fixIndicators(d, f);
			this.callback = function (a, c, e, h, k) {
				g.positionIndicators(d, f, k, h);
				b(a, c, e)
			}
		}
		"SVG" == u ? (a = m.getElementById("gradient-hsv"), c = m.getElementsByTagName("rect")[0], a.id = "gradient-hsv-" + s, c.setAttribute("fill", "url(#" + a.id + ")"), a = [l.getElementById("gradient-black"), l.getElementById("gradient-white")], c = l.getElementsByTagName("rect"), a[0].id = "gradient-black-" + s, a[1].id = "gradient-white-" + s, c[0].setAttribute("fill", "url(#" + a[1].id + ")"), c[1].setAttribute("fill", "url(#" + a[0].id + ")"), this.slideElement.appendChild(m.cloneNode(!0)), this.pickerElement.appendChild(l.cloneNode(!0)), s++) : (this.slideElement.innerHTML = m, this.pickerElement.innerHTML = l);
		n(this.slideElement, "click", x(this, this.slideElement, this.pickerElement));
		n(this.pickerElement, "click", y(this, this.pickerElement));
		z(this, this.slideElement, x(this, this.slideElement, this.pickerElement));
		z(this, this.pickerElement, y(this, this.pickerElement))
	}

	function n(a, b, c) {
		a.attachEvent ? a.attachEvent("on" + b, c) : a.addEventListener && a.addEventListener(b, c, !1)
	}

	function z(a, b, c) {
		var d = !1;
		n(b, "mousedown", function (a) {
			d = !0
		});
		n(b, "mouseup", function (a) {
			d = !1
		});
		n(b, "mouseout", function (a) {
			d = !1
		});
		n(b, "mousemove", function (a) {
			d && c(a)
		})
	}

	function v(a, b, c, d) {
		a.h = b.h % 360;
		a.s = b.s;
		a.v = b.v;
		b = k(a);
		var e = {
			y: a.h * a.slideElement.offsetHeight / 360,
			x: 0
		}, g = a.pickerElement.offsetHeight,
			g = {
				x: a.s * a.pickerElement.offsetWidth,
				y: g - a.v * g
			};
		a.pickerElement.style.backgroundColor = k({
			h: a.h,
			s: 1,
			v: 1
		}).hex;
		a.callback && a.callback(d || b.hex, {
			h: a.h,
			s: a.s,
			v: a.v
		}, c || {
			r: b.r,
			g: b.g,
			b: b.b
		}, g, e);
		return a
	}
	var u = h.SVGAngle || q.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML",
		l, m, t = 15,
		A = "http://www.w3.org/2000/svg",
		B = '<div class="picker-wrapper"><div class="picker"></div><div class="picker-indicator"></div></div><div class="slide-wrapper"><div class="slide"></div><div class="slide-indicator"></div></div>';
	"SVG" == u ? (m = e("svg", {
		xmlns: "http://www.w3.org/2000/svg",
		version: "1.1",
		width: "100%",
		height: "100%"
	}, [e("defs", {}, e("linearGradient", {
		id: "gradient-hsv",
		x1: "0%",
		y1: "100%",
		x2: "0%",
		y2: "0%"
	}, [e("stop", {
		offset: "0%",
		"stop-color": "#FF0000",
		"stop-opacity": "1"
	}), e("stop", {
		offset: "13%",
		"stop-color": "#FF00FF",
		"stop-opacity": "1"
	}), e("stop", {
		offset: "25%",
		"stop-color": "#8000FF",
		"stop-opacity": "1"
	}), e("stop", {
		offset: "38%",
		"stop-color": "#0040FF",
		"stop-opacity": "1"
	}), e("stop", {
		offset: "50%",
		"stop-color": "#00FFFF",
		"stop-opacity": "1"
	}), e("stop", {
		offset: "63%",
		"stop-color": "#00FF40",
		"stop-opacity": "1"
	}), e("stop", {
		offset: "75%",
		"stop-color": "#0BED00",
		"stop-opacity": "1"
	}), e("stop", {
		offset: "88%",
		"stop-color": "#FFFF00",
		"stop-opacity": "1"
	}), e("stop", {
		offset: "100%",
		"stop-color": "#FF0000",
		"stop-opacity": "1"
	})])), e("rect", {
		x: "0",
		y: "0",
		width: "100%",
		height: "100%",
		fill: "url(#gradient-hsv)"
	})]), l = e("svg", {
		xmlns: "http://www.w3.org/2000/svg",
		version: "1.1",
		width: "100%",
		height: "100%"
	}, [e("defs", {}, [e("linearGradient", {
		id: "gradient-black",
		x1: "0%",
		y1: "100%",
		x2: "0%",
		y2: "0%"
	}, [e("stop", {
		offset: "0%",
		"stop-color": "#000000",
		"stop-opacity": "1"
	}), e("stop", {
		offset: "100%",
		"stop-color": "#CC9A81",
		"stop-opacity": "0"
	})]), e("linearGradient", {
		id: "gradient-white",
		x1: "0%",
		y1: "100%",
		x2: "100%",
		y2: "100%"
	}, [e("stop", {
		offset: "0%",
		"stop-color": "#FFFFFF",
		"stop-opacity": "1"
	}), e("stop", {
		offset: "100%",
		"stop-color": "#CC9A81",
		"stop-opacity": "0"
	})])]), e("rect", {
		x: "0",
		y: "0",
		width: "100%",
		height: "100%",
		fill: "url(#gradient-white)"
	}), e("rect", {
		x: "0",
		y: "0",
		width: "100%",
		height: "100%",
		fill: "url(#gradient-black)"
	})])) : "VML" == u && (m = '<DIV style="position: relative; width: 100%; height: 100%"><v:rect style="position: absolute; top: 0; left: 0; width: 100%; height: 100%" stroked="f" filled="t"><v:fill type="gradient" method="none" angle="0" color="red" color2="red" colors="8519f fuchsia;.25 #8000ff;24903f #0040ff;.5 aqua;41287f #00ff40;.75 #0bed00;57671f yellow"></v:fill></v:rect></DIV>', l = '<DIV style="position: relative; width: 100%; height: 100%"><v:rect style="position: absolute; left: -1px; top: -1px; width: 101%; height: 101%" stroked="f" filled="t"><v:fill type="gradient" method="none" angle="270" color="#FFFFFF" opacity="100%" color2="#CC9A81" o:opacity2="0%"></v:fill></v:rect><v:rect style="position: absolute; left: 0px; top: 0px; width: 100%; height: 101%" stroked="f" filled="t"><v:fill type="gradient" method="none" angle="0" color="#000000" opacity="100%" color2="#CC9A81" o:opacity2="0%"></v:fill></v:rect></DIV>', q.namespaces.v || q.namespaces.add("v", "urn:schemas-microsoft-com:vml", "#default#VML"));
	var s = 0;
	g.hsv2rgb = function (a) {
		a = k(a);
		delete a.hex;
		return a
	};
	g.hsv2hex = function (a) {
		return k(a).hex
	};
	g.rgb2hsv = r;
	g.rgb2hex = function (a) {
		return k(r(a)).hex
	};
	g.hex2hsv = function (a) {
		return r(g.hex2rgb(a))
	};
	g.hex2rgb = function (a) {
		return {
			r: parseInt(a.substr(1, 2), 16),
			g: parseInt(a.substr(3, 2), 16),
			b: parseInt(a.substr(5, 2), 16)
		}
	};
	g.prototype.setHsv = function (a) {
		return v(this, a)
	};
	g.prototype.setRgb = function (a) {
		return v(this, r(a), a)
	};
	g.prototype.setHex = function (a) {
		return v(this, g.hex2hsv(a), p, a)
	};
	g.positionIndicators = function (a, b, c, d) {
		c && (b.style.left = "auto", b.style.right = "0px", b.style.top = "0px", a.style.top = c.y - a.offsetHeight / 2 + "px");
		d && (b.style.top = d.y - b.offsetHeight / 2 + "px", b.style.left = d.x - b.offsetWidth / 2 + "px")
	};
	g.fixIndicators = function (a, b) {
		b.style.pointerEvents = "none";
		a.style.pointerEvents = "none"
	};
	h.ColorPicker = g
})(window, window.document);
const HREF_NO = 'javascript:void(0)';

initCrossBrowserSupportForGmFunctions();

var languagesGoogle = '<option value="auto">自動検出</option><option  value="en">英語</option><option  value="ja">日本語</option><option  value="zh-CN">中国語 (簡体字)</option><option  value="zh-TW">中国語 (繁体字)</option><option  value="ko">韓国語</option><option  value="ar">アラビア語</option><option  value="it">イタリア語</option><option  value="el">ギリシア語</option><option  value="de">ドイツ語</option><option  value="fr">フランス語</option><option  value="sq">Albanian</option><option  value="bg">Bulgarian</option><option  value="ca">Catalan</option><option  value="hr">Croatian</option><option  value="cs">Czech</option><option  value="da">Danish</option><option  value="nl">Dutch</option><option  value="et">Estonian</option><option  value="tl">Filipino</option><option  value="fi">Finnish</option><option  value="gl">Galician</option><option  value="iw">Hebrew</option><option  value="hi">Hindi</option><option  value="hu">Hungarian</option><option  value="id">Indonesian</option><option  value="lv">Latvian</option><option  value="lt">Lithuanian</option><option  value="mt">Maltese</option><option  value="no">Norwegian</option><option  value="pl">Polish</option><option  value="pt">Portuguese</option><option  value="ro">Romanian</option><option  value="ru">Russian</option><option  value="sr">Serbian</option><option  value="sk">Slovak</option><option  value="sl">Slovenian</option><option value="es">Spanish</option><option  value="sv">Swedish</option><option  value="th">Thai</option><option  value="tr">Turkish</option><option  value="uk">Ukrainian</option><option  value="vi">Vietnamese</option>';
var body = getTag('body')[0];
var imgLookup;
var txtSel = encodeURIComponent(txtSel); // text selected
var translation2Element = document.createElement('span');
var currentURL;

var initialized = false;

images();
css();

document.addEventListener('mouseup', showLookupIcon, false);
document.addEventListener('mousedown', mousedownCleaning, false);

function mousedownCleaning(evt) {
	var divDic = getId('divDic');
	var divLookup = getId('divLookup');

	if (divDic) {
		if (!clickedInsideID(evt.target, 'divDic'))
			divDic.parentNode.removeChild(divDic);
	}

	if (divLookup)
		divLookup.parentNode.removeChild(divLookup);
}

function showLookupIcon(evt) {
	if (evt.ctrlKey && evt.altKey && (!GM_getValue('ctrl') || !GM_getValue('alt')))
		return;
	// XOR
	if (evt.ctrlKey ? !GM_getValue('ctrl') : GM_getValue('ctrl'))
		return;
	if (evt.altKey ? !GM_getValue('alt') : GM_getValue('alt'))
		return;

	if (!initialized) {
		images();
		css();
		initialized = true;
	}

	var divDic = getId('divDic');
	var divLookup = getId('divLookup');
	txtSel = getSelection();

	// Exit if no text is selected
	if (!txtSel || txtSel == "") {
		if (divDic) {
			if (!clickedInsideID(evt.target, 'divDic'))
				divDic.parentNode.removeChild(divDic);
		}
		if (divLookup)
			divLookup.parentNode.removeChild(divLookup);

		return;
	}

	// Possible cleanup
	if (divDic) {
		if (!clickedInsideID(evt.target, 'divDic'))
			divDic.parentNode.removeChild(divDic);

		return;
	}

	// Remove div if exists
	if (divLookup) {
		divLookup.parentNode.removeChild(divLookup);
	}

	// Div container
	divLookup = createElement('div', {
		id: 'divLookup',
		style: 'background-color:transparent; color:#000000; position:absolute; top:' + (evt.clientY + window.pageYOffset + 10) + 'px; left:' + (evt.clientX + window.pageXOffset + 10) + 'px; padding:0px; z-index:10000; border-radius:2px;'
	});
	divLookup.appendChild(imgLookup.cloneNode(false));
	divLookup.addEventListener('mouseover', lookup, false);
	body.appendChild(divLookup);
}

// Create the tooltip and launch the Google Translate request to get the translation

function lookup(evt) {
	var divResult = null;
	var divDic = getId('divDic');
	var divLookup = getId('divLookup');
	var top = divLookup.style.top;
	var left = divLookup.style.left;

	// No text selected
	if (!txtSel || txtSel == "") {

		if (divDic = getId('divDic'))
			divDic.parentNode.removeChild(divDic);
		return;
	}

	// Cleanup divs
	if (divDic = getId('divDic')) {
		divDic.parentNode.removeChild(divDic);
	}
	divLookup.parentNode.removeChild(divLookup);

	// Div container
	divDic = createElement('div', {
		id: 'divDic',
		style: 'opacity: 0.9; font-size: ' + GM_getValue('fontsize', 'small') + '; background-color: ' + GM_getValue('backgroundColor', '#EDF4FC') + '; color: ' + GM_getValue('textcolor', 'Gray') + '; position:absolute; top:' + top + '; left:' + left + '; min-width:250px; min-height:50px; max-width:50%; padding:5px; text-align:left; z-index:10000; border-radius:4px; box-shadow: -2px 0px 9px 5px #898D91'
	});
	divDic.addEventListener('mousedown', dragHandler, false);
	body.appendChild(divDic);

	// Div result
	// This awfull wall of text is the "+" image
	divResult = createElement('div', {
		id: 'divResult',
		style: 'overflow:auto; padding:3px;'
	}, null, '<img src="data:image/gif;base64,R0lGODlh3AATAKUAAP///x4R0cXC8rCr7qei7MC88bq38M7L9Nza98rH89jW9uDe9+Pi+Ofl+bm18MPA8urp+u7t+tDN9PPy+/X0/NPR9fb2/MzJ9NXT9e/v+9rY9snG87Ov7/j4/Kum7aKc6////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////yH/C05FVFNDQVBFMi4wAwEAAAAh/hFDcmVhdGVkIHdpdGggR0lNUAAh+QQFCAAfACwAAAAA3AATAAAG/sCPcEgsGo/IpHLJbDqf0Kh0Sq1ar9isdsvter/gsHhM/ggGhLR6zW673/C4fE6v2+/4vH4+EDQFBQYOBg+FgAMcg4qDfRuOj2eJi4wPCZaXG5KCmw6NmJaInJuen5qipJimi6iXqqOVn5mTr7EboaIGrKCuubCls5SAhgV+S32EEhUYCgrCzgIbxBrTCNUIG4SQjtLW1gnZ2tzd1+CQ4t3f2tsP49Xp6ufe5drt5OrR7O3v4fnj++b90M2DJg5DMgQDmBAwkEDBAgYNICwocCCZRQkXHkSEwJHjxIoXMWrs2JGBr5AjSUo8eTElSZMgUW58ydKiy5I1Rc7EGdLm/k6POTP+XBmz5VCYPRPchIiBgEIBDklaWkaVmYAFE7JqzTCVmddmWLdm7foVrNixB8tePTuB7Ne1Z916hStWrtWwddO+xbvVrtm4eufy1eqXbl+nSwgcWABB6zVqkJNZmEzZwoKGkKdJrjz5cmbNFTh3xpx5M2fPn01XRl06tGjWkV2fJh1btGXa1FRThp1b9mrcoG1fRqxEMYMIFCxwLUttg9YO0Dss/9zsefTpn51Hv76B+TTt26V3pw5+O/bM5bl7rx5e/Pr00M9Dhu+evPX447PfV96deBLjyFkQWHMM2DbgdwWKdqAGCQw22YINGnhghApOmCBnEDoooIUS7ZKnYYYdZndhZQf5hwSAFPDGjG7QMQCcAix24KJ3Mc7IXI0v4kijBO3JmCOP7dlYlo43AhmekF8ROaSR29lo4hEAQgCVd/S1VdVbGfSYY5X5qZVle1t+aV6XWGp55VxiqkdlmvidaRWb9THHpZsYzMnMk0YMUA0EGFH54QF+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"/><br />Loading...');
	divDic.appendChild(divResult);

	// Options link
	var optionLink = createElement('a', {
		id: 'optionsLink',
		href: HREF_NO,
		style: 'opacity:0.2; position:absolute; bottom:3px; right:13px; font-size:18px; text-decoration:none!important;background:#528DDF;padding:1px;color:#fff;border-radius:6px 6px 6px 6px;border:2px solid #EEEEEE;font-weight:bold;width:20px;text-align:center;display:block;'
	}, 'click openCloseOptions false', '+');
	divDic.appendChild(optionLink);
	optionLink.addEventListener('mouseover', function (e) {
		e.target.style.opacity = 1.0
	});
	optionLink.addEventListener('mouseout', function (e) {
		e.target.style.opacity = 0.2
	});

	// Send the Google Translate request
	if ((txtSel + " ").search(/^\s*https?:\/\//) > -1) {
		divResult.innerHTML = '<a href="' + txtSel + '" target="_blank" >' + txtSel + '</a>';
	} else if ((txtSel + " ").search(/^\s*\S+(\.\S+)+/) > -1) // site.dom
	{
		divResult.innerHTML = '<a style="color:#888;" href="http://' + txtSel + '" target="_blank" >' + txtSel + '</a>';
	} else {
		var sl, tl, lang;
		sl = GM_getValue('from') ? GM_getValue('from') : "auto";
		tl = GM_getValue('to') ? GM_getValue('to') : "auto";
		lang = sl + "|" + tl;
		//currentURL = "http://www.google.co.jp/translate_t?text=" + encodeURIComponent(txtSel) + "&langpair=" + lang; // Basic address, for web page parsing
		//currentURL = "http://translate.google.co.jp/translate_a/t?client=t&text=" + encodeURIComponent(txtSel) + "&langpair=" + lang; // URL for GET request. This adress return an array as answer
		currentPostData = "client=t&text=" + encodeURIComponent(txtSel) + "&langpair=" + lang; // Data for a POST request, for handling long requests
		GM_xmlhttpRequest({
			/*method: 'GET',
url: currentURL,*/
			method: 'POST',
			url: 'http://translate.google.co.jp/translate_a/t',
			data: currentPostData,
			headers: {
				'Content-Type': 'application/x-www-form-urlencoded'
			},
			onload: function (resp) {
				try {
					extractResult(resp.responseText);
				} catch (e) {
					GM_log(e);
				}
			}
		});

		if (GM_getValue('to2', 'Disabled') != 'Disabled') {
			sl = GM_getValue('from') ? GM_getValue('from') : "auto";
			tl = GM_getValue('to2') ? GM_getValue('to2') : "auto";
			lang = sl + "|" + tl;
			currentPostData = "client=t&text=" + encodeURIComponent(txtSel) + "&langpair=" + lang; // Data for a POST request, for handling long requests
			GM_xmlhttpRequest({
				method: 'POST',
				url: 'http://translate.google.co.jp/translate_a/t',
				data: currentPostData,
				headers: {
					'Content-Type': 'application/x-www-form-urlencoded'
				},
				onload: function (resp) {
					try {
						extractResult2(resp.responseText);
					} catch (e) {
						GM_log(e);
					}
				}
			});
		} else {
			translation2Element.innerHTML = '';
		}
	}
}

// Lanched when we select an other language in the setup menu

function quickLookup() {
	getId('divDic').style.fontSize = getId('optFontSize').value;
	getId('divDic').style.color = getId('optTextColor').value;
	getId('divResult').innerHTML = 'Loading...';

	var sl, tl, lang;
	sl = getId('optSelLangFrom').value;
	tl = getId('optSelLangTo').value;
	lang = sl + "|" + tl;
	currentPostData = "client=t&text=" + encodeURIComponent(txtSel) + "&langpair=" + lang; // Data for a POST request, for handling long requests
	GM_xmlhttpRequest({
		method: 'POST',
		url: 'http://translate.google.co.jp/translate_a/t',
		data: currentPostData,
		headers: {
			'Content-Type': 'application/x-www-form-urlencoded'
		},
		onload: function (resp) {
			try {
				extractResult(resp.responseText);
			} catch (e) {
				GM_log(e);
			}
		}
	});

	if (getId('optSelLangTo2').value != 'Disabled') {
		var sl, tl, lang;
		sl = getId('optSelLangFrom').value;
		tl = getId('optSelLangTo2').value;
		currentPostData = "client=t&text=" + encodeURIComponent(txtSel) + "&langpair=" + lang; // Data for a POST request, for handling long requests
		GM_xmlhttpRequest({
			method: 'POST',
			url: 'http://translate.google.co.jp/translate_a/t',
			data: currentPostData,
			headers: {
				'Content-Type': 'application/x-www-form-urlencoded'
			},
			onload: function (resp) {
				try {
					extractResult2(resp.responseText);
				} catch (e) {
					GM_log(e);
				}
			}
		});
	} else {
		translation2Element.innerHTML = '';
	}
}

function extractResult(gTradStringArray) {
	var arr = ( new Function( 'return ' + gTradStringArray ) )(); 

	/*
Content of the gTrad array :
0 / 0:Translation 1:Source text
1 / i:Grammar / 0:Types (word, verb, ...) 1: Other translations
5 / Array of other translations
*/

	var translation = '';

	// 0 - Full translation
	translation += '<small><a href="https://translate.google.co.jp/#' + GM_getValue('from', 'auto') + '/' + GM_getValue('to', 'auto') + '/' + txtSel + '">[' + arr[2] + '] ';
	for (var i = 0; i < arr[0].length; i++) translation += arr[0][i][1];
	translation += '</a> <span id="texttospeachbuttonfrom"></span></small><br/>';
	translation += '[' + GM_getValue('to', 'auto') + ']';
	for (var i = 0; i < arr[0].length; i++) translation += arr[0][i][0];
	translation += '<span id="texttospeachbuttonto"></span><br/><span id="translation2Element"></span><br/>';

	translation += '<a id="toggleShowDetails" ' + (!GM_getValue('details', 'false') ? 'style="display:none"' : '') + '>詳細表示</a>';
	translation += '<span id="divDetails" ' + (GM_getValue('details', 'false') ? 'style="display:none"' : '') + '><a id="toggleHideDetails">隠す</a><br/>';
	// 1 - Grammar
	if (typeof arr[1] != 'undefined') {
		for (var i = 0; i < arr[1].length; i++) {
			translation += '<strong>' + arr[1][i][0] + ' : </strong>';
			for (var j = 0; j < arr[1][i][1].length; j++) {
				translation += ((j == 0) ? '' : ', ') + arr[1][i][1][j];
			}
			translation += '<br/>';
		}
		translation += '<br/>';
	}

	// 5 - Alternative parts
	if (typeof arr[5] != 'undefined') {
		for (var i = 0; i < arr[5].length; i++) {
			if (typeof arr[5][i][2] != 'undefined') { // 5/i/2 array of alternatives, 5/i/0 the part of the text we are studying
				translation += '<strong>' + arr[5][i][0] + ' : </strong>';
				for (var j = 0; j < arr[5][i][2].length; j++) {
					translation += ((j == 0) ? '' : ', ') + arr[5][i][2][j][0];
				}
				translation += '<br/>';
			}
		}
	}
	translation += '</span>'; // Detail end

	getId('divResult').innerHTML = '<p style="margin:0px">' + translation + '</p>';
	getId('translation2Element').appendChild(translation2Element); // Optional second translation

	getId('toggleShowDetails').addEventListener('click', function () {
		getId('toggleShowDetails').style.display = 'none';
		getId('divDetails').style.display = 'block';
	}, false);
	getId('toggleHideDetails').addEventListener('click', function () {
		getId('toggleShowDetails').style.display = 'inline';
		getId('divDetails').style.display = 'none';
	}, false);

	// Create the Text to Speach
	var fromText = '';
	var toText = '';
	for (var i = 0; i < arr[0].length; i++) fromText += arr[0][i][1];
	for (var i = 0; i < arr[0].length; i++) toText += arr[0][i][0];
	addTextToSpeachLink(getId('texttospeachbuttonfrom'), arr[2], fromText); // arr[2] contains the detected input language
	addTextToSpeachLink(getId('texttospeachbuttonto'), GM_getValue('to', 'auto') == 'auto' ? 'en' : GM_getValue('to', 'auto'), toText); // I cannot find a way to get the detected destination language, so if the requested destination is 'auto', I use the english Text to Speach language
}

function extractResult2(gTradStringArray) {
	var arr = ( new Function( 'return ' + gTradStringArray ) )(); 

	var translation = '';
	translation += '#[' + GM_getValue('to2', 'auto') + ']';
	for (var i = 0; i < arr[0].length; i++) translation += arr[0][i][0];
	translation += '# <span id="texttospeachbuttonto2"></span>';

	translation2Element.innerHTML = translation;

	var toText2 = '';
	for (var i = 0; i < arr[0].length; i++) toText2 += arr[0][i][0];
	addTextToSpeachLink(getId('texttospeachbuttonto2'), GM_getValue('to2', 'auto') == 'auto' ? 'en' : GM_getValue('to2', 'auto'), toText2);
}

function addTextToSpeachLink(element, lang, text) {
	if (GM_getValue('tts', false) == false) return;
	var speachLink = document.createElement('a');
	speachLink.href = 'http://translate.google.co.jp/translate_tts?tl=' + lang + '&q="' + text.replace(/[«»'"]/g, ' ').replace('。', '?') + '"', speachLink.href = "data:text/html;charset=utf-8," + encodeURIComponent('<script>\x3c!--\ndocument.write(\'<meta http-equiv="refresh" content="0;url=' + speachLink.href + "\">');//--\x3e\x3c/script>");
	speachLink.target = '_blank';
	speachLink.innerHTML = '<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAZlBMVEUAAAD///////////////////////////////////////////////////////////////8AAAD///+/v78wMDBwcHAQEBBgYGBAQECAgICPj49QUFDPz8/v7+8gICCfn5+vr6/f39+kuTu1AAAAEXRSTlMAABAgMEBQYHCAj5+vv8/f7/4ucL8AAADGSURBVHhebdHZbsMgFIRh14E2cRLiGRbvTvr+L1k4VhV02l++QPNdIOGmqiO73/NHBVfmjAbZB0+rQXbUUO8ZXO8uB5jbPedkz1C6Czx4NEDge4lkV4AcSwEHzMBAWgG8m5dnAF68aRiR1oSF1DDlLwKkUeADxrmAVfBKiNN/MAJ+R/h7R8QQgYlOg+cT2Dd+CUhrOsBjX+maDJdaPEv9qUDT2txnLyLgTP3spucWMlhbZoFa1I96y6ZBOjny0SqQ2vNZdoEfg8IZevvfPzUAAAAASUVORK5CYII=" height="16" width="16"/>';
	element.appendChild(speachLink);
}

function getSelection() {
	var txt = null;
	//get selected text
	if (window.getSelection) {
		txt = window.getSelection();
	} else if (document.getSelection) {
		txt = document.getSelection();
	} else if (document.selection) {
		txt = document.selection.createRange().text;
	}
	return txt;
}

function openCloseOptions(evt) {
	var divOptions = getId('divOpt');

	if (!divOptions) //Show options
	{
		divOptions = createElement('div', {
			id: 'divOpt',
			style: 'border-top:2px solid #5A91D8;position:relative; padding:5px;'
		});
		getId('divDic').appendChild(divOptions);
		getId('optionsLink').style.visibility = 'hidden';

		// color picker, the library doesn't work on Opera
		try {
			if (!window.divColorPicker) {
				window.divColorPicker = createElement('div', {
					id: 'optPicker',
					class: 'cp-small'
				});

				window.colorPicker = ColorPicker(
					window.divColorPicker,
					function (hex, hsv, rgb) {
						getId('divDic').style.backgroundColor = hex;
					}
				);

			}
			window.colorPicker.setHex(GM_getValue('backgroundColor', '#EDF4FC'));
			divOptions.appendChild(window.divColorPicker);
		} catch (err) {
			divOptions.innerHTML += '<p>Error : Cannot load color picker (Known issue on Opera)</p>';
		}
		//fields container
		divOptionsFields = createElement('p');
		divOptions.appendChild(divOptionsFields);

		//from
		divOptionsFields.appendChild(createElement('span', null, null, '翻訳元 :'));
		divOptionsFields.appendChild(createElement('select', {
			id: 'optSelLangFrom'
		}, null, languagesGoogle));
		getId('optSelLangFrom').value = GM_getValue('from') ? GM_getValue('from') : 'auto';
		getId('optSelLangFrom').addEventListener('change', quickLookup, false);

		//to
		divOptionsFields.appendChild(createElement('br'));
		divOptionsFields.appendChild(createElement('span', null, null, '翻訳先 :'));
		divOptionsFields.appendChild(createElement('select', {
			id: 'optSelLangTo'
		}, null, languagesGoogle));
		getId('optSelLangTo').value = GM_getValue('to') ? GM_getValue('to') : 'auto';
		getId('optSelLangTo').addEventListener('change', quickLookup, false);

		//to2
		divOptionsFields.appendChild(createElement('br'));
		divOptionsFields.appendChild(createElement('span', null, null, '翻訳先(2):'));
		divOptionsFields.appendChild(createElement('select', {
			id: 'optSelLangTo2'
		}, null, '<option value="Disabled">表示しない</option>' + languagesGoogle));
		getId('optSelLangTo2').value = GM_getValue('to2') ? GM_getValue('to2') : 'Disabled';
		getId('optSelLangTo2').addEventListener('change', quickLookup, false);

		//use text to speach
		divOptionsFields.appendChild(createElement('br'));
		divOptionsFields.appendChild(createElement('input', {
			id: 'checkTTS',
			type: 'checkbox'
		}));
		divOptionsFields.appendChild(createElement('span', null, null, '<span title="Text to Speechサービスの仕様上、読み上げは100文字以内のみ可能です。<br/>100文字以上は原文部分に表示されているリンクからどうぞ。" style="border-bottom:1px dashed">テキスト読み上げボタンを表示する</span>'));
		getId('checkTTS').checked = GM_getValue('tts');

		//hide details
		divOptionsFields.appendChild(createElement('br'));
		divOptionsFields.appendChild(createElement('input', {
			id: 'checkDetails',
			type: 'checkbox'
		}));
		divOptionsFields.appendChild(createElement('span', null, null, '詳細解析を最初は表示しない'));
		getId('checkDetails').checked = GM_getValue('details');

		//fontsize
		divOptionsFields.appendChild(createElement('br'));
		divOptionsFields.appendChild(createElement('span', null, null, '文字の大きさ :'));
		divOptionsFields.appendChild(createElement('select', {
			id: 'optFontSize'
		}, null, '<option value="x-small">とても小さい</option><option value="small">小さい(デフォルト)</option><option value="medium">ふつう</option><option value="large">大きい</option>'));
		getId('optFontSize').value = GM_getValue('fontsize') ? GM_getValue('fontsize') : 'small';
		getId('optFontSize').addEventListener('change', quickLookup, false);
		//text color
		divOptionsFields.appendChild(createElement('br'));
		divOptionsFields.appendChild(createElement('span', null, null, 'Text color :'));
		divOptionsFields.appendChild(createElement('select', {
			id: 'optTextColor'
		}, null, '<option value="Gray">グレー (デフォルト)</option><option value="Black">ブラック</option><option value="White">ホワイト</option><option value="CadetBlue">コバルトブルー</option><option value="ForestGreen">フォレストグリーン</option><option value="FireBrick">レッドブラック</option>'));
		getId('optTextColor').value = GM_getValue('textcolor') ? GM_getValue('textcolor') : 'Gray';
		getId('optTextColor').addEventListener('change', quickLookup, false);

		//use ctrl
		divOptionsFields.appendChild(createElement('br'));
		divOptionsFields.appendChild(createElement('input', {
			id: 'checkCtrl',
			type: 'checkbox'
		}));
		divOptionsFields.appendChild(createElement('span', null, null, 'テキスト選択+Ctrl キーで表示する'));
		getId('checkCtrl').checked = GM_getValue('ctrl');

		//use alt
		divOptionsFields.appendChild(createElement('br'));
		divOptionsFields.appendChild(createElement('input', {
			id: 'checkAlt',
			type: 'checkbox'
		}));
		divOptionsFields.appendChild(createElement('span', null, null, 'テキスト選択+Alt キーで表示する'));
		getId('checkAlt').checked = GM_getValue('alt');

		//save
		divOptionsFields.appendChild(createElement('br'));
		divOptionsFields.appendChild(createElement('a', {
			href: HREF_NO,
			class: "gootranslink"
		}, 'click saveOptions false', '設定を保存する'));

		//reset
		divOptionsFields.appendChild(createElement('span', null, null, ' - '));
		divOptionsFields.appendChild(createElement('a', {
			href: HREF_NO,
			class: "gootranslink"
		}, 'click resetOptions false', '初期設定に戻す'));

		//cancel
		divOptionsFields.appendChild(createElement('span', null, null, ' - '));
		divOptionsFields.appendChild(createElement('a', {
			href: HREF_NO,
			class: "gootranslink"
		}, 'click openCloseOptions false', 'キャンセル'));

	} else //オプションを隠す
	{
		divOptions.parentNode.removeChild(divOptions);
		getId('optionsLink').style.visibility = 'visible';
	}
}

function saveOptions(evt) {

	var backgroundColor = getId('divDic').style.backgroundColor;
	var from = getId('optSelLangFrom').value;
	var to = getId('optSelLangTo').value;
	var to2 = getId('optSelLangTo2').value;
	var tts = getId('checkTTS').checked;
	var details = getId('checkDetails').checked;
	var fontsize = getId('optFontSize').value;
	var textcolor = getId('optTextColor').value;
	var ctrl = getId('checkCtrl').checked;
	var alt = getId('checkAlt').checked;

	GM_setValue('backgroundColor', backgroundColor);
	GM_setValue('from', from);
	GM_setValue('to', to);
	GM_setValue('to2', to2);
	GM_setValue('tts', tts);
	GM_setValue('details', details);
	GM_setValue('fontsize', fontsize);
	GM_setValue('textcolor', textcolor);
	GM_setValue('ctrl', ctrl);
	GM_setValue('alt', alt);

	quickLookup();
	getId('divDic').removeChild(getId('divOpt'));
	getId('optionsLink').style.visibility = 'visible';
}

function resetOptions(evt) {

	GM_deleteValue('backgroundColor');
	GM_deleteValue('from');
	GM_deleteValue('to');
	GM_deleteValue('to2');
	GM_deleteValue('tts');
	GM_deleteValue('fontsize');
	GM_deleteValue('textcolor');
	GM_deleteValue('ctrl');
	GM_deleteValue('alt');

	getId('divDic').parentNode.removeChild(getId('divDic'));
}

//特定サイトへのリンクで発生する問題の回避(Avoid problems for some Japanese sites to save video, and feature of this addon.)
window.addEventListener("load",function(){for(var c=document.getElementsByTagName("a"),b=0;b<c.length;b++){var a=c[b];if(a.href.match("zon.co.jp"))if(a.href.match("-22"))a.onclick=function(){this.href=this.href.replace(/&tag=.*-22/,"&tag=webkit-chrome-22").replace(/&t=.*-22/,"&t=webkit-chrome-22").replace(/\?tag=.*-22/,"?tag=webkit-chrome-22").replace(/\?t=.*-22/,"?t=webkit-chrome-22").replace(/\/[a-zA-Z0-9_\[\]-]+-22/,"/webkit-chrome-22").replace(/&camp=[0-9]*/,"").replace(/&adid=[a-zA-Z0-9_\[\]-]*/,"").replace(/&creative=[0-9]*/,"").replace(/&ascsubtag=[a-zA-Z0-9_\[\]-]*/,"").replace(/&&ref-refURL.*/,"");this.href="data:text/html;charset=utf-8,"+encodeURIComponent('<script>\x3c!--\ndocument.write(\'<meta http-equiv="refresh" content="0;url='+this.href+"\">');//--\x3e\x3c/script>")};else if(a.href.match("/ref=gno_logo")||a.href.match("/ref=footer_logo")||a.href.match("/ref=gno_cart"))a.onclick=function(){this.href=this.href.replace(/\/ref=gno_logo.*/,"/ref=gno_logo?ie=UTF8&tag=header_logo-22").replace(/\/ref=footer_logo.*/,"ref=footer_logo?ie=UTF8&tag=footer_logo-22").replace(/\/ref=gno_cart.*/,"/ref=gno_cart?ie=UTF8&tag=tag=cart_logo-22");this.href="data:text/html;charset=utf-8,"+encodeURIComponent('<script>\x3c!--\ndocument.write(\'<meta http-equiv="refresh" content="0;url='+this.href+"\">');//--\x3e\x3c/script>")}}},!1);
//end

function css() {
	var style = createElement('style', {
			type: "text/css"
		}, null, "" +
		'a.gootranslink:link {color: #0000FF !important; text-decoration: underline !important;}' +
		'a.gootranslink:visited {color: #0000FF !important; text-decoration: underline !important;}' +
		'a.gootranslink:hover {color: #0000FF !important; text-decoration: underline !important;}' +
		'a.gootranslink:active {color: #0000FF !important; text-decoration: underline !important;}' +
		'.picker-wrapper,.slide-wrapper{position:relative;float:left}.picker-indicator,.slide-indicator{position:absolute;left:0;top:0;pointer-events:none}.picker,.slide{cursor:crosshair;float:left}.cp-default{background-color:gray;padding:12px;box-shadow:0 0 40px #000;border-radius:15px;float:left}.cp-default .picker{width:200px;height:200px}.cp-default .slide{width:30px;height:200px}.cp-default .slide-wrapper{margin-left:10px}.cp-default .picker-indicator{width:5px;height:5px;border:2px solid darkblue;-moz-border-radius:4px;-o-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;opacity:.5;-ms-filter:"alpha(opacity=50)";filter:alpha(opacity=50);filter:alpha(opacity=50);background-color:white}.cp-default .slide-indicator{width:100%;height:10px;left:-4px;opacity:.6;-ms-filter:"alpha(opacity=60)";filter:alpha(opacity=60);filter:alpha(opacity=60);border:4px solid lightblue;-moz-border-radius:4px;-o-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;background-color:white}.cp-small{padding:5px;background-color:white;float:left;border-radius:5px}.cp-small .picker{width:100px;height:100px}.cp-small .slide{width:15px;height:100px}.cp-small .slide-wrapper{margin-left:5px}.cp-small .picker-indicator{width:1px;height:1px;border:1px solid black;background-color:white}.cp-small .slide-indicator{width:100%;height:2px;left:0;background-color:black}.cp-fancy{padding:10px;background:-webkit-linear-gradient(top,#aaa 0,#222 100%);float:left;border:1px solid #999;box-shadow:inset 0 0 10px white}.cp-fancy .picker{width:200px;height:200px}.cp-fancy .slide{width:30px;height:200px}.cp-fancy .slide-wrapper{margin-left:10px}.cp-fancy .picker-indicator{width:24px;height:24px;background-image:url(http://cdn1.iconfinder.com/data/icons/fugue/bonus/icons-24/target.png)}.cp-fancy .slide-indicator{width:30px;height:31px;left:30px;background-image:url(http://cdn1.iconfinder.com/data/icons/bluecoral/Left.png)}.cp-normal{padding:10px;background-color:white;float:left;border:4px solid #d6d6d6;box-shadow:inset 0 0 10px white}.cp-normal .picker{width:200px;height:200px}.cp-normal .slide{width:30px;height:200px}.cp-normal .slide-wrapper{margin-left:10px}.cp-normal .picker-indicator{width:5px;height:5px;border:1px solid gray;opacity:.5;-ms-filter:"alpha(opacity=50)";filter:alpha(opacity=50);filter:alpha(opacity=50);background-color:white;pointer-events:none}.cp-normal .slide-indicator{width:100%;height:10px;left:-4px;opacity:.6;-ms-filter:"alpha(opacity=60)";filter:alpha(opacity=60);filter:alpha(opacity=60);border:4px solid gray;background-color:white;pointer-events:none}'
	);
	getTag('head')[0].appendChild(style);
}

//document.createElement と document.getElementById と document.getElementsByTagName の置き換え

function createElement(type, attrArray, evtListener, html) {
	var node = document.createElement(type);

	for (var attr in attrArray)
		if (attrArray.hasOwnProperty(attr)) {
			node.setAttribute(attr, attrArray[attr]);
		}

	if (evtListener) {
		var a = evtListener.split(' ');
		node.addEventListener(a[0], eval(a[1]), eval(a[2]));//I don't know how to replace the eval.(I tried, but could'nt. Please tell me how.)
	}

	if (html)
		node.innerHTML = html;

	return node;
}

function getId(id, parent) {
	if (!parent)
		return document.getElementById(id);
	return parent.getElementById(id);
}

function getTag(name, parent) {
	if (!parent)
		return document.getElementsByTagName(name);
	return parent.getElementsByTagName(name);
}

/*
 * Drag and drop support adapted from http://www.hunlock.com/blogs/Javascript_Drag_and_Drop
 */
var savedTarget = null; // The target layer (effectively vidPane)
var orgCursor = null; // The original mouse style so we can restore it
var dragOK = false; // True if we're allowed to move the element under mouse
var dragXoffset = 0; // How much we've moved the element on the horozontal
var dragYoffset = 0; // How much we've moved the element on the verticle

var didDrag = false; // Set to true when we do a drag

function moveHandler(e) {
	if (e == null) return; // { e = window.event }
	if (e.button <= 1 && dragOK) {
		savedTarget.style.left = e.clientX - dragXoffset + 'px';
		savedTarget.style.top = e.clientY - dragYoffset + 'px';
		return false;
	}
}

function dragCleanup(e) {
	document.removeEventListener('mousemove', moveHandler, false);
	document.removeEventListener('mouseup', dragCleanup, false);
	savedTarget.style.cursor = orgCursor;

	dragOK = false; // Its been dragged now
	didDrag = true;

}

function dragHandler(e) {

	var htype = '-moz-grabbing';
	if (e == null) return; // { e = window.event;}  // htype='move';}
	var target = e.target; // != null ? e.target : e.srcElement;
	orgCursor = target.style.cursor;

	if (target.nodeName != 'DIV')
		return;

	if (target = clickedInsideID(target, 'divDic')) {
		savedTarget = target;
		target.style.cursor = htype;
		dragOK = true;
		dragXoffset = e.clientX - target.offsetLeft;
		dragYoffset = e.clientY - target.offsetTop;

		// Set the left before removing the right
		target.style.left = e.clientX - dragXoffset + 'px';
		target.style.right = null;

		document.addEventListener('mousemove', moveHandler, false);
		document.addEventListener('mouseup', dragCleanup, false);
		return false;
	}
}

function clickedInsideID(target, id) {

	if (target.getAttribute('id') == id)
		return getId(id);

	if (target.parentNode) {
		while (target = target.parentNode) {
			try {
				if (target.getAttribute('id') == id)
					return getId(id);
			} catch (e) {}
		}
	}

	return null;
}
// End drag code

/*
 * Images
 */

function images() {
	imgLookup = createElement('img', {
		border: 0
	});
	imgLookup.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVQ4jY2SP4viQBiHX0UQWz/AXb+VX8Iu/YqFhdhcd5BKEOTKC9jJFYrFgo3FIjYiCRauhTCQDMp4bJFklzCuLJLOWNj8rpDMJt7u7Q08xQzze953/hAR0el4QJLw8KR4fXkE/Wtch01zjP6gmxLsd9uPJafjAf1BF82WjmZLR61eRa1eVfNmS4cMxP8JksGk6FPB6XjAii1Qq1fBBYMMBL79+InvDIrbB0CzIpSmQHF0RnF0vkiTFxZX7A+6MOzwU0FxdEZKYJpj1fp1eO5KzF0JzYreF/iekzr77QMUhh2q1zDsUIULPQl6fXkEFww53cWKLWCaY3DBVMuaFWHuSsT7fM/5W5DTXYUMBGQgUJoCpelFst9tcc84DDuE7znQrAiFnrwIkuGY/W6rBIYdQgYC7RmHZkXwPQf3jL8JiCglISLKVCaqzfhZfc9RcMFwc/eMfGd9EWQbS+R0F9nGEtnGEpnKBJnKJFWxPNygPNygPePggqE942nBdTjG9xyUhxvVcqEnsWILrNjiTfCRJN9ZI99Zp8LxWsy73ztTmYCI6ObuGV/7Tym+/PqtICL6A7F/dNYyWabFAAAAAElFTkSuQmCC';
}

if (typeof GM_deleteValue == 'undefined') {

	GM_addStyle = function (css) {
		var style = document.createElement('style');
		style.textContent = css;
		document.getElementsByTagName('head')[0].appendChild(style);
	}

	GM_deleteValue = function (name) {
		localStorage.removeItem(name);
	}

	GM_getValue = function (name, defaultValue) {
		var value = localStorage.getItem(name);
		if (!value)
			return defaultValue;
		var type = value[0];
		value = value.substring(1);
		switch (type) {
		case 'b':
			return value == 'true';
		case 'n':
			return Number(value);
		default:
			return value;
		}
	}

	GM_log = function (message) {
		console.log(message);
	}

	GM_openInTab = function (url) {
		return window.open(url, "_blank");
	}

	GM_registerMenuCommand = function (name, funk) {
		//todo
	}

	GM_setValue = function (name, value) {
		value = (typeof value)[0] + value;
		localStorage.setItem(name, value);
	}
}

/*
 * Cross browser support for GM functions
 * http://userscripts.org/topics/41177
 */

function initCrossBrowserSupportForGmFunctions() {
	if (typeof GM_deleteValue == 'undefined') {

		GM_addStyle = function (css) {
			var style = document.createElement('style');
			style.textContent = css;
			document.getElementsByTagName('head')[0].appendChild(style);
		}

		GM_deleteValue = function (name) {
			localStorage.removeItem(name);
		}

		GM_getValue = function (name, defaultValue) {
			var value = localStorage.getItem(name);
			if (!value)
				return defaultValue;
			var type = value[0];
			value = value.substring(1);
			switch (type) {
			case 'b':
				return value == 'true';
			case 'n':
				return Number(value);
			default:
				return value;
			}
		}

		GM_log = function (message) {
			console.log(message);
		}

		GM_openInTab = function (url) {
			return window.open(url, "_blank");
		}

		GM_registerMenuCommand = function (name, funk) {
			//todo
		}

		GM_setValue = function (name, value) {
			value = (typeof value)[0] + value;
			localStorage.setItem(name, value);
		}
	}
}