summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Xu <alex_y_xu@yahoo.ca>2014-04-16 15:17:31 -0400
committerAlex Xu <alex_y_xu@yahoo.ca>2014-04-16 15:17:31 -0400
commite417662dce5cae2e95ef98ee38baa8f53a02b9d5 (patch)
treedce94fb8524dece7e3fcc677ec0cf908a6ec2a97
parent6a50d79523cf215001cdd55c74c040bd410775df (diff)
downloadhtml5ks-e417662dce5cae2e95ef98ee38baa8f53a02b9d5.tar.xz
html5ks-e417662dce5cae2e95ef98ee38baa8f53a02b9d5.zip
mbleh
-rwxr-xr-x.travis.sh2
-rw-r--r--Makefile37
-rwxr-xr-xast2json/rpyc2json.py2
-rwxr-xr-xast2json/script2json.py2
-rwxr-xr-xast2json/settings2json.py19
-rw-r--r--nginx.inc.conf17
-rwxr-xr-xnginx.sh52
-rw-r--r--www/css/index.css30
-rw-r--r--www/js/api.js125
-rw-r--r--www/js/html5ks.js26
-rw-r--r--www/js/menu.js13
-rw-r--r--www/warn.html21
-rw-r--r--www/warned.html16
-rw-r--r--www/warned.php2
14 files changed, 168 insertions, 196 deletions
diff --git a/.travis.sh b/.travis.sh
index c5a46aa..c637b4f 100755
--- a/.travis.sh
+++ b/.travis.sh
@@ -4,7 +4,7 @@ set -e -x
case "$1" in
before_install)
- ln -s $(command -v python) /usr/local/bin/python
+ sudo ln -s $(command -v python) /usr/local/bin/python
sudo service postgresql stop
sudo service mysql stop
sudo apt-get update -qq
diff --git a/Makefile b/Makefile
index c606599..58f9960 100644
--- a/Makefile
+++ b/Makefile
@@ -50,14 +50,16 @@ www/js/lib/when.js: when
IRPYC := ast2json/imachine.rpyc ast2json/imachine_replay.rpyc
IJSON := $(IRPYC:ast2json/%.rpyc=www/json/%.json)
-URPYC := ast2json/ui-strings.rpyc ast2json/ui-strings_FR.rpyc
-UJSON := $(URPYC:ast2json/%.rpyc=www/json/%.json)
+TRPYC := ast2json/ui-strings.rpyc ast2json/ui-strings_FR.rpyc
+TJSON := $(TRPYC:ast2json/%.rpyc=www/json/%.json)
+
+ERPYC := ast2json/ui_settings.rpyc
+EJSON := $(ERPYC:ast2json/%.rpyc=www/json/%.json)
SRPYC := $(wildcard ast2json/script-a*.rpyc)
-JSONI := $(SRPYC:%.rpyc=%.json.i)
SJSON := $(SRPYC:ast2json/%.rpyc=www/json/%.json)
-JSON := $(IJSON) $(UJSON) $(SJSON)
+JSON := $(IJSON) $(TJSON) $(EJSON) $(SJSON)
JSONGZ := $(JSON:=.gz)
AJSON := $(JSON) $(JSONGZ)
@@ -69,21 +71,24 @@ json: $(AJSON)
$(SJSON): www/json/%.json: ast2json/script2json.py ast2json/%.json.i
$^ $@
-$(UJSON): www/json/%.json: ast2json/strings2json.py ast2json/%.json.i
+$(TJSON): www/json/%.json: ast2json/strings2json.py ast2json/%.json.i
$^ $@
$(IJSON): www/json/%.json: ast2json/imachine2json.py ast2json/%.json.i
$^ $@
+$(EJSON): www/json/%.json: ast2json/settings2json.py ast2json/%.json.i
+ $^ $@
+
%.json.gz: %.json
-ifdef GZIP
-ifdef DEFLUFF
- $(GZIP) -c $< | $(DEFLUFF) > $@
-else
- $(GZIP) -c $< > $@
-endif
- touch $< $@
-endif
+ $(if $(GZIP),
+ $(if $(DEFLUFF),
+ $(GZIP) -c $< | $(DEFLUFF) > $@
+ ,
+ $(GZIP) -c $< > $@
+ )
+ touch $< $@
+ )
# === VIDEO ===
@@ -189,7 +194,7 @@ www/dump/ui/ctc_anim.webp: $(CTC_ANIM_TMP_WEBP)
# === MISC ===
-test: $(MYJS)
+test: $(MYJS) $(AJSON)
jshint --show-non-errors $^
space:
@@ -209,5 +214,5 @@ MAKEFLAGS=-LRr
.SUFFIXES:
.PRECIOUS: $(WAV)
-.INTERMEDIATE: $(WAV) $(JSONO) $(Y4M) $(CTC_ANIM_TMP_ALL) $(CTC_ANIM_TMP_WEBP)
-.PHONY: video audio images js jshint space watch
+.INTERMEDIATE: $(WAV) $(Y4M) $(CTC_ANIM_TMP_ALL) $(CTC_ANIM_TMP_WEBP)
+.PHONY: video audio images js test space watch
diff --git a/ast2json/rpyc2json.py b/ast2json/rpyc2json.py
index b1dc592..7c8518b 100755
--- a/ast2json/rpyc2json.py
+++ b/ast2json/rpyc2json.py
@@ -79,6 +79,8 @@ def get_value(attr_value):
}
if isinstance(attr_value, renpy.ast.ArgumentInfo):
return list(map(lambda x: getattr(attr_value, x), ["arguments", "extrapos", "extrakw"]))
+ if isinstance(attr_value, renpy.ast.ParameterInfo):
+ return dict((name, getattr(attr_value, name)) for name in dir(attr_value) if not name.startswith('__'))
if isinstance(attr_value, renpy.atl.RawBlock):
return 'ATL not implemented'
diff --git a/ast2json/script2json.py b/ast2json/script2json.py
index 60be575..d5cafa2 100755
--- a/ast2json/script2json.py
+++ b/ast2json/script2json.py
@@ -44,7 +44,7 @@ def print_Return(stmt):
return [stmt['expression']]
def print_UserStatement(stmt):
- return [stmt['line']]
+ return [stmt['line'], stmt['parsed']]
def print_Init(stmt):
raise NotImplementedError()
diff --git a/ast2json/settings2json.py b/ast2json/settings2json.py
new file mode 100755
index 0000000..a72239d
--- /dev/null
+++ b/ast2json/settings2json.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+
+import json
+import sys
+
+def settings2json(ast):
+ ret = {}
+ if ast[0]['_type'] != 'Label':
+ raise TypeError('obj does not start with Label, wrong file?')
+ for label in ast:
+ if label['parameters'] is not None:
+ raise NotImplementedError()
+ ret[label['name']] = label['block']
+ return ret
+
+with open(sys.argv[1], 'r') as f:
+ output = settings2json(json.load(f))
+
+json.dump(output, open(sys.argv[2], 'w'), separators=(',', ':'))
diff --git a/nginx.inc.conf b/nginx.inc.conf
index bdc514f..9d8804e 100644
--- a/nginx.inc.conf
+++ b/nginx.inc.conf
@@ -13,21 +13,8 @@ location ~ ^/(css/font|js/lib)/ {
expires 1d;
}
-location ~ ^/(index\.(html|php))?$ {
- set $warned NO;
- if ($http_cookie ~ "warned") {
- set $warned YES;
- }
- if ($args ~ "warned") {
- set $warned YES;
- }
- if ($warned = NO) {
- return 307 /warn.html;
- }
-}
-
-location /warned.php {
- return 301 "/warned.html?$args&language=$http_accept_language";
+location /language.php {
+ return 301 "/language.php?$args&language=$http_accept_language";
}
expires 5s;
diff --git a/nginx.sh b/nginx.sh
index b16f3e3..b0c6cad 100755
--- a/nginx.sh
+++ b/nginx.sh
@@ -1,35 +1,33 @@
#!/bin/bash
-set -e
cd "$(dirname $0)"
# empty file
> nginx.gen.conf
-V=$(nginx -V 2>&1)
-
-if echo ${V} | grep -q -- --with-http_gzip_static_module; then
- echo "gzip_static on;" >> nginx.gen.conf
-else
- echo >&2 "The gzip_static module for nginx is highly recommended to reduce server load and utilize zopfli's higher compression ratio."
-fi
-
-if ! echo ${V} | grep -q -- --without-http_proxy_module; then
- echo "proxy_temp_path /dev/null;" >> nginx.gen.conf
-fi
-
-if ! echo ${V} | grep -q -- --without-http_fastcgi_module; then
- echo "fastcgi_temp_path /dev/null;" >> nginx.gen.conf
-fi
-
-if ! echo ${V} | grep -q -- --without-http_scgi_module; then
- echo "scgi_temp_path /dev/null;" >> nginx.gen.conf
-fi
-
-if ! echo ${V} | grep -q -- --without-http_uwsgi_module; then
- echo "uwsgi_temp_path /dev/null;" >> nginx.gen.conf
-fi
-
-echo >&2 "Ignore the following message from nginx about the error log, if any."
-
+V="$(nginx -V 2>&1)"
+
+check() {
+ if [[ "$V" == *"$1"* ]]; then
+ if [[ -n "$3" ]]; then
+ echo "$2" >> nginx.gen.conf
+ fi
+ else
+ if [[ -n "$3" ]]; then
+ echo "$3" >> nginx.gen.conf
+ fi
+ if [[ -n "$4" ]]; then
+ echo "$4" >&2
+ fi
+ fi
+}
+
+check --with-http_gzip_static_module "gzip_static on;" "" "The gzip_static module for nginx is highly recommended to reduce server load and utilize zopfli's higher compression ratio."
+
+check --without-http_proxy_module "" "proxy_temp_path /dev/null;"
+check --without-http_fastcgi_module "" "fastcgi_temp_path /dev/null;"
+check --without-http_scgi_module "" "scgi_temp_path /dev/null;"
+check --without-http_uwsgi_module "" "uwsgi_temp_path /dev/null;"
+
+echo "Ignore any following messages from nginx about the error log." >&2
exec nginx -p "$PWD/" -c nginx.conf
diff --git a/www/css/index.css b/www/css/index.css
index bc35230..9c8a62c 100644
--- a/www/css/index.css
+++ b/www/css/index.css
@@ -36,11 +36,6 @@ h2 {
#interstitial {
display: none;
cursor: auto;
-}
-.no-js #interstitial {
- display: block;
-}
-#warn {
background-color: rgb(128, 128, 128);
background-color: rgba(128, 128, 128, 0.8);
border-radius: 10px 10px;
@@ -53,18 +48,18 @@ h2 {
width: 600px;
z-index: 100;
}
-.no-js #warn li { display: none; }
-.js #warn #js { display: none; }
- #warn #ie { display: none; }
-.video #warn #video { display: none; }
-.audio #warn #audio { display: none; }
- #warn #opus { display: none; }
-.fontface #warn #fontface { display: none; }
-.csstransforms #warn #csstransforms { display: none; }
-#gotit {
- text-align: center;
+.js.video.audio.fontface.csstransforms #missing-features {
+ display: none;
}
-.no-js #gotit {
+.no-js #features li:not(#js) { display: none; }
+.js #js { display: none; }
+ #ie { display: none; }
+.video #video { display: none; }
+.audio #audio { display: none; }
+ #opus { display: none; }
+.fontface #fontface { display: none; }
+.csstransforms #csstransforms { display: none; }
+.no-js #lets-go {
display: none;
}
@@ -361,6 +356,7 @@ label {
}
.button:not(.disabled):hover {
opacity: 1;
+ cursor: pointer;
}
input[type="checkbox"] {
display: none;
@@ -376,7 +372,7 @@ input[type="checkbox"] + span:before {
height: 19px;
width: 20px;
content: "";
- background: white left bottom no-repeat;
+ background: left bottom no-repeat;
}
.no-webp input[type="checkbox"]:checked + span:before {
background-image: url("../dump/ui/bt-cf-checked.png");
diff --git a/www/js/api.js b/www/js/api.js
index 0043724..67c8320 100644
--- a/www/js/api.js
+++ b/www/js/api.js
@@ -12,25 +12,24 @@ window.html5ks.api = {
_fading: {},
- set_volume: function (target, delay, channel) {
+ set_volume: function (target, fade, channel) {
var audio = html5ks.elements.audio[channel],
- step = (target - audio.volume) / (delay * 20);
- if (!delay) {
- audio.volume = target;
- } else {
- this._fading[channel] = setInterval(function () {
- // clamp new volume 0-1
- audio.volume = Math.min(Math.max(audio.volume + step, 0), 1);
- switch (audio.volume) {
- case 0:
- audio.pause();
- /* falls through */
- case 1:
- clearInterval(this._fading[channel]);
- delete this._fading[channel];
- }
- }.bind(this), 50);
- }
+ step = (target - audio.volume) / (fade * 20);
+ var nextVol = function () {
+ // clamp new volume 0-1
+ audio.volume = Math.min(Math.max(audio.volume + step, 0), 1);
+ switch (audio.volume) {
+ case 0:
+ audio.pause();
+ /* falls through */
+ case 1:
+ clearInterval(this._fading[channel]);
+ delete this._fading[channel];
+ return false;
+ }
+ return true;
+ };
+ if (nextVol()) this._fading[channel] = setInterval(nextVol, 50);
return when.resolve();
},
@@ -77,7 +76,8 @@ window.html5ks.api = {
_nextType();
},
- play: function (channel, name, _, fade) {
+ play: function (cmd, args) {
+ var channel = cmd[1];
this.stop(channel);
var deferred = when.defer(),
audio = html5ks.elements.audio[channel];
@@ -85,13 +85,13 @@ window.html5ks.api = {
audio.loop = true;
}
html5ks.elements.audio[channel] = audio;
- html5ks.store[channel] = name;
+ html5ks.store[channel] = args.file;
var src = "dump/", volume;
switch (channel) {
case "music":
- var fname = html5ks.data.music[name];
+ var fname = html5ks.data.music[args.file.replace(/ $/, '')];
src += "bgm/" + fname;
volume = html5ks.persistent.musicVolume;
document.getElementById("current-music-track").innerHTML = fname.replace(/_/g, " ");
@@ -104,13 +104,13 @@ window.html5ks.api = {
audio.addEventListener("playing", function playing() {
audio.removeEventListener("playing", playing, false);
- if (fade) {
- html5ks.api.set_volume(volume, fade, channel);
+ if (args.fadein) {
+ html5ks.api.set_volume(volume, args.fadein, channel);
}
deferred.resolve();
}, false);
- audio.volume = fade ? 0 : volume;
+ audio.volume = args.fadein ? 0 : volume;
this._loadMedia(audio, src, [
['audio/ogg; codecs="opus"', "opus"],
['audio/ogg; codecs="vorbis"', "ogg"],
@@ -194,8 +194,8 @@ window.html5ks.api = {
real_target = html5ks.persistent.language + "_" + target.replace(/"/g, ''),
i = 0;
html5ks.fetch('script', real_target).then(function run(l) {
- if (l[i]) {
- html5ks.api.runInst(l[i++]).then(run, console.error);
+ if (l[i++]) {
+ html5ks.api.runInst(l[i]).then(function(){run(l)}, console.error);
} else {
deferred.resolve();
}
@@ -203,22 +203,28 @@ window.html5ks.api = {
return deferred.promise;
},
+ _safeCall: function (n, f, args) {
+ if (f) return f.apply(this, args);
+ else {
+ console.error("no such function " + n);
+ debugger;
+ return when.resolve();
+ }
+ },
+
runInst: function (inst) {
- var cmd = inst[0].replace(/"/g, ''),
- args = inst.slice(1);
- if (html5ks.data.characters[cmd]) {
- return this.say(cmd, args[0]);
- } else {
- if (this[cmd]) {
- return this[cmd].apply(this, args);
- } else if (inst.length === 1) {
- return this.say("name_only", cmd);
- } else {
- console.error("no such cmd " + cmd);
- return when.resolve();
- }
- }
+ var cmd = inst[0].replace(/"/g, '');
+ return this._safeCall(cmd, this[cmd], inst.slice(1));
+ },
+
+ UserStatement: function (line, parsed) {
+ var c = parsed[0][0];
+ return this._safeCall(c, this[c], parsed);
+ },
+
+ With: function () {
+ return when.resolve();
},
@@ -240,9 +246,9 @@ window.html5ks.api = {
},
- scene: function () {
+ Scene: function () {
html5ks.elements.show.innerHTML = "";
- return this.show.apply(this, arguments);
+ return this.Show.apply(this, arguments);
},
@@ -265,8 +271,11 @@ window.html5ks.api = {
bgright: { xpos: 0.6, xanchor: 0.5, ypos: 1.0, yanchor: 1.0 }
},
- show: function (name, type, location) {
+ Show: function (imspec) {
var deferred = when.defer();
+ var name =
+ console.log(imspec);
+ return when.resolve();
var lookup = document.getElementById(name),
el = lookup || document.createElement("img");
if (!location && !lookup) location = "center";
@@ -406,31 +415,27 @@ window.html5ks.api = {
});
},
- say: function (chrName, str, extend) {
+ Say: function (who, what, with_, extend) {
var deferred = when.defer(),
- chr = typeof chrName === "string" ? html5ks.data.characters[chrName] : chrName,
- w = /{w=?(\d*\.\d*)?}(.*)/.exec(str);
+ chr = html5ks.data.characters[who],
+ w = /{w=?(\d*\.\d*)?}(.*)/.exec(what);
if (!chr) {
- chr = {
- name: chrName
- };
- }
- if (typeof chr.what_prefix === "undefined") {
- chr.what_prefix = "“";
- chr.what_suffix = "”";
+ chr = { name: who };
}
+ chr.what_prefix = chr.what_prefix || "“";
+ chr.what_suffix = chr.what_suffix || "“";
this._lastchar = chr;
if (!extend && chr.what_prefix) {
- str = chr.what_prefix + str;
+ what = chr.what_prefix + what;
}
if ((!w || !w[1]) && chr.what_suffix) {
- str = str + chr.what_suffix;
+ what += chr.what_suffix;
}
- var text = this.dlgTag(str),
+ var text = this.dlgTag(what),
say, ctc;
if (chr.kind === "nvl") {
@@ -478,14 +483,14 @@ window.html5ks.api = {
ctc.style.display = "none";
deferred.resolve();
}
- html5ks.api._setNextTimeout(str, true);
+ html5ks.api._setNextTimeout(what, true);
};
if (html5ks.persistent.textSpeed == 200) {
ptxt(true);
}
- this._setNextTimeout(str, false);
+ this._setNextTimeout(what, false);
return deferred.promise;
},
@@ -501,10 +506,6 @@ window.html5ks.api = {
}
},
- extend: function (str) {
- return this.say(this._lastchar, str, true);
- },
-
Pause: function (duration) {
var deferred = when.defer();
setTimeout(function () {
diff --git a/www/js/html5ks.js b/www/js/html5ks.js
index 13bd198..4113c1d 100644
--- a/www/js/html5ks.js
+++ b/www/js/html5ks.js
@@ -143,7 +143,7 @@ window.html5ks = {
},
initEvents: function () {
window.onresize = html5ks.scale;
- this.elements.container.addEventListener("mouseup", function (e) {
+ this.elements.container.addEventListener("click", function (e) {
if (html5ks.store.status === "scene") {
switch (e.button) {
case 0:
@@ -157,39 +157,33 @@ window.html5ks = {
e.preventDefault();
}, false);
},
- warnUnsupported: function () {
+ warn: function () {
if (!html5ks.persistent.gotit) {
var interstitial = document.getElementById("interstitial");
- document.getElementById("gotit").addEventListener("mouseup", function () {
- interstitial.style.mozAnimation = "1s dissolveout";
- interstitial.style.webkitAnimation = "1s dissolveout";
- interstitial.style.animation = "1s dissolveout";
- interstitial.style.opacity = 0;
+ interstitial.style.display = "block";
+ document.getElementById("lets-go").addEventListener("click", function () {
+ interstitial.style.display = "none";
html5ks.persistent.gotit = true;
html5ks.start();
}, false);
- var warns = document.getElementById("warns").children;
+ var features = document.getElementById("features").children;
if (/MSIE/.test(navigator.userAgent)) {
document.getElementById("ie").style.display = "block";
+ document.getElementById("missing-features").style.display = "block";
}
if (!Modernizr.audio.opus) {
document.getElementById("opus").style.display = "block";
- }
- for (var i = 0; i < warns.length; i++) {
- var warn = warns[i];
- if (window.getComputedStyle(warns[i]).getPropertyValue("display") !== "none") {
- warn.style.display = "block";
- return true;
- }
+ document.getElementById("missing-features").style.display = "block";
}
}
+ return !html5ks.persistent.gotit;
},
onload: function () {
FastClick.attach(document.body);
this.initElements();
this.scale();
this.initEvents();
- if (!this.warnUnsupported()) {
+ if (!this.warn()) {
this.start();
}
this.i18n.init();
diff --git a/www/js/menu.js b/www/js/menu.js
index 93616db..5b646b9 100644
--- a/www/js/menu.js
+++ b/www/js/menu.js
@@ -5,8 +5,8 @@ html5ks.menu = {
this.context(false);
html5ks.api.stop("all");
html5ks.api.window("hide");
- html5ks.api.play("music", "music_menus");
- html5ks.api.show("url", "ui/main/bg-main.png");
+ html5ks.api.play(['', "music"], {file: "music_menus", fadein: 5});
+ html5ks.api.Show("url", "ui/main/bg-main.png");
this.elements.mainMenu.style.display = "block";
html5ks.store.status = "menu";
},
@@ -161,6 +161,15 @@ html5ks.menu = {
console.error("unknown option type %s", option.type);
}
}
+
+ document.getElementById("clear-persistent").addEventListener("click", function () {
+ if (delete localStorage.persistent) {
+ alert("clear succeeded, refreshing...");
+ location.reload();
+ } else {
+ alert("clear failed");
+ }
+ }, false);
},
init: function () {
diff --git a/www/warn.html b/www/warn.html
deleted file mode 100644
index d3ece15..0000000
--- a/www/warn.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>Katawa Shoujo - Disclaimer</title>
- </head>
- <body>
- <p>Okay, before we start, we need to go through a few things first.</p>
- <p>If you don't know what Katawa Shoujo is, see <a href="http://www.katawa-shoujo.com/">http://www.katawa-shoujo.com/</a>, then come back.</p>
- <p>There's like, a little bit of... inappropriate content, so we have to make you promise you're over 18.</p>
- <p>If you don't want to see any, er, explicit content, hit the appropriate checkbox at the bottom of the page.</p>
- <p>Also, please don't bother the original developers on the forums or IRC about bugs in this. This is entirely unofficial and not controlled by them whatsoever.<br>
- This includes missing features, typos, downtime, and any other glitches of any sort. Bug me instead: <a href="https://bugzilla.happinessforme.com/">https://bugzilla.happinessforme.com/</a>, or use the official distribution until HTML5KS is feature-complete.
- </p>
- <p>FYI, this site sets a single anonymous cookie (warned=1) so that you won't have to keep seeing this page. It also sets localStorage to keep your settings and saves. The latter always stays on your computer and never goes anywhere. If you live in the EU, please don't sue me.</p>
- <form method="GET" action="warned.php">
- <p><input type="checkbox" name="hdisable" id="hdisable"><label for="hdisable">Disable adult content</label>
- <br>
- <input type="submit" value="Let's go!">
- </form>
- </body>
-</html>
diff --git a/www/warned.html b/www/warned.html
deleted file mode 100644
index 3cc0a91..0000000
--- a/www/warned.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<html><head><script>
-document.cookie = "warned=1; Expires=Tue, 19 Jan 2038 00:00:00 GMT; HttpOnly";
-var l = /language=[^&]*/.exec(location.search)[0].replace(/[ \t]/g, '').split(",");
-loop: for (var i = 0; i < l.length; i++) {
- switch (l[i].split(';')[0]) {
- case "en": var lang = "en"; break loop;
- case "fr": var lang = "fr"; break loop;
- }
-}
-localStorage.persistent = {
- hdisable: location.search.indexOf("hdisable=on") > -1,
- language: lang || "en"
-};
-location.replace("./");
-</script></head><body>If you're seeing this, something's gone wrong. Go back and try again, and if it still doesn't work, file a bug.</body></html>
diff --git a/www/warned.php b/www/warned.php
deleted file mode 100644
index 04c300b..0000000
--- a/www/warned.php
+++ /dev/null
@@ -1,2 +0,0 @@
-<?php
-header("Location: /warned.html?".$_SERVER['QUERY_STRING']."&language=".$_SERVER['HTTP_ACCEPT_LANGUAGE']);