>>10&1023|55296),d=56320|1023&d),o.push(d),i+=u}var f=o,p=f.length;if(p<=g)return String.fromCharCode.apply(String,f);for(var h="",m=0;mthis.length)return"";if((n=void 0===n||n>this.length?this.length:n)<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":var a=this,r=t,s=n,c=a.length;(!s||s<0||ct&&(e+=" ... "),""},u.prototype.compare=function(e,t,n,o,i){if(A(e,Uint8Array)&&(e=u.from(e,e.offset,e.byteLength)),!u.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===n&&(n=e?e.length:0),void 0===o&&(o=0),void 0===i&&(i=this.length),(t=void 0===t?0:t)<0||n>e.length||o<0||i>this.length)throw new RangeError("out of range index");if(i<=o&&n<=t)return 0;if(i<=o)return-1;if(n<=t)return 1;if(this===e)return 0;for(var a=(i>>>=0)-(o>>>=0),r=(n>>>=0)-(t>>>=0),s=Math.min(a,r),c=this.slice(o,i),l=e.slice(t,n),d=0;d>>=0,isFinite(n)?(n>>>=0,void 0===o&&(o="utf8")):(o=n,n=void 0)}var i=this.length-t;if((void 0===n||ithis.length)throw new RangeError("Attempt to write outside buffer bounds");o=o||"utf8";for(var a,r,s,c,l,d=!1;;)switch(o){case"hex":var u=this,f=e,p=t,h=n,m=(p=Number(p)||0,u.length-p);(!h||(h=Number(h))>m)&&(h=m),(m=f.length)/2>8,i.push(n%256),i.push(o);return i}(e,(a=this).length-s),a,s,r);default:if(d)throw new TypeError("Unknown encoding: "+o);o=(""+o).toLowerCase(),d=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var g=4096;function l(e,t,n){if(e%1!=0||e<0)throw new RangeError("offset is not uint");if(ne.length)throw new RangeError("Index out of range")}function v(e,t,n,o){if(n+o>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function b(e,t,n,o,i){return t=+t,n>>>=0,i||v(e,0,n,4),a.write(e,t,n,o,23,4),n+4}function w(e,t,n,o,i){return t=+t,n>>>=0,i||v(e,0,n,8),a.write(e,t,n,o,52,8),n+8}u.prototype.slice=function(e,t){var n=this.length,n=((e=~~e)<0?(e+=n)<0&&(e=0):n>>=0,t>>>=0,n||l(e,t,this.length);for(var o=this[e],i=1,a=0;++a>>=0,t>>>=0,n||l(e,t,this.length);for(var o=this[e+--t],i=1;0>>=0,t||l(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return e>>>=0,t||l(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return e>>>=0,t||l(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return e>>>=0,t||l(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return e>>>=0,t||l(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,n){e>>>=0,t>>>=0,n||l(e,t,this.length);for(var o=this[e],i=1,a=0;++a=(i*=128)&&(o-=Math.pow(2,8*t)),o},u.prototype.readIntBE=function(e,t,n){e>>>=0,t>>>=0,n||l(e,t,this.length);for(var o=t,i=1,a=this[e+--o];0=(i*=128)&&(a-=Math.pow(2,8*t)),a},u.prototype.readInt8=function(e,t){return e>>>=0,t||l(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){e>>>=0,t||l(e,2,this.length);t=this[e]|this[e+1]<<8;return 32768&t?4294901760|t:t},u.prototype.readInt16BE=function(e,t){e>>>=0,t||l(e,2,this.length);t=this[e+1]|this[e]<<8;return 32768&t?4294901760|t:t},u.prototype.readInt32LE=function(e,t){return e>>>=0,t||l(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return e>>>=0,t||l(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return e>>>=0,t||l(e,4,this.length),a.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return e>>>=0,t||l(e,4,this.length),a.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return e>>>=0,t||l(e,8,this.length),a.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return e>>>=0,t||l(e,8,this.length),a.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,n,o){e=+e,t>>>=0,n>>>=0,o||m(this,e,t,n,Math.pow(2,8*n)-1,0);var i=1,a=0;for(this[t]=255&e;++a>>=0,n>>>=0,o||m(this,e,t,n,Math.pow(2,8*n)-1,0);var i=n-1,a=1;for(this[t+i]=255&e;0<=--i&&(a*=256);)this[t+i]=e/a&255;return t+n},u.prototype.writeUInt8=function(e,t,n){return e=+e,t>>>=0,n||m(this,e,t,1,255,0),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t>>>=0,n||m(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t>>>=0,n||m(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t>>>=0,n||m(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t>>>=0,n||m(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},u.prototype.writeIntLE=function(e,t,n,o){e=+e,t>>>=0,o||m(this,e,t,n,(o=Math.pow(2,8*n-1))-1,-o);var i=0,a=1,r=0;for(this[t]=255&e;++i>0)-r&255;return t+n},u.prototype.writeIntBE=function(e,t,n,o){e=+e,t>>>=0,o||m(this,e,t,n,(o=Math.pow(2,8*n-1))-1,-o);var i=n-1,a=1,r=0;for(this[t+i]=255&e;0<=--i&&(a*=256);)e<0&&0===r&&0!==this[t+i+1]&&(r=1),this[t+i]=(e/a>>0)-r&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t>>>=0,n||m(this,e,t,1,127,-128),this[t]=255&(e=e<0?255+e+1:e),t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t>>>=0,n||m(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t>>>=0,n||m(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t>>>=0,n||m(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t>>>=0,n||m(this,e,t,4,2147483647,-2147483648),this[t]=(e=e<0?4294967295+e+1:e)>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},u.prototype.writeFloatLE=function(e,t,n){return b(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return b(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return w(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return w(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,o){if(!u.isBuffer(e))throw new TypeError("argument should be a Buffer");if(n=n||0,o||0===o||(o=this.length),t>=e.length&&(t=e.length),(o=0=this.length)throw new RangeError("Index out of range");if(o<0)throw new RangeError("sourceEnd out of bounds");o>this.length&&(o=this.length);var i=(o=e.length-t>>=0,n=void 0===n?this.length:n>>>0,"number"==typeof(e=e||0))for(a=t;a>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function T(e){return x.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace(_,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function E(e,t,n,o){for(var i=0;i=t.length||i>=e.length);++i)t[i+n]=e[i];return i}function A(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function M(e){return e!=e}}.call(this)}.call(this,k("buffer").Buffer)},{"base64-js":2,buffer:3,ieee754:4}],4:[function(e,t,n){n.read=function(e,t,n,o,i){var a,r,s=8*i-o-1,c=(1<>1,d=-7,u=n?i-1:0,f=n?-1:1,i=e[t+u];for(u+=f,a=i&(1<<-d)-1,i>>=-d,d+=s;0>=-d,d+=o;0>1,u=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,f=o?0:a-1,p=o?1:-1,a=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,r=l):(r=Math.floor(Math.log(t)/Math.LN2),t*(o=Math.pow(2,-r))<1&&(r--,o*=2),2<=(t+=1<=r+d?u/o:u*Math.pow(2,1-d))*o&&(r++,o/=2),l<=r+d?(s=0,r=l):1<=r+d?(s=(t*o-1)*Math.pow(2,i),r+=d):(s=t*Math.pow(2,d-1)*Math.pow(2,i),r=0));8<=i;e[n+f]=255&s,f+=p,s/=256,i-=8);for(r=r<=this._reconnectionAttempts?(d("reconnect failed"),this.backoff.reset(),this.emitAll("reconnect_failed"),this.reconnecting=!1):(e=this.backoff.duration(),d("will wait %dms before reconnect attempt",e),this.reconnecting=!0,t=setTimeout(function(){n.skipReconnect||(d("attempting reconnect"),n.emitAll("reconnect_attempt",n.backoff.attempts),n.emitAll("reconnecting",n.backoff.attempts),n.skipReconnect||n.open(function(e){e?(d("reconnect attempt error"),n.reconnecting=!1,n.reconnect(),n.emitAll("reconnect_error",e.data)):(d("reconnect success"),n.onreconnect())}))},e),this.subs.push({destroy:function(){clearTimeout(t)}}))},p.prototype.onreconnect=function(){var e=this.backoff.attempts;this.reconnecting=!1,this.backoff.reset(),this.updateSocketIds(),this.emitAll("reconnect",e)}},function(e,t,n){var r=n(106),s=n(381),c=n(390),n=n(391);t.polling=function(e){var t,n,o=!1,i=!1,a=!1!==e.jsonp;if("undefined"!=typeof location&&(t="https:"===location.protocol,n=(n=location.port)||(t?443:80),o=e.hostname!==location.hostname||n!==e.port,i=e.secure!==t),e.xdomain=o,e.xscheme=i,"open"in new r(e)&&!e.forceJSONP)return new s(e);if(a)return new c(e);throw new Error("JSONP disabled")},t.websocket=n},function(e,t,n){var o=n(107),i=n(75),a=n(51),r=n(76),s=n(152),c=n(77)("engine.io-client:polling"),l=(e.exports=d,null!=new(n(106))({xdomain:!1}).responseType);function d(e){var t=e&&e.forceBase64;l&&!t||(this.supportsBinary=!1),o.call(this,e)}r(d,o),d.prototype.name="polling",d.prototype.doOpen=function(){this.poll()},d.prototype.pause=function(e){var t,n=this;function o(){c("paused"),n.readyState="paused",e()}this.readyState="pausing",this.polling||!this.writable?(t=0,this.polling&&(c("we are currently polling - waiting to pause"),t++,this.once("pollComplete",function(){c("pre-pause polling complete"),--t||o()})),this.writable||(c("we are currently writing - waiting to pause"),t++,this.once("drain",function(){c("pre-pause writing complete"),--t||o()}))):o()},d.prototype.poll=function(){c("polling"),this.polling=!0,this.doPoll(),this.emit("poll")},d.prototype.onData=function(e){var o=this;c("polling got data %s",e),a.decodePayload(e,this.socket.binaryType,function(e,t,n){if("opening"===o.readyState&&o.onOpen(),"close"===e.type)return o.onClose(),!1;o.onPacket(e)}),"closed"!==this.readyState&&(this.polling=!1,this.emit("pollComplete"),"open"===this.readyState?this.poll():c('ignoring poll - transport state "%s"',this.readyState))},d.prototype.doClose=function(){var e=this;function t(){c("writing close packet"),e.write([{type:"close"}])}"open"===this.readyState?(c("transport open - closing"),t()):(c("transport not open - deferring close"),this.once("open",t))},d.prototype.write=function(e){function t(){n.writable=!0,n.emit("drain")}var n=this;this.writable=!1;a.encodePayload(e,this.supportsBinary,function(e){n.doWrite(e,t)})},d.prototype.uri=function(){var e=this.query||{},t=this.secure?"https":"http",n="";return!1!==this.timestampRequests&&(e[this.timestampParam]=s()),this.supportsBinary||e.sid||(e.b64=1),e=i.encode(e),this.port&&("https"==t&&443!==Number(this.port)||"http"==t&&80!==Number(this.port))&&(n=":"+this.port),e.length&&(e="?"+e),t+"://"+(-1!==this.hostname.indexOf(":")?"["+this.hostname+"]":this.hostname)+n+this.path+e}},function(t,e,n){!function(a){var e=Object.prototype.toString,r="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===e.call(Blob),s="function"==typeof File||"undefined"!=typeof File&&"[object FileConstructor]"===e.call(File);t.exports=function e(t){if(!t||"object"!=typeof t)return!1;if(Array.isArray(t)){for(var n=0,o=t.length;nthis.options.threshold){var s={};for(c in this.direction)this.direction.hasOwnProperty(c)&&(s[c]=this.direction[c]);var c,l={};for(c in this.direction={x:n,y:o,angle:t},e.direction=this.direction,s)s[c]===this.direction[c]&&(l[c]=!0);if(l.x&&l.y&&l.angle)return e;l.x&&l.y||this.trigger("plain",e),l.x||this.trigger("plain:"+n,e),l.y||this.trigger("plain:"+o,e),l.angle||this.trigger("dir dir:"+t,e)}return e},o.prototype=new e,(o.constructor=o).id=0,o.prototype.prepareNipples=function(){var e=this,o=e.nipples;o.on=e.on.bind(e),o.off=e.off.bind(e),o.options=e.options,o.destroy=e.destroy.bind(e),o.ids=e.ids,o.id=e.id,o.processOnMove=e.processOnMove.bind(e),o.processOnEnd=e.processOnEnd.bind(e),o.get=function(e){if(void 0===e)return o[0];for(var t=0,n=o.length;t>2]|=e[a]<>6:(o<55296||57344<=o?c[i++]=224|o>>12:(o=65536+((1023&o)<<10|1023&e.charCodeAt(++a)),c[i++]=240|o>>18,c[i++]=128|o>>12&63),c[i++]=128|o>>6&63),c[i++]=128|63&o);else for(i=this.start;a>2]|=o<>2]|=(192|o>>6)<>2]|=(224|o>>12)<>2]|=(240|o>>18)<>2]|=(128|o>>12&63)<>2]|=(128|o>>6&63)<>2]|=(128|63&o)<>2]|=u[3&t],56<=t&&(this.hashed||this.hash(),e[0]=e[16],e[16]=e[1]=e[2]=e[3]=e[4]=e[5]=e[6]=e[7]=e[8]=e[9]=e[10]=e[11]=e[12]=e[13]=e[14]=e[15]=0),e[14]=this.bytes<<3,e[15]=this.hBytes<<3|this.bytes>>>29,this.hash())},g.prototype.hash=function(){var e,t,n,o,i,a=this.blocks,r=this.first?((r=((e=((e=a[0]-680876937)<<7|e>>>25)-271733879<<0)^(t=((t=(-271733879^(n=((n=(-1732584194^2004318071&e)+a[1]-117830708)<<12|n>>>20)+e<<0)&(-271733879^e))+a[2]-1126478375)<<17|t>>>15)+n<<0)&(n^e))+a[3]-1316259209)<<22|r>>>10)+t<<0:(e=this.h0,r=this.h1,t=this.h2,((r+=((e=((e+=((n=this.h3)^r&(t^n))+a[0]-680876936)<<7|e>>>25)+r<<0)^(t=((t+=(r^(n=((n+=(t^e&(r^t))+a[1]-389564586)<<12|n>>>20)+e<<0)&(e^r))+a[2]+606105819)<<17|t>>>15)+n<<0)&(n^e))+a[3]-1044525330)<<22|r>>>10)+t<<0);r=((r+=((e=((e+=(n^r&(t^n))+a[4]-176418897)<<7|e>>>25)+r<<0)^(t=((t+=(r^(n=((n+=(t^e&(r^t))+a[5]+1200080426)<<12|n>>>20)+e<<0)&(e^r))+a[6]-1473231341)<<17|t>>>15)+n<<0)&(n^e))+a[7]-45705983)<<22|r>>>10)+t<<0,r=((r+=((e=((e+=(n^r&(t^n))+a[8]+1770035416)<<7|e>>>25)+r<<0)^(t=((t+=(r^(n=((n+=(t^e&(r^t))+a[9]-1958414417)<<12|n>>>20)+e<<0)&(e^r))+a[10]-42063)<<17|t>>>15)+n<<0)&(n^e))+a[11]-1990404162)<<22|r>>>10)+t<<0,r=((r+=((e=((e+=(n^r&(t^n))+a[12]+1804603682)<<7|e>>>25)+r<<0)^(t=((t+=(r^(n=((n+=(t^e&(r^t))+a[13]-40341101)<<12|n>>>20)+e<<0)&(e^r))+a[14]-1502002290)<<17|t>>>15)+n<<0)&(n^e))+a[15]+1236535329)<<22|r>>>10)+t<<0,r=((r+=((n=((n+=(r^t&((e=((e+=(t^n&(r^t))+a[1]-165796510)<<5|e>>>27)+r<<0)^r))+a[6]-1069501632)<<9|n>>>23)+e<<0)^e&((t=((t+=(e^r&(n^e))+a[11]+643717713)<<14|t>>>18)+n<<0)^n))+a[0]-373897302)<<20|r>>>12)+t<<0,r=((r+=((n=((n+=(r^t&((e=((e+=(t^n&(r^t))+a[5]-701558691)<<5|e>>>27)+r<<0)^r))+a[10]+38016083)<<9|n>>>23)+e<<0)^e&((t=((t+=(e^r&(n^e))+a[15]-660478335)<<14|t>>>18)+n<<0)^n))+a[4]-405537848)<<20|r>>>12)+t<<0,r=((r+=((n=((n+=(r^t&((e=((e+=(t^n&(r^t))+a[9]+568446438)<<5|e>>>27)+r<<0)^r))+a[14]-1019803690)<<9|n>>>23)+e<<0)^e&((t=((t+=(e^r&(n^e))+a[3]-187363961)<<14|t>>>18)+n<<0)^n))+a[8]+1163531501)<<20|r>>>12)+t<<0,r=((r+=((n=((n+=(r^t&((e=((e+=(t^n&(r^t))+a[13]-1444681467)<<5|e>>>27)+r<<0)^r))+a[2]-51403784)<<9|n>>>23)+e<<0)^e&((t=((t+=(e^r&(n^e))+a[7]+1735328473)<<14|t>>>18)+n<<0)^n))+a[12]-1926607734)<<20|r>>>12)+t<<0,r=((r+=((i=(n=((n+=((o=r^t)^(e=((e+=(o^n)+a[5]-378558)<<4|e>>>28)+r<<0))+a[8]-2022574463)<<11|n>>>21)+e<<0)^e)^(t=((t+=(i^r)+a[11]+1839030562)<<16|t>>>16)+n<<0))+a[14]-35309556)<<23|r>>>9)+t<<0,r=((r+=((i=(n=((n+=((o=r^t)^(e=((e+=(o^n)+a[1]-1530992060)<<4|e>>>28)+r<<0))+a[4]+1272893353)<<11|n>>>21)+e<<0)^e)^(t=((t+=(i^r)+a[7]-155497632)<<16|t>>>16)+n<<0))+a[10]-1094730640)<<23|r>>>9)+t<<0,r=((r+=((i=(n=((n+=((o=r^t)^(e=((e+=(o^n)+a[13]+681279174)<<4|e>>>28)+r<<0))+a[0]-358537222)<<11|n>>>21)+e<<0)^e)^(t=((t+=(i^r)+a[3]-722521979)<<16|t>>>16)+n<<0))+a[6]+76029189)<<23|r>>>9)+t<<0,r=((r+=((i=(n=((n+=((o=r^t)^(e=((e+=(o^n)+a[9]-640364487)<<4|e>>>28)+r<<0))+a[12]-421815835)<<11|n>>>21)+e<<0)^e)^(t=((t+=(i^r)+a[15]+530742520)<<16|t>>>16)+n<<0))+a[2]-995338651)<<23|r>>>9)+t<<0,r=((r+=((n=((n+=(r^((e=((e+=(t^(r|~n))+a[0]-198630844)<<6|e>>>26)+r<<0)|~t))+a[7]+1126891415)<<10|n>>>22)+e<<0)^((t=((t+=(e^(n|~r))+a[14]-1416354905)<<15|t>>>17)+n<<0)|~e))+a[5]-57434055)<<21|r>>>11)+t<<0,r=((r+=((n=((n+=(r^((e=((e+=(t^(r|~n))+a[12]+1700485571)<<6|e>>>26)+r<<0)|~t))+a[3]-1894986606)<<10|n>>>22)+e<<0)^((t=((t+=(e^(n|~r))+a[10]-1051523)<<15|t>>>17)+n<<0)|~e))+a[1]-2054922799)<<21|r>>>11)+t<<0,r=((r+=((n=((n+=(r^((e=((e+=(t^(r|~n))+a[8]+1873313359)<<6|e>>>26)+r<<0)|~t))+a[15]-30611744)<<10|n>>>22)+e<<0)^((t=((t+=(e^(n|~r))+a[6]-1560198380)<<15|t>>>17)+n<<0)|~e))+a[13]+1309151649)<<21|r>>>11)+t<<0,r=((r+=((n=((n+=(r^((e=((e+=(t^(r|~n))+a[4]-145523070)<<6|e>>>26)+r<<0)|~t))+a[11]-1120210379)<<10|n>>>22)+e<<0)^((t=((t+=(e^(n|~r))+a[2]+718787259)<<15|t>>>17)+n<<0)|~e))+a[9]-343485551)<<21|r>>>11)+t<<0,this.first?(this.h0=e+1732584193<<0,this.h1=r-271733879<<0,this.h2=t-1732584194<<0,this.h3=n+271733878<<0,this.first=!1):(this.h0=this.h0+e<<0,this.h1=this.h1+r<<0,this.h2=this.h2+t<<0,this.h3=this.h3+n<<0)},g.prototype.toString=g.prototype.hex=function(){this.finalize();var e=this.h0,t=this.h1,n=this.h2,o=this.h3;return c[e>>4&15]+c[15&e]+c[e>>12&15]+c[e>>8&15]+c[e>>20&15]+c[e>>16&15]+c[e>>28&15]+c[e>>24&15]+c[t>>4&15]+c[15&t]+c[t>>12&15]+c[t>>8&15]+c[t>>20&15]+c[t>>16&15]+c[t>>28&15]+c[t>>24&15]+c[n>>4&15]+c[15&n]+c[n>>12&15]+c[n>>8&15]+c[n>>20&15]+c[n>>16&15]+c[n>>28&15]+c[n>>24&15]+c[o>>4&15]+c[15&o]+c[o>>12&15]+c[o>>8&15]+c[o>>20&15]+c[o>>16&15]+c[o>>28&15]+c[o>>24&15]},g.prototype.array=g.prototype.digest=function(){this.finalize();var e=this.h0,t=this.h1,n=this.h2,o=this.h3;return[255&e,e>>8&255,e>>16&255,e>>24&255,255&t,t>>8&255,t>>16&255,t>>24&255,255&n,n>>8&255,n>>16&255,n>>24&255,255&o,o>>8&255,o>>16&255,o>>24&255]},g.prototype.buffer=g.prototype.arrayBuffer=function(){this.finalize();var e=new ArrayBuffer(16),t=new Uint32Array(e);return t[0]=this.h0,t[1]=this.h1,t[2]=this.h2,t[3]=this.h3,e},g.prototype.base64=function(){for(var e,t,n,o="",i=this.array(),a=0;a<15;)e=i[a++],t=i[a++],n=i[a++],o+=h[e>>>2]+h[63&(e<<4|t>>>4)]+h[63&(t<<2|n>>>6)]+h[63&n];return e=i[a],o+(h[e>>>2]+h[e<<4&63]+"==")};var v=function(){var t=o("hex");(t=r?i(t):t).create=function(){return new g},t.update=function(e){return t.create().update(e)};for(var e=0;es?o.message=n.slice(0,s):(o.message=n,o.last=!0,o.isobject=l),a.send(o,r),(c=n.slice(o.message.length)).length&&setTimeout(function(){e(null,c)},i.chunkInterval||100)}(e)}},a={handle:function(n){var o={};n.onFileStart=function(e){var t=document.createElement("div");if(t.title=e.name,t.innerHTML=" ",e.remoteUserId&&(t.innerHTML+=" (Sharing with:"+e.remoteUserId+")"),n.filesContainer||(n.filesContainer=document.body||document.documentElement),n.filesContainer.insertBefore(t,n.filesContainer.firstChild),!e.remoteUserId)return o[e.uuid]={div:t,progress:t.querySelector("progress"),label:t.querySelector("label")},void(o[e.uuid].progress.max=e.maxChunks);o[e.uuid]||(o[e.uuid]={}),o[e.uuid][e.remoteUserId]={div:t,progress:t.querySelector("progress"),label:t.querySelector("label")},o[e.uuid][e.remoteUserId].progress.max=e.maxChunks},n.onFileProgress=function(e){var t=o[e.uuid];!t||e.remoteUserId&&!(t=o[e.uuid][e.remoteUserId])||(t.progress.value=e.currentPosition||e.maxChunks||t.progress.max,e=t.progress,t=t.label,-1!==e.position&&(e=+e.position.toFixed(2).split(".")[1]||100,t.innerHTML=e+"%"))},n.onFileEnd=function(e){var t=o[e.uuid];t?e.remoteUserId&&!(t=o[e.uuid][e.remoteUserId])||(t=t.div,-1!=e.type.indexOf("image")?t.innerHTML='Download '+e.name+'
':t.innerHTML='Download '+e.name+'
'):console.error("No such progress-helper element exist.",e)}}},t={handle:function(i){i.autoTranslateText=!1,i.language="en",i.googKey="AIzaSyCgB5hmFY74WYB-EoWkhr9cAGr6TiTHrEE",i.Translator={TranslateText:function(e,t){var n=document.createElement("script"),e=(n.type="text/javascript",encodeURIComponent(e)),o="method"+i.token(),o=(window[o]=function(e){e.data&&e.data.translations[0]&&t?t(e.data.translations[0].translatedText):e.error&&"Daily Limit Exceeded"===e.error.message?console.error('Text translation failed. Error message: "Daily Limit Exceeded."'):e.error?console.error(e.error.message):console.error(e)},"https://www.googleapis.com/language/translate/v2?key="+i.googKey+"&target="+(i.language||"en-US")+"&callback=window."+o+"&q="+e);n.src=o,document.getElementsByTagName("head")[0].appendChild(n)},getListOfLanguages:function(t){var n=new XMLHttpRequest,e=(n.onreadystatechange=function(){var e;n.readyState==XMLHttpRequest.DONE&&((e=JSON.parse(n.responseText))&&e.data&&e.data.languages?t(e.data.languages):e.error&&"Daily Limit Exceeded"===e.error.message?console.error('Text translation failed. Error message: "Daily Limit Exceeded."'):e.error?console.error(e.error.message):console.error(e))},"https://www.googleapis.com/language/translate/v2/languages?key="+i.googKey+"&target=en");n.open("GET",e,!0),n.send(null)}}}};function L(t){if(P.socketAutoReConnect=!0,P.socket)t&&t(P.socket);else{if(void 0===n)if("undefined"!=typeof FirebaseConnection)window.SocketConnection=FirebaseConnection;else{if("undefined"==typeof PubNubConnection)throw"SocketConnection.js seems missed.";window.SocketConnection=PubNubConnection}new n(P,function(e){t&&t(P.socket)})}}function ke(n,o){P.socket.emit("join-room",{sessionid:P.sessionid,session:P.session,mediaConstraints:P.mediaConstraints,sdpConstraints:P.sdpConstraints,streams:Oe(),extra:P.extra,password:void 0!==P.password&&"object"!==ze(P.password)?P.password:""},function(e,t){if(!0===e){if(P.enableLogs&&console.log("isRoomJoined: ",e," roomid: ",P.sessionid),P.peers[P.sessionid])return;I.onNegotiationNeeded(n)}!1===e&&P.enableLogs&&console.warn("isRoomJoined: ",t," roomid: ",P.sessionid),o(e,P.sessionid,t)})}function Re(n){P.enableLogs&&console.log("Sending open-room signal to socket.io"),P.waitingForLocalMedia=!1,P.socket.emit("open-room",{sessionid:P.sessionid,session:P.session,mediaConstraints:P.mediaConstraints,sdpConstraints:P.sdpConstraints,streams:Oe(),extra:P.extra,identifier:P.publicRoomIdentifier,password:void 0!==P.password&&"object"!==ze(P.password)?P.password:""},function(e,t){!0===e&&(P.enableLogs&&console.log("isRoomOpened: ",e," roomid: ",P.sessionid),n(e,P.sessionid)),!1===e&&(P.enableLogs&&console.warn("isRoomOpened: ",t," roomid: ",P.sessionid),n(e,P.sessionid,t))})}function Oe(){try{return P.streamEvents.selectAll("local").map(function(e){return{streamid:e.streamid,tracks:e.stream.getTracks().length}})}catch(e){return[]}}function Pe(e,n){var t,o;P.dontCaptureUserMedia||e.isDataOnly?n():(t={},e.localPeerSdpConstraints.OfferToReceiveAudio&&(t.audio=P.mediaConstraints.audio),e.localPeerSdpConstraints.OfferToReceiveVideo&&(t.video=P.mediaConstraints.video),(o=e.session||P.session).oneway&&"two-way"!==o.audio&&"two-way"!==o.video&&"two-way"!==o.screen?n():((o=o.oneway&&o.audio&&"two-way"===o.audio?{audio:!0}:o).audio||o.video||o.screen)&&(o.screen?"Edge"===DetectRTC.browser.name?navigator.getDisplayMedia({video:!0,audio:_(P)}).then(function(e){e.isScreen=!0,I.onGettingLocalMedia(e),!o.audio&&!o.video||_(P)?n(e):P.invokeGetUserMedia(null,n)},function(e){console.error("Unable to capture screen on Edge. HTTPs and version 17+ is required.")}):P.getScreenConstraints(function(e,t){P.invokeGetUserMedia({audio:!!_(P)&&le(t),video:t,isScreen:!0},!o.audio&&!o.video||_(P)?n:P.invokeGetUserMedia(null,n))}):(o.audio||o.video)&&P.invokeGetUserMedia(null,n,o)))}function Ie(e,t){e?(t.audio&&S(e,"audio").forEach(function(e){e.applyConstraints(t.audio)}),t.video&&S(e,"video").forEach(function(e){e.applyConstraints(t.video)})):P.enableLogs&&console.error("No stream to applyConstraints.")}function Ne(t,e,n){e?I.replaceTrack(t,e,n):P.peers.getAllParticipants().forEach(function(e){I.replaceTrack(t,e,n)})}B=B||{useDefaultDevices:!0},(P=this).channel=P.sessionid=(D||location.href.replace(/\/|:|#|\?|\$|\^|%|\.|`|~|!|\+|@|\[|\||]|\|*. /g,"").split("\n").join("").split("\r").join(""))+"",I=new z(P),Ee={},I.onGettingLocalMedia=function(t,i){if(i=i||function(){},Ee[t.streamid])i();else{Ee[t.streamid]=!0;try{t.type="local"}catch(e){}P.setStreamEndHandler(t),j(t,function(e){e.id=t.streamid,e.muted=!0,e.volume=0,-1===P.attachStreams.indexOf(t)&&P.attachStreams.push(t),void 0!==M&&M.setHandlers(t,!0,P),P.streamEvents[t.streamid]={stream:t,type:"local",mediaElement:e,userid:P.userid,extra:P.extra,streamid:t.streamid,isAudioMuted:!0};try{var n=P,o=P.streamEvents[t.streamid];if(o.stream&&S(o.stream,"audio").length){if(!n||!o)throw"Both arguments are required.";if(n.onspeaking&&n.onsilence){if("undefined"==typeof hark)throw"hark.js not found.";hark(o.stream,{onspeaking:function(){n.onspeaking(o)},onsilence:function(){n.onsilence(o)},onvolumechange:function(e,t){n.onvolumechange&&n.onvolumechange(je({volume:e,threshold:t},o))}})}}F(P,P.streamEvents[t.streamid]),P.onstream(P.streamEvents[t.streamid])}catch(e){}i()},P)}},I.onGettingRemoteMedia=function(t,n){try{t.type="remote"}catch(e){}P.setStreamEndHandler(t,"remote-stream"),j(t,function(e){e.id=t.streamid,void 0!==M&&M.setHandlers(t,!1,P),P.streamEvents[t.streamid]={stream:t,type:"remote",userid:n,extra:P.peers[n]?P.peers[n].extra:{},mediaElement:e,streamid:t.streamid},F(P,P.streamEvents[t.streamid]),P.onstream(P.streamEvents[t.streamid])},P)},I.onRemovingRemoteMedia=function(e,t){var n=(n=P.streamEvents[e.streamid])||{stream:e,type:"remote",userid:t,extra:P.peers[t]?P.peers[t].extra:{},streamid:e.streamid,mediaElement:P.streamEvents[e.streamid]?P.streamEvents[e.streamid].mediaElement:null};P.peersBackup[n.userid]&&(n.extra=P.peersBackup[n.userid].extra),P.onstreamended(n),delete P.streamEvents[e.streamid]},I.onNegotiationNeeded=function(e,t,n){n=n||function(){};var o={remoteUserId:t=t||e.remoteUserId,message:e=e||"",sender:P.userid};e.remoteUserId&&e.message&&e.sender&&(o=e),L(function(){P.socket.emit(P.socketMessageEvent,o,n)})},I.onUserLeft=function(e){P.deletePeer(e)},I.disconnectWith=function(e,t){P.socket&&P.socket.emit("disconnect-with",e,t||function(){}),P.deletePeer(e)},P.socketOptions={transport:"polling"},P.openOrJoin=function(e,r){r=r||function(){},P.checkPresence(e,function(e,t){var n,o,i,a;e?(P.sessionid=t,e=!!P.session.oneway,n=c(P.session),o={OfferToReceiveAudio:P.sdpConstraints.mandatory.OfferToReceiveAudio,OfferToReceiveVideo:P.sdpConstraints.mandatory.OfferToReceiveVideo},i={OfferToReceiveAudio:e?!!P.session.audio:P.sdpConstraints.mandatory.OfferToReceiveAudio,OfferToReceiveVideo:e?!!P.session.video||!!P.session.screen:P.sdpConstraints.mandatory.OfferToReceiveVideo},Pe((a={remoteUserId:P.sessionid,message:{newParticipationRequest:!0,isOneWay:e,isDataOnly:n,localPeerSdpConstraints:i,remotePeerSdpConstraints:o},sender:P.userid}).message,function(){ke(a,r)})):(P.waitingForLocalMedia=!0,P.isInitiator=!0,P.sessionid=t||P.sessionid,c(P.session)?Re(r):P.captureUserMedia(function(){Re(r)}))})},P.waitingForLocalMedia=!1,P.open=function(e,t){t=t||function(){},P.waitingForLocalMedia=!0,P.isInitiator=!0,P.sessionid=e||P.sessionid,L(function(){c(P.session)?Re(t):P.captureUserMedia(function(){Re(t)})})},P.peersBackup={},P.deletePeer=function(e){if(e&&P.peers[e]){var t={userid:e,extra:P.peers[e]?P.peers[e].extra:{}};if(P.peersBackup[t.userid]&&(t.extra=P.peersBackup[t.userid].extra),P.onleave(t),P.peers[e]){P.peers[e].streams.forEach(function(e){e.stop()});t=P.peers[e].peer;if(t&&"closed"!==t.iceConnectionState)try{t.close()}catch(e){}P.peers[e]&&(P.peers[e].peer=null,delete P.peers[e])}}},P.rejoin=function(e){var t;!P.isInitiator&&e&&Object.keys(e).length&&(t={},P.peers[e.remoteUserId]&&(t=P.peers[e.remoteUserId].extra,P.deletePeer(e.remoteUserId)),e&&e.remoteUserId&&(P.join(e.remoteUserId),P.onReConnecting({userid:e.remoteUserId,extra:t})))},P.join=function(e,t){P.sessionid=!!e&&(e.sessionid||e.remoteUserId||e)||P.sessionid,P.sessionid+="";var n=!1,o=!1,i=!1,a=!1,r=((e&&e.session||!e||"string"==typeof e)&&(i=!!(e=e&&e.session||P.session).oneway,a=c(e),o={OfferToReceiveAudio:P.sdpConstraints.mandatory.OfferToReceiveAudio,OfferToReceiveVideo:P.sdpConstraints.mandatory.OfferToReceiveVideo},n={OfferToReceiveAudio:i?!!P.session.audio:P.sdpConstraints.mandatory.OfferToReceiveAudio,OfferToReceiveVideo:i?!!P.session.video||!!P.session.screen:P.sdpConstraints.mandatory.OfferToReceiveVideo}),function(){}),s=("function"==typeof(t=t||{})&&(r=t,t={}),void 0!==t.localPeerSdpConstraints&&(n=t.localPeerSdpConstraints),void 0!==t.remotePeerSdpConstraints&&(o=t.remotePeerSdpConstraints),void 0!==t.isOneWay&&(i=t.isOneWay),void 0!==t.isDataOnly&&(a=t.isDataOnly),{remoteUserId:P.sessionid,message:{newParticipationRequest:!0,isOneWay:i,isDataOnly:a,localPeerSdpConstraints:n,remotePeerSdpConstraints:o},sender:P.userid});return Pe(s.message,function(){L(function(){ke(s,r)})}),s},P.publicRoomIdentifier="",P.getUserMedia=P.captureUserMedia=function(o,i){o=o||function(){};var a=i||P.session;P.dontCaptureUserMedia||c(a)?o():(a.audio||a.video||a.screen)&&(a.screen?"Edge"===DetectRTC.browser.name?navigator.getDisplayMedia({video:!0,audio:_(P)}).then(function(e){if(e.isScreen=!0,I.onGettingLocalMedia(e),!a.audio&&!a.video||_(P))o(e);else{var t,n={};for(t in a)"screen"!==t&&(n[t]=a[t]);P.invokeGetUserMedia(i,o,n)}},function(e){console.error("Unable to capture screen on Edge. HTTPs and version 17+ is required.")}):P.getScreenConstraints(function(e,t){if(e)throw e;P.invokeGetUserMedia({audio:!!_(P)&&le(t),video:t,isScreen:!0},function(e){if(!a.audio&&!a.video||_(P))o(e);else{var t,n={};for(t in a)"screen"!==t&&(n[t]=a[t]);P.invokeGetUserMedia(i,o,n)}})}):(a.audio||a.video)&&P.invokeGetUserMedia(i,o,a))},P.onbeforeunload=function(e,t){P.closeBeforeUnload&&(P.peers.getAllParticipants().forEach(function(e){I.onNegotiationNeeded({userLeft:!0},e),P.peers[e]&&P.peers[e].peer&&P.peers[e].peer.close(),delete P.peers[e]}),t||P.closeSocket(),P.isInitiator=!1)},window.ignoreBeforeUnload?P.closeBeforeUnload=!1:(P.closeBeforeUnload=!0,window.addEventListener("beforeunload",P.onbeforeunload,!1)),P.userid=f(),P.changeUserId=function(e,t){t=t||function(){},P.userid=e||f(),P.socket.emit("changed-uuid",P.userid,t)},P.extra={},P.attachStreams=[],P.session={audio:!0,video:!0},P.enableFileSharing=!1,P.bandwidth={screen:!1,audio:!1,video:!1},P.codecs={audio:"opus",video:"VP9"},P.processSdp=function(e){return function(){var t=!1;try{if("undefined"==typeof RTCRtpTransceiver)return;if(!("currentDirection"in RTCRtpTransceiver.prototype))return;var e=new T;try{e.addTransceiver("audio"),t=!0}catch(e){}e.close()}catch(e){t=!1}return t&&function(){var t=!1;try{var e=new T({sdpSemantics:"unified-plan"});try{var n=e.getConfiguration(),t="unified-plan"==n.sdpSemantics||(n.sdpSemantics,!1)}catch(e){t=!1}}catch(e){t=!1}return t}()}()||"Safari"!==DetectRTC.browser.name&&("VP8"===P.codecs.video.toUpperCase()&&(e=E.preferCodec(e,"vp8")),"VP9"===P.codecs.video.toUpperCase()&&(e=E.preferCodec(e,"vp9")),"H264"===P.codecs.video.toUpperCase()&&(e=E.preferCodec(e,"h264")),"G722"===P.codecs.audio&&(e=E.removeNonG722(e)),"Firefox"!==DetectRTC.browser.name&&((P.bandwidth.video||P.bandwidth.screen)&&(e=E.setApplicationSpecificBandwidth(e,P.bandwidth,!!P.session.screen)),P.bandwidth.video&&(e=E.setVideoBitrates(e,{min:8*P.bandwidth.video*1024,max:8*P.bandwidth.video*1024})),P.bandwidth.audio&&(e=E.setOpusAttributes(e,{maxaveragebitrate:8*P.bandwidth.audio*1024,maxplaybackrate:8*P.bandwidth.audio*1024,stereo:1,maxptime:3})))),e},void 0!==E&&(P.BandwidthHandler=P.CodecsHandler=E),P.mediaConstraints={audio:{mandatory:{},optional:P.bandwidth.audio?[{bandwidth:8*P.bandwidth.audio*1024||1048576}]:[]},video:{mandatory:{},optional:P.bandwidth.video?[{bandwidth:8*P.bandwidth.video*1024||1048576},{facingMode:"user"}]:[{facingMode:"user"}]}},"Firefox"===DetectRTC.browser.name&&(P.mediaConstraints={audio:!0,video:!0}),B.useDefaultDevices||DetectRTC.isMobileDevice||DetectRTC.load(function(){var t,n;if(DetectRTC.MediaDevices.forEach(function(e){"audioinput"===e.kind&&!1!==P.mediaConstraints.audio&&(t=e),"videoinput"===e.kind&&!1!==P.mediaConstraints.video&&(n=e)}),t){if("Firefox"===DetectRTC.browser.name)return void(!0!==P.mediaConstraints.audio?P.mediaConstraints.audio.deviceId=t.id:P.mediaConstraints.audio={deviceId:t.id});1==P.mediaConstraints.audio&&(P.mediaConstraints.audio={mandatory:{},optional:[]}),P.mediaConstraints.audio.optional||(P.mediaConstraints.audio.optional=[]);var e=[{sourceId:t.id}];P.mediaConstraints.audio.optional=e.concat(P.mediaConstraints.audio.optional)}n&&("Firefox"===DetectRTC.browser.name?!0!==P.mediaConstraints.video?P.mediaConstraints.video.deviceId=n.id:P.mediaConstraints.video={deviceId:n.id}:(1==P.mediaConstraints.video&&(P.mediaConstraints.video={mandatory:{},optional:[]}),P.mediaConstraints.video.optional||(P.mediaConstraints.video.optional=[]),e=[{sourceId:n.id}],P.mediaConstraints.video.optional=e.concat(P.mediaConstraints.video.optional)))}),P.sdpConstraints={mandatory:{OfferToReceiveAudio:!0,OfferToReceiveVideo:!0},optional:[{VoiceActivityDetection:!1}]},P.sdpSemantics=null,P.iceCandidatePoolSize=null,P.bundlePolicy=null,P.rtcpMuxPolicy=null,P.iceTransportPolicy=null,P.optionalArgument={optional:[{DtlsSrtpKeyAgreement:!0},{googImprovedWifiBwe:!0},{googScreencastMinBitrate:300},{googIPv6:!0},{googDscp:!0},{googCpuUnderuseThreshold:55},{googCpuOveruseThreshold:85},{googSuspendBelowMinBitrate:!0},{googCpuOveruseDetection:!0}],mandatory:{}},P.iceServers=l(P),P.candidates={host:!0,stun:!0,turn:!0},P.iceProtocols={tcp:!0,udp:!0},P.onopen=function(e){P.enableLogs&&console.info("Data connection has been opened between you & ",e.userid)},P.onclose=function(e){P.enableLogs&&console.warn("Data connection has been closed between you & ",e.userid)},P.onerror=function(e){P.enableLogs&&console.error(e.userid,"data-error",e)},P.onmessage=function(e){P.enableLogs&&console.debug("data-message",e.userid,e.data)},P.send=function(e,t){P.peers.send(e,t)},P.close=P.disconnect=P.leave=function(){P.onbeforeunload(!1,!0)},P.closeEntireSession=function(t){t=t||function(){},P.socket.emit("close-entire-session",function e(){P.getAllParticipants().length?setTimeout(e,100):(P.onEntireSessionClosed({sessionid:P.sessionid,userid:P.userid,extra:P.extra}),P.changeUserId(null,function(){P.close(),t()}))})},P.onEntireSessionClosed=function(e){P.enableLogs&&console.info("Entire session is closed: ",e.sessionid,e.extra)},P.onstream=function(e){var t=P.videosContainer,t=(t.insertBefore(e.mediaElement,t.firstChild),e.mediaElement.play());void 0===t?setTimeout(function(){e.mediaElement.play()},2e3):t.catch(function(){}).then(function(){setTimeout(function(){e.mediaElement.play()},2e3)})},P.onstreamended=function(e){e.mediaElement||(e.mediaElement=document.getElementById(e.streamid)),e.mediaElement&&e.mediaElement.parentNode&&e.mediaElement.parentNode.removeChild(e.mediaElement)},P.direction="many-to-many",P.removeStream=function(t,n){var o;P.attachStreams.forEach(function(e){e.id===t&&(o=e)}),o?(P.peers.getAllParticipants().forEach(function(e){if(!n||e===n){e=P.peers[e];try{e.peer.removeStream(o)}catch(e){}}}),P.renegotiate()):console.warn("No such stream exist.",t)},P.addStream=function(n,t){if(n.getTracks)return-1===P.attachStreams.indexOf(n)&&(n.streamid||(n.streamid=n.id),P.attachStreams.push(n)),void P.renegotiate(t);function o(e){n.streamCallback&&n.streamCallback(e),P.renegotiate(t)}c(n)?P.renegotiate(t):(n.audio||n.video||n.screen)&&(n.screen?"Edge"===DetectRTC.browser.name?navigator.getDisplayMedia({video:!0,audio:_(P)}).then(function(e){e.isScreen=!0,I.onGettingLocalMedia(e),!n.audio&&!n.video||_(P)?o(e):P.invokeGetUserMedia(null,function(e){o(e)})},function(e){console.error("Unable to capture screen on Edge. HTTPs and version 17+ is required.")}):P.getScreenConstraints(function(e,t){if(e)return"PermissionDeniedError"===e?(n.streamCallback&&n.streamCallback(null),void(P.enableLogs&&console.error("User rejected to share his screen."))):alert(e);P.invokeGetUserMedia({audio:!!_(P)&&le(t),video:t,isScreen:!0},function(e){!n.audio&&!n.video||_(P)?o(e):P.invokeGetUserMedia(null,function(e){o(e)})})}):(n.audio||n.video)&&P.invokeGetUserMedia(null,o))},P.invokeGetUserMedia=function(n,o,e){e=e||P.session,we({onGettingLocalMedia:function(e){var t=n.video;t&&(t.mediaSource||t.mozMediaSource||t.mandatory&&t.mandatory.chromeMediaSource)&&(e.isScreen=!0),e.isScreen||(e.isVideo=!!S(e,"video").length,e.isAudio=!e.isVideo&&S(e,"audio").length),I.onGettingLocalMedia(e,function(){"function"==typeof o&&o(e)})},onLocalMediaError:function(e,t){I.onLocalMediaError(e,t)},localMediaConstraints:(n=n||P.mediaConstraints)||{audio:!!e.audio&&n.audio,video:!!e.video&&n.video}})},P.applyConstraints=function(t,e){var n;C&&C.prototype.applyConstraints?e?Ie(n=P.streamEvents[e]?P.streamEvents[e].stream:n,t):P.attachStreams.forEach(function(e){Ie(e,t)}):alert("track.applyConstraints is NOT supported in your browser.")},P.replaceTrack=function(n,t,o){if(n=n||{},T.prototype.getSenders)if(n instanceof C)Ne(n,t,o);else{if(n instanceof w)return S(n,"video").length&&Ne(S(n,"video")[0],t,!0),void(S(n,"audio").length&&Ne(S(n,"audio")[0],t,!1));if(c(n))throw"connection.replaceTrack requires audio and/or video and/or screen.";(n.audio||n.video||n.screen)&&(n.screen?"Edge"===DetectRTC.browser.name?navigator.getDisplayMedia({video:!0,audio:_(P)}).then(function(e){e.isScreen=!0,I.onGettingLocalMedia(e),!n.audio&&!n.video||_(P)?i(e):P.invokeGetUserMedia(null,i)},function(e){console.error("Unable to capture screen on Edge. HTTPs and version 17+ is required.")}):P.getScreenConstraints(function(e,t){if(e)return alert(e);P.invokeGetUserMedia({audio:!!_(P)&&le(t),video:t,isScreen:!0},!n.audio&&!n.video||_(P)?i:P.invokeGetUserMedia(null,i))}):(n.audio||n.video)&&P.invokeGetUserMedia(null,i))}else P.addStream(n);function i(e){P.replaceTrack(e,t,o||n.video||n.screen)}},P.resetTrack=function(e,n){(e="string"==typeof(e=e||P.getAllParticipants())?[e]:e).forEach(function(e){var t=P.peers[e].peer;void 0!==n&&!0!==n||!t.lastVideoTrack||P.replaceTrack(t.lastVideoTrack,e,!0),void 0!==n&&!1!==n||!t.lastAudioTrack||P.replaceTrack(t.lastAudioTrack,e,!1)})},P.renegotiate=function(e){e?I.renegotiatePeer(e):P.peers.getAllParticipants().forEach(function(e){I.renegotiatePeer(e)})},P.setStreamEndHandler=function(o,i){var e;o&&o.addEventListener&&(i=!!i,!o.alreadySetEndHandler)&&(o.alreadySetEndHandler=!0,e="ended","oninactive"in o&&(e="inactive"),o.addEventListener(e,function(){o.idInstance&¤tUserMediaRequest.remove(o.idInstance),i||(t=[],P.attachStreams.forEach(function(e){e.id!=o.id&&t.push(e)}),P.attachStreams=t);var e,t,n=(n=P.streamEvents[o.streamid])||{stream:o,streamid:o.streamid,type:i?"remote":"local",userid:P.userid,extra:P.extra,mediaElement:P.streamEvents[o.streamid]?P.streamEvents[o.streamid].mediaElement:null};i&&P.peers[n.userid]&&(e=P.peers[n.userid].peer,t=[],e.getRemoteStreams().forEach(function(e){e.id!=o.id&&t.push(e)}),P.peers[n.userid].streams=t),n.userid===P.userid&&"remote"===n.type||(P.peersBackup[n.userid]&&(n.extra=P.peersBackup[n.userid].extra),P.onstreamended(n),delete P.streamEvents[o.streamid])},!1))},P.onMediaError=function(e,t){P.enableLogs&&console.error(e,t)},P.autoCloseEntireSession=!1,P.filesContainer=P.videosContainer=document.body||document.documentElement,P.isInitiator=!1,P.shareFile=I.shareFile,a.handle(P),t.handle(P),P.token=f,P.onNewParticipant=function(e,t){P.acceptParticipationRequest(e,t)},P.acceptParticipationRequest=function(e,t){t.successCallback&&(t.successCallback(),delete t.successCallback),I.createNewPeer(e,t)},void 0!==M&&(P.StreamsHandler=M),P.onleave=function(e){},P.invokeSelectFileDialog=function(e){var t=new Fe;t.accept="*.*",t.selectSingleFile(e)},P.onmute=function(e){var t;e&&e.mediaElement&&("both"===e.muteType||"video"===e.muteType?(e.mediaElement.src=null,void 0!==(t=e.mediaElement.pause())?t.then(function(){e.mediaElement.poster=e.snapshot||"https://cdn.webrtc-experiment.com/images/muted.png"}):e.mediaElement.poster=e.snapshot||"https://cdn.webrtc-experiment.com/images/muted.png"):"audio"===e.muteType&&(e.mediaElement.muted=!0))},P.onunmute=function(e){e&&e.mediaElement&&e.stream&&("both"===e.unmuteType||"video"===e.unmuteType?(e.mediaElement.poster=null,e.mediaElement.srcObject=e.stream,e.mediaElement.play()):"audio"===e.unmuteType&&(e.mediaElement.muted=!1))},P.onExtraDataUpdated=function(e){e.status="online",P.onUserStatusChanged(e,!0)},P.getAllParticipants=function(e){return P.peers.getAllParticipants(e)},void 0!==M&&(M.onSyncNeeded=function(t,n,o){P.peers.getAllParticipants().forEach(function(e){I.onNegotiationNeeded({streamid:t,action:n,streamSyncNeeded:!0,type:o||"both"},e)})}),P.connectSocket=function(e){L(e)},P.closeSocket=function(){try{Be.a.sockets={}}catch(e){}P.socket&&("function"==typeof P.socket.disconnect&&P.socket.disconnect(),"function"==typeof P.socket.resetProps&&P.socket.resetProps(),P.socket=null)},P.getSocket=function(e){return!e&&P.enableLogs&&console.warn("getSocket.callback paramter is required."),e=e||function(){},P.socket?e(P.socket):L(function(){e(P.socket)}),P.socket},P.getRemoteStreams=I.getRemoteStreams,Ae=["selectFirst","selectAll","forEach"],P.streamEvents={selectFirst:function(e){return P.streamEvents.selectAll(e)[0]},selectAll:function(n){"video"==(n="audio"==(n="screen"==(n="remote"==(n="local"==(n=n||{local:!0,remote:!0,isScreen:!0,isAudio:!0,isVideo:!0})?{local:!0}:n)?{remote:!0}:n)?{isScreen:!0}:n)?{isAudio:!0}:n)&&(n={isVideo:!0});var o=[];return Object.keys(P.streamEvents).forEach(function(e){var t=P.streamEvents[e];-1===Ae.indexOf(e)&&(e=!0,n.local&&"local"===t.type&&(e=!1),n.remote&&"remote"===t.type&&(e=!1),n.isScreen&&t.stream.isScreen&&(e=!1),n.isVideo&&t.stream.isVideo&&(e=!1),n.isAudio&&t.stream.isAudio&&(e=!1),!1===(e=n.userid&&t.userid===n.userid?!1:e)&&o.push(t))}),o}},P.socketURL="/",P.socketMessageEvent="RTCMultiConnection-Message",P.socketCustomEvent="RTCMultiConnection-Custom-Message",P.DetectRTC=DetectRTC,P.setCustomSocketEvent=function(e){e&&(P.socketCustomEvent=e),P.socket&&P.socket.emit("set-custom-socket-event-listener",P.socketCustomEvent)},P.getNumberOfBroadcastViewers=function(e,t){P.socket&&e&&t&&P.socket.emit("get-number-of-users-in-specific-broadcast",e,t)},P.onNumberOfBroadcastViewersUpdated=function(e){P.enableLogs&&P.isInitiator&&console.info("Number of broadcast (",e.broadcastId,") viewers",e.numberOfBroadcastViewers)},P.onUserStatusChanged=function(e,t){P.enableLogs&&!t&&console.info(e.userid,e.status)},P.getUserMediaHandler=we,P.multiPeersHandler=I,P.enableLogs=!0,P.setCustomSocketHandler=function(e){void 0!==n&&(n=e)},P.chunkSize=4e4,P.maxParticipantsAllowed=1e3,P.disconnectWith=I.disconnectWith,P.checkPresence=function(e,o){e=e||P.sessionid,"SSEConnection"!==n.name?P.socket?P.socket.emit("check-presence",e+"",function(e,t,n){P.enableLogs&&console.log("checkPresence.isRoomExist: ",e," roomid: ",t),o(e,t,n)}):P.connectSocket(function(){P.checkPresence(e,o)}):SSEConnection.checkPresence(e,function(e,t,n){if(!P.socket)return e||(P.userid=t),void P.connectSocket(function(){o(e,t,n)});o(e,t)})},P.onReadyForOffer=function(e,t){P.multiPeersHandler.createNewPeer(e,t)},P.setUserPreferences=function(e){return P.dontAttachStream&&(e.dontAttachLocalStream=!0),P.dontGetRemoteStream&&(e.dontGetRemoteStream=!0),e},P.updateExtraData=function(){P.socket.emit("extra-data-updated",P.extra)},P.enableScalableBroadcast=!1,P.maxRelayLimitPerUser=3,P.dontCaptureUserMedia=!1,P.dontAttachStream=!1,P.dontGetRemoteStream=!1,P.onReConnecting=function(e){P.enableLogs&&console.info("ReConnecting with",e.userid,"...")},P.beforeAddingStream=function(e){return e},P.beforeRemovingStream=function(e){return e},P.checkIfChromeExtensionAvailable=Se,"undefined"!=typeof isFirefoxExtensionAvailable&&(P.checkIfChromeExtensionAvailable=isFirefoxExtensionAvailable),P.getChromeExtensionStatus=xe,P.getScreenConstraints=function(n,e){_(P,e)&&(e=!0);var o,i=function(e,t){e||(t=P.modifyScreenConstraints(t),n(e,t))};Te?i(null,{mozMediaSource:"window",mediaSource:"window"}):(o={mandatory:{chromeMediaSource:O,maxWidth:1920>16&255,i[a++]=t>>8&255,i[a++]=255&t;return 2===n&&(t=c[e.charCodeAt(s)]<<2|c[e.charCodeAt(s+1)]>>4,i[a++]=255&t),1===n&&(t=c[e.charCodeAt(s)]<<10|c[e.charCodeAt(s+1)]<<4|c[e.charCodeAt(s+2)]>>2,i[a++]=t>>8&255,i[a++]=255&t),i},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],a=0,r=n-o;a>18&63]+s[o>>12&63]+s[o>>6&63]+s[63&o]);return i.join("")}(e,a,r>2]+s[t<<4&63]+"==")):2==o&&(t=(e[n-2]<<8)+e[n-1],i.push(s[t>>10]+s[t>>4&63]+s[t<<2&63]+"=")),i.join("")};for(var s=[],c=[],l="undefined"!=typeof Uint8Array?Uint8Array:Array,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0,a=o.length;i>1,d=-7,u=n?i-1:0,f=n?-1:1,i=e[t+u];for(u+=f,a=i&(1<<-d)-1,i>>=-d,d+=s;0>=-d,d+=o;0>1,u=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,f=o?0:a-1,p=o?1:-1,a=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,r=l):(r=Math.floor(Math.log(t)/Math.LN2),t*(o=Math.pow(2,-r))<1&&(r--,o*=2),2<=(t+=1<=r+d?u/o:u*Math.pow(2,1-d))*o&&(r++,o/=2),l<=r+d?(s=0,r=l):1<=r+d?(s=(t*o-1)*Math.pow(2,i),r+=d):(s=t*Math.pow(2,d-1)*Math.pow(2,i),r=0));8<=i;e[n+f]=255&s,f+=p,s/=256,i-=8);for(r=r<>t&63|128)}function g(){if(u<=f)throw Error("Invalid byte index");var e=255&d[f];if(f++,128==(192&e))return 63&e;throw Error("Invalid continuation byte")}e.exports={version:"2.1.2",encode:function(e,t){for(var n=!1!==(t=t||{}).strict,o=h(e),i=o.length,a=-1,r="";++a>6&31|192):0==(4294901760&e)?(m(e,t)||(e=65533),n=p(e>>12&15|224),n+=s(e,6)):0==(4292870144&e)&&(n=p(e>>18&7|240),n=(n+=s(e,12))+s(e,6)),n+p(63&e|128)}(o[a],n);return r},decode:function(e,t){var n=!1!==(t=t||{}).strict;d=h(e),u=d.length,f=0;for(var o,i=[];!1!==(o=function(e){var t,n;if(u>>10&1023|55296),a=56320|1023&a),l+=p(a);return l}}},function(e,t){!function(){"use strict";for(var a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",d=new Uint8Array(256),e=0;e>2])+a[(3&t[i])<<4|t[i+1]>>4])+a[(15&t[i+1])<<2|t[i+2]>>6])+a[63&t[i+2]];return n%3==2?o=o.substring(0,o.length-1)+"=":n%3==1&&(o=o.substring(0,o.length-2)+"=="),o},t.decode=function(e){for(var t,n,o,i,a=.75*e.length,r=e.length,s=0,a=("="===e[e.length-1]&&(a--,"="===e[e.length-2]&&a--),new ArrayBuffer(a)),c=new Uint8Array(a),l=0;l>4,c[s++]=(15&n)<<4|o>>2,c[s++]=(3&o)<<6|63&i;return a}}()},function(e,t){var o=void 0!==o?o:"undefined"!=typeof WebKitBlobBuilder?WebKitBlobBuilder:"undefined"!=typeof MSBlobBuilder?MSBlobBuilder:"undefined"!=typeof MozBlobBuilder&&MozBlobBuilder,n=function(){try{return 2===new Blob(["hi"]).size}catch(e){return!1}}(),i=n&&function(){try{return 2===new Blob([new Uint8Array([1,2])]).size}catch(e){return!1}}(),a=o&&o.prototype.append&&o.prototype.getBlob;function r(e){return e.map(function(e){var t,n;return e.buffer instanceof ArrayBuffer?(t=e.buffer,e.byteLength!==t.byteLength&&((n=new Uint8Array(e.byteLength)).set(new Uint8Array(t,e.byteOffset,e.byteLength)),t=n.buffer),t):e})}function s(e,t){t=t||{};var n=new o;return r(e).forEach(function(e){n.append(e)}),t.type?n.getBlob(t.type):n.getBlob()}function c(e,t){return new Blob(r(e),t||{})}"undefined"!=typeof Blob&&(s.prototype=Blob.prototype,c.prototype=Blob.prototype),e.exports=n?i?Blob:c:a?s:void 0},function(e,c,t){function n(e){var r;function s(){if(s.enabled){var o=s,e=+new Date,t=e-(r||e);o.diff=t,o.prev=r,o.curr=e,r=e;for(var i=new Array(arguments.length),n=0;n';n=document.createElement(e)}catch(e){(n=document.createElement("iframe")).name=r.iframeId,n.src="javascript:0"}n.id=r.iframeId,r.form.appendChild(n),r.iframe=n}this.form||(o=document.createElement("form"),i=document.createElement("textarea"),a=this.iframeId="eio_iframe_"+this.index,o.className="socketio",o.style.position="absolute",o.style.top="-1000px",o.style.left="-1000px",o.target=a,o.method="POST",o.setAttribute("accept-charset","utf-8"),i.name="d",o.appendChild(i),document.body.appendChild(o),this.form=o,this.area=i),this.form.action=this.uri(),c(),e=e.replace(d,"\\\n"),this.area.value=e.replace(l,"\\n");try{this.form.submit()}catch(e){}this.iframe.attachEvent?this.iframe.onreadystatechange=function(){"complete"===r.iframe.readyState&&s()}:this.iframe.onload=s}}.call(this,s(31))},function(u,e,f){!function(a){var t,n,o=f(107),r=f(51),i=f(75),e=f(76),s=f(152),c=f(77)("engine.io-client:websocket");if("undefined"!=typeof WebSocket)t=WebSocket;else if("undefined"!=typeof self)t=self.WebSocket||self.MozWebSocket;else try{n=f(392)}catch(e){}var l=t||n;function d(e){e&&e.forceBase64&&(this.supportsBinary=!1),this.perMessageDeflate=e.perMessageDeflate,this.usingBrowserWebSocket=t&&!e.forceNode,this.protocols=e.protocols,this.usingBrowserWebSocket||(l=n),o.call(this,e)}e(u.exports=d,o),d.prototype.name="websocket",d.prototype.supportsBinary=!0,d.prototype.doOpen=function(){if(this.check()){var e=this.uri(),t=this.protocols,n={agent:this.agent,perMessageDeflate:this.perMessageDeflate};n.pfx=this.pfx,n.key=this.key,n.passphrase=this.passphrase,n.cert=this.cert,n.ca=this.ca,n.ciphers=this.ciphers,n.rejectUnauthorized=this.rejectUnauthorized,this.extraHeaders&&(n.headers=this.extraHeaders),this.localAddress&&(n.localAddress=this.localAddress);try{this.ws=this.usingBrowserWebSocket&&!this.isReactNative?t?new l(e,t):new l(e):new l(e,t,n)}catch(e){return this.emit("error",e)}void 0===this.ws.binaryType&&(this.supportsBinary=!1),this.ws.supports&&this.ws.supports.binary?(this.supportsBinary=!0,this.ws.binaryType="nodebuffer"):this.ws.binaryType="arraybuffer",this.addEventListeners()}},d.prototype.addEventListeners=function(){var t=this;this.ws.onopen=function(){t.onOpen()},this.ws.onclose=function(){t.onClose()},this.ws.onmessage=function(e){t.onData(e.data)},this.ws.onerror=function(e){t.onError("websocket error",e)}},d.prototype.write=function(e){var o=this;this.writable=!1;for(var i=e.length,t=0,n=i;t= 130\n#define COMPAT_VARYING out\n#define COMPAT_ATTRIBUTE in\n#define COMPAT_TEXTURE texture\n#else\n#define COMPAT_VARYING varying \n#define COMPAT_ATTRIBUTE attribute \n#define COMPAT_TEXTURE texture2D\n#endif\n\n#ifdef GL_ES\n#define COMPAT_PRECISION mediump\n#else\n#define COMPAT_PRECISION\n#endif\n\nCOMPAT_ATTRIBUTE vec4 VertexCoord;\nCOMPAT_ATTRIBUTE vec4 COLOR;\nCOMPAT_ATTRIBUTE vec4 TexCoord;\nCOMPAT_VARYING vec4 COL0;\nCOMPAT_VARYING vec4 TEX0;\nCOMPAT_VARYING vec4 t1;\nCOMPAT_VARYING vec4 t2;\nCOMPAT_VARYING vec4 t3;\nCOMPAT_VARYING vec4 t4;\n\nvec4 _oPosition1; \nuniform mat4 MVPMatrix;\nuniform COMPAT_PRECISION int FrameDirection;\nuniform COMPAT_PRECISION int FrameCount;\nuniform COMPAT_PRECISION vec2 OutputSize;\nuniform COMPAT_PRECISION vec2 TextureSize;\nuniform COMPAT_PRECISION vec2 InputSize;\n\n// compatibility #defines\n#define vTexCoord TEX0.xy\n#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize\n#define OutSize vec4(OutputSize, 1.0 / OutputSize)\n\nvoid main()\n{\ngl_Position = MVPMatrix * VertexCoord;\nTEX0.xy = TexCoord.xy;\nfloat x = 0.5 * SourceSize.z;\nfloat y = 0.5 * SourceSize.w;\nvec2 dg1 = vec2( x, y);\nvec2 dg2 = vec2(-x, y);\nvec2 dx = vec2(x, 0.0);\nvec2 dy = vec2(0.0, y);\nt1 = vec4(vTexCoord - dg1, vTexCoord - dy);\nt2 = vec4(vTexCoord - dg2, vTexCoord + dx);\nt3 = vec4(vTexCoord + dg1, vTexCoord + dy);\nt4 = vec4(vTexCoord + dg2, vTexCoord - dx);\n}\n\n#elif defined(FRAGMENT)\n\n#if __VERSION__ >= 130\n#define COMPAT_VARYING in\n#define COMPAT_TEXTURE texture\nout vec4 FragColor;\n#else\n#define COMPAT_VARYING varying\n#define FragColor gl_FragColor\n#define COMPAT_TEXTURE texture2D\n#endif\n\n#ifdef GL_ES\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n#define COMPAT_PRECISION mediump\n#else\n#define COMPAT_PRECISION\n#endif\n\nuniform COMPAT_PRECISION int FrameDirection;\nuniform COMPAT_PRECISION int FrameCount;\nuniform COMPAT_PRECISION vec2 OutputSize;\nuniform COMPAT_PRECISION vec2 TextureSize;\nuniform COMPAT_PRECISION vec2 InputSize;\nuniform sampler2D Texture;\nCOMPAT_VARYING vec4 TEX0;\nCOMPAT_VARYING vec4 t1;\nCOMPAT_VARYING vec4 t2;\nCOMPAT_VARYING vec4 t3;\nCOMPAT_VARYING vec4 t4;\n\n// compatibility #defines\n#define Source Texture\n#define vTexCoord TEX0.xy\n\n#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize\n#define OutSize vec4(OutputSize, 1.0 / OutputSize)\n\nfloat mx = 0.325; // start smoothing wt.\nfloat k = -0.250; // wt. decrease factor\nfloat max_w = 0.25; // max filter weight\nfloat min_w =-0.05; // min filter weight\nfloat lum_add = 0.25; // affects smoothing\nvec3 dt = vec3(1.0);\n\nvoid main()\n{\nvec3 c00 = COMPAT_TEXTURE(Source, t1.xy).xyz; \nvec3 c10 = COMPAT_TEXTURE(Source, t1.zw).xyz; \nvec3 c20 = COMPAT_TEXTURE(Source, t2.xy).xyz; \nvec3 c01 = COMPAT_TEXTURE(Source, t4.zw).xyz; \nvec3 c11 = COMPAT_TEXTURE(Source, vTexCoord).xyz; \nvec3 c21 = COMPAT_TEXTURE(Source, t2.zw).xyz; \nvec3 c02 = COMPAT_TEXTURE(Source, t4.xy).xyz; \nvec3 c12 = COMPAT_TEXTURE(Source, t3.zw).xyz; \nvec3 c22 = COMPAT_TEXTURE(Source, t3.xy).xyz; \n\nfloat md1 = dot(abs(c00 - c22), dt);\nfloat md2 = dot(abs(c02 - c20), dt);\n\nfloat w1 = dot(abs(c22 - c11), dt) * md2;\nfloat w2 = dot(abs(c02 - c11), dt) * md1;\nfloat w3 = dot(abs(c00 - c11), dt) * md2;\nfloat w4 = dot(abs(c20 - c11), dt) * md1;\n\nfloat t1 = w1 + w3;\nfloat t2 = w2 + w4;\nfloat ww = max(t1, t2) + 0.0001;\n\nc11 = (w1 * c00 + w2 * c20 + w3 * c22 + w4 * c02 + ww * c11) / (t1 + t2 + ww);\n\nfloat lc1 = k / (0.12 * dot(c10 + c12 + c11, dt) + lum_add);\nfloat lc2 = k / (0.12 * dot(c01 + c21 + c11, dt) + lum_add);\n\nw1 = clamp(lc1 * dot(abs(c11 - c10), dt) + mx, min_w, max_w);\nw2 = clamp(lc2 * dot(abs(c11 - c21), dt) + mx, min_w, max_w);\nw3 = clamp(lc1 * dot(abs(c11 - c12), dt) + mx, min_w, max_w);\nw4 = clamp(lc2 * dot(abs(c11 - c01), dt) + mx, min_w, max_w);\nFragColor = vec4(w1 * c10 + w2 * c21 + w3 * c12 + w4 * c01 + (1.0 - w1 - w2 - w3 - w4) * c11, 1.0);\n} \n#endif\n","4xScaleHQ.glsl":"/*\n4xGLSLHqFilter shader\n\nCopyright (C) 2005 guest(r) - guest.r@gmail.com\n\nThis program is free software; you can redistribute it and/or\nmodify it under the terms of the GNU General Public License\nas published by the Free Software Foundation; either version 2\nof the License, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program; if not, write to the Free Software\nFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n*/\n\n#if defined(VERTEX)\n\n#if __VERSION__ >= 130\n#define COMPAT_VARYING out\n#define COMPAT_ATTRIBUTE in\n#define COMPAT_TEXTURE texture\n#else\n#define COMPAT_VARYING varying \n#define COMPAT_ATTRIBUTE attribute \n#define COMPAT_TEXTURE texture2D\n#endif\n\n#ifdef GL_ES\n#define COMPAT_PRECISION mediump\n#else\n#define COMPAT_PRECISION\n#endif\n\nCOMPAT_ATTRIBUTE vec4 VertexCoord;\nCOMPAT_ATTRIBUTE vec4 COLOR;\nCOMPAT_ATTRIBUTE vec4 TexCoord;\nCOMPAT_VARYING vec4 COL0;\nCOMPAT_VARYING vec4 TEX0;\nCOMPAT_VARYING vec4 t1;\nCOMPAT_VARYING vec4 t2;\nCOMPAT_VARYING vec4 t3;\nCOMPAT_VARYING vec4 t4;\nCOMPAT_VARYING vec4 t5;\nCOMPAT_VARYING vec4 t6;\n\nvec4 _oPosition1; \nuniform mat4 MVPMatrix;\nuniform COMPAT_PRECISION int FrameDirection;\nuniform COMPAT_PRECISION int FrameCount;\nuniform COMPAT_PRECISION vec2 OutputSize;\nuniform COMPAT_PRECISION vec2 TextureSize;\nuniform COMPAT_PRECISION vec2 InputSize;\n\n// compatibility #defines\n#define vTexCoord TEX0.xy\n#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize\n#define OutSize vec4(OutputSize, 1.0 / OutputSize)\n\nvoid main()\n{\ngl_Position = MVPMatrix * VertexCoord;\nTEX0.xy = TexCoord.xy;\nfloat x = 0.5 * SourceSize.z;\nfloat y = 0.5 * SourceSize.w;\nvec2 dg1 = vec2( x, y);\nvec2 dg2 = vec2(-x, y);\nvec2 sd1 = dg1 * 0.5;\nvec2 sd2 = dg2 * 0.5;\nvec2 ddx = vec2(x, 0.0);\nvec2 ddy = vec2(0.0, y);\nt1 = vec4(vTexCoord - sd1, vTexCoord - ddy);\nt2 = vec4(vTexCoord - sd2, vTexCoord + ddx);\nt3 = vec4(vTexCoord + sd1, vTexCoord + ddy);\nt4 = vec4(vTexCoord + sd2, vTexCoord - ddx);\nt5 = vec4(vTexCoord - dg1, vTexCoord - dg2);\nt6 = vec4(vTexCoord + dg1, vTexCoord + dg2);\n}\n\n#elif defined(FRAGMENT)\n\n#if __VERSION__ >= 130\n#define COMPAT_VARYING in\n#define COMPAT_TEXTURE texture\nout vec4 FragColor;\n#else\n#define COMPAT_VARYING varying\n#define FragColor gl_FragColor\n#define COMPAT_TEXTURE texture2D\n#endif\n\n#ifdef GL_ES\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n#define COMPAT_PRECISION mediump\n#else\n#define COMPAT_PRECISION\n#endif\n\nuniform COMPAT_PRECISION int FrameDirection;\nuniform COMPAT_PRECISION int FrameCount;\nuniform COMPAT_PRECISION vec2 OutputSize;\nuniform COMPAT_PRECISION vec2 TextureSize;\nuniform COMPAT_PRECISION vec2 InputSize;\nuniform sampler2D Texture;\nCOMPAT_VARYING vec4 TEX0;\nCOMPAT_VARYING vec4 t1;\nCOMPAT_VARYING vec4 t2;\nCOMPAT_VARYING vec4 t3;\nCOMPAT_VARYING vec4 t4;\nCOMPAT_VARYING vec4 t5;\nCOMPAT_VARYING vec4 t6;\n\n// compatibility #defines\n#define Source Texture\n#define vTexCoord TEX0.xy\n\n#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize\n#define OutSize vec4(OutputSize, 1.0 / OutputSize)\n\nfloat mx = 1.0; // start smoothing wt.\nfloat k = -1.10; // wt. decrease factor\nfloat max_w = 0.75; // max filter weight\nfloat min_w = 0.03; // min filter weight\nfloat lum_add = 0.33; // affects smoothing\nvec3 dt = vec3(1.0);\n\nvoid main()\n{\nvec3 c = COMPAT_TEXTURE(Source, vTexCoord).xyz;\nvec3 i1 = COMPAT_TEXTURE(Source, t1.xy).xyz; \nvec3 i2 = COMPAT_TEXTURE(Source, t2.xy).xyz; \nvec3 i3 = COMPAT_TEXTURE(Source, t3.xy).xyz; \nvec3 i4 = COMPAT_TEXTURE(Source, t4.xy).xyz; \nvec3 o1 = COMPAT_TEXTURE(Source, t5.xy).xyz; \nvec3 o3 = COMPAT_TEXTURE(Source, t6.xy).xyz; \nvec3 o2 = COMPAT_TEXTURE(Source, t5.zw).xyz;\nvec3 o4 = COMPAT_TEXTURE(Source, t6.zw).xyz;\nvec3 s1 = COMPAT_TEXTURE(Source, t1.zw).xyz; \nvec3 s2 = COMPAT_TEXTURE(Source, t2.zw).xyz; \nvec3 s3 = COMPAT_TEXTURE(Source, t3.zw).xyz; \nvec3 s4 = COMPAT_TEXTURE(Source, t4.zw).xyz; \n\nfloat ko1=dot(abs(o1-c),dt);\nfloat ko2=dot(abs(o2-c),dt);\nfloat ko3=dot(abs(o3-c),dt);\nfloat ko4=dot(abs(o4-c),dt);\n\nfloat k1=min(dot(abs(i1-i3),dt),max(ko1,ko3));\nfloat k2=min(dot(abs(i2-i4),dt),max(ko2,ko4));\n\nfloat w1 = k2; if(ko3= 130\n #define COMPAT_VARYING out\n #define COMPAT_ATTRIBUTE in\n #define COMPAT_TEXTURE texture\n #else\n #define COMPAT_VARYING varying\n #define COMPAT_ATTRIBUTE attribute\n #define COMPAT_TEXTURE texture2D\n #endif\n \n #ifdef GL_ES\n #define COMPAT_PRECISION mediump\n #else\n #define COMPAT_PRECISION\n #endif\n COMPAT_VARYING float _frame_rotation;\n struct input_dummy {\n vec2 _video_size;\n vec2 _texture_size;\n vec2 _output_dummy_size;\n float _frame_count;\n float _frame_direction;\n float _frame_rotation;\n };\n vec4 _oPosition1;\n vec4 _r0005;\n COMPAT_ATTRIBUTE vec4 VertexCoord;\n COMPAT_ATTRIBUTE vec4 TexCoord;\n COMPAT_VARYING vec4 TEX0;\n \n uniform mat4 MVPMatrix;\n uniform int FrameDirection;\n uniform int FrameCount;\n uniform COMPAT_PRECISION vec2 OutputSize;\n uniform COMPAT_PRECISION vec2 TextureSize;\n uniform COMPAT_PRECISION vec2 InputSize;\n void main()\n {\n vec2 _oTex;\n _r0005 = VertexCoord.x*MVPMatrix[0];\n _r0005 = _r0005 + VertexCoord.y*MVPMatrix[1];\n _r0005 = _r0005 + VertexCoord.z*MVPMatrix[2];\n _r0005 = _r0005 + VertexCoord.w*MVPMatrix[3];\n _oPosition1 = _r0005;\n _oTex = TexCoord.xy;\n gl_Position = _r0005;\n TEX0.xy = TexCoord.xy;\n }\n #elif defined(FRAGMENT)\n \n #if __VERSION__ >= 130\n #define COMPAT_VARYING in\n #define COMPAT_TEXTURE texture\n out vec4 FragColor;\n #else\n #define COMPAT_VARYING varying\n #define FragColor gl_FragColor\n #define COMPAT_TEXTURE texture2D\n #endif\n \n #ifdef GL_ES\n #ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp float;\n #else\n precision mediump float;\n #endif\n #define COMPAT_PRECISION mediump\n #else\n #define COMPAT_PRECISION\n #endif\n COMPAT_VARYING float _frame_rotation;\n struct input_dummy {\n vec2 _video_size;\n vec2 _texture_size;\n vec2 _output_dummy_size;\n float _frame_count;\n float _frame_direction;\n float _frame_rotation;\n };\n vec4 _ret_0;\n float _TMP30;\n float _TMP29;\n float _TMP28;\n float _TMP13;\n float _TMP32;\n float _TMP11;\n float _TMP10;\n float _TMP31;\n float _TMP9;\n float _TMP8;\n float _TMP15;\n float _TMP14;\n float _TMP33;\n vec4 _TMP34;\n vec4 _TMP27;\n vec4 _TMP25;\n vec4 _TMP23;\n vec4 _TMP21;\n vec4 _TMP26;\n vec4 _TMP24;\n vec4 _TMP22;\n vec4 _TMP20;\n float _TMP4;\n vec4 _TMP3;\n vec4 _TMP2;\n float _TMP19;\n float _TMP18;\n float _TMP17;\n float _TMP16;\n vec4 _TMP1;\n vec2 _TMP0;\n uniform sampler2D Texture;\n input_dummy _IN1;\n float _TMP43;\n float _x_step0044;\n float _curve0044;\n float _a0048;\n float _val0052;\n float _a0052;\n vec4 _TMP57;\n vec4 _x0072;\n vec2 _c0086;\n vec4 _x0088;\n vec4 _x0094;\n vec2 _c0098;\n vec4 _x0100;\n vec2 _c0104;\n vec4 _x0106;\n vec4 _sample_min0110;\n vec4 _sample_max0110;\n vec4 _r0112;\n vec4 _TMP117;\n vec2 _co0124;\n vec2 _c0126;\n vec4 _x0128;\n vec4 _x0134;\n vec2 _c0138;\n vec4 _x0140;\n vec2 _c0144;\n vec4 _x0146;\n vec4 _sample_min0150;\n vec4 _sample_max0150;\n vec4 _r0152;\n vec4 _TMP157;\n float _TMP163;\n float _x_step0164;\n float _curve0164;\n float _a0168;\n float _val0172;\n float _a0172;\n float _TMP183;\n float _TMP189;\n float _x0190;\n float _a0196;\n float _x0198;\n vec2 _x0200;\n float _x0208;\n COMPAT_VARYING vec4 TEX0;\n \n uniform COMPAT_PRECISION vec2 OutputSize;\n uniform COMPAT_PRECISION vec2 TextureSize;\n uniform COMPAT_PRECISION vec2 InputSize;\n void main()\n {\n vec2 _dx1;\n vec2 _dy;\n vec2 _pix_co;\n vec2 _tex_co;\n vec2 _dist;\n vec3 _col2;\n vec3 _col21;\n vec4 _coeffs1;\n float _luma;\n float _bright;\n float _scan_weight;\n vec2 _mod_fac;\n int _dot_no;\n vec3 _mask_weight;\n vec3 _TMP37;\n _dx1 = vec2(1.00000000E+00/TextureSize.x, 0.00000000E+00);\n _dy = vec2(0.00000000E+00, 1.00000000E+00/TextureSize.y);\n _pix_co = TEX0.xy*TextureSize - vec2( 5.00000000E-01, 5.00000000E-01);\n _TMP0 = floor(_pix_co);\n _tex_co = (_TMP0 + vec2( 5.00000000E-01, 5.00000000E-01))/TextureSize;\n _dist = fract(_pix_co);\n _x_step0044 = float((_dist.x >= 5.00000000E-01));\n _a0048 = 2.50000000E-01 - (_dist.x - _x_step0044)*(_dist.x - _x_step0044);\n _TMP33 = inversesqrt(_a0048);\n _TMP14 = 1.00000000E+00/_TMP33;\n _a0052 = 5.00000000E-01 - _dist.x;\n _val0052 = float((_a0052 > 0.00000000E+00));\n _TMP15 = _val0052 - float((_a0052 < 0.00000000E+00));\n _curve0044 = 5.00000000E-01 - _TMP14*_TMP15;\n _TMP43 = _dist.x + 2.50000000E-01*(_curve0044 - _dist.x);\n _coeffs1 = 3.14159274E+00*vec4(1.00000000E+00 + _TMP43, _TMP43, 1.00000000E+00 - _TMP43, 2.00000000E+00 - _TMP43);\n _TMP1 = abs(_coeffs1);\n _TMP57 = max(_TMP1, vec4( 9.99999975E-06, 9.99999975E-06, 9.99999975E-06, 9.99999975E-06));\n _TMP16 = sin(_TMP57.x);\n _TMP17 = sin(_TMP57.y);\n _TMP18 = sin(_TMP57.z);\n _TMP19 = sin(_TMP57.w);\n _TMP2 = vec4(_TMP16, _TMP17, _TMP18, _TMP19);\n _x0072 = _TMP57/2.00000000E+00;\n _TMP16 = sin(_x0072.x);\n _TMP17 = sin(_x0072.y);\n _TMP18 = sin(_x0072.z);\n _TMP19 = sin(_x0072.w);\n _TMP3 = vec4(_TMP16, _TMP17, _TMP18, _TMP19);\n _coeffs1 = ((2.00000000E+00*_TMP2)*_TMP3)/(_TMP57*_TMP57);\n _TMP4 = dot(_coeffs1, vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00));\n _coeffs1 = _coeffs1/_TMP4;\n _c0086 = _tex_co - _dx1;\n _TMP20 = COMPAT_TEXTURE(Texture, _c0086);\n _x0088 = vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00) + (_TMP20 - vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00));\n _TMP21 = _TMP20*_x0088;\n _TMP22 = COMPAT_TEXTURE(Texture, _tex_co);\n _x0094 = vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00) + (_TMP22 - vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00));\n _TMP23 = _TMP22*_x0094;\n _c0098 = _tex_co + _dx1;\n _TMP24 = COMPAT_TEXTURE(Texture, _c0098);\n _x0100 = vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00) + (_TMP24 - vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00));\n _TMP25 = _TMP24*_x0100;\n _c0104 = _tex_co + 2.00000000E+00*_dx1;\n _TMP26 = COMPAT_TEXTURE(Texture, _c0104);\n _x0106 = vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00) + (_TMP26 - vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00));\n _TMP27 = _TMP26*_x0106;\n _r0112 = _coeffs1.x*_TMP21;\n _r0112 = _r0112 + _coeffs1.y*_TMP23;\n _r0112 = _r0112 + _coeffs1.z*_TMP25;\n _r0112 = _r0112 + _coeffs1.w*_TMP27;\n _sample_min0110 = min(_TMP23, _TMP25);\n _sample_max0110 = max(_TMP23, _TMP25);\n _TMP34 = min(_sample_max0110, _r0112);\n _TMP117 = max(_sample_min0110, _TMP34);\n _co0124 = _tex_co + _dy;\n _c0126 = _co0124 - _dx1;\n _TMP20 = COMPAT_TEXTURE(Texture, _c0126);\n _x0128 = vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00) + (_TMP20 - vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00));\n _TMP21 = _TMP20*_x0128;\n _TMP22 = COMPAT_TEXTURE(Texture, _co0124);\n _x0134 = vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00) + (_TMP22 - vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00));\n _TMP23 = _TMP22*_x0134;\n _c0138 = _co0124 + _dx1;\n _TMP24 = COMPAT_TEXTURE(Texture, _c0138);\n _x0140 = vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00) + (_TMP24 - vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00));\n _TMP25 = _TMP24*_x0140;\n _c0144 = _co0124 + 2.00000000E+00*_dx1;\n _TMP26 = COMPAT_TEXTURE(Texture, _c0144);\n _x0146 = vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00) + (_TMP26 - vec4( 1.00000000E+00, 1.00000000E+00, 1.00000000E+00, 1.00000000E+00));\n _TMP27 = _TMP26*_x0146;\n _r0152 = _coeffs1.x*_TMP21;\n _r0152 = _r0152 + _coeffs1.y*_TMP23;\n _r0152 = _r0152 + _coeffs1.z*_TMP25;\n _r0152 = _r0152 + _coeffs1.w*_TMP27;\n _sample_min0150 = min(_TMP23, _TMP25);\n _sample_max0150 = max(_TMP23, _TMP25);\n _TMP34 = min(_sample_max0150, _r0152);\n _TMP157 = max(_sample_min0150, _TMP34);\n _x_step0164 = float((_dist.y >= 5.00000000E-01));\n _a0168 = 2.50000000E-01 - (_dist.y - _x_step0164)*(_dist.y - _x_step0164);\n _TMP33 = inversesqrt(_a0168);\n _TMP14 = 1.00000000E+00/_TMP33;\n _a0172 = 5.00000000E-01 - _dist.y;\n _val0172 = float((_a0172 > 0.00000000E+00));\n _TMP15 = _val0172 - float((_a0172 < 0.00000000E+00));\n _curve0164 = 5.00000000E-01 - _TMP14*_TMP15;\n _TMP163 = _dist.y + (_curve0164 - _dist.y);\n _col2 = _TMP117.xyz + _TMP163*(_TMP157.xyz - _TMP117.xyz);\n _luma = dot(vec3( 2.12599993E-01, 7.15200007E-01, 7.22000003E-02), _col2);\n _TMP8 = max(_col2.y, _col2.z);\n _TMP9 = max(_col2.x, _TMP8);\n _bright = (_TMP9 + _luma)/2.00000000E+00;\n _TMP31 = min(6.49999976E-01, _bright);\n _TMP183 = max(3.49999994E-01, _TMP31);\n _x0190 = _bright*1.50000000E+00;\n _TMP31 = min(1.50000000E+00, _x0190);\n _TMP189 = max(1.50000000E+00, _TMP31);\n _a0196 = TEX0.y*2.00000000E+00*3.14159274E+00*TextureSize.y;\n _TMP10 = cos(_a0196);\n _x0198 = _TMP10*5.00000000E-01 + 5.00000000E-01;\n _TMP11 = pow(_x0198, _TMP189);\n _scan_weight = 1.00000000E+00 - _TMP11;\n _x0200 = (TEX0.xy*OutputSize*TextureSize)/InputSize;\n _mod_fac = floor(_x0200);\n _x0208 = _mod_fac.x/3.00000000E+00;\n _TMP32 = floor(_x0208);\n _TMP13 = _mod_fac.x - 3.00000000E+00*_TMP32;\n _dot_no = int(_TMP13);\n if (_dot_no == 0) {\n _mask_weight = vec3( 1.00000000E+00, 6.99999988E-01, 6.99999988E-01);\n } else {\n if (_dot_no == 1) {\n _mask_weight = vec3( 6.99999988E-01, 1.00000000E+00, 6.99999988E-01);\n } else {\n _mask_weight = vec3( 6.99999988E-01, 6.99999988E-01, 1.00000000E+00);\n }\n }\n if (InputSize.y >= 4.00000000E+02) {\n _scan_weight = 1.00000000E+00;\n }\n _col21 = _col2.xyz;\n _col2 = _col2*vec3(_scan_weight, _scan_weight, _scan_weight);\n _col2 = _col2 + _TMP183*(_col21 - _col2);\n _col2 = _col2*_mask_weight;\n _TMP28 = pow(_col2.x, 5.55555582E-01);\n _TMP29 = pow(_col2.y, 5.55555582E-01);\n _TMP30 = pow(_col2.z, 5.55555582E-01);\n _col2 = vec3(_TMP28, _TMP29, _TMP30);\n _TMP37 = _col2*1.20000005E+00;\n _ret_0 = vec4(_TMP37.x, _TMP37.y, _TMP37.z, 1.00000000E+00);\n FragColor = _ret_0;\n return;\n }\n #endif\n","crt-aperture.glsl":'\n/*\nCRT Shader by EasyMode\nLicense: GPL\n*/\n/*\n#pragma parameter SHARPNESS_IMAGE "Sharpness Image" 1.0 1.0 5.0 1.0\n#pragma parameter SHARPNESS_EDGES "Sharpness Edges" 3.0 1.0 5.0 1.0\n#pragma parameter GLOW_WIDTH "Glow Width" 0.5 0.05 0.65 0.05\n#pragma parameter GLOW_HEIGHT "Glow Height" 0.5 0.05 0.65 0.05\n#pragma parameter GLOW_HALATION "Glow Halation" 0.1 0.0 1.0 0.01\n#pragma parameter GLOW_DIFFUSION "Glow Diffusion" 0.05 0.0 1.0 0.01\n#pragma parameter MASK_COLORS "Mask Colors" 2.0 2.0 3.0 1.0\n#pragma parameter MASK_STRENGTH "Mask Strength" 0.3 0.0 1.0 0.05\n#pragma parameter MASK_SIZE "Mask Size" 1.0 1.0 9.0 1.0\n#pragma parameter SCANLINE_SIZE_MIN "Scanline Size Min." 0.5 0.5 1.5 0.05\n#pragma parameter SCANLINE_SIZE_MAX "Scanline Size Max." 1.5 0.5 1.5 0.05\n#pragma parameter GAMMA_INPUT "Gamma Input" 2.4 1.0 5.0 0.1\n#pragma parameter GAMMA_OUTPUT "Gamma Output" 2.4 1.0 5.0 0.1\n#pragma parameter BRIGHTNESS "Brightness" 1.5 0.0 2.0 0.05\n* */\n\n#define Coord TEX0\n\n#if defined(VERTEX)\n\n#if __VERSION__ >= 130\n#define OUT out\n#define IN in\n#define tex2D texture\n#else\n#define OUT varying \n#define IN attribute \n#define tex2D texture2D\n#endif\n\n#ifdef GL_ES\n#define PRECISION mediump\n#else\n#define PRECISION\n#endif\n\nIN vec4 VertexCoord;\nIN vec4 Color;\nIN vec2 TexCoord;\nOUT vec4 color;\nOUT vec2 Coord;\n\nuniform mat4 MVPMatrix;\nuniform PRECISION int FrameDirection;\nuniform PRECISION int FrameCount;\nuniform PRECISION vec2 OutputSize;\nuniform PRECISION vec2 TextureSize;\nuniform PRECISION vec2 InputSize;\n\nvoid main()\n{\ngl_Position = MVPMatrix * VertexCoord;\ncolor = Color;\nCoord = TexCoord;\n}\n\n#elif defined(FRAGMENT)\n\n#if __VERSION__ >= 130\n#define IN in\n#define tex2D texture\nout vec4 FragColor;\n#else\n#define IN varying\n#define FragColor gl_FragColor\n#define tex2D texture2D\n#endif\n\n#ifdef GL_ES\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n#define PRECISION mediump\n#else\n#define PRECISION\n#endif\n\nuniform PRECISION int FrameDirection;\nuniform PRECISION int FrameCount;\nuniform PRECISION vec2 OutputSize;\nuniform PRECISION vec2 TextureSize;\nuniform PRECISION vec2 InputSize;\nuniform sampler2D Texture;\nIN vec2 Coord;\n\n#ifdef PARAMETER_UNIFORM\nuniform PRECISION float SHARPNESS_IMAGE;\nuniform PRECISION float SHARPNESS_EDGES;\nuniform PRECISION float GLOW_WIDTH;\nuniform PRECISION float GLOW_HEIGHT;\nuniform PRECISION float GLOW_HALATION;\nuniform PRECISION float GLOW_DIFFUSION;\nuniform PRECISION float MASK_COLORS;\nuniform PRECISION float MASK_STRENGTH;\nuniform PRECISION float MASK_SIZE;\nuniform PRECISION float SCANLINE_SIZE_MIN;\nuniform PRECISION float SCANLINE_SIZE_MAX;\nuniform PRECISION float GAMMA_INPUT;\nuniform PRECISION float GAMMA_OUTPUT;\nuniform PRECISION float BRIGHTNESS;\n#else\n#define SHARPNESS_IMAGE 1.0\n#define SHARPNESS_EDGES 3.0\n#define GLOW_WIDTH 0.5\n#define GLOW_HEIGHT 0.5\n#define GLOW_HALATION 0.1\n#define GLOW_DIFFUSION 0.05\n#define MASK_COLORS 2.0\n#define MASK_STRENGTH 0.3\n#define MASK_SIZE 1.0\n#define SCANLINE_SIZE_MIN 0.5\n#define SCANLINE_SIZE_MAX 1.5\n#define GAMMA_INPUT 2.4\n#define GAMMA_OUTPUT 2.4\n#define BRIGHTNESS 1.5\n#endif\n\n#define FIX(c) max(abs(c), 1e-5)\n#define PI 3.141592653589\n#define saturate(c) clamp(c, 0.0, 1.0)\n#define TEX2D(c) pow(tex2D(tex, c).rgb, vec3(GAMMA_INPUT))\n\nmat3 get_color_matrix(sampler2D tex, vec2 co, vec2 dx)\n{\nreturn mat3(TEX2D(co - dx), TEX2D(co), TEX2D(co + dx));\n}\n\nvec3 blur(mat3 m, float dist, float rad)\n{\nvec3 x = vec3(dist - 1.0, dist, dist + 1.0) / rad;\nvec3 w = exp2(x * x * -1.0);\n\nreturn (m[0] * w.x + m[1] * w.y + m[2] * w.z) / (w.x + w.y + w.z);\n}\n\nvec3 filter_gaussian(sampler2D tex, vec2 co, vec2 tex_size)\n{\nvec2 dx = vec2(1.0 / tex_size.x, 0.0);\nvec2 dy = vec2(0.0, 1.0 / tex_size.y);\nvec2 pix_co = co * tex_size;\nvec2 tex_co = (floor(pix_co) + 0.5) / tex_size;\nvec2 dist = (fract(pix_co) - 0.5) * -1.0;\n\nmat3 line0 = get_color_matrix(tex, tex_co - dy, dx);\nmat3 line1 = get_color_matrix(tex, tex_co, dx);\nmat3 line2 = get_color_matrix(tex, tex_co + dy, dx);\nmat3 column = mat3(blur(line0, dist.x, GLOW_WIDTH),\n blur(line1, dist.x, GLOW_WIDTH),\n blur(line2, dist.x, GLOW_WIDTH));\n\nreturn blur(column, dist.y, GLOW_HEIGHT);\n}\n\nvec3 filter_lanczos(sampler2D tex, vec2 co, vec2 tex_size, float sharp)\n{\ntex_size.x *= sharp;\n\nvec2 dx = vec2(1.0 / tex_size.x, 0.0);\nvec2 pix_co = co * tex_size - vec2(0.5, 0.0);\nvec2 tex_co = (floor(pix_co) + vec2(0.5, 0.0)) / tex_size;\nvec2 dist = fract(pix_co);\nvec4 coef = PI * vec4(dist.x + 1.0, dist.x, dist.x - 1.0, dist.x - 2.0);\n\ncoef = FIX(coef);\ncoef = 2.0 * sin(coef) * sin(coef / 2.0) / (coef * coef);\ncoef /= dot(coef, vec4(1.0));\n\nvec4 col1 = vec4(TEX2D(tex_co), 1.0);\nvec4 col2 = vec4(TEX2D(tex_co + dx), 1.0);\n\nreturn (mat4(col1, col1, col2, col2) * coef).rgb;\n}\n\nvec3 get_scanline_weight(float x, vec3 col)\n{\nvec3 beam = mix(vec3(SCANLINE_SIZE_MIN), vec3(SCANLINE_SIZE_MAX), col);\nvec3 x_mul = 2.0 / beam;\nvec3 x_offset = x_mul * 0.5;\n\nreturn smoothstep(0.0, 1.0, 1.0 - abs(x * x_mul - x_offset)) * x_offset;\n}\n\nvec3 get_mask_weight(float x)\n{\nfloat i = mod(floor(x * OutputSize.x * TextureSize.x / (InputSize.x * MASK_SIZE)), MASK_COLORS);\n\nif (i == 0.0) return mix(vec3(1.0, 0.0, 1.0), vec3(1.0, 0.0, 0.0), MASK_COLORS - 2.0);\nelse if (i == 1.0) return vec3(0.0, 1.0, 0.0);\nelse return vec3(0.0, 0.0, 1.0);\n}\n\nvoid main()\n{\nvec3 col_glow = filter_gaussian(Texture, Coord, TextureSize);\nvec3 col_soft = filter_lanczos(Texture, Coord, TextureSize, SHARPNESS_IMAGE);\nvec3 col_sharp = filter_lanczos(Texture, Coord, TextureSize, SHARPNESS_EDGES);\nvec3 col = sqrt(col_sharp * col_soft);\n\ncol *= get_scanline_weight(fract(Coord.y * TextureSize.y), col_soft);\ncol_glow = saturate(col_glow - col);\ncol += col_glow * col_glow * GLOW_HALATION;\ncol = mix(col, col * get_mask_weight(Coord.x) * MASK_COLORS, MASK_STRENGTH);\ncol += col_glow * GLOW_DIFFUSION;\ncol = pow(col * BRIGHTNESS, vec3(1.0 / GAMMA_OUTPUT));\n\nFragColor = vec4(col, 1.0);\n}\n\n#endif\n',"crt-geom.glsl":'\n/*\nCRT-interlaced\n\nCopyright (C) 2010-2012 cgwg, Themaister and DOLLS\n\nThis program is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License as published by the Free\nSoftware Foundation; either version 2 of the License, or (at your option)\nany later version.\n\n(cgwg gave their consent to have the original version of this shader\ndistributed under the GPL in this message:\n\nhttp://board.byuu.org/viewtopic.php?p=26075#p26075\n\n"Feel free to distribute my shaders under the GPL. After all, the\nbarrel distortion code was taken from the Curvature shader, which is\nunder the GPL."\n)\nThis shader variant is pre-configured with screen curvature\n*/\n/*\n#pragma parameter CRTgamma "CRTGeom Target Gamma" 2.4 0.1 5.0 0.1\n#pragma parameter monitorgamma "CRTGeom Monitor Gamma" 2.2 0.1 5.0 0.1\n#pragma parameter d "CRTGeom Distance" 1.6 0.1 3.0 0.1\n#pragma parameter CURVATURE "CRTGeom Curvature Toggle" 1.0 0.0 1.0 1.0\n#pragma parameter R "CRTGeom Curvature Radius" 2.0 0.1 10.0 0.1\n#pragma parameter cornersize "CRTGeom Corner Size" 0.03 0.001 1.0 0.005\n#pragma parameter cornersmooth "CRTGeom Corner Smoothness" 1000.0 80.0 2000.0 100.0\n#pragma parameter x_tilt "CRTGeom Horizontal Tilt" 0.0 -0.5 0.5 0.05\n#pragma parameter y_tilt "CRTGeom Vertical Tilt" 0.0 -0.5 0.5 0.05\n#pragma parameter overscan_x "CRTGeom Horiz. Overscan %" 100.0 -125.0 125.0 1.0\n#pragma parameter overscan_y "CRTGeom Vert. Overscan %" 100.0 -125.0 125.0 1.0\n#pragma parameter DOTMASK "CRTGeom Dot Mask Toggle" 0.3 0.0 0.3 0.3\n#pragma parameter SHARPER "CRTGeom Sharpness" 1.0 1.0 3.0 1.0\n#pragma parameter scanline_weight "CRTGeom Scanline Weight" 0.3 0.1 0.5 0.05\n*/\n\n#ifndef PARAMETER_UNIFORM\n#define CRTgamma 2.4\n#define monitorgamma 2.2\n#define d 1.6\n#define CURVATURE 1.0\n#define R 2.0\n#define cornersize 0.03\n#define cornersmooth 1000.0\n#define x_tilt 0.0\n#define y_tilt 0.0\n#define overscan_x 100.0\n#define overscan_y 100.0\n#define DOTMASK 0.3\n#define SHARPER 1.0\n#define scanline_weight 0.3\n#endif\n\n#if defined(VERTEX)\n\n#if __VERSION__ >= 130\n#define COMPAT_VARYING out\n#define COMPAT_ATTRIBUTE in\n#define COMPAT_TEXTURE texture\n#else\n#define COMPAT_VARYING varying \n#define COMPAT_ATTRIBUTE attribute \n#define COMPAT_TEXTURE texture2D\n#endif\n\n#ifdef GL_ES\n#define COMPAT_PRECISION mediump\n#else\n#define COMPAT_PRECISION\n#endif\n\nCOMPAT_ATTRIBUTE vec4 VertexCoord;\nCOMPAT_ATTRIBUTE vec4 COLOR;\nCOMPAT_ATTRIBUTE vec4 TexCoord;\nCOMPAT_VARYING vec4 COL0;\nCOMPAT_VARYING vec4 TEX0;\n\nvec4 _oPosition1; \nuniform mat4 MVPMatrix;\nuniform COMPAT_PRECISION int FrameDirection;\nuniform COMPAT_PRECISION int FrameCount;\nuniform COMPAT_PRECISION vec2 OutputSize;\nuniform COMPAT_PRECISION vec2 TextureSize;\nuniform COMPAT_PRECISION vec2 InputSize;\n\nCOMPAT_VARYING vec2 overscan;\nCOMPAT_VARYING vec2 aspect;\nCOMPAT_VARYING vec3 stretch;\nCOMPAT_VARYING vec2 sinangle;\nCOMPAT_VARYING vec2 cosangle;\nCOMPAT_VARYING vec2 one;\nCOMPAT_VARYING float mod_factor;\nCOMPAT_VARYING vec2 ilfac;\n\n#ifdef PARAMETER_UNIFORM\nuniform COMPAT_PRECISION float CRTgamma;\nuniform COMPAT_PRECISION float monitorgamma;\nuniform COMPAT_PRECISION float d;\nuniform COMPAT_PRECISION float CURVATURE;\nuniform COMPAT_PRECISION float R;\nuniform COMPAT_PRECISION float cornersize;\nuniform COMPAT_PRECISION float cornersmooth;\nuniform COMPAT_PRECISION float x_tilt;\nuniform COMPAT_PRECISION float y_tilt;\nuniform COMPAT_PRECISION float overscan_x;\nuniform COMPAT_PRECISION float overscan_y;\nuniform COMPAT_PRECISION float DOTMASK;\nuniform COMPAT_PRECISION float SHARPER;\nuniform COMPAT_PRECISION float scanline_weight;\n#endif\n\n#define FIX(c) max(abs(c), 1e-5);\n\nfloat intersect(vec2 xy)\n{\nfloat A = dot(xy,xy)+d*d;\nfloat B = 2.0*(R*(dot(xy,sinangle)-d*cosangle.x*cosangle.y)-d*d);\nfloat C = d*d + 2.0*R*d*cosangle.x*cosangle.y;\nreturn (-B-sqrt(B*B-4.0*A*C))/(2.0*A);\n}\n\nvec2 bkwtrans(vec2 xy)\n{\nfloat c = intersect(xy);\nvec2 point = vec2(c)*xy;\npoint -= vec2(-R)*sinangle;\npoint /= vec2(R);\nvec2 tang = sinangle/cosangle;\nvec2 poc = point/cosangle;\nfloat A = dot(tang,tang)+1.0;\nfloat B = -2.0*dot(poc,tang);\nfloat C = dot(poc,poc)-1.0;\nfloat a = (-B+sqrt(B*B-4.0*A*C))/(2.0*A);\nvec2 uv = (point-a*sinangle)/cosangle;\nfloat r = R*acos(a);\nreturn uv*r/sin(r/R);\n}\n\nvec2 fwtrans(vec2 uv)\n{\nfloat r = FIX(sqrt(dot(uv,uv)));\nuv *= sin(r/R)/r;\nfloat x = 1.0-cos(r/R);\nfloat D = d/R + x*cosangle.x*cosangle.y+dot(uv,sinangle);\nreturn d*(uv*cosangle-x*sinangle)/D;\n}\n\nvec3 maxscale()\n{\nvec2 c = bkwtrans(-R * sinangle / (1.0 + R/d*cosangle.x*cosangle.y));\nvec2 a = vec2(0.5,0.5)*aspect;\nvec2 lo = vec2(fwtrans(vec2(-a.x,c.y)).x, fwtrans(vec2(c.x,-a.y)).y)/aspect;\nvec2 hi = vec2(fwtrans(vec2(+a.x,c.y)).x, fwtrans(vec2(c.x,+a.y)).y)/aspect;\nreturn vec3((hi+lo)*aspect*0.5,max(hi.x-lo.x,hi.y-lo.y));\n}\n\nvoid main()\n{\n// START of parameters\n\n// gamma of simulated CRT\n//\tCRTgamma = 1.8;\n// gamma of display monitor (typically 2.2 is correct)\n//\tmonitorgamma = 2.2;\n// overscan (e.g. 1.02 for 2% overscan)\noverscan = vec2(1.00,1.00);\n// aspect ratio\naspect = vec2(1.0, 0.75);\n// lengths are measured in units of (approximately) the width\n// of the monitor simulated distance from viewer to monitor\n//\td = 2.0;\n// radius of curvature\n//\tR = 1.5;\n// tilt angle in radians\n// (behavior might be a bit wrong if both components are\n// nonzero)\nconst vec2 angle = vec2(0.0,0.0);\n// size of curved corners\n//\tcornersize = 0.03;\n// border smoothness parameter\n// decrease if borders are too aliased\n//\tcornersmooth = 1000.0;\n\n// END of parameters\n\nvec4 _oColor;\nvec2 _otexCoord;\ngl_Position = VertexCoord.x * MVPMatrix[0] + VertexCoord.y * MVPMatrix[1] + VertexCoord.z * MVPMatrix[2] + VertexCoord.w * MVPMatrix[3];\n_oPosition1 = gl_Position;\n_oColor = COLOR;\n_otexCoord = TexCoord.xy;\nCOL0 = COLOR;\nTEX0.xy = TexCoord.xy;\n\n// Precalculate a bunch of useful values we\'ll need in the fragment\n// shader.\nsinangle = sin(vec2(x_tilt, y_tilt)) + vec2(0.001);//sin(vec2(max(abs(x_tilt), 1e-3), max(abs(y_tilt), 1e-3)));\ncosangle = cos(vec2(x_tilt, y_tilt)) + vec2(0.001);//cos(vec2(max(abs(x_tilt), 1e-3), max(abs(y_tilt), 1e-3)));\nstretch = maxscale();\n\nilfac = vec2(1.0,clamp(floor(InputSize.y/200.0), 1.0, 2.0));\n\n// The size of one texel, in texture-coordinates.\nvec2 sharpTextureSize = vec2(SHARPER * TextureSize.x, TextureSize.y);\none = ilfac / sharpTextureSize;\n\n// Resulting X pixel-coordinate of the pixel we\'re drawing.\nmod_factor = TexCoord.x * TextureSize.x * OutputSize.x / InputSize.x;\n\n}\n\n#elif defined(FRAGMENT)\n\n#if __VERSION__ >= 130\n#define COMPAT_VARYING in\n#define COMPAT_TEXTURE texture\nout vec4 FragColor;\n#else\n#define COMPAT_VARYING varying\n#define FragColor gl_FragColor\n#define COMPAT_TEXTURE texture2D\n#endif\n\n#ifdef GL_ES\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n#define COMPAT_PRECISION mediump\n#else\n#define COMPAT_PRECISION\n#endif\n\nstruct output_dummy {\nvec4 _color;\n};\n\nuniform COMPAT_PRECISION int FrameDirection;\nuniform COMPAT_PRECISION int FrameCount;\nuniform COMPAT_PRECISION vec2 OutputSize;\nuniform COMPAT_PRECISION vec2 TextureSize;\nuniform COMPAT_PRECISION vec2 InputSize;\nuniform sampler2D Texture;\nCOMPAT_VARYING vec4 TEX0;\n\n// Comment the next line to disable interpolation in linear gamma (and\n// gain speed).\n#define LINEAR_PROCESSING\n\n// Enable screen curvature.\n// #define CURVATURE\n\n// Enable 3x oversampling of the beam profile\n#define OVERSAMPLE\n\n// Use the older, purely gaussian beam profile\n//#define USEGAUSSIAN\n\n// Macros.\n#define FIX(c) max(abs(c), 1e-5);\n#define PI 3.141592653589\n\n#ifdef LINEAR_PROCESSING\n# define TEX2D(c) pow(COMPAT_TEXTURE(Texture, (c)), vec4(CRTgamma))\n#else\n# define TEX2D(c) COMPAT_TEXTURE(Texture, (c))\n#endif\n\nCOMPAT_VARYING vec2 one;\nCOMPAT_VARYING float mod_factor;\nCOMPAT_VARYING vec2 ilfac;\nCOMPAT_VARYING vec2 overscan;\nCOMPAT_VARYING vec2 aspect;\nCOMPAT_VARYING vec3 stretch;\nCOMPAT_VARYING vec2 sinangle;\nCOMPAT_VARYING vec2 cosangle;\n\n#ifdef PARAMETER_UNIFORM\nuniform COMPAT_PRECISION float CRTgamma;\nuniform COMPAT_PRECISION float monitorgamma;\nuniform COMPAT_PRECISION float d;\nuniform COMPAT_PRECISION float CURVATURE;\nuniform COMPAT_PRECISION float R;\nuniform COMPAT_PRECISION float cornersize;\nuniform COMPAT_PRECISION float cornersmooth;\nuniform COMPAT_PRECISION float x_tilt;\nuniform COMPAT_PRECISION float y_tilt;\nuniform COMPAT_PRECISION float overscan_x;\nuniform COMPAT_PRECISION float overscan_y;\nuniform COMPAT_PRECISION float DOTMASK;\nuniform COMPAT_PRECISION float SHARPER;\nuniform COMPAT_PRECISION float scanline_weight;\n#endif\n\nfloat intersect(vec2 xy)\n{\nfloat A = dot(xy,xy)+d*d;\nfloat B = 2.0*(R*(dot(xy,sinangle)-d*cosangle.x*cosangle.y)-d*d);\nfloat C = d*d + 2.0*R*d*cosangle.x*cosangle.y;\nreturn (-B-sqrt(B*B-4.0*A*C))/(2.0*A);\n}\n\nvec2 bkwtrans(vec2 xy)\n{\nfloat c = intersect(xy);\nvec2 point = vec2(c)*xy;\npoint -= vec2(-R)*sinangle;\npoint /= vec2(R);\nvec2 tang = sinangle/cosangle;\nvec2 poc = point/cosangle;\nfloat A = dot(tang,tang)+1.0;\nfloat B = -2.0*dot(poc,tang);\nfloat C = dot(poc,poc)-1.0;\nfloat a = (-B+sqrt(B*B-4.0*A*C))/(2.0*A);\nvec2 uv = (point-a*sinangle)/cosangle;\nfloat r = FIX(R*acos(a));\nreturn uv*r/sin(r/R);\n}\n\nvec2 transform(vec2 coord)\n{\ncoord *= TextureSize / InputSize;\ncoord = (coord-vec2(0.5))*aspect*stretch.z+stretch.xy;\nreturn (bkwtrans(coord)/vec2(overscan_x / 100.0, overscan_y / 100.0)/aspect+vec2(0.5)) * InputSize / TextureSize;\n}\n\nfloat corner(vec2 coord)\n{\ncoord *= TextureSize / InputSize;\ncoord = (coord - vec2(0.5)) * vec2(overscan_x / 100.0, overscan_y / 100.0) + vec2(0.5);\ncoord = min(coord, vec2(1.0)-coord) * aspect;\nvec2 cdist = vec2(cornersize);\ncoord = (cdist - min(coord,cdist));\nfloat dist = sqrt(dot(coord,coord));\nreturn clamp((cdist.x-dist)*cornersmooth,0.0, 1.0);\n}\n\n// Calculate the influence of a scanline on the current pixel.\n//\n// \'distance\' is the distance in texture coordinates from the current\n// pixel to the scanline in question.\n// \'color\' is the colour of the scanline at the horizontal location of\n// the current pixel.\nvec4 scanlineWeights(float distance, vec4 color)\n{\n// "wid" controls the width of the scanline beam, for each RGB\n// channel The "weights" lines basically specify the formula\n// that gives you the profile of the beam, i.e. the intensity as\n// a function of distance from the vertical center of the\n// scanline. In this case, it is gaussian if width=2, and\n// becomes nongaussian for larger widths. Ideally this should\n// be normalized so that the integral across the beam is\n// independent of its width. That is, for a narrower beam\n// "weights" should have a higher peak at the center of the\n// scanline than for a wider beam.\n#ifdef USEGAUSSIAN\nvec4 wid = 0.3 + 0.1 * pow(color, vec4(3.0));\nvec4 weights = vec4(distance / wid);\nreturn 0.4 * exp(-weights * weights) / wid;\n#else\nvec4 wid = 2.0 + 2.0 * pow(color, vec4(4.0));\nvec4 weights = vec4(distance / scanline_weight);\nreturn 1.4 * exp(-pow(weights * inversesqrt(0.5 * wid), wid)) / (0.6 + 0.2 * wid);\n#endif\n}\n\nvoid main()\n{\n// Here\'s a helpful diagram to keep in mind while trying to\n// understand the code:\n//\n// | | | | |\n// -------------------------------\n// | | | | |\n// | 01 | 11 | 21 | 31 | <-- current scanline\n// | | @ | | |\n// -------------------------------\n// | | | | |\n// | 02 | 12 | 22 | 32 | <-- next scanline\n// | | | | |\n// -------------------------------\n// | | | | |\n//\n// Each character-cell represents a pixel on the output\n// surface, "@" represents the current pixel (always somewhere\n// in the bottom half of the current scan-line, or the top-half\n// of the next scanline). The grid of lines represents the\n// edges of the texels of the underlying texture.\n\n// Texture coordinates of the texel containing the active pixel.\nvec2 xy = (CURVATURE > 0.5) ? transform(TEX0.xy) : TEX0.xy;\n\nfloat cval = corner(xy);\n\n// Of all the pixels that are mapped onto the texel we are\n// currently rendering, which pixel are we currently rendering?\nvec2 ilvec = vec2(0.0,ilfac.y > 1.5 ? mod(float(FrameCount),2.0) : 0.0);\nvec2 ratio_scale = (xy * TextureSize - vec2(0.5) + ilvec)/ilfac;\n#ifdef OVERSAMPLE\nfloat filter_ = InputSize.y/OutputSize.y;//fwidth(ratio_scale.y);\n#endif\nvec2 uv_ratio = fract(ratio_scale);\n\n// Snap to the center of the underlying texel.\nxy = (floor(ratio_scale)*ilfac + vec2(0.5) - ilvec) / TextureSize;\n\n// Calculate Lanczos scaling coefficients describing the effect\n// of various neighbour texels in a scanline on the current\n// pixel.\nvec4 coeffs = PI * vec4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x);\n\n// Prevent division by zero.\ncoeffs = FIX(coeffs);\n\n// Lanczos2 kernel.\ncoeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs);\n\n// Normalize.\ncoeffs /= dot(coeffs, vec4(1.0));\n\n// Calculate the effective colour of the current and next\n// scanlines at the horizontal location of the current pixel,\n// using the Lanczos coefficients above.\nvec4 col = clamp(mat4(\n TEX2D(xy + vec2(-one.x, 0.0)),\n TEX2D(xy),\n TEX2D(xy + vec2(one.x, 0.0)),\n TEX2D(xy + vec2(2.0 * one.x, 0.0))) * coeffs,\n 0.0, 1.0);\nvec4 col2 = clamp(mat4(\n TEX2D(xy + vec2(-one.x, one.y)),\n TEX2D(xy + vec2(0.0, one.y)),\n TEX2D(xy + one),\n TEX2D(xy + vec2(2.0 * one.x, one.y))) * coeffs,\n 0.0, 1.0);\n\n#ifndef LINEAR_PROCESSING\ncol = pow(col , vec4(CRTgamma));\ncol2 = pow(col2, vec4(CRTgamma));\n#endif\n\n// Calculate the influence of the current and next scanlines on\n// the current pixel.\nvec4 weights = scanlineWeights(uv_ratio.y, col);\nvec4 weights2 = scanlineWeights(1.0 - uv_ratio.y, col2);\n#ifdef OVERSAMPLE\nuv_ratio.y =uv_ratio.y+1.0/3.0*filter_;\nweights = (weights+scanlineWeights(uv_ratio.y, col))/3.0;\nweights2=(weights2+scanlineWeights(abs(1.0-uv_ratio.y), col2))/3.0;\nuv_ratio.y =uv_ratio.y-2.0/3.0*filter_;\nweights=weights+scanlineWeights(abs(uv_ratio.y), col)/3.0;\nweights2=weights2+scanlineWeights(abs(1.0-uv_ratio.y), col2)/3.0;\n#endif\n\nvec3 mul_res = (col * weights + col2 * weights2).rgb * vec3(cval);\n\n// dot-mask emulation:\n// Output pixels are alternately tinted green and magenta.\nvec3 dotMaskWeights = mix(\nvec3(1.0, 1.0 - DOTMASK, 1.0),\nvec3(1.0 - DOTMASK, 1.0, 1.0 - DOTMASK),\nfloor(mod(mod_factor, 2.0))\n);\n\nmul_res *= dotMaskWeights;\n\n// Convert the image gamma for display on our output device.\nmul_res = pow(mul_res, vec3(1.0 / monitorgamma));\n\n// Color the texel.\noutput_dummy _OUT;\n_OUT._color = vec4(mul_res, 1.0);\nFragColor = _OUT._color;\nreturn;\n} \n#endif\n\n'},o=e(57),ve=e.n(o),K=e(11),J={addStyleHook:function(){V(this.elements.container,this.config.selectors.container.replace(".",""),!0),V(this.elements.container,this.config.classNames.uiSupported,!0),V(this.elements.container,this.config.classNames.hideControls,!0)},build:function(){this.listeners.media(),z.element(this.elements.controls)||(te.inject.call(this),this.listeners.controls()),this.volume=null,this.muted=null,te.updateVolume.call(this),V(this.elements.container,this.config.classNames.isTouch,this.touch),this.ready=!0},toggleControls:function(e){var n,t,o=this.elements.controls;o&&(n=0,t=s.call(this,".".concat(H({ejs__dialogs:!0})," > .").concat(H({ejs__dialog:!0}))),Array.from(t).forEach(function(e,t){!0!==e.hidden&&(n+=1)}),0>>0},r.prototype.readU24=function(){return this.littleEndian?this._lastRead=this._u8array[this.offset]+(this._u8array[this.offset+1]<<8)+(this._u8array[this.offset+2]<<16):this._lastRead=(this._u8array[this.offset]<<16)+(this._u8array[this.offset+1]<<8)+this._u8array[this.offset+2],this.offset+=3,this._lastRead>>>0},r.prototype.readU32=function(){return this.littleEndian?this._lastRead=this._u8array[this.offset]+(this._u8array[this.offset+1]<<8)+(this._u8array[this.offset+2]<<16)+(this._u8array[this.offset+3]<<24):this._lastRead=(this._u8array[this.offset]<<24)+(this._u8array[this.offset+1]<<16)+(this._u8array[this.offset+2]<<8)+this._u8array[this.offset+3],this.offset+=4,this._lastRead>>>0},r.prototype.readBytes=function(e){this._lastRead=new Array(e);for(var t=0;t>8):(this._u8array[this.offset]=e>>8,this._u8array[this.offset+1]=255&e),this.offset+=2},r.prototype.writeU24=function(e){this.littleEndian?(this._u8array[this.offset]=255&e,this._u8array[this.offset+1]=(65280&e)>>8,this._u8array[this.offset+2]=(16711680&e)>>16):(this._u8array[this.offset]=(16711680&e)>>16,this._u8array[this.offset+1]=(65280&e)>>8,this._u8array[this.offset+2]=255&e),this.offset+=3},r.prototype.writeU32=function(e){this.littleEndian?(this._u8array[this.offset]=255&e,this._u8array[this.offset+1]=(65280&e)>>8,this._u8array[this.offset+2]=(16711680&e)>>16,this._u8array[this.offset+3]=(4278190080&e)>>24):(this._u8array[this.offset]=(4278190080&e)>>24,this._u8array[this.offset+1]=(16711680&e)>>16,this._u8array[this.offset+2]=(65280&e)>>8,this._u8array[this.offset+3]=255&e),this.offset+=4},r.prototype.writeBytes=function(e){for(var t=0;tn&&(n=i.offset+i.length):i.offset+i.data.length>n&&(n=i.offset+i.data.length)}n===e.fileSize?t=e.slice(0,e.fileSize):(t=new Q(n),e.copyToFile(t,0))}for(e.seek(0),o=0;o>>1:n>>>1;e[t]=n}return e}();function $(e,t,n){for(var o=t?new Uint8Array(e._u8array.buffer,t):e._u8array,i=-1,a=n?o.length-4:o.length,r=0;r>>8^we[255&(i^o[r])];return(-1^i)>>>0}var _e=1,Se=2,Te=3;function xe(){this.sourceSize=0,this.targetSize=0,this.metaData="",this.actions=[],this.sourceChecksum=0,this.targetChecksum=0,this.patchChecksum=0}function Ce(e){e.readVLV=Ee,e.littleEndian=!0;var t=new xe,n=(e.seek(4),t.sourceSize=e.readVLV(),t.targetSize=e.readVLV(),e.readVLV());n&&(t.metaData=e.readString(n));for(var o=e.fileSize-12;e.offset>2)};a.type===_e?a.bytes=e.readBytes(a.length):a.type!==Se&&a.type!==Te||(i=e.readVLV(),a.relativeOffset=(1&i?-1:1)*(i>>1)),t.actions.push(a)}if(t.sourceChecksum=e.readU32(),t.targetChecksum=e.readU32(),t.patchChecksum=e.readU32(),t.patchChecksum!==$(e,0,!0))throw new Error("error_crc_patch");return t}function Ee(){for(var e=0,t=1;;){var n=this.readU8();if(e+=(127&n)*t,128&n)break;e+=t<<=7}return this._lastRead=e}function Ae(e){for(;;){var t=127&e;if(0==(e>>=7)){this.writeU8(128|t);break}this.writeU8(t),e--}}function Me(e){for(var t=0;;){if(0==(e>>=7)){t++;break}t++,e--}return t}xe.prototype.toString=function(){var e="Source size: "+this.sourceSize;return(e=(e+="\nTarget size: "+this.targetSize)+("\nMetadata: "+this.metaData))+("\n#Actions: "+this.actions.length)},xe.prototype.validateSource=function(e,t){return this.sourceChecksum===$(e,t)},xe.prototype.apply=function(e,t){if(t&&!this.validateSource(e))throw new Error("error_crc_input");for(var n=new Q(this.targetSize),o=0,i=0,a=0;a>=7)){this.writeU8(128|t);break}this.writeU8(t),--e}}function Oe(){for(var e=0,t=1;;){var n=this.readU8();if(-1==n)throw new Error("Can't read UPS VLV at 0x"+(this.offset-1).toString(16));if(e+=(127&n)*t,0!=(128&n))break;e+=t<<=7}return e}function Pe(e){for(var t=0;t++,0!=(e>>=7);)--e;return t}function Ie(e){var t=new u;for(e.readVLV=Oe,e.seek(ke.length),t.sizeInput=e.readVLV(),t.sizeOutput=e.readVLV();e.offset\n \n \n \n ",e=j("iframe",{src:v.adUrl,scrolling:"no",frameborder:"no",style:"width:300px !important;height:250px !important;display: block !important;"}),Z.loading.querySelector(".".concat(T.ad)).removeChild(Z.loading.querySelector(".".concat(T.ad," iframe"))),Z.loading.querySelector(".".concat(T.ad)).appendChild(e),X.webgl.DETECTED||(G(Z.loading.querySelector(".".concat(T["start-game"])),!0),Z.loading.querySelector(".".concat(T.p3)).innerHTML='Failed to initialize WebGL.'),Z.loading.querySelector(".".concat(T.ad," iframe")).style.setProperty("display","block","important"),Z.loading.querySelector(".".concat(T.ad," iframe")).style.setProperty("visibility","visible","important"),Z.loading.querySelector(".".concat(T.ad)).style.setProperty("display","block","important"),Z.loading.querySelector(".".concat(T.ad)).style.setProperty("visibility","visible","important")):(Z.loading.innerHTML='\n "),X.webgl.DETECTED||(G(Z.loading.querySelector(".".concat(T["start-game"])),!0),Z.loading.querySelector(".".concat(T.p3)).innerHTML='Failed to initialize WebGL.')),window.URL||window.webkitURL),x=function(e){var t;return 80===e[0]&&75===e[1]&&3===e[2]&&4===e[3]||80===e[0]&&75===e[1]&&5===e[2]&&6===e[3]||80===e[0]&&75===e[1]&&7===e[2]&&8===e[3]?t="zip":55===e[0]&&122===e[1]&&188===e[2]&&175===e[3]&&39===e[4]&&28===e[5]?t="7z":82===e[0]&&97===e[1]&&114===e[2]&&33===e[3]&&26===e[4]&&7===e[5]&&0==e[6]&&(t="rar"),t},C=function(e){var e=new Blob(['importScripts("'+e+'");'],{type:"application/javascript"}),n=window.URL.createObjectURL(e);return new Promise(function(e,t){e(new Worker(n))})},E=function(e,t){var n="",t=("rar"==t&&(n="\nvar dataToPass = [];\nModule = {\n monitorRunDependencies: function(left) {\n if (left == 0) {\n setTimeout(function() {\n unrar(dataToPass, null);\n }, 100);\n }\n },\n onRuntimeInitialized: function() {\n },\n locateFile: function(file) {\n return '".concat(e+".mem","';\n }\n};\nimportScripts(\"").concat(e,'");\nvar unrar = function(data, password) {\n var cb = function(fileName, fileSize, progress) {\n postMessage({"t":4,"current":progress,"total":fileSize, "name": fileName});\n };\n\n var rarContent = readRARContent(data.map(function(d) {\n return {\n name: d.name,\n content: new Uint8Array(d.content)\n }\n }), password, cb)\n var rec = function(entry) {\n if (entry.type === \'file\') {\n postMessage({"t":2,"file":entry.fullFileName,"size":entry.fileSize,"data":entry.fileContent});\n } else if (entry.type === \'dir\') {\n Object.keys(entry.ls).forEach(function(k) {\n rec(entry.ls[k]);\n })\n } else {\n throw "Unknown type";\n }\n }\n rec(rarContent);\n postMessage({"t":1});\n return rarContent;\n};\nonmessage = function(data) {\n dataToPass.push({name: \'test.rar\', content: data.data});\n};\n ')),new Blob([n],{type:"application/javascript"})),o=window.URL.createObjectURL(t);return new Promise(function(e,t){e(new Worker(o))})},A=null,d=null,c=null,u=null;try{A=new ve.a({dbVersion:1,storePrefix:"ejs-",storeName:"system",keyPath:null,autoIncrement:!1,onStoreReady:function(){o=!0},onError:function(){o=!0}}),d=new ve.a({dbVersion:1,storePrefix:"ejs-",storeName:"roms",keyPath:null,autoIncrement:!1,onStoreReady:function(){i=!0},onError:function(){i=!0}}),c=new ve.a({dbVersion:1,storePrefix:"ejs-",storeName:"bios",keyPath:null,autoIncrement:!1,onStoreReady:function(){a=!0},onError:function(){a=!0}}),u=new ve.a({dbVersion:1,storePrefix:"ejs-",storeName:"romsdata",keyPath:null,autoIncrement:!1,onStoreReady:function(){},onError:function(){}})}catch(e){a=i=o=!0,console.log(e)}U.call(v,v.elements.container,"start-game",function(e){v.started=!0,v.playing=!0,G(Z.loading.querySelector(".".concat(T["loading-info"])),!0),!ee||"undefined"!=ee.virtualGamepadContainer&&null!==ee.virtualGamepadContainer||J.toggleControls.call(v,!0);var t,n,o,i,a,r,s,c,l=H({"ejs__tooltip--visible":!0}),d=v.elements.buttons.gamepad.querySelector(".".concat(H({ejs__tooltip:!0}))),u=(V(d,l,!0),setTimeout(function(){V(d,l,!1)},5e3),"string"==typeof v.adUrl&&(G(Z.loading.querySelector(".".concat(T["close-ad"])),!1),!0!==v.config.noAutoAdClose&&setTimeout(function(){v.started&&Z.loading.querySelector(".".concat(T.ad))&&Z.loading.querySelector(".".concat(T.ad)).parentNode.removeChild(Z.loading.querySelector(".".concat(T.ad)))},1e4)),G(Z.loading.querySelector(".".concat(T["start-game"])),!0),Y(te.defaultCoreOptionsValues.call(p),te.storage.get("core-options")||{})),f=("n64"===v.system&&u&&Object.keys(u).forEach(function(e){"glupen64-aspect"===e&&"16:9"===u[e]&&(S.height=S.width/16*9,Z.aspectRatio=16/9)}),"arcade"!==p.system&&"fba0.2.97.29"!==p.system||u&&Object.keys(u).forEach(function(e){"fba-aspect"===e&&"PAR"===u[e]&&(S.height=S.width/16*9,Z.aspectRatio=16/9)}),"gba"===v.system&&(S.height=S.width/1.5,Z.aspectRatio=1.5),window.setTimeout(function(){},150),f=p,"undefined"!=typeof RI?(document.removeEventListener("mousemove",RI.eventHandler,!1),S.removeEventListener("mousedown",RI.canvasEventHandler,!1),S.removeEventListener("mouseup",RI.canvasEventHandler,!1),f.elements.container.addEventListener("mousemove",function(e){var t=0,n=0,o=e.offsetX-Z.Module.canvas.offsetLeft,i=e.offsetY-Z.Module.canvas.offsetTop;if("mousemove"===e.type){t=o<0?(o=0,-Z.Module.canvas.offsetWidth):o>Z.Module.canvas.offsetWidth?(o=Z.Module.canvas.offsetWidth,Z.Module.canvas.offsetWidth):o-RI.currentX,n=i<0?(i=0,-Z.Module.canvas.offsetHeight):i>Z.Module.canvas.offsetHeight?(i=Z.Module.canvas.offsetHeight,Z.Module.canvas.offsetHeight):i-RI.currentY,RI.currentX=o,RI.currentY=i;for(var a=0;a>2]=t,HEAP32[RI.contexts[a].state+36>>2]=n}},!1),f.elements.container.addEventListener("mousedown",RI.canvasEventHandler,!1),f.elements.container.addEventListener("mouseup",RI.canvasEventHandler,!1),f.elements.container.addEventListener("touchstart",t=function(e){if(e.targetTouches[0]){var t,n=0,o=0,i=e.target.getBoundingClientRect(),a=e.targetTouches[0].clientX-i.left,i=e.targetTouches[0].clientY-i.top,n=a<0?(a=0,-Z.Module.canvas.offsetWidth):a>Z.Module.canvas.offsetWidth?(a=Z.Module.canvas.offsetWidth,Z.Module.canvas.offsetWidth):a-RI.currentX,o=i<0?(i=0,-Z.Module.canvas.offsetHeight):i>Z.Module.canvas.offsetHeight?(i=Z.Module.canvas.offsetHeight,Z.Module.canvas.offsetHeight):i-RI.currentY;RI.currentX=a,RI.currentY=i;for(var r=0;r>2]=n,HEAP32[RI.contexts[r].state+36>>2]=o;switch(e.type){case"touchend":case"touchstart":if(0===e.button)t=40;else{if(2!==e.button)break;t=41}for(var s="touchend"===e.type?0:1,c=0;c>0]=s}}},!1),f.elements.container.addEventListener("touchend",t,!1)):(f=function(e){e=new MouseEvent(e.type,e);Z.Module.canvas.dispatchEvent(e)},q.call(p,".".concat(H({ejs__dialogs:!0}))).addEventListener("mousemove",f,!1),q.call(p,".".concat(H({ejs__dialogs:!0}))).addEventListener("mousedown",f,!1),q.call(p,".".concat(H({ejs__dialogs:!0}))).addEventListener("mouseup",f,!1)),"msx"===v.system&&"undefined"!=typeof RI&&(document.removeEventListener("keydown",RI.eventHandler,!1),document.removeEventListener("keyup",RI.eventHandler,!1),t=function(e){var t=e.keyCode,n=t>>3,o=1<<(7&t);switch(e.type){case"keyup":case"keydown":if(32<=n)throw"key code error! bad code: "+t;for(var i=0;i>0];"keyup"===e.type?a&=~o:a|=o,HEAP8[RI.contexts[i].state+n>>0]=a}}},document.addEventListener("keydown",t,!1),document.addEventListener("keyup",t,!1)),setTimeout(function(){var i=W.info();null===ee.setVolume&&"undefined"!=typeof RA?(RA.queueAudio=function(){var e=v.volume,t=RA.bufIndex,n=RA.bufIndex?RA.buffers[RA.bufIndex-1].endTime:RA.context.currentTime,o=(RA.buffers[t].endTime=n+RA.buffers[t].duration,RA.context.createBufferSource());o.buffer=RA.buffers[t],1===(e=v.muted?0:e)?o.connect(RA.context.destination):(t=RA.context.createGain(),o.connect(t),t.connect(RA.context.destination),W.isEdge||"chrome"===i.name&&parseInt(i.version,10)<=60||"firefox"===i.name&&parseInt(i.version,10)<=56||"opera"===i.name&&parseInt(i.version,10)<=44?t.gain.value=e:"firefox"===i.name?t.gain.setValueAtTime(e,RA.context.currentTime):t.gain.setValueAtTime(e,RA.context.currentTime,0)),o.start(n),RA.bufIndex+=1,RA.bufOffset=0},W.isIos&&window.addEventListener("touchstart",function(){var e;RA.context&&(RA.context.resume(),(e=RA.context.createBufferSource()).connect(RA.context.destination),e.start())},!1)):ee.setVolume()},500),setTimeout(function(){v.elements.container.focus()},30),void 0===window.addRunDependency&&(window.Module=void 0),Z.FS.readFile(v.startName));f.length<=33554432&&".cue"!=v.startName.substr(-4)&&(o="snes"===v.system||["snes2002","snes2005","snes2010"].includes(v.system)?(n=f.length%1024,new Q(n?f.slice?f.slice(n):f.subarray(n):f)):new Q(f),i=Ne.a.create(),a=new FileReader,r=0,s=o._u8array.length,c=function(){var e;r'+f.localization("Missing mame config")+"");var c=s.split("|");Z.coreFileName="".concat(f.system,"-").concat(c[0]),i="1"===c[1],z.element(f.elements.buttons.saveState)&&G(f.elements.buttons.saveState,!i),z.element(f.elements.buttons.loadState)&&G(f.elements.buttons.loadState,!i),G(te.contextMenu.querySelectorAll("ul li").item(2),!i),G(te.contextMenu.querySelectorAll("ul li").item(3),!i),d=2===f.coreVer?"":f.system.concat("-old-").concat(c[0],"-wasm.data"),c[0]?(X.wasm&&r?h=!0:(c.innerHTML=''+f.localization("Webassembly support is not detected in this browser")+"",d=""),d&&(A.db?A.get(d,function(e){e&&e.version===n?2===v.coreVer?D(e.data):((e=e.data.slice?e.data.slice(12):e.data.subarray(12)).set([55,122,188,175,39,28,0,3],0),D(e)):u(d,n)}):u(d,n))):c.innerHTML=''+f.localization("Unsupported Game")+""}else{var l,d=!1;if(X.wasm&&r?(l="wasm",d=!0,"n64"!==f.system||e||(l="legacy-wasm"),h=!0):a&&(d=!0,l="asmjs","n64"!==f.system||e||(l="legacy-asmjs")),!0!==(d="undefined"!=typeof EJS_CUSTOM_COREFILE?EJS_CUSTOM_COREFILE:d))return void(c.innerHTML=''+f.localization("Please upgrade your browser to the latest version")+"");d=2===f.coreVer?t+"-"+l+".data":t+"-old-"+l+".data","undefined"!=typeof EJS_CUSTOM_COREFILE&&(d=EJS_CUSTOM_COREFILE),A.db?A.get(d,function(e){!e||e.version!==n||"undefined"!=typeof EJS_DEBUG_XX&&!0===EJS_DEBUG_XX?u(d,n):2===v.coreVer?D(e.data):((e=e.data.slice?e.data.slice(12):e.data.subarray(12)).set([55,122,188,175,39,28,0,3],0),D(e))}):u(d,n)}2!==f.coreVer||"undefined"!=typeof EJS_DEBUG_XX&&!0===EJS_DEBUG_XX||z.element(f.elements.buttons.gamepad)&&G(f.elements.buttons.gamepad,!0),o||z.element(f.elements.buttons.netplay)&&G(f.elements.buttons.netplay,!0),z.element(f.elements.buttons.saveState)&&G(f.elements.buttons.saveState,!i),z.element(f.elements.buttons.loadState)&&G(f.elements.buttons.loadState,!i),G(te.contextMenu.querySelectorAll("ul li").item(2),!i),G(te.contextMenu.querySelectorAll("ul li").item(3),!i),v.setStatesSupported(i)}).catch(function(e){B(e,t,v)}),clearInterval(n),Z.romdb=d)},500),!1;var t,f,n}var M=function(){d.db&&d.getAll(function(e){Array.isArray(e)&&10Failed to start game'}try{r()}catch(e){}}if(2===e.data.t){var n=e.data.file.split("/"),o=(i=n.pop()).split(".").pop(),i=i.replace(/\#/g,"");Z._FS.createPath("/",n.join("/"),!0,!0);for(var a=m[l].length-1;0<=a;--a)m[l][a]===o.toLowerCase()&&dFailed to start game'}try{r()}catch(e){}}},s=function(){var t=p,n=Z.loading.querySelector(".".concat(T.p3)),e=p.config,o=(e.gameId,e.gameUrl),i=e.system,e=("vbanext"==i&&(i="gba"),o.split("/")),l=e[e.length-1];(l=-1')),!t)return!0;for(var n in t)je(n);return!0}),playerName:"",players:[],waitingList:{},roomMaster:null,inputsData:{},coreOptionData:{},currentFrame:0,wait:!(je=function(e){if(!document.getElementById(e))return!1}),progressHelper:{},icons:{lock:''},disableInput:!1,disableControl:function(e){if(e){for(var t=0;t<24;t+=1)v.simulateInputFn(0,t,0),v.simulateInputFn(1,t,0),v.simulateInputFn(2,t,0),v.simulateInputFn(3,t,0);v.disableInput=!0}else v.disableInput=!1},loadRoomsListTimer:null,loadRoomsList:function(){},stopLoadRooms:function(){v.loadRoomsListTimer&&clearTimeout(v.loadRoomsListTimer)},openRoom:function(){},isPaused:null,setVolume:null,setVariable:null,simulateInput:null,simulateInputFn:null,toggleShader:null,saveState:null,screenRecord:null,loadState:null,quickSaveState:null,quickLoadState:null,changeStateSlot:null,getScreenData:null,getStateInfo:null,setCheat:null,resetCheat:null,getGameCoreOptions:null,classNames:{"dialog-container":H({"dialog-container":!0}),tabs:H({tabs:!0}),"dialog-title":H({"dialog-title":!0}),"dialog-content":H({"dialog-content":!0}),"dialog-buttons":H({"dialog-buttons":!0}),overlay:H({overlay:!0}),"key-setting-popup":H({"key-setting-popup":!0}),"tabs-panel":H({"tabs-panel":!0}),"tabs-content":H({"tabs-content":!0}),"button-container":H({"button-container":!0}),set:H({set:!0}),active:H({active:!0}),"btn-cancel":H({"btn-cancel":!0}),"btn-reset":H({"btn-reset":!0}),"btn-clear":H({"btn-clear":!0}),"btn-create":H({"btn-create":!0}),"btn-submit":H({"btn-submit":!0}),"btn-join-room":H({"btn-join-room":!0}),"btn-quit":H({"btn-quit":!0}),"btn-create-room":H({"btn-create-room":!0}),"netplay-player-name":H({"netplay-player-name":!0}),"netplay-roomlist":H({"netplay-roomlist":!0}),"netplay-room-name-input":H({"netplay-room-name-input":!0}),"netplay-room-password-input":H({"netplay-room-password-input":!0}),"netplay-create-room-set":H({"netplay-create-room-set":!0}),"netplay-room":H({"netplay-room":!0}),modal:H({modal:!0}),modal__overlay:H({modal__overlay:!0}),modal__container:H({modal__container:!0}),modal__header:H({modal__header:!0}),modal__title:H({modal__title:!0}),modal__close:H({modal__close:!0}),modal__content:H({modal__content:!0}),modal__btn:H({modal__btn:!0}),"modal__btn-primary":H({"modal__btn-primary":!0}),"micromodal-slide":H({"micromodal-slide":!0}),modal__errmsg:H({modal__errmsg:!0}),modal__footer:H({modal__footer:!0}),"cheats-add":H({"cheats-add":!0}),"cheats-list":H({"cheats-list":!0}),"cheat-code-input":H({"cheat-code-input":!0}),"cheat-name-input":H({"cheat-name-input":!0}),"ejs-switch":H({"ejs-switch":!0}),"ejs-delete-cheat":H({"ejs-delete-cheat":!0})},initShaders:function(){for(var e,t=ge,n=Object.keys(t),o=0;o\n \n
'+s.localization("Control Settings")+'
\n
\n \n \n \n \n \n
\n
[Select]\n
'+s.localization("Press keyboard or gamepad")+"
\n
\n
\n \n ",'\n \n
\n
\n
Connected gamepad: n/a
\n
\n
\n
\n
\n
'+s.localization("Gamepad")+'
\n
'+s.localization("Keyboard")+'
\n
\n
\n
\n
\n
')),n='\n \n
\n \n
\n
\n
\n
\n
');a="nes"===s.system?{0:"B",2:"SELECT",3:"START",4:"UP",5:"DOWN",6:"LEFT",7:"RIGHT",8:"A",24:s.localization("QUICK SAVE STATE"),25:s.localization("QUICK LOAD STATE"),26:s.localization("CHANGE STATE SLOT")}:"snes"===s.system?{0:"B",1:"Y",2:"SELECT",3:"START",4:"UP",5:"DOWN",6:"LEFT",7:"RIGHT",8:"A",9:"X",10:"L",11:"R",24:s.localization("QUICK SAVE STATE"),25:s.localization("QUICK LOAD STATE"),26:s.localization("CHANGE STATE SLOT")}:"n64"===s.system?{0:"B",3:"START",4:"UP",5:"DOWN",6:"LEFT",7:"RIGHT",8:"A",10:"L",11:"R",12:"Z",19:"L STICK UP",18:"L STICK DOWN",17:"L STICK LEFT",16:"L STICK RIGHT",23:"R STICK UP",22:"R STICK DOWN",21:"R STICK LEFT",20:"R STICK RIGHT",24:s.localization("QUICK SAVE STATE"),25:s.localization("QUICK LOAD STATE"),26:s.localization("CHANGE STATE SLOT")}:"nds"===s.system?{0:"B",1:"Y",2:"SELECT",3:"START",4:"UP",5:"DOWN",6:"LEFT",7:"RIGHT",8:"A",9:"X",10:"L",11:"R",14:"Microphone",24:s.localization("QUICK SAVE STATE"),25:s.localization("QUICK LOAD STATE"),26:s.localization("CHANGE STATE SLOT")}:{0:"B",1:"Y",2:"SELECT",3:"START",4:"UP",5:"DOWN",6:"LEFT",7:"RIGHT",8:"A",9:"X",10:"L",11:"R",12:"L2",13:"R2",14:"L3",15:"R3",19:"L STICK UP",18:"L STICK DOWN",17:"L STICK LEFT",16:"L STICK RIGHT",23:"R STICK UP",22:"R STICK DOWN",21:"R STICK LEFT",20:"R STICK RIGHT",24:s.localization("QUICK SAVE STATE"),25:s.localization("QUICK LOAD STATE"),26:s.localization("CHANGE STATE SLOT")},["arcade","mame"].includes(s.system)&&(a[2]=s.localization("INSERT COIN")),!1===s.statesSupported&&(delete a[24],delete a[25],delete a[26]);for(var o=[2,3,4,5,6,7,8,0,9,1,10,11,12,13,14,15,19,18,17,16,23,22,21,20,24,25,26],t=0;t<=3;t+=1)!function(t){s.elements.dialogs.gamepad.querySelector(".".concat(v.classNames["tabs-content"])).innerHTML+=e.replace(/{index}/g,t),o.forEach(function(e){a[e]&&(s.elements.dialogs.gamepad.querySelector("#controls-".concat(t)).innerHTML+=n.replace(/{index}/g,t).replace(/{id}/g,e).replace(/{label}/g,a[e]))}),s.elements.dialogs.gamepad.querySelector('[data-id="16"][data-index="'.concat(t,'"][data-type="2"]'))&&(s.elements.dialogs.gamepad.querySelector('[data-id="16"][data-index="'.concat(t,'"][data-type="2"]')).style.backgroundColor="#ccc"),s.elements.dialogs.gamepad.querySelector('[data-id="17"][data-index="'.concat(t,'"][data-type="2"]'))&&(s.elements.dialogs.gamepad.querySelector('[data-id="17"][data-index="'.concat(t,'"][data-type="2"]')).style.backgroundColor="#ccc"),s.elements.dialogs.gamepad.querySelector('[data-id="18"][data-index="'.concat(t,'"][data-type="2"]'))&&(s.elements.dialogs.gamepad.querySelector('[data-id="18"][data-index="'.concat(t,'"][data-type="2"]')).style.backgroundColor="#ccc"),s.elements.dialogs.gamepad.querySelector('[data-id="19"][data-index="'.concat(t,'"][data-type="2"]'))&&(s.elements.dialogs.gamepad.querySelector('[data-id="19"][data-index="'.concat(t,'"][data-type="2"]')).style.backgroundColor="#ccc"),s.elements.dialogs.gamepad.querySelector('[data-id="20"][data-index="'.concat(t,'"][data-type="2"]'))&&(s.elements.dialogs.gamepad.querySelector('[data-id="20"][data-index="'.concat(t,'"][data-type="2"]')).style.backgroundColor="#ccc"),s.elements.dialogs.gamepad.querySelector('[data-id="21"][data-index="'.concat(t,'"][data-type="2"]'))&&(s.elements.dialogs.gamepad.querySelector('[data-id="21"][data-index="'.concat(t,'"][data-type="2"]')).style.backgroundColor="#ccc"),s.elements.dialogs.gamepad.querySelector('[data-id="22"][data-index="'.concat(t,'"][data-type="2"]'))&&(s.elements.dialogs.gamepad.querySelector('[data-id="22"][data-index="'.concat(t,'"][data-type="2"]')).style.backgroundColor="#ccc"),s.elements.dialogs.gamepad.querySelector('[data-id="23"][data-index="'.concat(t,'"][data-type="2"]'))&&(s.elements.dialogs.gamepad.querySelector('[data-id="23"][data-index="'.concat(t,'"][data-type="2"]')).style.backgroundColor="#ccc")}(t);Object.keys(v.controllers).forEach(function(o){v.controllers[o]&&Object.keys(v.controllers[o]).forEach(function(e){var t=s.elements.dialogs.gamepad.querySelector('[data-id="'.concat(e,'"][data-index="').concat(o,'"][data-type="1"]')),n=s.elements.dialogs.gamepad.querySelector('[data-id="'.concat(e,'"][data-index="').concat(o,'"][data-type="2"]'));if(!t||!n)return!1;e=v.controllers[o][e];e&&(e.type&&1!==parseInt(e.type,10)?n.value="":e.value&&(t.value=v.keyMap[e.value]||"",t.setAttribute("data-value",e.value)),e.value2&&(n.value=isNaN(e.value2)?e.value2:"button ".concat(parseInt(e.value2,10)+1),n.setAttribute("data-value",e.value2)))})}),U.call(this,s.elements.dialogs.gamepad.querySelector(".".concat(v.classNames["btn-submit"])),"click",function(e){var t=s.elements.dialogs.gamepad.querySelectorAll("input"),i={};return Array.from(t).forEach(function(e){var t,n=e.getAttribute("data-index"),o=e.getAttribute("data-value"),e=(2===parseInt(e.getAttribute("data-type"),10)&&(t=e.getAttribute("data-value")),e.getAttribute("data-id"));i[n]||(i[n]={}),i[n][e]||(i[n][e]={}),o&&(i[n][e].value=o),t&&(i[n][e].value2=t)}),te.storage.set({controllers:i}),v.controllers=i,G(s.elements.dialogs.gamepad,!0),s.elements.container.focus(),e.stopPropagation(),!1}),U.call(this,s.elements.dialogs.gamepad.querySelector(".".concat(v.classNames["btn-reset"])),"click",function(e){v.controllers=JSON.parse(JSON.stringify(v.defaultControllers)),localStorage.removeItem(te.storage.key);for(var t=s.elements.dialogs.gamepad.querySelectorAll("input"),n=0;nGamepad:'.concat(v.gamepad.gamepads[o].id,"
"+s.localization("Press keyboard or gamepad")+"
"+s.localization("Press escape (esc) to clear")):t+="
Press keyboard
"+s.localization("Press escape (esc) to clear"),r.querySelector(".".concat(v.classNames["key-setting-popup"])).innerHTML=t,e.stopPropagation()})})},setCacheDialog:function(){var t=this;t.elements.dialogs.cache.innerHTML='\n \n
\n
'+t.localization("Cache Manager")+'
\n \n
\n\n
\n
\n
\n "),U.call(this,t.elements.dialogs.cache.querySelector(".".concat(v.classNames["btn-cancel"])),"click",function(e){return G(t.elements.dialogs.cache,!0),t.elements.container.focus(),e.stopPropagation(),!1}),U.call(this,t.elements.dialogs.cache.querySelector(".".concat(v.classNames["dialog-title"]," a")),"click",function(e){return m.romdb&&(m.romdb.clear(),t.elements.dialogs.cache.querySelector(".".concat(v.classNames["dialog-content"])).innerHTML=''+t.localization("Empty")+"
"),e.stopPropagation(),!1})},showLoading:function(e){g.show("modal-6ed698f3d04061f5",{closeByEsckey:!1}),e&&console.log(""),G(this.elements.dialogs.loading,!1)},hideLoading:function(){g.close(),G(this.elements.dialogs.loading,!0)},setLoadingDialog:function(){this.elements.dialogs.loading&&(this.elements.dialogs.loading.innerHTML='\n \n
\n
\n '+this.localization("Loading")+"...\n
\n
\n
"))},setCheatDialog:function(){var a,r,o,s=this;s.elements.dialogs.cheat&&(s.elements.dialogs.cheat.innerHTML='\n \n\n \n\n \n
\n
\n \n
\n\n \n '+s.localization("Code")+'
\n
\n '+s.localization("Description")+'
\n
\n\n \n \n
\n
\n
\n "),a=s.elements.dialogs.cheat.querySelector("#modal-85cd7a1c543a484b"),U.call(this,s.elements.dialogs.cheat.querySelector(".".concat(v.classNames["cheats-add"])),"click",function(e){return g.show("modal-85cd7a1c543a484b",{closeTrigger:"data-modal-close"}),!1}),r=s.elements.dialogs.cheat.querySelector(".".concat(v.classNames["cheats-list"])),U.call(this,a.querySelector(".".concat(v.classNames["modal__btn-primary"])),"click",function(e){var t,n,o=a.querySelector(".".concat(v.classNames["cheat-name-input"])).value,i=a.querySelector(".".concat(v.classNames["cheat-code-input"])).value;return o&&i&&(t=r.querySelectorAll("input:checked"),a.querySelector(".".concat(v.classNames["cheat-name-input"])).value="",a.querySelector(".".concat(v.classNames["cheat-code-input"])).value="",g.close(),n=s.cheats.length,s.cheats.push([o,i]),r.innerHTML+='\n
\n
\n
×\n
'),t.forEach(function(e,t){r.querySelector("#ejs-cheat-switch-".concat(t)).setAttribute("checked","checked")})),"localStorage"in window&&localStorage.setItem("".concat(s.system,"-").concat(s.startName,"-cheats"),JSON.stringify(s.cheats)),e.stopPropagation(),!1}),o=function(){if("localStorage"in window){var e=localStorage.getItem("".concat(s.system,"-").concat(s.startName,"-cheats"));try{e=JSON.parse(e)}catch(e){}e&&(s.cheats=e)}r.innerHTML="",s.cheats&&Array.isArray(s.cheats)&&s.cheats.forEach(function(e,t){var n=e[0];e[1],r.innerHTML+='\n
\n
\n
×\n
')})},U.call(s,r,"click",function(e){var t,n;return e.target&&e.target.classList.contains(v.classNames["ejs-delete-cheat"])&&e.target.getAttribute("data-idx")&&(t=e.target.getAttribute("data-idx"),s.cheats.splice(t,1),"localStorage"in window&&localStorage.setItem("".concat(s.system,"-").concat(s.startName,"-cheats"),JSON.stringify(s.cheats)),n=[],r.querySelectorAll("input").forEach(function(e,t){n[t]=!!r.querySelector("#ejs-cheat-switch-".concat(t,":checked"))}),n.splice(t,1),o(),n.forEach(function(e,t){e&&r.querySelector("#ejs-cheat-switch-".concat(t)).setAttribute("checked","checked")})),e.stopPropagation(),!1}),U.call(s,s.elements.container,"start-game",function(e){o()}),U.call(this,s.elements.dialogs.cheat.querySelector(".".concat(v.classNames["btn-cancel"])),"click",function(e){return G(s.elements.dialogs.cheat,!0),e.stopPropagation(),s.elements.container.focus(),!1}),U.call(this,s.elements.dialogs.cheat.querySelector(".".concat(v.classNames["btn-submit"])),"click",function(e){return v.resetCheat(),r.querySelectorAll("input:checked").forEach(function(e,t){e=s.cheats[e.value];e&&v.setCheat(t,1,e[1])}),G(s.elements.dialogs.cheat,!0),s.elements.container.focus(),!1}),"arcade"!==s.system&&"mame"!==s.system&&"mame2003"!==s.system&&"mame2010"!==s.system||(z.element(s.elements.buttons.cheat)&&G(s.elements.buttons.cheat,!0),v.allowCheat=!1),v.setCheat||(G(s.elements.buttons.cheat,!0),v.allowCheat=!1))},setNetplayDialog:function(){var n,a,o,i,l,s,c,d,e,r,u,f,p=this,h=this;h.elements.dialogs.netplay&&(h.elements.dialogs.netplay.innerHTML='\n \n
\n
'+h.localization("Netplay")+'
\n \n
\n
\n
'+h.localization("Rooms")+'\n
\n \n \n '+h.localization("Room Name")+" | \n "+h.localization("Players")+' | \n | \n
\n \n \n \n | \n | \n | \n
\n \n
\n
\n\n
\n
'+h.localization("Room Name")+"\n
"+h.localization("Password")+':
\n
\n \n \n '+h.localization("Player")+" | \n "+h.localization("Name")+" | \n | \n
\n \n \n \n 1 | \n "+h.localization("Name")+" 1 | \n | \n
\n \n 2 | \n "+h.localization("Name")+" 2 | \n | \n
\n \n 3 | \n "+h.localization("Name")+" 3 | \n | \n
\n \n 4 | \n "+h.localization("Name")+' 4 | \n | \n
\n \n
\n
\n
\n
\n
\n\n \n \n
\n
\n \n
\n\n \n '+h.localization("Player Name")+'
\n
\n\n \n \n
\n
\n
\n \n \n \n \n \n \n \n \n '),U.call(this,h.elements.dialogs.netplay.querySelector(".".concat(v.classNames["btn-cancel"])),"click",function(e){return G(h.elements.dialogs.netplay,!0),v.disableControl(!1),v.stopLoadRooms(),e.stopPropagation(),h.elements.container.focus(),!1}),window.setInterval(function(){var o="";v.players.forEach(function(e,t){var n=null;e?(v.connection.peers[e]?n=v.connection.peers[e].extra:v.connection.userid===e&&(n=v.connection.extra),o+="- ".concat(t+1,". ").concat(n.name,"
")):o+="- ".concat(t+1,".
")}),o+="
",h.elements.widgets.netplay.innerHTML=o},500),n=h.elements.dialogs.netplay.querySelector("#modal-9de6c4e9ce2b9361"),a=h.elements.dialogs.netplay.querySelector("#modal-85cd7a1c543a484a"),o=h.elements.dialogs.netplay.querySelector("#modal-7d8fd50ed642340b"),i=h.elements.dialogs.netplay.querySelector("#modal-5aa765d61d8327de"),l={},v.connection=new Le.a,(e=p.socketUrl).endsWith("/")||(e+="/"),v.connection.socketURL="/",v.connection.socketURL=e,v.connection.socketMessageEvent="emulatorjs-message",v.connection.socketCustomEvent="emulatorjs-custom-message",e=W.info(),v.connection.extra={name:v.playerName,game_id:h.config.gameId,browser_name:e.name,room_name:" ",domain:document.domain},v.connection.socketMessageEvent="netplay",v.connection.enableFileSharing=!0,v.connection.enableLogs=!1,v.connection.session={data:!0},v.connection.sdpConstraints.mandatory={OfferToReceiveAudio:!1,OfferToReceiveVideo:!1},v.connection.onclose=function(e){},v.connection.iceServers=[{urls:"turn:turn.emulatorjs.com:3478",credential:"dSnmrtehverella",username:"ejs"},{urls:["stun:stun.l.google.com:19302","stun:stun1.l.google.com:19302","stun:stun2.l.google.com:19302","stun:stun.l.google.com:19302?transport=udp"]}],v.connection.maxParticipantsAllowed=4,s=v.netPlayInitFrame=0,c=!1,Module.postMainLoop=function(){var e,t;if(v.currentFrame=parseInt(v.currentFrameNum(),10),v.connected)if(s+=1,v.connection.isInitiator)if(1<=s){for(var n=[],o=v.currentFrame-1;ov.currentFrame){console.log("lost",v.currentFrame),i=!0;break}i?v.wait||(!c||c<(new Date).valueOf()-3e3)&&(v.inputsData={},c=(new Date).valueOf(),v.connection.send(JSON.stringify({act:"sync-mem",value:v.connection.userid}),v.roomMaster)):(v.wait=!0,v.systemPause(1),m.Module.pauseMainLoop())}v.currentFrame%100==0&&Object.keys(v.inputsData).forEach(function(e,t){e>0;"reset"===t[0]?(n=0,v.connection.isInitiator?(v.systemPause(0),v.disableControl(!1),h.playing=!0,m.Module.resumeMainLoop()):K.a.get(e.url,{responseType:"arraybuffer"}).then(function(e){v.inputsData={};e=new Uint8Array(e.data);v.loadState(e,n),v.wait=!1,v.systemPause(0),v.disableInput=!1,h.playing=!0,m.Module.resumeMainLoop()})):"game.state"===t[1]&&(v.connection.isInitiator?(v.openRoom(h),v.wait=!1,v.systemPause(0),m.Module.resumeMainLoop()):(v.netPlayInitFrame=n,K.a.get(e.url,{responseType:"arraybuffer"}).then(function(e){e=new Uint8Array(e.data);v.loadState(e,n),v.wait=!1,v.disableInput=!1,v.connection.send(JSON.stringify({act:"wait-end",value:v.connection.userid})),v.hideLoading.call(h),h.playing=!0,m.Module.resumeMainLoop()}))),v.connection.isInitiator||console.log("recv mem end",v.currentFrame,e.name)}),v.connection.onmessage=function(e){var t,r,n,e=e.data||e;try{t=JSON.parse(e)}catch(e){t=null}if(t){if("room-master"===t.act&&(v.roomMaster=t.value),t.act,"short-pause"!==t.act||d||(v.systemPause(1),m.Module.pauseMainLoop(),d=!0,v.wait=!0,setTimeout(function(){v.systemPause(0),m.Module.resumeMainLoop(),v.wait=!1,d=!1},48)),"sync-control"===t.act&&(e=t.value,h.playing||v.wait,r=v.connection.userid,v.players.indexOf(r),v.connection.isInitiator,e.forEach(function(e,t){var e=e.split("|"),n=e[0]>>0,o=e[1]>>0,i=e[2]>>0,e=e[3]>>0,a=v.currentFrame;v.inputsData[e]||(v.inputsData[e]=[]),-1!=n&&e===a&&v.simulateInputFn(n,o,i),v.connection.isInitiator?0<=n&&(v.inputsData[a]||(v.inputsData[a]=[]),-2!=o&&(v.inputsData[a].push({index:n,key:o,status:i,frame:a}),v.simulateInputFn(n,o,i)),d||e<=a-10&&(v.systemPause(1),m.Module.pauseMainLoop(),d=!0,v.wait=!0,setTimeout(function(){v.systemPause(0),m.Module.resumeMainLoop(),v.wait=!1,d=!1},48))):(""!==n&&v.inputsData[e].push({index:n,key:o,status:i,frame:e}),v.inputsData[v.currentFrame]&&m.Module.resumeMainLoop(),a+10<=e&&e>v.netPlayInitFrame+100&&v.connection.send(JSON.stringify({act:"short-pause",value:r}),v.roomMaster))})),t.act,t.act,"update-core-option"!==t.act||v.connection.isInitiator||(v.coreOptionData[t.frame]={key:t.key,value:t.value}),"restart-game"===t.act&&(v.inputsData={},v.connection.send(JSON.stringify({act:"sync-mem",value:v.connection.userid}),v.roomMaster)),"pause"===t.act&&m.Module.pauseMainLoop(),"resume"===t.act&&m.Module.resumeMainLoop(),"wait"===t.act&&(v.wait=!0,v.systemPause(1),t.value!==v.connection.userid&&(v.waitingList[t.value]=1),v.disableControl(!0)),"wait-end"===t.act&&(v.waitingList[t.value]&&delete v.waitingList[t.value],0===Object.keys(v.waitingList).length&&(v.wait=!1,v.systemPause(0),v.disableInput=!1)),"sync-mem"===t.act){v.wait=!0,v.systemPause(1);e=t.value;v.disableControl(!0),v.connection.send(JSON.stringify({act:"wait",value:e}));for(var o=v.getStateInfo().split("|"),i=o[0]>>0,a=new Uint8Array(i),s=o[1]>>0,c=0;cJoin'):"",i=t.country||"?";n.innerHTML="[".concat(i,"] ").concat(o," ").concat(t.room_name," | ").concat(t.current,"/").concat(t.max," | ").concat(e," | "),U.call(p,n.querySelector(".".concat(v.classNames["btn-join-room"])),"click",f),c.appendChild(n)}),c.querySelectorAll("tr").forEach(function(e){r.includes(e.id)||c.removeChild(e)})),v.loadRoomsListTimer=setTimeout(v.loadRoomsList,2e3)}).catch(function(e){console.log("Network Error",e),v.loadRoomsListTimer=setTimeout(v.loadRoomsList,2e3)})},v.openRoom=function(e){v.stopLoadRooms(),G(e.elements.dialogs.netplay.querySelector(".".concat(v.classNames["netplay-roomlist"])),!0),G(e.elements.dialogs.netplay.querySelector(".".concat(v.classNames["netplay-room"])),!1),G(e.elements.dialogs.netplay.querySelector(".".concat(v.classNames["btn-create-room"])),!0),G(e.elements.dialogs.netplay.querySelector(".".concat(v.classNames["btn-quit"])),!1),v.resetCheat(),G(e.elements.buttons.cheat,!0);var e=e.elements.dialogs.netplay.querySelector(".".concat(v.classNames["netplay-room"])),t=e.querySelector("[data-room-password]"),o=(null===v.connection.password?G(t,!0):(G(t,!1),t.querySelector("span").innerText=v.connection.password),e.querySelector("tbody"));o.innerHTML="",e.querySelector("strong").innerText=l.room_name,v.players.forEach(function(e,t){var n=null;e&&(v.connection.peers[e]?n=v.connection.peers[e].extra:v.connection.userid===e&&(n=v.connection.extra),n&&n.name)&&((e=document.createElement("tr")).innerHTML="".concat(t+1," | ").concat(n.name," | | "),o.appendChild(e))})},U.call(this,i.querySelector(".".concat(v.classNames["modal__btn-primary"])),"click",function(e){var t=i.querySelector(".".concat(v.classNames["netplay-room-password-input"])).value,t=(v.showLoading.call(h),v.connection.password=t,i.getAttribute("data-id"));v.connection.join(t,function(e,t,n){u(e,0,n),e&&i.classList.remove(H({"is-open":!0}))}),e.stopPropagation()}),U.call(this,n.querySelector(".".concat(v.classNames["modal__btn-primary"])),"click",function(e){var t=(t=n.querySelector(".".concat(v.classNames["netplay-player-name"])).value).replace(/<|>/g,"");n.querySelector(".".concat(v.classNames.modal__errmsg)).innerHTML="",t.trim()&&(v.playerName=t.trim(),v.connection.extra.name=t.trim(),g.close()),e.stopPropagation()}),U.call(this,a.querySelector(".".concat(v.classNames["modal__btn-primary"])),"click",function(e){var t=(t=a.querySelector(".".concat(v.classNames["netplay-room-name-input"])).value).replace(/<|>/g,""),n=a.querySelector("select[data-max-players] option:checked").value;4<(n=n<2?2:n)&&(n=4);for(var o=0;o')+(''),!0===n.LandR&&(i="n64"===t.system?(i=(i+='
L
')+'
Z
')+'
R
':(i+='
L
')+'
R
'),i=(i=(i+="
")+(''))+(''),i="n64"===t.system?(i+='
'+t.localization("Menu")+"
")+'
'+t.localization("Start")+"
":(i=(i+='
'+t.localization("Start")+"
")+'
'+t.localization("Menu")+"
")+'
'+t.localization("Select")+"
",i=(i+="
")+(''),"n64"===t.system&&(i=(i=(i=(i+='
')+'
')+'
')+'
');for(var a=0;a
'+n.order[a]+" "}v.virtualGamepadContainer.innerHTML=i+="",G(v.virtualGamepadContainer,!e);o=me.a.create({zone:q.call(this,".".concat(H({"ejs-virtual-gamepad":!0})," .").concat(H({left:!0}))),mode:"static",position:{left:"50%",top:"50%"},color:"red"});function s(){var e;return"n64"!==t.system||"d-pad"===(e=te&&"function"==typeof te.getCoreOptionsValues?te.getCoreOptionsValues()["joystick-input"]:e)?{downVal:1,4:4,5:5,6:6,7:7}:{downVal:32767,4:19,5:18,6:17,7:16}}o.on("end",function(e,t){v.syncInput(0,s()[4],0),v.syncInput(0,s()[5],0),v.syncInput(0,s()[6],0),v.syncInput(0,s()[7],0)}),o.on("move",function(e,t){t=t.angle.degree;30<=t&&t<150?v.syncInput(0,s()[4],s().downVal):window.setTimeout(function(){v.syncInput(0,s()[4],0)},30),210<=t&&t<330?v.syncInput(0,s()[5],s().downVal):window.setTimeout(function(){v.syncInput(0,s()[5],0)},30),120<=t&&t<240?v.syncInput(0,s()[6],s().downVal):window.setTimeout(function(){v.syncInput(0,s()[6],0)},30),300<=t||0<=t&&t<60?v.syncInput(0,s()[7],s().downVal):window.setTimeout(function(){v.syncInput(0,s()[7],0)},30)});var c,l=H({"virtual-gamepad":!0}),d=H({touch:!0});W.isIos||U.call(this,q.call(this,".".concat(l)),"touchmove",function(e){e.stopPropagation()}),[{id:{b_a:!0},number:8},{id:{b_b:!0},number:0},{id:{b_x:!0},number:9},{id:{b_y:!0},number:1},{id:{b_l:!0},number:10},{id:{b_z:!0},number:12},{id:{b_r:!0},number:11},{id:{b_start:!0},number:3},{id:{b_select:!0},number:2},{id:{b_cu:!0},number:23},{id:{b_cd:!0},number:22},{id:{b_cl:!0},number:21},{id:{b_cr:!0},number:20}].forEach(t=>{U.call(this,q.call(this,".".concat(l," .").concat(H(t.id))),"touchstart touchend mousedown mouseup mouseout",function(e){["touchend","mouseup","mouseout"].includes(e.type)?(V(e.target,d,!1),window.setTimeout(function(){v.syncInput(0,t.number,0)},30)):(V(e.target,d,!0),v.syncInput(0,t.number,1)),e.stopPropagation()})}),U.call(this,q.call(this,".".concat(l," .").concat(H({b_c:!0}))),"touchstart touchend mousedown mouseup mouseout",function(e){["touchend","mouseup","mouseout"].includes(e.type)?V(e.target,d,!1):(V(e.target,d,!0),clearTimeout(c),J.toggleControls.call(t,!0),c=setTimeout(function(){J.toggleControls.call(t,!1)},5e3))})}else G(v.virtualGamepadContainer,!e)},setup:function(){var e,t,n,o=this;this.game?(v.playerName=o.config.playerName,V(this.elements.container,this.config.classNames.type,!0),this.elements.container.setAttribute("tabindex","0"),this.color&&(e=function(e){var t=e.toLowerCase();if(t&&/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(t)){if(4===t.length){for(var n="#",o=1;o<4;o+=1)n+=t.slice(o,o+1).concat(t.slice(o,o+1));t=n}for(var i=[],a=1;a<7;a+=2)i.push(parseInt("0x".concat(t.slice(a,a+2)),16));return i}return null}(this.color))&&this.elements.container.setAttribute("style","--ejs-primary-color: ".concat(e[0],", ").concat(e[1],", ").concat(e[2])),this.elements.wrapper=j("div",{class:this.config.classNames.video}),P(this.game,this.elements.wrapper),"video"!==o.game.tagName.toLocaleLowerCase()&&(t=this.config.volume,Object.defineProperty(o.game,"volume",{get:function(){return t},set:function(e){t=e,F.call(o,o.game,"volumechange")}}),n=o.storage.get("muted"),Object.defineProperty(o.game,"muted",{get:function(){return n},set:function(e){e=!!z.boolean(e)&&e;n=e,F.call(o,o.game,"volumechange")}})),window.addEventListener("beforeunload",function(e){if(o.started){var t=o.startName.split("/").pop().split("."),t=t.slice(0,t.length-1).join(".");m.FS.syncfs(function(e){});try{var n="srm";"nds"===o.system&&(n="dsv"),m.FS.unlink("/data/saves/".concat(t,".").concat(n))}catch(e){console.log("fail to save")}v.saveSavFiles(),m.FS.syncfs(function(e){})}},!0)):console.warn("No game element found!")},listeners:function(){var r=this;r.elements.buttons.restart&&U.call(r,r.elements.buttons.restart,"click",function(e){if(v.restartGame(),v.inputsData={},v.connected&&v.connection.isInitiator){for(var t=v.getStateInfo().split("|"),n=t[0]>>0,o=(t[2],new Uint8Array(n)),i=t[1]>>0,a=0;a>0==0&&(c[t]!==n&&(o?(v.inputsData[a]||(v.inputsData[a]=[]),v.inputsData[a].push({index:i,key:t,status:n,frame:a}),v.simulateInputFn(i,t,n)):v.connection.send(JSON.stringify({act:"sync-control",value:["".concat(i,"|").concat(t,"|").concat(n,"|").concat(a)]}),v.roomMaster)),c[t]=n)):v.disableInput||v.simulateInputFn(e,t,n)},v.syncInput=v.simulateInput,window.simulateInput=v.simulateInput,m.Module.cwrap("shader_enable","null",["number"])),l=(v.toggleShader=function(e){return n(e)},v.getStateInfo=m.Module.cwrap("get_state_info","string",[]),v.saveState=function(){var e=v.getStateInfo().split("|"),t=e[0]>>0;if(0>0,i=0;i>0,o=(e[2],new Uint8Array(n)),i=e[1]>>0,a=0;a".concat(this.icons[e],"");for(var o=t.childNodes[0].childNodes,i=0;i",""]),a=[];function n(e,t,n){"function"==typeof n?a.push(n):a.push(function(){});n=i.length-1;t?i.splice(n,0,''+e+""):i.splice(n,0,''+e+"")}n(o.localization("Take Screenshot"),!1,function(e){var t=v.getScreenData(),n=(n="string"==typeof o.gameName?o.gameName:n)?"".concat(n,"-screenshot.png"):"game.png";return he()(new Blob([t]),n),!1}),n(o.localization("Cache Manage"),!0,function(e){var n;return m.romdb&&(G(o.elements.dialogs.cache,!1),(n=o.elements.dialogs.cache.querySelector(".".concat(v.classNames["dialog-content"]))).innerHTML=""+o.localization("Loading")+"
",m.romdb.getAll(function(e){var t,l;e?(t=j("table",{style:"width:100%;padding-left:10px;text-align:left"}),l=j("tbody"),0Remove',a.appendChild(r),a.appendChild(s),a.appendChild(c),l.appendChild(a),c.querySelector("a").onclick=function(e){m.romdb.removeBatch(o);try{l.removeChild(a)}catch(e){}return e.stopPropagation(),!1}}}),t.appendChild(l),n.appendChild(t)):n.innerHTML=''+o.localization("Empty")+"
"):n.innerHTML=''+o.localization("Empty")+"
"},function(){})),!1}),n(o.localization("Quick Save")+" (F2)",!1,function(e){v.quickSaveState(),te.contextMenu.style.display="none"}),n(o.localization("Quick Load")+" (F4)",!1,function(e){v.quickLoadState(),te.contextMenu.style.display="none"}),h.contextMenu.innerHTML=i.join("");for(var r=h.contextMenu.getElementsByTagName("li"),s=0;s',"exit-fullscreen":'',gamepad:'',"load-state":'',muted:'',netplay:'',pause:'',play:'',restart:'',"save-state":'',"screen-record":'',settings:'',volume:'\n \n ',cheat:''},this.id=Math.floor(1e4*Math.random()),null),t=(this.elements.controls=null,{id:this.id}),o=!0;z.function(this.config.controls)&&(this.config.controls=this.config.controls.call(this.props)),this.config.controls||(this.config.controls=[]),z.element(this.config.controls)||z.string(this.config.controls)?e=this.config.controls:(e=h.create.call(this,{id:this.id,seektime:this.config.seekTime,speed:this.speed,quality:this.quality}),o=!1);function i(e){var n=e;return Object.entries(t).forEach(function(e){t=2;var e=function(e){if(Array.isArray(e))return e}(e=e)||function(e,t){var n=[],o=!0,i=!1,a=void 0;try{for(var r,s=e[Symbol.iterator]();!(o=(r=s.next()).done)&&(n.push(r.value),!t||n.length!==t);o=!0);}catch(e){i=!0,a=e}finally{try{o||null==s.return||s.return()}finally{if(i)throw a}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}(),t=e[0],e=e[1];n=le(n,"{".concat(t,"}"),e)}),n}var a,r;o&&(z.string(this.config.controls)?e=i(e):z.element(e)&&(e.innerHTML=i(e.innerHTML))),z.string(this.config.selectors.controls.container)&&(a=document.querySelector(this.config.selectors.controls.container)),(a=z.element(a)?a:this.elements.container)[z.element(e)?"insertAdjacentElement":"insertAdjacentHTML"]("afterbegin",e),z.element(this.elements.controls)||h.findElements.call(this),z.empty(this.elements.buttons)||(r=function(e){var t=n.config.classNames.controlPressed;Object.defineProperty(e,"pressed",{enumerable:!0,get:function(){return D(e,t)},set:function(){V(e,t,0Math.abs(n)?o:n),n=(a.increaseVolume(o/50),a.game.volume);(1===o&&n<1||-1===o&&0 {
if (response.ok) {
response.text().then(body => {
@@ -13,6 +14,24 @@
})
}
var scriptTag = document.getElementsByTagName('script')[0];
+ function loadStyle(file) {
+ return new Promise(function(resolve, reject) {
+ var css = document.createElement('link');
+ css.rel = 'stylesheet';
+ css.href = function() {
+ if ('undefined' != typeof EJS_paths && typeof EJS_paths[file] == 'string') {
+ return EJS_paths[file];
+ } else if ('undefined' != typeof EJS_pathtodata) {
+ if (!EJS_pathtodata.endsWith('/')) EJS_pathtodata+='/';
+ return EJS_pathtodata+file+'?v='+VERSION;
+ } else {
+ return file+'?v='+VERSION;
+ }
+ }();
+ css.onload = resolve;
+ document.head.appendChild(css);
+ })
+ }
function loadScript(file) {
return new Promise(function (resolve, reject) {
var script = document.createElement('script');
@@ -20,22 +39,24 @@
if ('undefined' != typeof EJS_paths && typeof EJS_paths[file] == 'string') {
return EJS_paths[file];
} else if ('undefined' != typeof EJS_pathtodata) {
+ if (!EJS_pathtodata.endsWith('/')) EJS_pathtodata+='/';
return EJS_pathtodata+file+'?v='+VERSION;
} else {
return file+'?v='+VERSION;
}
}();
scriptTag.parentNode.insertBefore(script, scriptTag);
- script.onload = function() {
- resolve();
- }
+ script.onload = resolve;
})
}
+ window.onerror = function(e) {alert(e)}
if ('undefined' != typeof EJS_DEBUG_XX && true === EJS_DEBUG_XX) {
+ await loadStyle('emu-css.css');
await loadScript('emu-main.js');
await loadScript('emulator.js');
} else {
- await loadScript('emu-min.js');
+ await loadStyle('emu-css.min.css');
+ await loadScript('emulator.min.js');
}
var config = {};
config.gameUrl = EJS_gameUrl;
@@ -51,6 +72,7 @@
'undefined' != typeof EJS_core && (config.system = EJS_core);
'undefined' != typeof EJS_loadStateURL && (config.loadStateOnStart = EJS_loadStateURL);
'undefined' != typeof EJS_language && (config.lang = EJS_language);
+ 'undefined' != typeof EJS_noAutoCloseAd && (config.noAutoAdClose = EJS_noAutoCloseAd);
'undefined' != typeof EJS_oldEJSNetplayServer && (config.oldNetplayServer = EJS_oldEJSNetplayServer);
'undefined' != typeof EJS_BETA && (config.useBeta = EJS_BETA);
config.onsavestate = null;
diff --git a/data/localization/af-FR.json b/data/localization/af-FR.json
new file mode 100644
index 0000000..7ad6b35
--- /dev/null
+++ b/data/localization/af-FR.json
@@ -0,0 +1,194 @@
+{
+ "i18n": {
+ "restart": "Redémarrer",
+ "play": "Jouer",
+ "pause": "Pause",
+ "played": "Joué",
+ "volume": "Volume",
+ "mute": "Muet (F9)",
+ "unmute": "Rétablir le son (F9)",
+ "enterFullscreen": "Entrer en plein écran",
+ "exitFullscreen": "Quitter le plein écran",
+ "settings": "Paramètres",
+ "saveState": "Enregistrer l'état (Maj + F2)",
+ "loadState": "État de charge (Maj + F4)",
+ "screenRecord": "Démarrer l'enregistrement d'écran",
+ "netplay": "Netplay",
+ "gamepad": "Paramètres de contrôle",
+ "cheat": "Tricheurs",
+ "menuBack": "Revenir au menu précédent",
+ "normal": "Normale",
+ "all": "Tous",
+ "reset": "Réinitialiser",
+ "disabled": "Désactivé",
+ "enabled": "Activé",
+ "playNow": "Jouer maintenant"
+ },
+ "normalOptions": {
+ "shader": {
+ "label": " Ombrage",
+ "options": {
+ "disabled": "Désactivé",
+ "2xScaleHQ.glslp": "2xScaleHQ",
+ "4xScaleHQ.glslp": "4xScaleHQ",
+ "crt-easymode.glslp": "CRT mode facile",
+ "crt-aperture.glslp": "Ouverture CRT",
+ "crt-geom.glslp": "CRT geom"
+ },
+ "default": "disabled"
+ },
+ "virtual-gamepad": {
+ "label": " Manette de jeu virtuelle",
+ "options": {
+ "disabled": "Désactivé",
+ "enabled": "Activé"
+ },
+ "default": "enabled"
+ }
+ },
+ "Control Settings": "Paramètres de contrôle",
+ "Player 1": "Joueur 1",
+ "Player 2": "Joueur 2",
+ "Player 3": "Joueur 3",
+ "Player 4": "Joueur 4",
+ "Update": "Mettre à jour",
+ "Reset": "Réinitialiser",
+ "Clear": "Effacer",
+ "Cancel": "Annuler",
+ "Close": "Fermer",
+ "Empty": "Vide",
+ "Loading": "Chargement",
+ "Submit": "Soumettre",
+ "Description": "Description",
+ "Code": "Code",
+ "Add Cheat Code": "Ajouter un code de triche",
+ "OK": "D'accord",
+ "Add Cheat": "Ajouter une triche",
+ "Cache Manager": "Gestionnaire de cache",
+ "Press keyboard or gamepad": "Appuyez sur le clavier ou la manette de jeu",
+ "Gamepad": "Manette de jeu",
+ "Keyboard": "Clavier",
+ "Set": "Définir",
+ "QUICK SAVE STATE": "ÉTAT DE SAUVEGARDE RAPIDE",
+ "QUICK LOAD STATE": "ÉTAT DE CHARGEMENT RAPIDE",
+ "CHANGE STATE SLOT": "CHANGER L'EMPLACEMENT D'ETAT",
+ "INSERT COIN": "INSÉRER UNE PIÈCE",
+ "Press escape (esc) to clear": "Appuyez sur Échap (esc) pour effacer",
+ "Netplay": "Netplay",
+ "Rooms": "Chambres",
+ "Players": "Joueurs",
+ "Player": "Joueur",
+ "Room Name": "Nom de la pièce",
+ "Password": "Mot de passe",
+ "Name": "Nom",
+ "Quit Room": "Quitter le salon",
+ "Create a Room": "Créer une pièce",
+ "Set Player Name": "Définir le nom du joueur",
+ "Player Name": "Nom du joueur",
+ "Password (optional)": "Mot de passe (facultatif)",
+ "Select": "Sélectionner",
+ "Start": "Démarrer",
+ "Menu": "Menu",
+ "Decompress Game Core": "Décompresser le noyau du jeu",
+ "Decompress Game Data": "Décompresser les données du jeu",
+ "Decompress Game Patch": "Décompresser le patch du jeu",
+ "Download Game Data": "Télécharger les données du jeu",
+ "Download Game Core": "Télécharger le noyau du jeu",
+ "Network Error": "Erreur réseau",
+ "Default": "Par défaut",
+ "default": "par défaut",
+ "Save State Location": "Enregistrer l'emplacement de l'état",
+ "Save State Slot": "Enregistrer l'emplacement de l'état",
+ "Color Palette": " Palette de couleurs",
+ "No Sprite Limit": "Pas de limite de sprites",
+ "Enabled": "Activé",
+ "Disabled": "Désactivé",
+ "enabled": "activé",
+ "disabled": "désactivé",
+ "Low": "Bas",
+ "High": "Élevé",
+ "Very High": "Très élevé",
+ "4 Players Support": " Prise en charge de 4 joueurs",
+ "Turbo Enable": "Activation turbo",
+ "None": "Aucun",
+ "Both": "Les deux",
+ "Region": "Région",
+ "SuperFX Overclock": "SuperFX Overclock",
+ "Sound Quality": "Qualité sonore",
+ "GB Colorization": "GB Colorisation",
+ "auto": "auto",
+ "internal": "interne",
+ "Internal Palette": "Palette interne",
+ "GBC - Blue": "GBC Bleu",
+ "GBC - Brown": "GBC Marron",
+ "GBC - Dark Blue": "GBC Bleu Foncé",
+ "GBC - Dark Brown": "GBC Marron Foncé",
+ "GBC - Dark Green": "GBC vert foncé",
+ "GBC - Grayscale": " Niveaux de gris GBC",
+ "GBC - Green": "GBC Vert",
+ "GBC - Inverted": "GBC Inversé",
+ "GBC - Orange": "GBC Orange",
+ "GBC - Red": "GBC Rouge",
+ "GBC - Pastel Mix": "mélange de pastels GBC",
+ "GBC - Yellow": "GBC Jaune",
+ "Frameskip": "Frameskip",
+ "Solar sensor level": "Niveau du capteur solaire",
+ "Enable Turbo Buttons": "Activer les boutons turbo",
+ "Turbo Delay in frames": "Turbo Delay dans les images",
+ "Auto": "Auto",
+ "Aspect Ratio (Need to refresh page)": "Aspect Ratio (Besoin d'actualiser la page)",
+ "16:9 Resolution": "Résolution 16:9",
+ "4:3 Resolution": " Résolution 4:3",
+ "Player 1 Pak": "Pack joueur 1",
+ "Player 2 Pak": "Pack joueur 2",
+ "Player 3 Pak": "Pack de 3 joueurs",
+ "Player 4 Pak": "Pack de 4 joueurs",
+ "none": "aucun",
+ "memory": "mémoire",
+ "rumble": "grondement",
+ "Screen layout": "Disposition de l'écran",
+ "right/left": "droite/gauche",
+ "left/right": "gauche/droite",
+ "bottom/top": "bas/haut",
+ "top/bottom": "haut/bas",
+ "top only": "haut seulement",
+ "bottom only": "en bas uniquement",
+ "quick switch": "commutateur rapide",
+ "hybrid/bottom": "hybride/fond",
+ "hybrid/top": "hybride/haut",
+ "Screen Rotation": " Rotation de l'écran",
+ "CPU speed": "Vitesse du processeur",
+ "Sound output": "Sortie sonore",
+ "mono": "mono",
+ "stereo": "stéréo",
+ "OFF": "OFF",
+ "ON": "ON",
+ "Fast Blitter": "Blitter rapide",
+ "Bios": "Bios",
+ "Enable second memory card": "Activer la deuxième carte mémoire",
+ "Pad 1 Type": "Type de tampon 1",
+ "Pad 2 Type": "Type de plaquette 2",
+ "Pad 3 Type": "Type de tampon 3",
+ "Pad 4 Type": "Type de tampon 4",
+ "standard": "norme",
+ "analog": "analogique",
+ "negcon": "negcon",
+ "Enable Vibration": "Activer les vibrations",
+ "Enable interlacing mode(s)": "Activer le(s) mode(s) d'entrelacement",
+ "Enhanced resolution (slow)": "Résolution améliorée (lente)",
+ "Enhanced resolution speed hack": "Hack de vitesse de résolution améliorée",
+ "Aspect ratio": "Rapport d'aspect",
+ "CPU overclock": " Surcadençage du processeur",
+ "Force Neo Geo mode": "Forcer le mode Neo Geo",
+ "Diagnostic Input": "Entrée de diagnostic",
+ "download": "télécharger",
+ "keep in browser": "garder dans le navigateur",
+ "Webassembly support is not detected in this browser": "La prise en charge de Webassembly n'est pas détectée dans ce navigateur",
+ "Please upgrade your browser to the latest version": "Veuillez mettre à niveau votre navigateur vers la dernière version",
+ "Missing mame config": "Configuration Mame manquante",
+ "Stop Screen Recording": "Arrêter l'enregistrement d'écran",
+ "Start Screen Recording": "Démarrer l'enregistrement d'écran",
+ "Take Screenshot": "Prendre une capture d'écran",
+ "Quick Save": "Enregistrement rapide",
+ "Quick Load": "Chargement rapide"
+}
\ No newline at end of file
diff --git a/data/localization/ar-AR.json b/data/localization/ar-AR.json
new file mode 100644
index 0000000..b6859cd
--- /dev/null
+++ b/data/localization/ar-AR.json
@@ -0,0 +1,194 @@
+{
+ "i18n": {
+ "restart": "اعادة البدء",
+ "play": " تشغيل",
+ "pause": " وقفة",
+ "played": " تم اللعب",
+ "volume": " الحجم",
+ "mute": " كتم الصوت (F9)",
+ "unmute": " إلغاء كتم الصوت (F9)",
+ "enterFullscreen": " أدخل ملء الشاشة",
+ "exitFullscreen": " الخروج من وضع ملء الشاشة",
+ "settings": " الإعدادات",
+ "saveState": " حفظ الحالة (إزاحة + F2)",
+ "loadState": " حالة التحميل (Shift + F4)",
+ "screenRecord": " بدء تسجيل الشاشة",
+ "netplay": " نيت بلاي",
+ "gamepad": " إعدادات التحكم",
+ "cheat": " غش",
+ "menuBack": " ارجع إلى القائمة السابقة",
+ "normal": " عادي",
+ "all": " الكل",
+ "reset": " إعادة تعيين",
+ "disabled": " معطل",
+ "enabled": " ممكّن",
+ "playNow": " العب الآن"
+ },
+ "normalOptions": {
+ "shader": {
+ "label": " شادر",
+ "options": {
+ "disabled": " معطل",
+ "2xScaleHQ.glslp": " 2x مقياس",
+ "4xScaleHQ.glslp": " 4xScaleHQ",
+ "crt-easymode.glslp": " وضع CRT السهل",
+ "crt-aperture.glslp": " فتحة CRT",
+ "crt-geom.glslp": " CRT geom"
+ },
+ "default": "disabled"
+ },
+ "virtual-gamepad": {
+ "label": " لوحة الألعاب الافتراضية",
+ "options": {
+ "disabled": " معطل",
+ "enabled": " ممكّن"
+ },
+ "default": "enabled"
+ }
+ },
+ "Control Settings": " إعدادات التحكم",
+ "Player 1": " اللاعب 1",
+ "Player 2": " اللاعب 2",
+ "Player 3": " اللاعب 3",
+ "Player 4": " اللاعب 4",
+ "Update": " تحديث",
+ "Reset": " إعادة تعيين",
+ "Clear": " مسح",
+ "Cancel": " إلغاء",
+ "Close": " إغلاق",
+ "Empty": " فارغ",
+ "Loading": " تحميل",
+ "Submit": " إرسال",
+ "Description": " الوصف",
+ "Code": " كود",
+ "Add Cheat Code": " أضف كود الغش",
+ "OK": " حسنًا",
+ "Add Cheat": " أضف الغش",
+ "Cache Manager": " مدير ذاكرة التخزين المؤقت",
+ "Press keyboard or gamepad": " اضغط على لوحة المفاتيح أو لوحة الألعاب",
+ "Gamepad": " Gamepad",
+ "Keyboard": " لوحة المفاتيح",
+ "Set": " مجموعة",
+ "QUICK SAVE STATE": " حالة الحفظ السريع",
+ "QUICK LOAD STATE": " حالة التحميل السريع",
+ "CHANGE STATE SLOT": " تغيير فتحة الدولة",
+ "INSERT COIN": " أدخل عملة",
+ "Press escape (esc) to clear": " اضغط على مفتاح الهروب (esc) للمسح",
+ "Netplay": " نيت بلاي",
+ "Rooms": " الغرف",
+ "Players": " اللاعبين",
+ "Player": " لاعب",
+ "Room Name": " اسم الغرفة",
+ "Password": " كلمة المرور",
+ "Name": " الاسم",
+ "Quit Room": " قم بإنهاء الغرفة",
+ "Create a Room": " إنشاء غرفة",
+ "Set Player Name": " تعيين اسم اللاعب",
+ "Player Name": " اسم اللاعب",
+ "Password (optional)": " كلمة المرور (اختياري)",
+ "Select": " حدد",
+ "Start": " ابدأ",
+ "Menu": " القائمة",
+ "Decompress Game Core": " فك ضغط جوهر اللعبة",
+ "Decompress Game Data": " فك ضغط بيانات اللعبة",
+ "Decompress Game Patch": " فك ضغط لعبة التصحيح",
+ "Download Game Data": " تنزيل بيانات اللعبة",
+ "Download Game Core": " تحميل Game Core",
+ "Network Error": " خطأ في الشبكة",
+ "Default": " افتراضي",
+ "default": " الافتراضي",
+ "Save State Location": " حفظ موقع الدولة",
+ "Save State Slot": " حفظ فتحة الدولة",
+ "Color Palette": " لوحة الألوان",
+ "No Sprite Limit": " لا يوجد حد سبرايت",
+ "Enabled": " ممكّن",
+ "Disabled": " معطل",
+ "enabled": " ممكّن",
+ "disabled": " معطل",
+ "Low": " منخفض",
+ "High": " مرتفع",
+ "Very High": " مرتفع جدا",
+ "4 Players Support": " دعم 4 لاعبين",
+ "Turbo Enable": " تمكين توربو",
+ "None": " لا شيء",
+ "Both": " كلاهما",
+ "Region": " المنطقة",
+ "SuperFX Overclock": " SuperFX فيركلوك",
+ "Sound Quality": " جودة الصوت",
+ "GB Colorization": " تلوين GB",
+ "auto": " تلقائي",
+ "internal": " داخلي",
+ "Internal Palette": " لوحة داخلية",
+ "GBC - Blue": " GBC Blue",
+ "GBC - Brown": " جي بي سي براون",
+ "GBC - Dark Blue": " GBC أزرق داكن",
+ "GBC - Dark Brown": " GBC بني غامق",
+ "GBC - Dark Green": " GBC أخضر غامق",
+ "GBC - Grayscale": " GBC Grayscale",
+ "GBC - Green": " GBC Green",
+ "GBC - Inverted": " GBC مقلوب",
+ "GBC - Orange": " GBC Orange",
+ "GBC - Red": " جي بي سي أحمر",
+ "GBC - Pastel Mix": " جي بي سي باستيل ميكس",
+ "GBC - Yellow": " GBC Yellow",
+ "Frameskip": " Frameskip",
+ "Solar sensor level": " مستوى استشعار الطاقة الشمسية",
+ "Enable Turbo Buttons": " تمكين أزرار Turbo",
+ "Turbo Delay in frames": " تربو تأخير في الإطارات",
+ "Auto": " تلقائي",
+ "Aspect Ratio (Need to refresh page)": " نسبة العرض إلى الارتفاع (يلزم تحديث الصفحة)",
+ "16:9 Resolution": " دقة 16: 9",
+ "4:3 Resolution": " دقة 4: 3",
+ "Player 1 Pak": " اللاعب 1 باك",
+ "Player 2 Pak": " اللاعب 2 باك",
+ "Player 3 Pak": " اللاعب 3 باك",
+ "Player 4 Pak": " اللاعب 4 باك",
+ "none": " لا شيء",
+ "memory": " الذاكرة",
+ "rumble": " قعقعة",
+ "Screen layout": " تخطيط الشاشة",
+ "right/left": " يمين / يسار",
+ "left/right": " يسار / يمين",
+ "bottom/top": " أسفل / أعلى",
+ "top/bottom": " أعلى / أسفل",
+ "top only": " الجزء العلوي فقط",
+ "bottom only": " أسفل فقط",
+ "quick switch": " التبديل السريع",
+ "hybrid/bottom": " هجين / سفلي",
+ "hybrid/top": " هجين / علوي",
+ "Screen Rotation": " دوران الشاشة",
+ "CPU speed": " سرعة وحدة المعالجة المركزية",
+ "Sound output": " إخراج الصوت",
+ "mono": " أحادي",
+ "stereo": " ستيريو",
+ "OFF": " إيقاف",
+ "ON": " تشغيل",
+ "Fast Blitter": " ضباب سريع",
+ "Bios": " السير",
+ "Enable second memory card": " تفعيل بطاقة الذاكرة الثانية",
+ "Pad 1 Type": " نوع الوسادة 1",
+ "Pad 2 Type": " نوع الوسادة 2",
+ "Pad 3 Type": " نوع الوسادة 3",
+ "Pad 4 Type": " نوع الوسادة 4",
+ "standard": " قياسي",
+ "analog": " التناظرية",
+ "negcon": " نيجكون",
+ "Enable Vibration": " تمكين الاهتزاز",
+ "Enable interlacing mode(s)": " تمكين وضع (أوضاع) التداخل",
+ "Enhanced resolution (slow)": " دقة محسنة (بطيئة)",
+ "Enhanced resolution speed hack": " تحسين دقة سرعة الاختراق",
+ "Aspect ratio": " نسبة العرض إلى الارتفاع",
+ "CPU overclock": " وحدة المعالجة المركزية فيركلوك",
+ "Force Neo Geo mode": " فرض الوضع الجغرافي الجديد",
+ "Diagnostic Input": " مدخلات التشخيص",
+ "download": " تنزيل",
+ "keep in browser": " ابق في المتصفح",
+ "Webassembly support is not detected in this browser": " لم يتم الكشف عن دعم Webassembly في هذا المستعرض",
+ "Please upgrade your browser to the latest version": " الرجاء ترقية متصفحك إلى أحدث إصدار",
+ "Missing mame config": " مفقود mame config",
+ "Stop Screen Recording": " إيقاف تسجيل الشاشة",
+ "Start Screen Recording": " بدء تسجيل الشاشة",
+ "Take Screenshot": " خذ لقطة شاشة",
+ "Quick Save": " حفظ سريع",
+ "Quick Load": " تحميل سريع"
+}
\ No newline at end of file
diff --git a/data/localization/ben-BEN.json b/data/localization/ben-BEN.json
new file mode 100644
index 0000000..01a11ef
--- /dev/null
+++ b/data/localization/ben-BEN.json
@@ -0,0 +1,194 @@
+{
+ "i18n": {
+ "restart": "আবার শুরু",
+ "play": "খেলা",
+ "pause": " বিরতি",
+ "played": " খেলেছে",
+ "volume": " ভলিউম",
+ "mute": "নিঃশব্দ (F9)",
+ "unmute": "আনমিউট (F9)",
+ "enterFullscreen": "পূর্ণ স্ক্রীনে প্রবেশ করুন",
+ "exitFullscreen": "ফুলস্ক্রিন থেকে প্রস্থান করুন",
+ "settings": "সেটিংস",
+ "saveState": "সেভ স্টেট (Shift + F2)",
+ "loadState": "লোড স্টেট (Shift + F4)",
+ "screenRecord": "স্ক্রিন রেকর্ডিং শুরু করুন",
+ "netplay": "নেটপ্লে",
+ "gamepad": "নিয়ন্ত্রণ সেটিংস",
+ "cheat": "প্রতারক",
+ "menuBack": "আগের মেনুতে ফিরে যান",
+ "normal": " স্বাভাবিক",
+ "all": "সব",
+ "reset": "রিসেট করুন",
+ "disabled": " প্রতিবন্ধী",
+ "enabled": "সক্রিয়",
+ "playNow": "এখন খেলুন"
+ },
+ "normalOptions": {
+ "shader": {
+ "label": "শাদের",
+ "options": {
+ "disabled": " প্রতিবন্ধী",
+ "2xScaleHQ.glslp": "2xScaleHQ",
+ "4xScaleHQ.glslp": "4xScaleHQ",
+ "crt-easymode.glslp": "সিআরটি ইজিমোড",
+ "crt-aperture.glslp": "সিআরটি অ্যাপারচার",
+ "crt-geom.glslp": "সিআরটি জিওম"
+ },
+ "default": "disabled"
+ },
+ "virtual-gamepad": {
+ "label": "ভার্চুয়াল গেমপ্যাড",
+ "options": {
+ "disabled": " প্রতিবন্ধী",
+ "enabled": "সক্রিয়"
+ },
+ "default": "enabled"
+ }
+ },
+ "Control Settings": "নিয়ন্ত্রণ সেটিংস",
+ "Player 1": "খেলোয়াড় 1",
+ "Player 2": "খেলোয়াড় 2",
+ "Player 3": "খেলোয়াড় 3",
+ "Player 4": "খেলোয়াড় 4",
+ "Update": "আপডেট",
+ "Reset": "রিসেট করুন",
+ "Clear": " পরিষ্কার",
+ "Cancel": "বাতিল করুন",
+ "Close": " বন্ধ",
+ "Empty": " খালি",
+ "Loading": "লোড হচ্ছে",
+ "Submit": " জমা দিন",
+ "Description": " বর্ণনা",
+ "Code": "কোড",
+ "Add Cheat Code": " চিট কোড যোগ করুন",
+ "OK": "ঠিক আছে",
+ "Add Cheat": "প্রতারণা যোগ করুন",
+ "Cache Manager": "ক্যাশ ম্যানেজার",
+ "Press keyboard or gamepad": "কীবোর্ড বা গেমপ্যাড টিপুন",
+ "Gamepad": "গেমপ্যাড",
+ "Keyboard": "কীবোর্ড",
+ "Set": " সেট",
+ "QUICK SAVE STATE": " দ্রুত সেভ স্টেট",
+ "QUICK LOAD STATE": "কুইক লোড স্টেট",
+ "CHANGE STATE SLOT": " রাজ্যের স্লট পরিবর্তন করুন৷",
+ "INSERT COIN": " কয়েন ঢোকান",
+ "Press escape (esc) to clear": " সাফ করতে escape (esc) টিপুন",
+ "Netplay": "নেটপ্লে",
+ "Rooms": "রুম",
+ "Players": "খেলোয়াড়",
+ "Player": "খেলোয়াড়",
+ "Room Name": "রুমের নাম",
+ "Password": "পাসওয়ার্ড",
+ "Name": "নাম",
+ "Quit Room": " রুম ছেড়ে দাও",
+ "Create a Room": " একটি রুম তৈরি করুনপ্লেয়ারের নাম সেট করুন",
+ "Set Player Name": "খেলোয়াড়ের নাম",
+ "Player Name": "পাসওয়ার্ড (ঐচ্ছিক)",
+ "Password (optional)": " নির্বাচন করুন",
+ "Select": "শুরু",
+ "Start": "মেনু",
+ "Menu": " গেম কোর ডিকম্প্রেস করুন",
+ "Decompress Game Core": "গেম ডেটা ডিকম্প্রেস করুন",
+ "Decompress Game Data": " ডিকম্প্রেস গেম প্যাচ",
+ "Decompress Game Patch": "গেম ডেটা ডাউনলোড করুন",
+ "Download Game Data": "গেম কোর ডাউনলোড করুন",
+ "Download Game Core": "নেটওয়ার্ক ত্রুটি",
+ "Network Error": "ডিফল্ট",
+ "Default": " ডিফল্ট",
+ "default": " রাজ্যের অবস্থান সংরক্ষণ করুন৷",
+ "Save State Location": " রাজ্য স্লট সংরক্ষণ করুন",
+ "Save State Slot": "রঙ প্যালেট",
+ "Color Palette": "কোন স্প্রাইট সীমা নেই",
+ "No Sprite Limit": "সক্রিয়",
+ "Enabled": " প্রতিবন্ধী",
+ "Disabled": "সক্রিয়",
+ "enabled": " অক্ষম",
+ "disabled": "নিম্ন",
+ "Low": " উচ্চ",
+ "High": "খুব উচ্চ",
+ "Very High": "4 প্লেয়ার সাপোর্ট",
+ "4 Players Support": "টার্বো সক্ষম",
+ "Turbo Enable": " কোনোটিই নয়",
+ "None": "দুটোই",
+ "Both": " অঞ্চল",
+ "Region": "SuperFX ওভারক্লক",
+ "SuperFX Overclock": " সাউন্ড কোয়ালিটি",
+ "Sound Quality": "জিবি কালারাইজেশন",
+ "GB Colorization": "অটো",
+ "auto": " অভ্যন্তরীণ",
+ "internal": "অভ্যন্তরীণ প্যালেট",
+ "Internal Palette": "জিবিসি ব্লু",
+ "GBC - Blue": "GBC ব্রাউন",
+ "GBC - Brown": "GBC গাঢ় নীল",
+ "GBC - Dark Blue": "GBC ডার্ক ব্রাউন",
+ "GBC - Dark Brown": "GBC গাঢ় সবুজ",
+ "GBC - Dark Green": "GBC গ্রেস্কেল",
+ "GBC - Grayscale": "জিবিসি গ্রিন",
+ "GBC - Green": "GBC উল্টানো",
+ "GBC - Inverted": "GBC কমলা",
+ "GBC - Orange": "GBC রেড",
+ "GBC - Red": "GBC প্যাস্টেল মিক্স",
+ "GBC - Pastel Mix": "GBC হলুদ",
+ "GBC - Yellow": "ফ্রেমস্কিপ",
+ "Frameskip": "সৌর সেন্সর স্তর",
+ "Solar sensor level": " টার্বো বোতাম সক্ষম করুন৷",
+ "Enable Turbo Buttons": "ফ্রেমে টার্বো বিলম্ব",
+ "Turbo Delay in frames": "অটো",
+ "Auto": "আসপেক্ট রেশিও (পৃষ্ঠা রিফ্রেশ করতে হবে)",
+ "Aspect Ratio (Need to refresh page)": "16:9 রেজোলিউশন",
+ "16:9 Resolution": "4:3 রেজোলিউশন",
+ "4:3 Resolution": "খেলোয়াড় 1 পাক",
+ "Player 1 Pak": "খেলোয়াড় 2 পাক",
+ "Player 2 Pak": "খেলোয়াড় ৩ পাক",
+ "Player 3 Pak": "প্লেয়ার 4 পাক",
+ "Player 4 Pak": " কোনোটিই নয়",
+ "none": "স্মৃতি",
+ "memory": "রম্বল",
+ "rumble": "স্ক্রিন লেআউট",
+ "Screen layout": "ডান/বাম",
+ "right/left": "বাম/ডান",
+ "left/right": "নিচে/উপরে",
+ "bottom/top": "শীর্ষ/নীচ",
+ "top/bottom": "শুধুমাত্র উপরে",
+ "top only": "শুধু নীচে",
+ "bottom only": " দ্রুত সুইচ",
+ "quick switch": "হাইব্রিড/নিচ",
+ "hybrid/bottom": "হাইব্রিড/টপ",
+ "hybrid/top": "স্ক্রিন ঘূর্ণন",
+ "Screen Rotation": " CPU গতি",
+ "CPU speed": " সাউন্ড আউটপুট",
+ "Sound output": "মনোস্টেরিও",
+ "mono": "বন্ধ",
+ "stereo": " চালু",
+ "OFF": "ফাস্ট ব্লিটার",
+ "ON": "বায়োস",
+ "Fast Blitter": "দ্বিতীয় মেমরি কার্ড সক্রিয় করুন",
+ "Bios": "প্যাড 1 প্রকার",
+ "Enable second memory card": "প্যাড 2 প্রকার",
+ "Pad 1 Type": "প্যাড 3 প্রকার",
+ "Pad 2 Type": "প্যাড 4 প্রকার",
+ "Pad 3 Type": "মান",
+ "Pad 4 Type": "অ্যানালগ",
+ "standard": "নেগকন",
+ "analog": "কম্পন সক্ষম করুন",
+ "negcon": "ইন্টারলেসিং মোড(গুলি) সক্ষম করুন",
+ "Enable Vibration": "বর্ধিত রেজোলিউশন (ধীরে)",
+ "Enable interlacing mode(s)": "বর্ধিত রেজোলিউশন গতি হ্যাক",
+ "Enhanced resolution (slow)": " আকৃতির অনুপাত",
+ "Enhanced resolution speed hack": "CPU ওভারক্লক",
+ "Aspect ratio": " নিও জিও মোড ফোর্স করুন",
+ "CPU overclock": "ডায়াগনস্টিক ইনপুট",
+ "Force Neo Geo mode": "ডাউনলোড করুনব্রাউজারে রাখুন",
+ "Diagnostic Input": "ওয়েবসেম্বলি সমর্থন এই ব্রাউজারে সনাক্ত করা হয়নি",
+ "download": "অনুগ্রহ করে আপনার ব্রাউজারটিকে সর্বশেষ সংস্করণে আপগ্রেড করুন৷",
+ "keep in browser": " mame কনফিগারেশন অনুপস্থিত",
+ "Webassembly support is not detected in this browser": "স্ক্রিন রেকর্ডিং বন্ধ করুন",
+ "Please upgrade your browser to the latest version": "স্ক্রিন রেকর্ডিং শুরু করুন",
+ "Missing mame config": "স্ক্রিনশট নিন",
+ "Stop Screen Recording": " দ্রুত সংরক্ষণ করুন",
+ "Start Screen Recording": " দ্রুত লোড",
+ "Take Screenshot": "",
+ "Quick Save": "undefined",
+ "Quick Load": "undefined"
+}
\ No newline at end of file
diff --git a/data/localization/chi-CHI.json b/data/localization/chi-CHI.json
new file mode 100644
index 0000000..c943fdd
--- /dev/null
+++ b/data/localization/chi-CHI.json
@@ -0,0 +1,194 @@
+{
+ "i18n": {
+ "restart": "重新开始",
+ "play": "播放",
+ "pause": "暂停",
+ "played": "玩过",
+ "volume": "音量",
+ "mute": "静音 (F9)",
+ "unmute": "取消静音 (F9)",
+ "enterFullscreen": "进入全屏",
+ "exitFullscreen": "退出全屏",
+ "settings": "设置",
+ "saveState": "保存状态(Shift + F2)",
+ "loadState": "加载状态 (Shift + F4)",
+ "screenRecord": "开始录屏",
+ "netplay": "网络游戏",
+ "gamepad": "控制设置",
+ "cheat": "秘籍",
+ "menuBack": "返回上一级菜单",
+ "normal": "正常",
+ "all": "全部",
+ "reset": "重置",
+ "disabled": "残疾人士",
+ "enabled": "启用",
+ "playNow": "立即播放"
+ },
+ "normalOptions": {
+ "shader": {
+ "label": "着色器",
+ "options": {
+ "disabled": "残疾人士",
+ "2xScaleHQ.glslp": "2xScaleHQ",
+ "4xScaleHQ.glslp": "4xScaleHQ",
+ "crt-easymode.glslp": "CRT 简易模式",
+ "crt-aperture.glslp": "CRT孔径",
+ "crt-geom.glslp": "CRT几何"
+ },
+ "default": "disabled"
+ },
+ "virtual-gamepad": {
+ "label": "虚拟游戏手柄",
+ "options": {
+ "disabled": "残疾人士",
+ "enabled": "启用"
+ },
+ "default": "enabled"
+ }
+ },
+ "Control Settings": "控制设置",
+ "Player 1": "玩家1",
+ "Player 2": "玩家2",
+ "Player 3": "玩家 3",
+ "Player 4": "玩家 4",
+ "Update": "更新",
+ "Reset": "重置",
+ "Clear": "清除",
+ "Cancel": "取消",
+ "Close": "关闭",
+ "Empty": "空",
+ "Loading": "加载中",
+ "Submit": "提交",
+ "Description": "说明",
+ "Code": "代码",
+ "Add Cheat Code": "添加作弊码",
+ "OK": "确定",
+ "Add Cheat": "添加作弊",
+ "Cache Manager": "缓存管理器",
+ "Press keyboard or gamepad": "按键盘或游戏手柄",
+ "Gamepad": "游戏手柄",
+ "Keyboard": "键盘",
+ "Set": "设置",
+ "QUICK SAVE STATE": "快速保存状态",
+ "QUICK LOAD STATE": "快速加载状态",
+ "CHANGE STATE SLOT": "更改状态槽",
+ "INSERT COIN": "插入硬币",
+ "Press escape (esc) to clear": "按退出 (esc) 清除",
+ "Netplay": "网络游戏",
+ "Rooms": "房间",
+ "Players": "球员",
+ "Player": "播放器",
+ "Room Name": "房间名称",
+ "Password": "密码",
+ "Name": "姓名",
+ "Quit Room": "戒烟室",
+ "Create a Room": "创建房间",
+ "Set Player Name": "设置玩家姓名",
+ "Player Name": "玩家姓名",
+ "Password (optional)": "密码(可选)",
+ "Select": "选择",
+ "Start": "开始",
+ "Menu": "菜单",
+ "Decompress Game Core": "解压游戏内核",
+ "Decompress Game Data": "解压游戏数据",
+ "Decompress Game Patch": "解压游戏补丁",
+ "Download Game Data": "下载游戏资料",
+ "Download Game Core": "下载游戏内核",
+ "Network Error": "网络错误",
+ "Default": "默认",
+ "default": "默认",
+ "Save State Location": "保存状态位置",
+ "Save State Slot": "保存状态槽",
+ "Color Palette": "调色板",
+ "No Sprite Limit": "没有精灵限制",
+ "Enabled": "启用",
+ "Disabled": "残疾人士",
+ "enabled": "启用",
+ "disabled": "已禁用",
+ "Low": "低",
+ "High": "高",
+ "Very High": "非常高",
+ "4 Players Support": "4 玩家支持",
+ "Turbo Enable": "加速启用",
+ "None": "无",
+ "Both": "两者",
+ "Region": "地区",
+ "SuperFX Overclock": "SuperFX 超频",
+ "Sound Quality": "音质",
+ "GB Colorization": "GB 着色",
+ "auto": "汽车",
+ "internal": "内部",
+ "Internal Palette": "内部调色板",
+ "GBC - Blue": "GBC蓝",
+ "GBC - Brown": "GBC 棕色",
+ "GBC - Dark Blue": "GBC 深蓝",
+ "GBC - Dark Brown": "GBC 深棕色",
+ "GBC - Dark Green": "GBC 深绿色",
+ "GBC - Grayscale": "GBC灰度",
+ "GBC - Green": "GBC 绿色",
+ "GBC - Inverted": "GBC 倒置",
+ "GBC - Orange": "GBC 橙",
+ "GBC - Red": "GBC红",
+ "GBC - Pastel Mix": "GBC 粉彩混合",
+ "GBC - Yellow": "GBC 黄色",
+ "Frameskip": "跳帧",
+ "Solar sensor level": "太阳能传感器级",
+ "Enable Turbo Buttons": "启用 Turbo 按钮",
+ "Turbo Delay in frames": "以帧为单位的涡轮延迟",
+ "Auto": "汽车",
+ "Aspect Ratio (Need to refresh page)": "长宽比(需要刷新页面)",
+ "16:9 Resolution": "16:9 分辨率",
+ "4:3 Resolution": "4:3 分辨率",
+ "Player 1 Pak": "玩家 1 朴",
+ "Player 2 Pak": "玩家 2 朴",
+ "Player 3 Pak": "玩家 3 朴",
+ "Player 4 Pak": "玩家 4 朴",
+ "none": "无",
+ "memory": "内存",
+ "rumble": "隆隆声",
+ "Screen layout": "画面布局",
+ "right/left": "右/左",
+ "left/right": "左/右",
+ "bottom/top": "底部/顶部",
+ "top/bottom": "上/下",
+ "top only": "仅顶部",
+ "bottom only": "仅底部",
+ "quick switch": "快速切换",
+ "hybrid/bottom": "混合/底部",
+ "hybrid/top": "混合/顶部",
+ "Screen Rotation": "屏幕旋转",
+ "CPU speed": "CPU 速度",
+ "Sound output": "声音输出",
+ "mono": "单声道",
+ "stereo": "立体声",
+ "OFF": "关闭",
+ "ON": "开",
+ "Fast Blitter": "快速Blitter",
+ "Bios": "简历",
+ "Enable second memory card": "启用第二张存储卡",
+ "Pad 1 Type": "垫1型",
+ "Pad 2 Type": "垫2型",
+ "Pad 3 Type": "垫3型",
+ "Pad 4 Type": "垫4型",
+ "standard": "标准",
+ "analog": "模拟",
+ "negcon": "negcon",
+ "Enable Vibration": "启用振动",
+ "Enable interlacing mode(s)": "启用隔行扫描模式",
+ "Enhanced resolution (slow)": "增强分辨率(慢)",
+ "Enhanced resolution speed hack": "增强的分辨率速度破解",
+ "Aspect ratio": "长宽比",
+ "CPU overclock": "CPU超频",
+ "Force Neo Geo mode": "强制 Neo Geo 模式",
+ "Diagnostic Input": "诊断输入",
+ "download": "下载",
+ "keep in browser": "保留在浏览器中",
+ "Webassembly support is not detected in this browser": "在此浏览器中未检测到 Web 程序集支持",
+ "Please upgrade your browser to the latest version": "请将您的浏览器升级到最新版本",
+ "Missing mame config": "缺少妈妈配置",
+ "Stop Screen Recording": "停止录屏",
+ "Start Screen Recording": "开始录屏",
+ "Take Screenshot": "截图",
+ "Quick Save": "快速保存",
+ "Quick Load": "快速加载"
+}
\ No newline at end of file
diff --git a/data/localization/de-GER.json b/data/localization/de-GER.json
new file mode 100644
index 0000000..ceb2ddc
--- /dev/null
+++ b/data/localization/de-GER.json
@@ -0,0 +1,194 @@
+{
+ "i18n": {
+ "restart": "Neu starten",
+ "play": "Spielen",
+ "pause": "Pause",
+ "played": "Gespielt",
+ "volume": "Lautstärke",
+ "mute": "Stumm (F9)",
+ "unmute": "Stumm aufheben (F9)",
+ "enterFullscreen": "Vollbild aufrufen",
+ "exitFullscreen": "Vollbild verlassen",
+ "settings": "Einstellungen",
+ "saveState": "Zustand speichern (Umschalt + F2)",
+ "loadState": "Zustand laden (Umschalt + F4)",
+ "screenRecord": "Bildschirmaufnahme starten",
+ "netplay": "Netzspiel",
+ "gamepad": "Steuerungseinstellungen",
+ "cheat": "Betrug",
+ "menuBack": "Zurück zum vorherigen Menü",
+ "normal": "Normal",
+ "all": "Alle",
+ "reset": "Zurücksetzen",
+ "disabled": "Deaktiviert",
+ "enabled": "Aktiviert",
+ "playNow": "Jetzt spielen"
+ },
+ "normalOptions": {
+ "shader": {
+ "label": "Shader",
+ "options": {
+ "disabled": "Deaktiviert",
+ "2xScaleHQ.glslp": "2xScaleHQ",
+ "4xScaleHQ.glslp": "4xScaleHQ",
+ "crt-easymode.glslp": "CRT Easymode",
+ "crt-aperture.glslp": "CRT-Öffnung",
+ "crt-geom.glslp": "Kathodengeom"
+ },
+ "default": "disabled"
+ },
+ "virtual-gamepad": {
+ "label": "Virtuelles Gamepad",
+ "options": {
+ "disabled": "Deaktiviert",
+ "enabled": "Aktiviert"
+ },
+ "default": "enabled"
+ }
+ },
+ "Control Settings": "Steuerungseinstellungen",
+ "Player 1": "Spieler 1",
+ "Player 2": "Spieler 2",
+ "Player 3": "Spieler 3",
+ "Player 4": "Spieler 4",
+ "Update": "Aktualisieren",
+ "Reset": "Zurücksetzen",
+ "Clear": "Löschen",
+ "Cancel": "Abbrechen",
+ "Close": "Schließen",
+ "Empty": "Leer",
+ "Loading": "Wird geladen",
+ "Submit": "Senden",
+ "Description": "Beschreibung",
+ "Code": "Code",
+ "Add Cheat Code": "Cheat-Code hinzufügen",
+ "OK": "Okay",
+ "Add Cheat": "Cheat hinzufügen",
+ "Cache Manager": "Cache-Manager",
+ "Press keyboard or gamepad": "Taste oder Gamepad drücken",
+ "Gamepad": "Gamepad",
+ "Keyboard": "Tastatur",
+ "Set": "Setzen",
+ "QUICK SAVE STATE": "SCHNELLSPEICHERSTATUS",
+ "QUICK LOAD STATE": "SCHNELLER LADEZUSTAND",
+ "CHANGE STATE SLOT": "STATUS SLOT ÄNDERN",
+ "INSERT COIN": "MÜNZE EINWERFEN",
+ "Press escape (esc) to clear": "Drücken Sie zum Löschen die Escape-Taste (esc).",
+ "Netplay": "Netzspiel",
+ "Rooms": "Zimmer",
+ "Players": "Spieler",
+ "Player": "Spieler",
+ "Room Name": "Raumname",
+ "Password": "Passwort",
+ "Name": "Name",
+ "Quit Room": "Raum verlassen",
+ "Create a Room": "Erstelle einen Raum",
+ "Set Player Name": "Spielernamen festlegen",
+ "Player Name": "Spielername",
+ "Password (optional)": "Passwort (optional)",
+ "Select": "Auswählen",
+ "Start": "Starten",
+ "Menu": "Menü",
+ "Decompress Game Core": "Spielkern dekomprimieren",
+ "Decompress Game Data": "Spieldaten dekomprimieren",
+ "Decompress Game Patch": "Spiel-Patch dekomprimieren",
+ "Download Game Data": "Spieldaten herunterladen",
+ "Download Game Core": "Spielkern herunterladen",
+ "Network Error": "Netzwerkfehler",
+ "Default": "Standard",
+ "default": "Standard",
+ "Save State Location": "Zustandsstandort speichern",
+ "Save State Slot": "Zustandsplatz speichern",
+ "Color Palette": "Farbpalette",
+ "No Sprite Limit": "Kein Sprite-Limit",
+ "Enabled": "Aktiviert",
+ "Disabled": "Deaktiviert",
+ "enabled": "aktiviert",
+ "disabled": "deaktiviert",
+ "Low": "Niedrig",
+ "High": "Hoch",
+ "Very High": "Sehr hoch",
+ "4 Players Support": "Unterstützung für 4 Spieler",
+ "Turbo Enable": "Turbo aktivieren",
+ "None": "Keine",
+ "Both": "Beide",
+ "Region": "Region",
+ "SuperFX Overclock": "SuperFX-Übertaktung",
+ "Sound Quality": "Tonqualität",
+ "GB Colorization": "GB Kolorierung",
+ "auto": "automat",
+ "internal": "intern",
+ "Internal Palette": "Interne Palette",
+ "GBC - Blue": "GBC-Blau",
+ "GBC - Brown": "GBC Braun",
+ "GBC - Dark Blue": "GBC Dunkelblau",
+ "GBC - Dark Brown": "GBC Dunkelbraun",
+ "GBC - Dark Green": "GBC Dunkelgrün",
+ "GBC - Grayscale": "GBC Graustufen",
+ "GBC - Green": "GBC-Grün",
+ "GBC - Inverted": "GBC invertiert",
+ "GBC - Orange": "GBC-Orange",
+ "GBC - Red": "GBC-Rot",
+ "GBC - Pastel Mix": "GBC Pastellmischung",
+ "GBC - Yellow": "GBC-Gelb",
+ "Frameskip": "Frameskip",
+ "Solar sensor level": " Niveau Solarsensor",
+ "Enable Turbo Buttons": "Turbo-Schaltflächen aktivieren",
+ "Turbo Delay in frames": "Turbo Delay in Frames",
+ "Auto": "Autom",
+ "Aspect Ratio (Need to refresh page)": "Seitenverhältnis (Seite muss aktualisiert werden)",
+ "16:9 Resolution": "16:9-Auflösung",
+ "4:3 Resolution": "4:3-Auflösung",
+ "Player 1 Pak": "Spieler 1 Pak",
+ "Player 2 Pak": "Spieler 2 Pak",
+ "Player 3 Pak": "Spieler 3 Pak",
+ "Player 4 Pak": "Spieler 4 Pak",
+ "none": "keine",
+ "memory": "Erinnerung",
+ "rumble": "Grollen",
+ "Screen layout": "Bildschirmlayout",
+ "right/left": "rechts/links",
+ "left/right": "links/rechts",
+ "bottom/top": "unten/oben",
+ "top/bottom": "oben/unten",
+ "top only": "nur oben",
+ "bottom only": "nur unten",
+ "quick switch": "schneller Wechsel",
+ "hybrid/bottom": "hybrid/unten",
+ "hybrid/top": "hybrid/top",
+ "Screen Rotation": "Bildschirmrotation",
+ "CPU speed": "CPU-Geschwindigkeit",
+ "Sound output": "Tonausgabe",
+ "mono": "Mono",
+ "stereo": "Stereo",
+ "OFF": "AUS",
+ "ON": "EIN",
+ "Fast Blitter": "Schneller Blitter",
+ "Bios": "Bios",
+ "Enable second memory card": "Zweite Speicherkarte aktivieren",
+ "Pad 1 Type": "Pad 1 Typ",
+ "Pad 2 Type": "Pad 2-Typ",
+ "Pad 3 Type": "Pad-3-Typ",
+ "Pad 4 Type": "Pad-4-Typ",
+ "standard": "Standard",
+ "analog": "analog",
+ "negcon": "negkon",
+ "Enable Vibration": "Vibration aktivieren",
+ "Enable interlacing mode(s)": "Interlacing-Modus(s) aktivieren",
+ "Enhanced resolution (slow)": "Erhöhte Auflösung (langsam)",
+ "Enhanced resolution speed hack": "Verbesserter Auflösungsgeschwindigkeits-Hack",
+ "Aspect ratio": "Seitenverhältnis",
+ "CPU overclock": "CPU-Übertaktung",
+ "Force Neo Geo mode": "Neo-Geo-Modus erzwingen",
+ "Diagnostic Input": "Diagnoseeingang",
+ "download": "herunterladen",
+ "keep in browser": "im Browser bleiben",
+ "Webassembly support is not detected in this browser": "Webassembly-Unterstützung wird in diesem Browser nicht erkannt",
+ "Please upgrade your browser to the latest version": "Bitte aktualisieren Sie Ihren Browser auf die neueste Version",
+ "Missing mame config": "Fehlende Mame-Konfiguration",
+ "Stop Screen Recording": "Beenden Sie die Bildschirmaufzeichnung",
+ "Start Screen Recording": "Bildschirmaufnahme starten",
+ "Take Screenshot": "Screenshot machen",
+ "Quick Save": "Schnellspeichern",
+ "Quick Load": "Schnelles Laden"
+}
\ No newline at end of file
diff --git a/data/localization/hi-HI.json b/data/localization/hi-HI.json
new file mode 100644
index 0000000..b430a09
--- /dev/null
+++ b/data/localization/hi-HI.json
@@ -0,0 +1,194 @@
+{
+ "i18n": {
+ "restart": "पुनर्प्रारंभ करें",
+ "play": "चलाएं",
+ "pause": "रोकें",
+ "played": "खेला",
+ "volume": "वॉल्यूम",
+ "mute": "म्यूट (F9)",
+ "unmute": "अनम्यूट (F9)",
+ "enterFullscreen": "पूर्ण स्क्रीन दर्ज करें",
+ "exitFullscreen": "फुलस्क्रीन से बाहर निकलें",
+ "settings": "सेटिंग्स",
+ "saveState": "राज्य बचाओ (Shift + F2)",
+ "loadState": "लोड स्टेट (Shift + F4)",
+ "screenRecord": "स्क्रीन रिकॉर्डिंग शुरू करें",
+ "netplay": "नेटप्ले",
+ "gamepad": "नियंत्रण सेटिंग्स",
+ "cheat": "धोखा",
+ "menuBack": "पिछले मेनू पर वापस जाएं",
+ "normal": "सामान्य",
+ "all": "ऑल",
+ "reset": "रीसेट",
+ "disabled": "अक्षम",
+ "enabled": "सक्षम",
+ "playNow": "अभी खेलें"
+ },
+ "normalOptions": {
+ "shader": {
+ "label": "शदर",
+ "options": {
+ "disabled": "अक्षम",
+ "2xScaleHQ.glslp": "2xScaleHQ",
+ "4xScaleHQ.glslp": "4xScaleHQ",
+ "crt-easymode.glslp": "सीआरटी ईज़ीमोड",
+ "crt-aperture.glslp": "सीआरटी एपर्चर",
+ "crt-geom.glslp": "सीआरटी जियोम"
+ },
+ "default": "disabled"
+ },
+ "virtual-gamepad": {
+ "label": "वर्चुअल गेमपैड",
+ "options": {
+ "disabled": "अक्षम",
+ "enabled": "सक्षम"
+ },
+ "default": "enabled"
+ }
+ },
+ "Control Settings": "नियंत्रण सेटिंग्स",
+ "Player 1": "खिलाड़ी 1",
+ "Player 2": "खिलाड़ी 2",
+ "Player 3": "खिलाड़ी 3",
+ "Player 4": "खिलाड़ी 4",
+ "Update": "अपडेट",
+ "Reset": "रीसेट",
+ "Clear": "साफ़ करें",
+ "Cancel": "रद्द करें",
+ "Close": "बंद",
+ "Empty": "खाली",
+ "Loading": "लोड हो रहा है",
+ "Submit": "सबमिट",
+ "Description": "विवरण",
+ "Code": "कोड",
+ "Add Cheat Code": "चीट कोड जोड़ें",
+ "OK": "ठीक है",
+ "Add Cheat": "धोखा जोड़ें",
+ "Cache Manager": "कैश मैनेजर",
+ "Press keyboard or gamepad": "कीबोर्ड या गेमपैड दबाएं",
+ "Gamepad": "गेमपैड",
+ "Keyboard": "कीबोर्ड",
+ "Set": "सेट",
+ "QUICK SAVE STATE": "क्विक सेव स्टेट",
+ "QUICK LOAD STATE": "त्वरित लोड स्थिति",
+ "CHANGE STATE SLOT": "राज्य स्लॉट बदलें",
+ "INSERT COIN": "इन्सर्ट कॉइन",
+ "Press escape (esc) to clear": "साफ़ करने के लिए एस्केप (esc) दबाएं",
+ "Netplay": "नेटप्ले",
+ "Rooms": "कमरे",
+ "Players": "खिलाड़ी",
+ "Player": "खिलाड़ी",
+ "Room Name": "कमरे का नाम",
+ "Password": "पासवर्ड",
+ "Name": "नाम",
+ "Quit Room": "छोड़ो कमरा",
+ "Create a Room": "एक कमरा बनाएं",
+ "Set Player Name": "सेट प्लेयर का नाम",
+ "Player Name": "खिलाड़ी का नाम",
+ "Password (optional)": "पासवर्ड (वैकल्पिक)",
+ "Select": "चुनें",
+ "Start": "स्टार्ट",
+ "Menu": "मेनू",
+ "Decompress Game Core": "डिकंप्रेस गेम कोर",
+ "Decompress Game Data": "डिकंप्रेस गेम डेटा",
+ "Decompress Game Patch": "डीकंप्रेस गेम पैच",
+ "Download Game Data": "गेम डेटा डाउनलोड करें",
+ "Download Game Core": "डाउनलोड गेम कोर",
+ "Network Error": "नेटवर्क त्रुटि",
+ "Default": "डिफ़ॉल्ट",
+ "default": "डिफ़ॉल्ट",
+ "Save State Location": "राज्य स्थान सहेजें",
+ "Save State Slot": "सेव स्टेट स्लॉट",
+ "Color Palette": "रंग पैलेट",
+ "No Sprite Limit": "कोई स्प्राइट सीमा नहीं",
+ "Enabled": "सक्षम",
+ "Disabled": "अक्षम",
+ "enabled": "सक्षम",
+ "disabled": "अक्षम",
+ "Low": "लो",
+ "High": "हाई",
+ "Very High": "वेरी हाई",
+ "4 Players Support": "4 खिलाड़ी समर्थन",
+ "Turbo Enable": "टर्बो सक्षम",
+ "None": "कोई नहीं",
+ "Both": "दोनों",
+ "Region": "क्षेत्र",
+ "SuperFX Overclock": "सुपरएफएक्स ओवरक्लॉक",
+ "Sound Quality": "ध्वनि गुणवत्ता",
+ "GB Colorization": "जीबी रंगीकरण",
+ "auto": "ऑटो",
+ "internal": "आंतरिक",
+ "Internal Palette": "आंतरिक पैलेट",
+ "GBC - Blue": "जीबीसी ब्लू",
+ "GBC - Brown": "जीबीसी ब्राउन",
+ "GBC - Dark Blue": "जीबीसी डार्क ब्लू",
+ "GBC - Dark Brown": "जीबीसी डार्क ब्राउन",
+ "GBC - Dark Green": "जीबीसी डार्क ग्रीन",
+ "GBC - Grayscale": "जीबीसी ग्रेस्केल",
+ "GBC - Green": "जीबीसी ग्रीन",
+ "GBC - Inverted": "जीबीसी उलटा",
+ "GBC - Orange": "जीबीसी ऑरेंज",
+ "GBC - Red": "जीबीसी रेड",
+ "GBC - Pastel Mix": "जीबीसी पेस्टल मिक्स",
+ "GBC - Yellow": "जीबीसी पीला",
+ "Frameskip": "फ्रेमस्किप",
+ "Solar sensor level": "सौर सेंसर स्तर",
+ "Enable Turbo Buttons": "टर्बो बटन सक्षम करें",
+ "Turbo Delay in frames": "फ्रेम में टर्बो विलंब",
+ "Auto": "ऑटो",
+ "Aspect Ratio (Need to refresh page)": "पहलू अनुपात (पेज को रीफ्रेश करने की आवश्यकता है)",
+ "16:9 Resolution": "16:9 संकल्प",
+ "4:3 Resolution": "4:3 संकल्प",
+ "Player 1 Pak": "खिलाड़ी 1 पाक",
+ "Player 2 Pak": "खिलाड़ी 2 पाक",
+ "Player 3 Pak": "खिलाड़ी 3 पाक",
+ "Player 4 Pak": "खिलाड़ी 4 पाक",
+ "none": "कोई नहीं",
+ "memory": "स्मृति",
+ "rumble": "रंबल",
+ "Screen layout": "स्क्रीन लेआउट",
+ "right/left": "दाएं/बाएं",
+ "left/right": "बाएं/दाएं",
+ "bottom/top": "नीचे/ऊपर",
+ "top/bottom": "ऊपर/नीचे",
+ "top only": "केवल शीर्ष",
+ "bottom only": "केवल नीचे",
+ "quick switch": "त्वरित स्विच",
+ "hybrid/bottom": "हाइब्रिड/बॉटम",
+ "hybrid/top": "हाइब्रिड/टॉप",
+ "Screen Rotation": "स्क्रीन रोटेशन",
+ "CPU speed": "सीपीयू स्पीड",
+ "Sound output": "ध्वनि आउटपुट",
+ "mono": "मोनो",
+ "stereo": "स्टीरियो",
+ "OFF": "ऑफ",
+ "ON": "ओएन",
+ "Fast Blitter": "फास्ट ब्लिटर",
+ "Bios": "बायोस",
+ "Enable second memory card": "दूसरा मेमोरी कार्ड सक्षम करें",
+ "Pad 1 Type": "पैड 1 प्रकार",
+ "Pad 2 Type": "पैड 2 प्रकार",
+ "Pad 3 Type": "पैड 3 प्रकार",
+ "Pad 4 Type": "पैड 4 प्रकार",
+ "standard": "मानक",
+ "analog": "एनालॉग",
+ "negcon": "नेगकॉन",
+ "Enable Vibration": "कंपन सक्षम करें",
+ "Enable interlacing mode(s)": "इंटरलेसिंग मोड सक्षम करें",
+ "Enhanced resolution (slow)": "उन्नत संकल्प (धीमा)",
+ "Enhanced resolution speed hack": "एन्हांस्ड रेजोल्यूशन स्पीड हैक",
+ "Aspect ratio": "पहलू अनुपात",
+ "CPU overclock": "सीपीयू ओवरक्लॉक",
+ "Force Neo Geo mode": "फोर्स नियो जियो मोड",
+ "Diagnostic Input": "नैदानिक इनपुट",
+ "download": "डाउनलोड",
+ "keep in browser": "ब्राउज़र में रखें",
+ "Webassembly support is not detected in this browser": "इस ब्राउज़र में Webassembly समर्थन का पता नहीं चला है",
+ "Please upgrade your browser to the latest version": "कृपया अपने ब्राउज़र को नवीनतम संस्करण में अपग्रेड करें",
+ "Missing mame config": "मिसिंग मैम कॉन्फिग",
+ "Stop Screen Recording": "स्क्रीन रिकॉर्डिंग बंद करो",
+ "Start Screen Recording": "स्क्रीन रिकॉर्डिंग शुरू करें",
+ "Take Screenshot": "स्क्रीनशॉट लें",
+ "Quick Save": "क्विक सेव",
+ "Quick Load": "त्वरित लोड"
+}
\ No newline at end of file
diff --git a/data/localization/jv-JV.json b/data/localization/jv-JV.json
new file mode 100644
index 0000000..8aa0020
--- /dev/null
+++ b/data/localization/jv-JV.json
@@ -0,0 +1,194 @@
+{
+ "i18n": {
+ "restart": "Baleni meneh",
+ "play": " Dolanan",
+ "pause": " Ngaso",
+ "played": " Diputer",
+ "volume": " Volume",
+ "mute": " Bisu (F9)",
+ "unmute": " Mbusak bisu (F9)",
+ "enterFullscreen": "Ketik layar wutuh",
+ "exitFullscreen": " Metu saka layar wutuh",
+ "settings": " Setelan",
+ "saveState": "Simpen Status (Shift + F2)",
+ "loadState": "Muat Status (Shift + F4)",
+ "screenRecord": " Miwiti Rekaman Layar",
+ "netplay": " Netplay",
+ "gamepad": " Setelan Kontrol",
+ "cheat": " Ngapusi",
+ "menuBack": " Bali menyang menu sadurungé",
+ "normal": " Biasa wae",
+ "all": " Kabeh",
+ "reset": " Reset",
+ "disabled": " Dipatèni",
+ "enabled": " Diaktifake",
+ "playNow": " Play Saiki"
+ },
+ "normalOptions": {
+ "shader": {
+ "label": " Shader",
+ "options": {
+ "disabled": " Dipatèni",
+ "2xScaleHQ.glslp": "2xSkalaHQ",
+ "4xScaleHQ.glslp": "4xSkalaHQ",
+ "crt-easymode.glslp": "CRT mode gampang",
+ "crt-aperture.glslp": " Bukaan CRT",
+ "crt-geom.glslp": " CRT geom"
+ },
+ "default": "disabled"
+ },
+ "virtual-gamepad": {
+ "label": " Virtual Gamepad",
+ "options": {
+ "disabled": " Dipatèni",
+ "enabled": " Diaktifake"
+ },
+ "default": "enabled"
+ }
+ },
+ "Control Settings": " Setelan Kontrol",
+ "Player 1": " Pamuter 1",
+ "Player 2": " Pamuter 2",
+ "Player 3": " Pamuter 3",
+ "Player 4": " Pamuter 4",
+ "Update": " Nganyari",
+ "Reset": " Reset",
+ "Clear": " Cetha",
+ "Cancel": " Batal",
+ "Close": " Nutup",
+ "Empty": "Kosong",
+ "Loading": " Loading",
+ "Submit": " Ngirim",
+ "Description": " Katrangan",
+ "Code": " Kode",
+ "Add Cheat Code": "Tambah Kode Ngapusi",
+ "OK": " OKE",
+ "Add Cheat": " Tambah Ngapusi",
+ "Cache Manager": " Pangurus Cache",
+ "Press keyboard or gamepad": "Pencet keyboard utawa gamepad",
+ "Gamepad": " Gamepad",
+ "Keyboard": " Papan ketik",
+ "Set": " Setel",
+ "QUICK SAVE STATE": " CEPAT SIMPEN NEGARA",
+ "QUICK LOAD STATE": " NEGARA MUNGKIN CEPAT",
+ "CHANGE STATE SLOT": "GANTENG STATE SLOT",
+ "INSERT COIN": " INSERT COIN",
+ "Press escape (esc) to clear": "Pencet escape (esc) kanggo mbusak",
+ "Netplay": " Netplay",
+ "Rooms": " Kamar",
+ "Players": " Pamuter",
+ "Player": " Pamuter",
+ "Room Name": " Jeneng Kamar",
+ "Password": " Sandi",
+ "Name": " Jeneng",
+ "Quit Room": " Metu Kamar",
+ "Create a Room": " Gawe Kamar",
+ "Set Player Name": " Setel Jeneng Pamuter",
+ "Player Name": " Jeneng Pamuter",
+ "Password (optional)": " Sandi (opsional)",
+ "Select": " Pilih",
+ "Start": " Miwiti",
+ "Menu": " Menu",
+ "Decompress Game Core": "Decompress Game Core",
+ "Decompress Game Data": "Decompress Game Data",
+ "Decompress Game Patch": " Dekompres Game Patch",
+ "Download Game Data": "Download Game Data",
+ "Download Game Core": " Unduh Game Core",
+ "Network Error": " Kesalahan Jaringan",
+ "Default": " Default",
+ "default": " gawan",
+ "Save State Location": "Simpen Lokasi Negara",
+ "Save State Slot": " Simpen Slot Negara",
+ "Color Palette": " Palet Warna",
+ "No Sprite Limit": " Ora ana watesan Sprite",
+ "Enabled": " Diaktifake",
+ "Disabled": " Dipatèni",
+ "enabled": " diaktifake",
+ "disabled": " dipatèni",
+ "Low": " Sedheng",
+ "High": " Dhuwur",
+ "Very High": " Dhuwur Banget",
+ "4 Players Support": "4 Dhukungan Pemain",
+ "Turbo Enable": " Turbo Aktifake",
+ "None": " Ora ana",
+ "Both": " Loro-lorone",
+ "Region": " Wilayah",
+ "SuperFX Overclock": " SuperFX Overclock",
+ "Sound Quality": " Kualitas Swara",
+ "GB Colorization": "Warna GB",
+ "auto": " otomatis",
+ "internal": " internal",
+ "Internal Palette": " Palet Internal",
+ "GBC - Blue": " GBC Biru",
+ "GBC - Brown": " GBC Coklat",
+ "GBC - Dark Blue": "GBC Biru Tua",
+ "GBC - Dark Brown": "GBC Coklat Tua",
+ "GBC - Dark Green": " GBC Ijo peteng",
+ "GBC - Grayscale": "GBC Grayscale",
+ "GBC - Green": " GBC Green",
+ "GBC - Inverted": "GBC Walik",
+ "GBC - Orange": " GBC Oranye",
+ "GBC - Red": " GBC Abang",
+ "GBC - Pastel Mix": "GBC Pastel Mix",
+ "GBC - Yellow": " GBC Kuning",
+ "Frameskip": " Frameskip",
+ "Solar sensor level": " Tingkat sensor surya",
+ "Enable Turbo Buttons": "Aktifake Tombol Turbo",
+ "Turbo Delay in frames": "Tundha Turbo ing pigura",
+ "Auto": " Otomatis",
+ "Aspect Ratio (Need to refresh page)": "Rasio Aspek (Perlu refresh kaca)",
+ "16:9 Resolution": " 16:9 Résolusi",
+ "4:3 Resolution": "4:3 Résolusi",
+ "Player 1 Pak": "Pemain 1 Pak",
+ "Player 2 Pak": " Pamuter 2 Pak",
+ "Player 3 Pak": "Pemain 3 Pak",
+ "Player 4 Pak": " Pamuter 4 Pak",
+ "none": " ora ana",
+ "memory": " memori",
+ "rumble": " gumujeng",
+ "Screen layout": " Tata letak layar",
+ "right/left": " tengen / kiwa",
+ "left/right": " kiwa/tengen",
+ "bottom/top": " ngisor / ndhuwur",
+ "top/bottom": " ndhuwur / ngisor",
+ "top only": " mung ndhuwur",
+ "bottom only": " mung ngisor",
+ "quick switch": " ngalih cepet",
+ "hybrid/bottom": " hibrida / ngisor",
+ "hybrid/top": " hibrida / ndhuwur",
+ "Screen Rotation": " Rotasi Layar",
+ "CPU speed": " Kacepetan CPU",
+ "Sound output": " Output swara",
+ "mono": " mono",
+ "stereo": " stereo",
+ "OFF": " MATI",
+ "ON": " ON",
+ "Fast Blitter": " Cepet Blitter",
+ "Bios": " Bios",
+ "Enable second memory card": "Aktifake kertu memori kapindho",
+ "Pad 1 Type": "Pad 1 Tipe",
+ "Pad 2 Type": " Tipe Pad 2",
+ "Pad 3 Type": " Tipe Pad 3",
+ "Pad 4 Type": "Pad 4 Tipe",
+ "standard": " standar",
+ "analog": " analog",
+ "negcon": "negkon",
+ "Enable Vibration": " Aktifake Geter",
+ "Enable interlacing mode(s)": "Aktifake mode interlacing",
+ "Enhanced resolution (slow)": "Resolusi sing ditingkatake (alon)",
+ "Enhanced resolution speed hack": "Retas kacepetan résolusi sing ditingkatake",
+ "Aspect ratio": " Rasio aspek",
+ "CPU overclock": " CPU overclock",
+ "Force Neo Geo mode": " Mode Force Neo Geo",
+ "Diagnostic Input": " Input Diagnostik",
+ "download": "undhuh",
+ "keep in browser": " tetep ing browser",
+ "Webassembly support is not detected in this browser": "Dhukungan webassembly ora dideteksi ing browser iki",
+ "Please upgrade your browser to the latest version": "Mangga upgrade browser sampeyan menyang versi paling anyar",
+ "Missing mame config": "Konfigurasi mame ilang",
+ "Stop Screen Recording": " Mungkasi Rekaman Layar",
+ "Start Screen Recording": " Miwiti Rekaman Layar",
+ "Take Screenshot": " Njupuk Screenshot",
+ "Quick Save": " Cepet Simpen",
+ "Quick Load": " Muatan Cepet"
+}
\ No newline at end of file
diff --git a/data/localization/ko-KO.json b/data/localization/ko-KO.json
new file mode 100644
index 0000000..9d5cb38
--- /dev/null
+++ b/data/localization/ko-KO.json
@@ -0,0 +1,194 @@
+{
+ "i18n": {
+ "restart": "재시작",
+ "play": "플레이",
+ "pause": "일시 중지",
+ "played": "플레이",
+ "volume": "볼륨",
+ "mute": "음소거(F9)",
+ "unmute": "음소거 해제(F9)",
+ "enterFullscreen": "전체 화면으로 전환",
+ "exitFullscreen": "전체 화면 종료",
+ "settings": "설정",
+ "saveState": "상태 저장(Shift + F2)",
+ "loadState": "로드 상태(Shift + F4)",
+ "screenRecord": "화면 녹화 시작",
+ "netplay": "넷플레이",
+ "gamepad": "제어 설정",
+ "cheat": "치트",
+ "menuBack": "이전 메뉴로 돌아가기",
+ "normal": "일반",
+ "all": "모두",
+ "reset": "리셋",
+ "disabled": "장애인",
+ "enabled": "활성화됨",
+ "playNow": "지금 플레이"
+ },
+ "normalOptions": {
+ "shader": {
+ "label": "쉐이더",
+ "options": {
+ "disabled": "장애인",
+ "2xScaleHQ.glslp": "2xScaleHQ",
+ "4xScaleHQ.glslp": "4xScaleHQ",
+ "crt-easymode.glslp": "CRT 이지모드",
+ "crt-aperture.glslp": "CRT 조리개",
+ "crt-geom.glslp": "CRT 지오메트리"
+ },
+ "default": "disabled"
+ },
+ "virtual-gamepad": {
+ "label": "가상 게임패드",
+ "options": {
+ "disabled": "장애인",
+ "enabled": "활성화됨"
+ },
+ "default": "enabled"
+ }
+ },
+ "Control Settings": "제어 설정",
+ "Player 1": "플레이어 1",
+ "Player 2": "플레이어 2",
+ "Player 3": "플레이어 3",
+ "Player 4": "플레이어 4",
+ "Update": "업데이트",
+ "Reset": "리셋",
+ "Clear": "클리어",
+ "Cancel": "취소",
+ "Close": "닫기",
+ "Empty": "비어 있음",
+ "Loading": "로드 중",
+ "Submit": "제출",
+ "Description": "설명",
+ "Code": "코드",
+ "Add Cheat Code": "치트 코드 추가",
+ "OK": "알았어",
+ "Add Cheat": "치트 추가",
+ "Cache Manager": "캐시 관리자",
+ "Press keyboard or gamepad": "키보드 또는 게임패드 누르기",
+ "Gamepad": "게임패드",
+ "Keyboard": "키보드",
+ "Set": "세트",
+ "QUICK SAVE STATE": "빠른 저장 상태",
+ "QUICK LOAD STATE": "빠른 로드 상태",
+ "CHANGE STATE SLOT": "상태 슬롯 변경",
+ "INSERT COIN": "코인 삽입",
+ "Press escape (esc) to clear": "이스케이프(esc)를 눌러 지우십시오.",
+ "Netplay": "넷플레이",
+ "Rooms": "객실",
+ "Players": "선수",
+ "Player": "플레이어",
+ "Room Name": "방 이름",
+ "Password": "비밀번호",
+ "Name": "이름",
+ "Quit Room": "퇴장실",
+ "Create a Room": "방 만들기",
+ "Set Player Name": "플레이어 이름 설정",
+ "Player Name": "플레이어 이름",
+ "Password (optional)": "비밀번호(선택사항)",
+ "Select": "선택",
+ "Start": "시작",
+ "Menu": "메뉴",
+ "Decompress Game Core": "게임 코어 압축 풀기",
+ "Decompress Game Data": "게임 데이터 압축 풀기",
+ "Decompress Game Patch": "게임 패치 압축 풀기",
+ "Download Game Data": "게임 데이터 다운로드",
+ "Download Game Core": "게임 코어 다운로드",
+ "Network Error": "네트워크 오류",
+ "Default": "기본값",
+ "default": "기본값",
+ "Save State Location": "상태 위치 저장",
+ "Save State Slot": "상태 슬롯 저장",
+ "Color Palette": "컬러 팔레트",
+ "No Sprite Limit": "스프라이트 제한 없음",
+ "Enabled": "활성화됨",
+ "Disabled": "장애인",
+ "enabled": "활성화",
+ "disabled": "장애인",
+ "Low": "낮음",
+ "High": "높음",
+ "Very High": "매우 높음",
+ "4 Players Support": "4인 지원",
+ "Turbo Enable": "터보 활성화",
+ "None": "없음",
+ "Both": "둘다",
+ "Region": "지역",
+ "SuperFX Overclock": "SuperFX 오버클럭",
+ "Sound Quality": "음질",
+ "GB Colorization": "GB 채색",
+ "auto": "자동",
+ "internal": "내부",
+ "Internal Palette": "내부 팔레트",
+ "GBC - Blue": "GBC 블루",
+ "GBC - Brown": "GBC 브라운",
+ "GBC - Dark Blue": "GBC 다크 블루",
+ "GBC - Dark Brown": "GBC 다크 브라운",
+ "GBC - Dark Green": "GBC 다크 그린",
+ "GBC - Grayscale": "GBC 그레이스케일",
+ "GBC - Green": "GBC 그린",
+ "GBC - Inverted": "GBC 반전",
+ "GBC - Orange": "GBC 오렌지",
+ "GBC - Red": "GBC 레드",
+ "GBC - Pastel Mix": "GBC 파스텔 믹스",
+ "GBC - Yellow": "GBC 옐로우",
+ "Frameskip": "프레임스킵",
+ "Solar sensor level": "태양광 센서 레벨",
+ "Enable Turbo Buttons": "터보 버튼 활성화",
+ "Turbo Delay in frames": "프레임의 터보 지연",
+ "Auto": "자동",
+ "Aspect Ratio (Need to refresh page)": "종횡비(페이지 새로고침 필요)",
+ "16:9 Resolution": "16:9 해상도",
+ "4:3 Resolution": "4:3 해상도",
+ "Player 1 Pak": "플레이어 1 박",
+ "Player 2 Pak": "플레이어 2 박",
+ "Player 3 Pak": "플레이어 3 박",
+ "Player 4 Pak": "플레이어 4 박",
+ "none": "없음",
+ "memory": "기억",
+ "rumble": "럼블",
+ "Screen layout": "화면 레이아웃",
+ "right/left": "오른쪽/왼쪽",
+ "left/right": "왼쪽/오른쪽",
+ "bottom/top": "하단/상단",
+ "top/bottom": "위/아래",
+ "top only": "상단만",
+ "bottom only": "하단만",
+ "quick switch": "빠른 전환",
+ "hybrid/bottom": "하이브리드/하단",
+ "hybrid/top": "하이브리드/탑",
+ "Screen Rotation": "화면 회전",
+ "CPU speed": "CPU 속도",
+ "Sound output": "음향 출력",
+ "mono": "모노",
+ "stereo": "스테레오",
+ "OFF": "꺼짐",
+ "ON": "켜기",
+ "Fast Blitter": "빠른 블리터",
+ "Bios": "바이오스",
+ "Enable second memory card": "두 번째 메모리 카드 활성화",
+ "Pad 1 Type": "패드 1종",
+ "Pad 2 Type": "패드 2형",
+ "Pad 3 Type": "패드 3종",
+ "Pad 4 Type": "패드 4종",
+ "standard": "표준",
+ "analog": "아날로그",
+ "negcon": "네그콘",
+ "Enable Vibration": "진동 활성화",
+ "Enable interlacing mode(s)": "인터레이스 모드 활성화",
+ "Enhanced resolution (slow)": "향상된 해상도(느림)",
+ "Enhanced resolution speed hack": "향상된 해상도 속도 해킹",
+ "Aspect ratio": "종횡비",
+ "CPU overclock": "CPU 오버클럭",
+ "Force Neo Geo mode": "포스 네오지오 모드",
+ "Diagnostic Input": "진단 입력",
+ "download": "다운로드",
+ "keep in browser": "브라우저에 보관",
+ "Webassembly support is not detected in this browser": "이 브라우저에서는 웹어셈블리 지원이 감지되지 않습니다.",
+ "Please upgrade your browser to the latest version": "브라우저를 최신 버전으로 업그레이드하십시오.",
+ "Missing mame config": "mame 구성이 누락되었습니다.",
+ "Stop Screen Recording": "화면 녹화 중지",
+ "Start Screen Recording": "화면 녹화 시작",
+ "Take Screenshot": "스크린샷 찍기",
+ "Quick Save": "빠른 저장",
+ "Quick Load": "빠른 로드"
+}
\ No newline at end of file
diff --git a/data/localization/readme.md b/data/localization/readme.md
index 9628f1f..2912277 100644
--- a/data/localization/readme.md
+++ b/data/localization/readme.md
@@ -8,6 +8,15 @@ Supported languages
`es-ES` - Spanish
`el-GR` - Greek
`ja-JA` - Japanese
+`chi-CHI` - Chinese
+`hi-HI` - Hindi
+`ar-AR` - Arabic
+`jv-JV` - Javanese
+`ben-BEN` - Bengali
+`ru-RU` - Russian
+`de-GER` - German
+`ko-KO` - Korean
+`af-FR` - French
default: `en-US`
@@ -26,10 +35,12 @@ If the language file is not found or there was an error fetching the file, the e
translated for `pt-BR` by [@cesarcristianodeoliveira](https://github.com/cesarcristianodeoliveira)
translated for `es-ES` by [@cesarcristianodeoliveira](https://github.com/cesarcristianodeoliveira)
translated for `el-GR` by [@imneckro](https://github.com/imneckro)
-translated for `ja-JA` by [@allancoding](https://github.com/allancoding)
+translated for `ja-JA`, `chi-CHI`, `hi-HI`, `ar-AR`, `jv-JV`, `ben-BEN`, `ru-RU`, `de-GER`, `ko-KO`, `af-FR` by [@allancoding](https://github.com/allancoding)
## contributing
download the default `en.json` file and simply translate all the words that start with the `-` (remove the dash afterwards) then perform a pull request or open an issue with the file uploaded and I will add your work
Please contribute!!
+
+Enything that is incorrect or needs to be fix please perform a pull request!
\ No newline at end of file
diff --git a/data/localization/ru-RU.json b/data/localization/ru-RU.json
new file mode 100644
index 0000000..4c0c65a
--- /dev/null
+++ b/data/localization/ru-RU.json
@@ -0,0 +1,194 @@
+{
+ "i18n": {
+ "restart": "Начать сначала",
+ "play": "Играть",
+ "pause": "Пауза",
+ "played": "Играл",
+ "volume": "Громкость",
+ "mute": "Отключить звук (F9)",
+ "unmute": "Включить звук (F9)",
+ "enterFullscreen": "Войти в полноэкранный режим",
+ "exitFullscreen": "Выйти из полноэкранного режима",
+ "settings": "Настройки",
+ "saveState": "Сохранить состояние (Shift + F2)",
+ "loadState": "Загрузить состояние (Shift + F4)",
+ "screenRecord": "Начать запись экрана",
+ "netplay": "Сетевая игра",
+ "gamepad": "Настройки управления",
+ "cheat": "Читы",
+ "menuBack": "Вернуться в предыдущее меню",
+ "normal": "Нормальный",
+ "all": "Все",
+ "reset": "Сбросить",
+ "disabled": "Отключено",
+ "enabled": "Включено",
+ "playNow": "Играть сейчас"
+ },
+ "normalOptions": {
+ "shader": {
+ "label": "Шейдер",
+ "options": {
+ "disabled": "Отключено",
+ "2xScaleHQ.glslp": "2xScaleHQ",
+ "4xScaleHQ.glslp": "4xScaleHQ",
+ "crt-easymode.glslp": "ЭЛТ простой режим",
+ "crt-aperture.glslp": "ЭЛТ-диафрагма",
+ "crt-geom.glslp": "ЭЛТ геометрия"
+ },
+ "default": "disabled"
+ },
+ "virtual-gamepad": {
+ "label": "Виртуальный геймпад",
+ "options": {
+ "disabled": "Отключено",
+ "enabled": "Включено"
+ },
+ "default": "enabled"
+ }
+ },
+ "Control Settings": "Настройки управления",
+ "Player 1": "Игрок 1",
+ "Player 2": "Игрок 2",
+ "Player 3": "Игрок 3",
+ "Player 4": "Игрок 4",
+ "Update": "Обновить",
+ "Reset": "Сбросить",
+ "Clear": "Очистить",
+ "Cancel": "Отменить",
+ "Close": "Закрыть",
+ "Empty": "Пустой",
+ "Loading": "Загрузка",
+ "Submit": "Отправить",
+ "Description": "Описание",
+ "Code": "Код",
+ "Add Cheat Code": "Добавить чит-код",
+ "OK": "ОК",
+ "Add Cheat": "Добавить чит",
+ "Cache Manager": "Менеджер кеша",
+ "Press keyboard or gamepad": "Нажмите клавиатуру или геймпад",
+ "Gamepad": "Геймпад",
+ "Keyboard": "Клавиатура",
+ "Set": "Установить",
+ "QUICK SAVE STATE": "БЫСТРОЕ СОХРАНЕНИЕ",
+ "QUICK LOAD STATE": "СОСТОЯНИЕ БЫСТРОЙ ЗАГРУЗКИ",
+ "CHANGE STATE SLOT": "ИЗМЕНИТЬ СОСТОЯНИЕ СЛОТА",
+ "INSERT COIN": "ВСТАВЬТЕ МОНЕТУ",
+ "Press escape (esc) to clear": "Нажмите escape (esc)",
+ "Netplay": " чтобы очистить",
+ "Rooms": "Сетевая игра",
+ "Players": "Комнаты",
+ "Player": "Игроки",
+ "Room Name": "Игрок",
+ "Password": "Название комнаты",
+ "Name": "Пароль",
+ "Quit Room": "Имя",
+ "Create a Room": "Выйти из комнаты",
+ "Set Player Name": "Создать комнату",
+ "Player Name": "Установить имя игрока",
+ "Password (optional)": "Имя игрока",
+ "Select": "Пароль (необязательно)",
+ "Start": "Выбрать",
+ "Menu": "Старт",
+ "Decompress Game Core": "Меню",
+ "Decompress Game Data": "Распаковать игровое ядро",
+ "Decompress Game Patch": "Распаковать игровые данные",
+ "Download Game Data": " Распаковать игровой патч",
+ "Download Game Core": "Загрузить игровые данные",
+ "Network Error": "Загрузить игровое ядро",
+ "Default": "Сетевая ошибка",
+ "default": "По умолчанию",
+ "Save State Location": "по умолчанию",
+ "Save State Slot": "Сохранить местоположение состояния",
+ "Color Palette": "Сохранить ячейку состояния",
+ "No Sprite Limit": "Цветовая палитра",
+ "Enabled": "Без ограничений по спрайтам",
+ "Disabled": "Включено",
+ "enabled": "Отключено",
+ "disabled": "включено",
+ "Low": "отключено",
+ "High": "Низкий",
+ "Very High": "Высокий",
+ "4 Players Support": "Очень высокий",
+ "Turbo Enable": "Поддержка 4 игроков",
+ "None": "Турбо включить",
+ "Both": "Нет",
+ "Region": "Оба",
+ "SuperFX Overclock": "Регион",
+ "Sound Quality": "Разгон SuperFX",
+ "GB Colorization": "Качество звука",
+ "auto": "GB раскрашивание",
+ "internal": "авто",
+ "Internal Palette": "внутренний",
+ "GBC - Blue": "Внутренняя палитра",
+ "GBC - Brown": "GBC Синий",
+ "GBC - Dark Blue": "ГБК Браун",
+ "GBC - Dark Brown": "GBC темно-синий",
+ "GBC - Dark Green": "GBC темно-коричневый",
+ "GBC - Grayscale": "GBC темно-зеленый",
+ "GBC - Green": "GBC Оттенки серого",
+ "GBC - Inverted": "GBC Зеленый",
+ "GBC - Orange": "GBC перевернутый",
+ "GBC - Red": "GBC Оранжевый",
+ "GBC - Pastel Mix": "GBC Красный",
+ "GBC - Yellow": "Пастельный микс GBC",
+ "Frameskip": "GBC Желтый",
+ "Solar sensor level": "Пропуск кадров",
+ "Enable Turbo Buttons": "Уровень солнечного датчика",
+ "Turbo Delay in frames": "Включить турбо-кнопки",
+ "Auto": " Турбо-задержка в кадрах",
+ "Aspect Ratio (Need to refresh page)": "Авто",
+ "16:9 Resolution": "Соотношение сторон (необходимо обновить страницу)",
+ "4:3 Resolution": "Разрешение 16:9",
+ "Player 1 Pak": "Разрешение 4:3",
+ "Player 2 Pak": "Игрок 1 пакет",
+ "Player 3 Pak": "Пакет игроков 2",
+ "Player 4 Pak": "Игрок 3 пакет",
+ "none": "Игрок 4 пакет",
+ "memory": "нет",
+ "rumble": "память",
+ "Screen layout": "гул",
+ "right/left": "Раскладка экрана",
+ "left/right": "право/лево",
+ "bottom/top": "влево/вправо",
+ "top/bottom": "низ/верх",
+ "top only": "сверху/снизу",
+ "bottom only": "только сверху",
+ "quick switch": "только снизу",
+ "hybrid/bottom": "быстрый переключатель",
+ "hybrid/top": "гибрид/низ",
+ "Screen Rotation": "гибрид/топ",
+ "CPU speed": "Поворот экрана",
+ "Sound output": "скорость процессора",
+ "mono": "Вывод звука",
+ "stereo": "моно",
+ "OFF": "стерео",
+ "ON": "ВЫКЛ.",
+ "Fast Blitter": "ВКЛ",
+ "Bios": "Быстрый налет",
+ "Enable second memory card": "биос",
+ "Pad 1 Type": "Включить вторую карту памяти",
+ "Pad 2 Type": "Пэд 1 Тип",
+ "Pad 3 Type": "Пэд 2 Тип",
+ "Pad 4 Type": "Пэд 3 Тип",
+ "standard": "Пэд 4 Тип",
+ "analog": "стандарт",
+ "negcon": "аналоговый",
+ "Enable Vibration": "негкон",
+ "Enable interlacing mode(s)": "Включить вибрацию",
+ "Enhanced resolution (slow)": "Включить режим чересстрочной развертки",
+ "Enhanced resolution speed hack": "Улучшенное разрешение (медленно)",
+ "Aspect ratio": "Хак с увеличенной скоростью разрешения",
+ "CPU overclock": "Соотношение сторон",
+ "Force Neo Geo mode": "Разгон процессора",
+ "Diagnostic Input": "Принудительный режим Neo Geo",
+ "download": "Диагностический ввод",
+ "keep in browser": "скачать",
+ "Webassembly support is not detected in this browser": "держать в браузере",
+ "Please upgrade your browser to the latest version": "Поддержка Webassembly не обнаружена в этом браузере",
+ "Missing mame config": "Пожалуйста",
+ "Stop Screen Recording": " обновите браузер до последней версии",
+ "Start Screen Recording": "Отсутствует конфигурация мамы",
+ "Take Screenshot": "Остановить запись экрана",
+ "Quick Save": "Начать запись экрана",
+ "Quick Load": "Сделать снимок экрана"
+}
\ No newline at end of file
diff --git a/data/minify/.gitignore b/data/minify/.gitignore
new file mode 100644
index 0000000..c2658d7
--- /dev/null
+++ b/data/minify/.gitignore
@@ -0,0 +1 @@
+node_modules/
diff --git a/data/minify/index.js b/data/minify/index.js
index 032de7a..99ce84a 100644
--- a/data/minify/index.js
+++ b/data/minify/index.js
@@ -1,5 +1,6 @@
const UglifyJS = require("uglify-js");
const fs = require('fs');
+const uglifycss = require('uglifycss');
if (!String.prototype.replaceAll) {
String.prototype.replaceAll = function(a, b) {
@@ -14,8 +15,10 @@ function minify(source){
var ast = UglifyJS.parse(source);
return UglifyJS.minify(ast).code;
}
-console.log('minifying')
+console.log('minifying');
+var css = fs.readFileSync('../emu-css.css', 'utf8');
+fs.writeFileSync('../emu-css.min.css', uglifycss.processString(css));
var min = minify(code);
-console.log('done!')
+console.log('done!');
-fs.writeFileSync('../emu-min.js', min);
+fs.writeFileSync('../emulator.min.js', min);
diff --git a/data/minify/package.json b/data/minify/package.json
index fd6cb51..604cfa2 100644
--- a/data/minify/package.json
+++ b/data/minify/package.json
@@ -9,7 +9,7 @@
},
"repository": {
"type": "git",
- "url": "git+https://github.com/ethanaobrien/youtube-downloader.git"
+ "url": "git+https://github.com/ethanaobrien/emulatorjs.git"
},
"author": "Ethan O'Brien",
"bugs": {
@@ -17,6 +17,7 @@
},
"homepage": "https://github.com/ethanaobrien/emulatorjs#readme",
"dependencies": {
- "uglify-js": "^3.15.3"
+ "uglify-js": "^3.15.3",
+ "uglifycss": "0.0.29"
}
}
diff --git a/data/minify/readme.md b/data/minify/readme.md
new file mode 100644
index 0000000..cba896b
--- /dev/null
+++ b/data/minify/readme.md
@@ -0,0 +1,11 @@
+## Minifying
+
+It is recommended to minify the javascript files before putting them on your server for production. This will make the emulator load faster (and use less bandwidth)
+
+to minify, first, if you do not have nodejs, please install it from [here](https://nodejs.org/en/download/)
+
+then, open a terminal window and navigate to the minify directory
+
+then, run `npm i`
+
+then, run `node index.js`
\ No newline at end of file
diff --git a/data/nds-wasm.data b/data/nds-wasm.data
deleted file mode 100644
index 48b07ce..0000000
Binary files a/data/nds-wasm.data and /dev/null differ
diff --git a/data/nes-wasm.data b/data/nes-wasm.data
deleted file mode 100644
index 2b77287..0000000
Binary files a/data/nes-wasm.data and /dev/null differ
diff --git a/data/snes-wasm.data b/data/snes-wasm.data
deleted file mode 100644
index 1bf86e4..0000000
Binary files a/data/snes-wasm.data and /dev/null differ
diff --git a/data/version.json b/data/version.json
index b26097e..3c4d4ed 100644
--- a/data/version.json
+++ b/data/version.json
@@ -1 +1 @@
-{ "current_version": 1.5 }
+{ "current_version": 1.6 }
diff --git a/docs/Contributors.md b/docs/Contributors.md
new file mode 100644
index 0000000..15c2a42
--- /dev/null
+++ b/docs/Contributors.md
@@ -0,0 +1,94 @@
+
+
+
+
+
+# Owner
+
+
+
+
+![Ethan Avatar]
+
+**[![Badge Ethan GitHub]][Ethan GitHub]**
+
+
+
+
+
+
+# Contributors
+
+
+
+
+![Archiver Avatar]
+
+***Documentation Design***
+
+**[![Badge Archiver GitHub]][Archiver GitHub]**
+
+**[![Badge Archiver Marked]][Archiver Marked]**
+
+
+
+
+
+
+![Allan Avatar]
+
+***Various Fixes & Additions***
+
+**[![Badge Allan GitHub]][Allan GitHub]**
+
+**[![Badge Allan Website]][Allan Website]**
+
+
+
+
+
+[![Avatar Nekro]][GitHub Nekro]
+[![Avatar Grey]][GitHub Grey]
+[![Avatar Kyle]][GitHub Kyle]
+
+
+
+
+
+
+[Avatar Nekro]: https://github.com/imneckro.png?size=120
+[GitHub Nekro]: https://github.com/imneckro 'ImNekro - ck-oneman'
+
+[Avatar Grey]: https://github.com/Grey41.png?size=120
+[GitHub Grey]: https://github.com/Grey41 'Grey41 - Grey Hope'
+
+[Avatar Kyle]: https://github.com/cheesykyle.png?size=120
+[GitHub Kyle]: https://github.com/cheesykyle 'CheesyKyle - Kyle Steffel'
+
+
+
+
+[Badge Ethan GitHub]: https://img.shields.io/badge/Ethan_O'_Brien-181717.svg?style=for-the-badge&logo=GitHub&logoColor=white
+
+[Ethan Avatar]: https://avatars.githubusercontent.com/u/77750390?s=80 'Ethan O\'Brien'
+[Ethan GitHub]: https://github.com/ethanaobrien
+
+
+
+
+[Badge Archiver GitHub]: https://img.shields.io/badge/ElectronicsArchiver-181717.svg?style=for-the-badge&logo=GitHub&logoColor=white
+[Badge Archiver Marked]: https://img.shields.io/badge/MarkedDown-49a2d5.svg?style=for-the-badge&logo=GitHub&logoColor=white
+
+[Archiver Avatar]: https://avatars.githubusercontent.com/u/85485984?s=80 'ElectronicsArchiver - トトも'
+[Archiver GitHub]: https://github.com/ElectronicsArchiver
+[Archiver Marked]: https://github.com/MarkedDown
+
+
+
+
+[Badge Allan GitHub]: https://img.shields.io/badge/allancoding-181717.svg?style=for-the-badge&logo=GitHub&logoColor=white
+[Badge Allan Website]: https://img.shields.io/badge/AllanCoding.ga-lightgray.svg?style=for-the-badge&logo=GitHub&logoColor=white
+
+[Allan Avatar]: https://avatars.githubusercontent.com/u/74841470?s=80 'AllanCoding - Allan Niles'
+[Allan GitHub]: https://github.com/allancoding
+[Allan Website]: https://allancoding.ga/