Merge pull request #44 from khaybarkhaybaryayahud/main

some games
This commit is contained in:
sky 2024-01-22 15:38:48 -05:00 committed by GitHub
commit 2a8f032e0f
92 changed files with 495224 additions and 0 deletions

161
ayun/asn1-parser.js Normal file
View File

@ -0,0 +1,161 @@
// Copyright 2018 AJ ONeal. All rights reserved
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
;(function (exports) {
'use strict';
if (!exports.ASN1) { exports.ASN1 = {}; }
if (!exports.Enc) { exports.Enc = {}; }
if (!exports.PEM) { exports.PEM = {}; }
var ASN1 = exports.ASN1;
var Enc = exports.Enc;
var PEM = exports.PEM;
//
// Parser
//
// Although I've only seen 9 max in https certificates themselves,
// but each domain list could have up to 100
ASN1.ELOOPN = 102;
ASN1.ELOOP = "uASN1.js Error: iterated over " + ASN1.ELOOPN + "+ elements (probably a malformed file)";
// I've seen https certificates go 29 deep
ASN1.EDEEPN = 60;
ASN1.EDEEP = "uASN1.js Error: element nested " + ASN1.EDEEPN + "+ layers deep (probably a malformed file)";
// Container Types are Sequence 0x30, Container Array? (0xA0, 0xA1)
// Value Types are Boolean 0x01, Integer 0x02, Null 0x05, Object ID 0x06, String 0x0C, 0x16, 0x13, 0x1e Value Array? (0x82)
// Bit String (0x03) and Octet String (0x04) may be values or containers
// Sometimes Bit String is used as a container (RSA Pub Spki)
ASN1.CTYPES = [ 0x30, 0x31, 0xa0, 0xa1 ];
ASN1.VTYPES = [ 0x01, 0x02, 0x05, 0x06, 0x0c, 0x82 ];
ASN1.parse = function parseAsn1Helper(buf) {
//var ws = ' ';
function parseAsn1(buf, depth, eager) {
if (depth.length >= ASN1.EDEEPN) { throw new Error(ASN1.EDEEP); }
var index = 2; // we know, at minimum, data starts after type (0) and lengthSize (1)
var asn1 = { type: buf[0], lengthSize: 0, length: buf[1] };
var child;
var iters = 0;
var adjust = 0;
var adjustedLen;
// Determine how many bytes the length uses, and what it is
if (0x80 & asn1.length) {
asn1.lengthSize = 0x7f & asn1.length;
// I think that buf->hex->int solves the problem of Endianness... not sure
asn1.length = parseInt(Enc.bufToHex(buf.slice(index, index + asn1.lengthSize)), 16);
index += asn1.lengthSize;
}
// High-order bit Integers have a leading 0x00 to signify that they are positive.
// Bit Streams use the first byte to signify padding, which x.509 doesn't use.
if (0x00 === buf[index] && (0x02 === asn1.type || 0x03 === asn1.type)) {
// However, 0x00 on its own is a valid number
if (asn1.length > 1) {
index += 1;
adjust = -1;
}
}
adjustedLen = asn1.length + adjust;
//console.warn(depth.join(ws) + '0x' + Enc.numToHex(asn1.type), index, 'len:', asn1.length, asn1);
function parseChildren(eager) {
asn1.children = [];
//console.warn('1 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', 0);
while (iters < ASN1.ELOOPN && index < (2 + asn1.length + asn1.lengthSize)) {
iters += 1;
depth.length += 1;
child = parseAsn1(buf.slice(index, index + adjustedLen), depth, eager);
depth.length -= 1;
// The numbers don't match up exactly and I don't remember why...
// probably something with adjustedLen or some such, but the tests pass
index += (2 + child.lengthSize + child.length);
//console.warn('2 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', (2 + child.lengthSize + child.length));
if (index > (2 + asn1.lengthSize + asn1.length)) {
if (!eager) { console.error(JSON.stringify(asn1, ASN1._replacer, 2)); }
throw new Error("Parse error: child value length (" + child.length
+ ") is greater than remaining parent length (" + (asn1.length - index)
+ " = " + asn1.length + " - " + index + ")");
}
asn1.children.push(child);
//console.warn(depth.join(ws) + '0x' + Enc.numToHex(asn1.type), index, 'len:', asn1.length, asn1);
}
if (index !== (2 + asn1.lengthSize + asn1.length)) {
//console.warn('index:', index, 'length:', (2 + asn1.lengthSize + asn1.length));
throw new Error("premature end-of-file");
}
if (iters >= ASN1.ELOOPN) { throw new Error(ASN1.ELOOP); }
delete asn1.value;
return asn1;
}
// Recurse into types that are _always_ containers
if (-1 !== ASN1.CTYPES.indexOf(asn1.type)) { return parseChildren(eager); }
// Return types that are _always_ values
asn1.value = buf.slice(index, index + adjustedLen);
if (-1 !== ASN1.VTYPES.indexOf(asn1.type)) { return asn1; }
// For ambigious / unknown types, recurse and return on failure
// (and return child array size to zero)
try { return parseChildren(true); }
catch(e) { asn1.children.length = 0; return asn1; }
}
var asn1 = parseAsn1(buf, []);
var len = buf.byteLength || buf.length;
if (len !== 2 + asn1.lengthSize + asn1.length) {
throw new Error("Length of buffer does not match length of ASN.1 sequence.");
}
return asn1;
};
ASN1._replacer = function (k, v) {
if ('type' === k) { return '0x' + Enc.numToHex(v); }
if (v && 'value' === k) { return '0x' + Enc.bufToHex(v.data || v); }
return v;
};
// don't replace the full parseBlock, if it exists
PEM.parseBlock = PEM.parseBlock || function (str) {
var der = str.split(/\n/).filter(function (line) {
return !/-----/.test(line);
}).join('');
return { der: Enc.base64ToBuf(der) };
};
Enc.base64ToBuf = function (b64) {
return Enc.binToBuf(atob(b64));
};
Enc.binToBuf = function (bin) {
var arr = bin.split('').map(function (ch) {
return ch.charCodeAt(0);
});
return 'undefined' !== typeof Uint8Array ? new Uint8Array(arr) : arr;
};
Enc.bufToHex = function (u8) {
var hex = [];
var i, h;
var len = (u8.byteLength || u8.length);
for (i = 0; i < len; i += 1) {
h = u8[i].toString(16);
if (h.length % 2) { h = '0' + h; }
hex.push(h);
}
return hex.join('').toLowerCase();
};
Enc.numToHex = function (d) {
d = d.toString(16);
if (d.length % 2) {
return '0' + d;
}
return d;
};
}('undefined' !== typeof window ? window : module.exports));

BIN
ayun/assets.epk Normal file

Binary file not shown.

341449
ayun/classes.js Normal file

File diff suppressed because one or more lines are too long

3
ayun/cover.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.6 KiB

84
ayun/favicon.ico Normal file
View File

@ -0,0 +1,84 @@
<!DOCTYPE html>
<html>
<head>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-261780635-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-261780635-1');
</script>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-TG85STRS');</script>
<!-- End Google Tag Manager -->
<title>Play Minecraft Online! | Online mc</title>
<link rel="icon" href="/icon.png">
<meta name="description" content="Play Minecraft (eaglercraft) Online For Free!" />
<meta name="keywords" content="free minecraft online, eaglercraft, minecraft, onlinemc, Onlinemc, ayuncraft, Ayuncraft, mc, eaglercraftx, eaglercraft shaders, eaglercraft download,eaglercraft, eaglercraftx, minecraft, 1.8, 1.8.8, eaglercraft, eaglercraft minecraft, eaglercraft 3kh0, eaglercraft github, eaglercraft singleplayer, eaglercraft hacks, eaglercraft 1.8, eaglercraft server, eaglecraft game, eaglercraft alternative, eaglercraft alt links, eaglercraft asspixel, eaglercraft anarchy server, eaglercraft aeon, eaglercraft asspixel server ip, eaglercraft all links, eaglercraft aeon server, eaglercraft beta, eaglecraft boats, eaglecraft boats for sale, eaglecraft boats for sale bc, eaglecraft bedwars server, eaglecraft boats inc, eaglercraft beta servers, eaglercraft blocked, eaglercraft client, eaglecraft custom boats, eaglecraft campbell river, eaglercraft creative, eaglercraft commands, eaglercraft code, eaglercraft controls, eaglercraft com, eaglercraft download, eaglercraft discord, eaglercraft dupe glitch, eaglercraft download file, eaglercraft download google drive, eaglercraft dmca, eaglercraft deleted, eaglercraft down, eaglercraft embed, eaglercraft epk file download, eaglercraft end of stream, eaglecraft apk download, eaglecraft eagtek, eaglercraft exploit, eaglecraft eggs, eaglercraft epk world file download, eaglercraft file, eaglercraft file download, eaglercraft free, eaglercraft forums, eaglercraft fork, eaglercraft faq, eaglercraft fps, eaglecraft free download, eaglercraft github servers, eaglercraft google drive, eaglercraft github lax1dude, eaglercraft github download, eaglercraft github.io, eaglercraft google sites, minecraft, applet, singleplayer, replit, html5, chromebook, lax1dude, games, eaglercraft singleplayer, eagler, minecraft for free, free minecraft">
<meta property="og:title" content="Online mc" />
<meta property="og:image" content="/icon.png" />
<meta property="og:description" content="Online Minecraft" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css">
<link href="/style.css" rel="stylesheet" />
<link href="/darkmode.css" rel="stylesheet" />
</head>
<body class="diff-bg">
<div id="loading"></div>
<div class="container container-table">
<div class="row vertical-center-row">
<div class="col-12">
</a>
<div class="d-flex justify-content-center">
</div>
<div class="col-12">
<div class="button-area d-block">
<h1 class="dark-text">404 Not Found!</h1>
<div class="splash-404">...</div>
<h3>&nbsp;</h3>
<a href="/">click here to go back to the main page!</a>
<img class="creeper ms-auto d-block" src="creeper.webp" alt=""/>
</div>
<div class="mc-footer d-flex justify-content-between">
<div class="footer-copyright text-end text-white">This website is not affiliated with Mojang.</div>
<div class="mc-dd">
</div>
</div>
</div>
</div>
</div>
</div>
<script defer src="/_vercel/insights/script.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
<script>
window.onload = function () {
//display loader on page load
$('#loading').fadeOut();
}
setTimeout(function () {
//display loader on page load
$('#loading').fadeOut();
}, 12 * 1000);
</script>
<script src="/darkmode.js"></script>
<script src="/splash-404.js"></script>
</body>
</html>

44
ayun/index.html Normal file
View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<title>ayuncraft</title>
<script type="text/javascript" src="jsbn/jsbn.js"></script>
<script type="text/javascript" src="jsbn/jsbn2.js"></script>
<script type="text/javascript" src="jsbn/base64.js"></script>
<script type="text/javascript" src="jsbn/prng4.js"></script>
<script type="text/javascript" src="jsbn/rng.js"></script>
<script type="text/javascript" src="jsbn/rsa.js"></script>
<script type="text/javascript" src="jsbn/rsa2.js"></script>
<script type="text/javascript" src="asn1-parser.js"></script>
<script type="text/javascript" src="music.js"></script>
<script type="text/javascript" src="classes.js?t=updateme0"></script>
<script type="text/javascript">
//window.eag_self_proxy=true;//set to true to set the default proxy to the current url
//window.eag_proxy_list="";//set to a string of comma-separated proxy ip:port combinations for a custom proxy list
var name="PixelCraft",motd="A public 1.5.2 server",ip="pixelcraft.me";
window.addEventListener("load", function(){
document.requestPointerLock=document.requestPointerLock||function(){};
document.exitPointerLock=document.exitPointerLock||function(){};
window.minecraftOpts = [
"game_frame","assets.epk",
btoa(atob("CgAACQAHc2VydmVycwoAAAABCAAKZm9yY2VkTU9URABtb3RkaGVyZQEAC2hpZGVBZGRyZXNzAQgAAmlwAGlwaGVyZQgABG5hbWUAbmFtZWhlcmUAAA==").replace("motdhere",String.fromCharCode(motd.length)+motd).replace("namehere",String.fromCharCode(name.length)+name).replace("iphere",String.fromCharCode(ip.length)+ip))
];
(function(){
var q = window.location.search;
if(typeof q === 'string' && q.startsWith("?")) {
q = new URLSearchParams(q);
var s = q.get("server");
if(s) window.minecraftOpts.push(s);
}
})();
main();
});
</script>
</head>
<body style="margin:0px;width:100vw;height:100vh;" id="game_frame">
</body>
</html>

71
ayun/jsbn/base64.js Normal file
View File

@ -0,0 +1,71 @@
var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var b64padchar="=";
function hex2b64(h) {
var i;
var c;
var ret = "";
for(i = 0; i+3 <= h.length; i+=3) {
c = parseInt(h.substring(i,i+3),16);
ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
}
if(i+1 == h.length) {
c = parseInt(h.substring(i,i+1),16);
ret += b64map.charAt(c << 2);
}
else if(i+2 == h.length) {
c = parseInt(h.substring(i,i+2),16);
ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
}
while((ret.length & 3) > 0) ret += b64padchar;
return ret;
}
// convert a base64 string to hex
function b64tohex(s) {
var ret = ""
var i;
var k = 0; // b64 state, 0-3
var slop;
for(i = 0; i < s.length; ++i) {
if(s.charAt(i) == b64padchar) break;
v = b64map.indexOf(s.charAt(i));
if(v < 0) continue;
if(k == 0) {
ret += int2char(v >> 2);
slop = v & 3;
k = 1;
}
else if(k == 1) {
ret += int2char((slop << 2) | (v >> 4));
slop = v & 0xf;
k = 2;
}
else if(k == 2) {
ret += int2char(slop);
ret += int2char(v >> 2);
slop = v & 3;
k = 3;
}
else {
ret += int2char((slop << 2) | (v >> 4));
ret += int2char(v & 0xf);
k = 0;
}
}
if(k == 1)
ret += int2char(slop << 2);
return ret;
}
// convert a base64 string to a byte/number array
function b64toBA(s) {
//piggyback on b64tohex for now, optimize later
var h = b64tohex(s);
var i;
var a = new Array();
for(i = 0; 2*i < h.length; ++i) {
a[i] = parseInt(h.substring(2*i,2*i+2),16);
}
return a;
}

559
ayun/jsbn/jsbn.js Normal file
View File

@ -0,0 +1,559 @@
// Copyright (c) 2005 Tom Wu
// All Rights Reserved.
// See "LICENSE" for details.
// Basic JavaScript BN library - subset useful for RSA encryption.
// Bits per digit
var dbits;
// JavaScript engine analysis
var canary = 0xdeadbeefcafe;
var j_lm = ((canary&0xffffff)==0xefcafe);
// (public) Constructor
function BigInteger(a,b,c) {
if(a != null)
if("number" == typeof a) this.fromNumber(a,b,c);
else if(b == null && "string" != typeof a) this.fromString(a,256);
else this.fromString(a,b);
}
// return new, unset BigInteger
function nbi() { return new BigInteger(null); }
// am: Compute w_j += (x*this_i), propagate carries,
// c is initial carry, returns final carry.
// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
// We need to select the fastest one that works in this environment.
// am1: use a single mult and divide to get the high bits,
// max digit bits should be 26 because
// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
function am1(i,x,w,j,c,n) {
while(--n >= 0) {
var v = x*this[i++]+w[j]+c;
c = Math.floor(v/0x4000000);
w[j++] = v&0x3ffffff;
}
return c;
}
// am2 avoids a big mult-and-extract completely.
// Max digit bits should be <= 30 because we do bitwise ops
// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
function am2(i,x,w,j,c,n) {
var xl = x&0x7fff, xh = x>>15;
while(--n >= 0) {
var l = this[i]&0x7fff;
var h = this[i++]>>15;
var m = xh*l+h*xl;
l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
w[j++] = l&0x3fffffff;
}
return c;
}
// Alternately, set max digit bits to 28 since some
// browsers slow down when dealing with 32-bit numbers.
function am3(i,x,w,j,c,n) {
var xl = x&0x3fff, xh = x>>14;
while(--n >= 0) {
var l = this[i]&0x3fff;
var h = this[i++]>>14;
var m = xh*l+h*xl;
l = xl*l+((m&0x3fff)<<14)+w[j]+c;
c = (l>>28)+(m>>14)+xh*h;
w[j++] = l&0xfffffff;
}
return c;
}
if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
BigInteger.prototype.am = am2;
dbits = 30;
}
else if(j_lm && (navigator.appName != "Netscape")) {
BigInteger.prototype.am = am1;
dbits = 26;
}
else { // Mozilla/Netscape seems to prefer am3
BigInteger.prototype.am = am3;
dbits = 28;
}
BigInteger.prototype.DB = dbits;
BigInteger.prototype.DM = ((1<<dbits)-1);
BigInteger.prototype.DV = (1<<dbits);
var BI_FP = 52;
BigInteger.prototype.FV = Math.pow(2,BI_FP);
BigInteger.prototype.F1 = BI_FP-dbits;
BigInteger.prototype.F2 = 2*dbits-BI_FP;
// Digit conversions
var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
var BI_RC = new Array();
var rr,vv;
rr = "0".charCodeAt(0);
for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
rr = "a".charCodeAt(0);
for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
rr = "A".charCodeAt(0);
for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
function int2char(n) { return BI_RM.charAt(n); }
function intAt(s,i) {
var c = BI_RC[s.charCodeAt(i)];
return (c==null)?-1:c;
}
// (protected) copy this to r
function bnpCopyTo(r) {
for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
r.t = this.t;
r.s = this.s;
}
// (protected) set from integer value x, -DV <= x < DV
function bnpFromInt(x) {
this.t = 1;
this.s = (x<0)?-1:0;
if(x > 0) this[0] = x;
else if(x < -1) this[0] = x+this.DV;
else this.t = 0;
}
// return bigint initialized to value
function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
// (protected) set from string and radix
function bnpFromString(s,b) {
var k;
if(b == 16) k = 4;
else if(b == 8) k = 3;
else if(b == 256) k = 8; // byte array
else if(b == 2) k = 1;
else if(b == 32) k = 5;
else if(b == 4) k = 2;
else { this.fromRadix(s,b); return; }
this.t = 0;
this.s = 0;
var i = s.length, mi = false, sh = 0;
while(--i >= 0) {
var x = (k==8)?s[i]&0xff:intAt(s,i);
if(x < 0) {
if(s.charAt(i) == "-") mi = true;
continue;
}
mi = false;
if(sh == 0)
this[this.t++] = x;
else if(sh+k > this.DB) {
this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
this[this.t++] = (x>>(this.DB-sh));
}
else
this[this.t-1] |= x<<sh;
sh += k;
if(sh >= this.DB) sh -= this.DB;
}
if(k == 8 && (s[0]&0x80) != 0) {
this.s = -1;
if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
}
this.clamp();
if(mi) BigInteger.ZERO.subTo(this,this);
}
// (protected) clamp off excess high words
function bnpClamp() {
var c = this.s&this.DM;
while(this.t > 0 && this[this.t-1] == c) --this.t;
}
// (public) return string representation in given radix
function bnToString(b) {
if(this.s < 0) return "-"+this.negate().toString(b);
var k;
if(b == 16) k = 4;
else if(b == 8) k = 3;
else if(b == 2) k = 1;
else if(b == 32) k = 5;
else if(b == 4) k = 2;
else return this.toRadix(b);
var km = (1<<k)-1, d, m = false, r = "", i = this.t;
var p = this.DB-(i*this.DB)%k;
if(i-- > 0) {
if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
while(i >= 0) {
if(p < k) {
d = (this[i]&((1<<p)-1))<<(k-p);
d |= this[--i]>>(p+=this.DB-k);
}
else {
d = (this[i]>>(p-=k))&km;
if(p <= 0) { p += this.DB; --i; }
}
if(d > 0) m = true;
if(m) r += int2char(d);
}
}
return m?r:"0";
}
// (public) -this
function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
// (public) |this|
function bnAbs() { return (this.s<0)?this.negate():this; }
// (public) return + if this > a, - if this < a, 0 if equal
function bnCompareTo(a) {
var r = this.s-a.s;
if(r != 0) return r;
var i = this.t;
r = i-a.t;
if(r != 0) return (this.s<0)?-r:r;
while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
return 0;
}
// returns bit length of the integer x
function nbits(x) {
var r = 1, t;
if((t=x>>>16) != 0) { x = t; r += 16; }
if((t=x>>8) != 0) { x = t; r += 8; }
if((t=x>>4) != 0) { x = t; r += 4; }
if((t=x>>2) != 0) { x = t; r += 2; }
if((t=x>>1) != 0) { x = t; r += 1; }
return r;
}
// (public) return the number of bits in "this"
function bnBitLength() {
if(this.t <= 0) return 0;
return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
}
// (protected) r = this << n*DB
function bnpDLShiftTo(n,r) {
var i;
for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
for(i = n-1; i >= 0; --i) r[i] = 0;
r.t = this.t+n;
r.s = this.s;
}
// (protected) r = this >> n*DB
function bnpDRShiftTo(n,r) {
for(var i = n; i < this.t; ++i) r[i-n] = this[i];
r.t = Math.max(this.t-n,0);
r.s = this.s;
}
// (protected) r = this << n
function bnpLShiftTo(n,r) {
var bs = n%this.DB;
var cbs = this.DB-bs;
var bm = (1<<cbs)-1;
var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
for(i = this.t-1; i >= 0; --i) {
r[i+ds+1] = (this[i]>>cbs)|c;
c = (this[i]&bm)<<bs;
}
for(i = ds-1; i >= 0; --i) r[i] = 0;
r[ds] = c;
r.t = this.t+ds+1;
r.s = this.s;
r.clamp();
}
// (protected) r = this >> n
function bnpRShiftTo(n,r) {
r.s = this.s;
var ds = Math.floor(n/this.DB);
if(ds >= this.t) { r.t = 0; return; }
var bs = n%this.DB;
var cbs = this.DB-bs;
var bm = (1<<bs)-1;
r[0] = this[ds]>>bs;
for(var i = ds+1; i < this.t; ++i) {
r[i-ds-1] |= (this[i]&bm)<<cbs;
r[i-ds] = this[i]>>bs;
}
if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
r.t = this.t-ds;
r.clamp();
}
// (protected) r = this - a
function bnpSubTo(a,r) {
var i = 0, c = 0, m = Math.min(a.t,this.t);
while(i < m) {
c += this[i]-a[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
if(a.t < this.t) {
c -= a.s;
while(i < this.t) {
c += this[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
c += this.s;
}
else {
c += this.s;
while(i < a.t) {
c -= a[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
c -= a.s;
}
r.s = (c<0)?-1:0;
if(c < -1) r[i++] = this.DV+c;
else if(c > 0) r[i++] = c;
r.t = i;
r.clamp();
}
// (protected) r = this * a, r != this,a (HAC 14.12)
// "this" should be the larger one if appropriate.
function bnpMultiplyTo(a,r) {
var x = this.abs(), y = a.abs();
var i = x.t;
r.t = i+y.t;
while(--i >= 0) r[i] = 0;
for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
r.s = 0;
r.clamp();
if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
}
// (protected) r = this^2, r != this (HAC 14.16)
function bnpSquareTo(r) {
var x = this.abs();
var i = r.t = 2*x.t;
while(--i >= 0) r[i] = 0;
for(i = 0; i < x.t-1; ++i) {
var c = x.am(i,x[i],r,2*i,0,1);
if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
r[i+x.t] -= x.DV;
r[i+x.t+1] = 1;
}
}
if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
r.s = 0;
r.clamp();
}
// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
// r != q, this != m. q or r may be null.
function bnpDivRemTo(m,q,r) {
var pm = m.abs();
if(pm.t <= 0) return;
var pt = this.abs();
if(pt.t < pm.t) {
if(q != null) q.fromInt(0);
if(r != null) this.copyTo(r);
return;
}
if(r == null) r = nbi();
var y = nbi(), ts = this.s, ms = m.s;
var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus
if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
else { pm.copyTo(y); pt.copyTo(r); }
var ys = y.t;
var y0 = y[ys-1];
if(y0 == 0) return;
var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
var i = r.t, j = i-ys, t = (q==null)?nbi():q;
y.dlShiftTo(j,t);
if(r.compareTo(t) >= 0) {
r[r.t++] = 1;
r.subTo(t,r);
}
BigInteger.ONE.dlShiftTo(ys,t);
t.subTo(y,y); // "negative" y so we can replace sub with am later
while(y.t < ys) y[y.t++] = 0;
while(--j >= 0) {
// Estimate quotient digit
var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out
y.dlShiftTo(j,t);
r.subTo(t,r);
while(r[i] < --qd) r.subTo(t,r);
}
}
if(q != null) {
r.drShiftTo(ys,q);
if(ts != ms) BigInteger.ZERO.subTo(q,q);
}
r.t = ys;
r.clamp();
if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder
if(ts < 0) BigInteger.ZERO.subTo(r,r);
}
// (public) this mod a
function bnMod(a) {
var r = nbi();
this.abs().divRemTo(a,null,r);
if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
return r;
}
// Modular reduction using "classic" algorithm
function Classic(m) { this.m = m; }
function cConvert(x) {
if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
else return x;
}
function cRevert(x) { return x; }
function cReduce(x) { x.divRemTo(this.m,null,x); }
function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
Classic.prototype.convert = cConvert;
Classic.prototype.revert = cRevert;
Classic.prototype.reduce = cReduce;
Classic.prototype.mulTo = cMulTo;
Classic.prototype.sqrTo = cSqrTo;
// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
// justification:
// xy == 1 (mod m)
// xy = 1+km
// xy(2-xy) = (1+km)(1-km)
// x[y(2-xy)] = 1-k^2m^2
// x[y(2-xy)] == 1 (mod m^2)
// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
// JS multiply "overflows" differently from C/C++, so care is needed here.
function bnpInvDigit() {
if(this.t < 1) return 0;
var x = this[0];
if((x&1) == 0) return 0;
var y = x&3; // y == 1/x mod 2^2
y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4
y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8
y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
// last step - calculate inverse mod DV directly;
// assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits
// we really want the negative inverse, and -DV < y < DV
return (y>0)?this.DV-y:-y;
}
// Montgomery reduction
function Montgomery(m) {
this.m = m;
this.mp = m.invDigit();
this.mpl = this.mp&0x7fff;
this.mph = this.mp>>15;
this.um = (1<<(m.DB-15))-1;
this.mt2 = 2*m.t;
}
// xR mod m
function montConvert(x) {
var r = nbi();
x.abs().dlShiftTo(this.m.t,r);
r.divRemTo(this.m,null,r);
if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
return r;
}
// x/R mod m
function montRevert(x) {
var r = nbi();
x.copyTo(r);
this.reduce(r);
return r;
}
// x = x/R mod m (HAC 14.32)
function montReduce(x) {
while(x.t <= this.mt2) // pad x so am has enough room later
x[x.t++] = 0;
for(var i = 0; i < this.m.t; ++i) {
// faster way of calculating u0 = x[i]*mp mod DV
var j = x[i]&0x7fff;
var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
// use am to combine the multiply-shift-add into one call
j = i+this.m.t;
x[j] += this.m.am(0,u0,x,i,0,this.m.t);
// propagate carry
while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
}
x.clamp();
x.drShiftTo(this.m.t,x);
if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
}
// r = "x^2/R mod m"; x != r
function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
// r = "xy/R mod m"; x,y != r
function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
Montgomery.prototype.convert = montConvert;
Montgomery.prototype.revert = montRevert;
Montgomery.prototype.reduce = montReduce;
Montgomery.prototype.mulTo = montMulTo;
Montgomery.prototype.sqrTo = montSqrTo;
// (protected) true iff this is even
function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
function bnpExp(e,z) {
if(e > 0xffffffff || e < 1) return BigInteger.ONE;
var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
g.copyTo(r);
while(--i >= 0) {
z.sqrTo(r,r2);
if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
else { var t = r; r = r2; r2 = t; }
}
return z.revert(r);
}
// (public) this^e % m, 0 <= e < 2^32
function bnModPowInt(e,m) {
var z;
if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
return this.exp(e,z);
}
// protected
BigInteger.prototype.copyTo = bnpCopyTo;
BigInteger.prototype.fromInt = bnpFromInt;
BigInteger.prototype.fromString = bnpFromString;
BigInteger.prototype.clamp = bnpClamp;
BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
BigInteger.prototype.drShiftTo = bnpDRShiftTo;
BigInteger.prototype.lShiftTo = bnpLShiftTo;
BigInteger.prototype.rShiftTo = bnpRShiftTo;
BigInteger.prototype.subTo = bnpSubTo;
BigInteger.prototype.multiplyTo = bnpMultiplyTo;
BigInteger.prototype.squareTo = bnpSquareTo;
BigInteger.prototype.divRemTo = bnpDivRemTo;
BigInteger.prototype.invDigit = bnpInvDigit;
BigInteger.prototype.isEven = bnpIsEven;
BigInteger.prototype.exp = bnpExp;
// public
BigInteger.prototype.toString = bnToString;
BigInteger.prototype.negate = bnNegate;
BigInteger.prototype.abs = bnAbs;
BigInteger.prototype.compareTo = bnCompareTo;
BigInteger.prototype.bitLength = bnBitLength;
BigInteger.prototype.mod = bnMod;
BigInteger.prototype.modPowInt = bnModPowInt;
// "constants"
BigInteger.ZERO = nbv(0);
BigInteger.ONE = nbv(1);

656
ayun/jsbn/jsbn2.js Normal file
View File

@ -0,0 +1,656 @@
// Copyright (c) 2005-2009 Tom Wu
// All Rights Reserved.
// See "LICENSE" for details.
// Extended JavaScript BN functions, required for RSA private ops.
// Version 1.1: new BigInteger("0", 10) returns "proper" zero
// Version 1.2: square() API, isProbablePrime fix
// (public)
function bnClone() { var r = nbi(); this.copyTo(r); return r; }
// (public) return value as integer
function bnIntValue() {
if(this.s < 0) {
if(this.t == 1) return this[0]-this.DV;
else if(this.t == 0) return -1;
}
else if(this.t == 1) return this[0];
else if(this.t == 0) return 0;
// assumes 16 < DB < 32
return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];
}
// (public) return value as byte
function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }
// (public) return value as short (assumes DB>=16)
function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }
// (protected) return x s.t. r^x < DV
function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
// (public) 0 if this == 0, 1 if this > 0
function bnSigNum() {
if(this.s < 0) return -1;
else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
else return 1;
}
// (protected) convert to radix string
function bnpToRadix(b) {
if(b == null) b = 10;
if(this.signum() == 0 || b < 2 || b > 36) return "0";
var cs = this.chunkSize(b);
var a = Math.pow(b,cs);
var d = nbv(a), y = nbi(), z = nbi(), r = "";
this.divRemTo(d,y,z);
while(y.signum() > 0) {
r = (a+z.intValue()).toString(b).substr(1) + r;
y.divRemTo(d,y,z);
}
return z.intValue().toString(b) + r;
}
// (protected) convert from radix string
function bnpFromRadix(s,b) {
this.fromInt(0);
if(b == null) b = 10;
var cs = this.chunkSize(b);
var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
for(var i = 0; i < s.length; ++i) {
var x = intAt(s,i);
if(x < 0) {
if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
continue;
}
w = b*w+x;
if(++j >= cs) {
this.dMultiply(d);
this.dAddOffset(w,0);
j = 0;
w = 0;
}
}
if(j > 0) {
this.dMultiply(Math.pow(b,j));
this.dAddOffset(w,0);
}
if(mi) BigInteger.ZERO.subTo(this,this);
}
// (protected) alternate constructor
function bnpFromNumber(a,b,c) {
if("number" == typeof b) {
// new BigInteger(int,int,RNG)
if(a < 2) this.fromInt(1);
else {
this.fromNumber(a,c);
if(!this.testBit(a-1)) // force MSB set
this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
if(this.isEven()) this.dAddOffset(1,0); // force odd
while(!this.isProbablePrime(b)) {
this.dAddOffset(2,0);
if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);
}
}
}
else {
// new BigInteger(int,RNG)
var x = new Array(), t = a&7;
x.length = (a>>3)+1;
b.nextBytes(x);
if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
this.fromString(x,256);
}
}
// (public) convert to bigendian byte array
function bnToByteArray() {
var i = this.t, r = new Array();
r[0] = this.s;
var p = this.DB-(i*this.DB)%8, d, k = 0;
if(i-- > 0) {
if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)
r[k++] = d|(this.s<<(this.DB-p));
while(i >= 0) {
if(p < 8) {
d = (this[i]&((1<<p)-1))<<(8-p);
d |= this[--i]>>(p+=this.DB-8);
}
else {
d = (this[i]>>(p-=8))&0xff;
if(p <= 0) { p += this.DB; --i; }
}
if((d&0x80) != 0) d |= -256;
if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
if(k > 0 || d != this.s) r[k++] = d;
}
}
return r;
}
function bnEquals(a) { return(this.compareTo(a)==0); }
function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
// (protected) r = this op a (bitwise)
function bnpBitwiseTo(a,op,r) {
var i, f, m = Math.min(a.t,this.t);
for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);
if(a.t < this.t) {
f = a.s&this.DM;
for(i = m; i < this.t; ++i) r[i] = op(this[i],f);
r.t = this.t;
}
else {
f = this.s&this.DM;
for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);
r.t = a.t;
}
r.s = op(this.s,a.s);
r.clamp();
}
// (public) this & a
function op_and(x,y) { return x&y; }
function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
// (public) this | a
function op_or(x,y) { return x|y; }
function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
// (public) this ^ a
function op_xor(x,y) { return x^y; }
function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
// (public) this & ~a
function op_andnot(x,y) { return x&~y; }
function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
// (public) ~this
function bnNot() {
var r = nbi();
for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];
r.t = this.t;
r.s = ~this.s;
return r;
}
// (public) this << n
function bnShiftLeft(n) {
var r = nbi();
if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
return r;
}
// (public) this >> n
function bnShiftRight(n) {
var r = nbi();
if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
return r;
}
// return index of lowest 1-bit in x, x < 2^31
function lbit(x) {
if(x == 0) return -1;
var r = 0;
if((x&0xffff) == 0) { x >>= 16; r += 16; }
if((x&0xff) == 0) { x >>= 8; r += 8; }
if((x&0xf) == 0) { x >>= 4; r += 4; }
if((x&3) == 0) { x >>= 2; r += 2; }
if((x&1) == 0) ++r;
return r;
}
// (public) returns index of lowest 1-bit (or -1 if none)
function bnGetLowestSetBit() {
for(var i = 0; i < this.t; ++i)
if(this[i] != 0) return i*this.DB+lbit(this[i]);
if(this.s < 0) return this.t*this.DB;
return -1;
}
// return number of 1 bits in x
function cbit(x) {
var r = 0;
while(x != 0) { x &= x-1; ++r; }
return r;
}
// (public) return number of set bits
function bnBitCount() {
var r = 0, x = this.s&this.DM;
for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);
return r;
}
// (public) true iff nth bit is set
function bnTestBit(n) {
var j = Math.floor(n/this.DB);
if(j >= this.t) return(this.s!=0);
return((this[j]&(1<<(n%this.DB)))!=0);
}
// (protected) this op (1<<n)
function bnpChangeBit(n,op) {
var r = BigInteger.ONE.shiftLeft(n);
this.bitwiseTo(r,op,r);
return r;
}
// (public) this | (1<<n)
function bnSetBit(n) { return this.changeBit(n,op_or); }
// (public) this & ~(1<<n)
function bnClearBit(n) { return this.changeBit(n,op_andnot); }
// (public) this ^ (1<<n)
function bnFlipBit(n) { return this.changeBit(n,op_xor); }
// (protected) r = this + a
function bnpAddTo(a,r) {
var i = 0, c = 0, m = Math.min(a.t,this.t);
while(i < m) {
c += this[i]+a[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
if(a.t < this.t) {
c += a.s;
while(i < this.t) {
c += this[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
c += this.s;
}
else {
c += this.s;
while(i < a.t) {
c += a[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
c += a.s;
}
r.s = (c<0)?-1:0;
if(c > 0) r[i++] = c;
else if(c < -1) r[i++] = this.DV+c;
r.t = i;
r.clamp();
}
// (public) this + a
function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }
// (public) this - a
function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }
// (public) this * a
function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }
// (public) this^2
function bnSquare() { var r = nbi(); this.squareTo(r); return r; }
// (public) this / a
function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }
// (public) this % a
function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }
// (public) [this/a,this%a]
function bnDivideAndRemainder(a) {
var q = nbi(), r = nbi();
this.divRemTo(a,q,r);
return new Array(q,r);
}
// (protected) this *= n, this >= 0, 1 < n < DV
function bnpDMultiply(n) {
this[this.t] = this.am(0,n-1,this,0,0,this.t);
++this.t;
this.clamp();
}
// (protected) this += n << w words, this >= 0
function bnpDAddOffset(n,w) {
if(n == 0) return;
while(this.t <= w) this[this.t++] = 0;
this[w] += n;
while(this[w] >= this.DV) {
this[w] -= this.DV;
if(++w >= this.t) this[this.t++] = 0;
++this[w];
}
}
// A "null" reducer
function NullExp() {}
function nNop(x) { return x; }
function nMulTo(x,y,r) { x.multiplyTo(y,r); }
function nSqrTo(x,r) { x.squareTo(r); }
NullExp.prototype.convert = nNop;
NullExp.prototype.revert = nNop;
NullExp.prototype.mulTo = nMulTo;
NullExp.prototype.sqrTo = nSqrTo;
// (public) this^e
function bnPow(e) { return this.exp(e,new NullExp()); }
// (protected) r = lower n words of "this * a", a.t <= n
// "this" should be the larger one if appropriate.
function bnpMultiplyLowerTo(a,n,r) {
var i = Math.min(this.t+a.t,n);
r.s = 0; // assumes a,this >= 0
r.t = i;
while(i > 0) r[--i] = 0;
var j;
for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);
for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);
r.clamp();
}
// (protected) r = "this * a" without lower n words, n > 0
// "this" should be the larger one if appropriate.
function bnpMultiplyUpperTo(a,n,r) {
--n;
var i = r.t = this.t+a.t-n;
r.s = 0; // assumes a,this >= 0
while(--i >= 0) r[i] = 0;
for(i = Math.max(n-this.t,0); i < a.t; ++i)
r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);
r.clamp();
r.drShiftTo(1,r);
}
// Barrett modular reduction
function Barrett(m) {
// setup Barrett
this.r2 = nbi();
this.q3 = nbi();
BigInteger.ONE.dlShiftTo(2*m.t,this.r2);
this.mu = this.r2.divide(m);
this.m = m;
}
function barrettConvert(x) {
if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);
else if(x.compareTo(this.m) < 0) return x;
else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
}
function barrettRevert(x) { return x; }
// x = x mod m (HAC 14.42)
function barrettReduce(x) {
x.drShiftTo(this.m.t-1,this.r2);
if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }
this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);
this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);
while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);
x.subTo(this.r2,x);
while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
}
// r = x^2 mod m; x != r
function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
// r = x*y mod m; x,y != r
function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
Barrett.prototype.convert = barrettConvert;
Barrett.prototype.revert = barrettRevert;
Barrett.prototype.reduce = barrettReduce;
Barrett.prototype.mulTo = barrettMulTo;
Barrett.prototype.sqrTo = barrettSqrTo;
// (public) this^e % m (HAC 14.85)
function bnModPow(e,m) {
var i = e.bitLength(), k, r = nbv(1), z;
if(i <= 0) return r;
else if(i < 18) k = 1;
else if(i < 48) k = 3;
else if(i < 144) k = 4;
else if(i < 768) k = 5;
else k = 6;
if(i < 8)
z = new Classic(m);
else if(m.isEven())
z = new Barrett(m);
else
z = new Montgomery(m);
// precomputation
var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
g[1] = z.convert(this);
if(k > 1) {
var g2 = nbi();
z.sqrTo(g[1],g2);
while(n <= km) {
g[n] = nbi();
z.mulTo(g2,g[n-2],g[n]);
n += 2;
}
}
var j = e.t-1, w, is1 = true, r2 = nbi(), t;
i = nbits(e[j])-1;
while(j >= 0) {
if(i >= k1) w = (e[j]>>(i-k1))&km;
else {
w = (e[j]&((1<<(i+1))-1))<<(k1-i);
if(j > 0) w |= e[j-1]>>(this.DB+i-k1);
}
n = k;
while((w&1) == 0) { w >>= 1; --n; }
if((i -= n) < 0) { i += this.DB; --j; }
if(is1) { // ret == 1, don't bother squaring or multiplying it
g[w].copyTo(r);
is1 = false;
}
else {
while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }
if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }
z.mulTo(r2,g[w],r);
}
while(j >= 0 && (e[j]&(1<<i)) == 0) {
z.sqrTo(r,r2); t = r; r = r2; r2 = t;
if(--i < 0) { i = this.DB-1; --j; }
}
}
return z.revert(r);
}
// (public) gcd(this,a) (HAC 14.54)
function bnGCD(a) {
var x = (this.s<0)?this.negate():this.clone();
var y = (a.s<0)?a.negate():a.clone();
if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
var i = x.getLowestSetBit(), g = y.getLowestSetBit();
if(g < 0) return x;
if(i < g) g = i;
if(g > 0) {
x.rShiftTo(g,x);
y.rShiftTo(g,y);
}
while(x.signum() > 0) {
if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);
if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);
if(x.compareTo(y) >= 0) {
x.subTo(y,x);
x.rShiftTo(1,x);
}
else {
y.subTo(x,y);
y.rShiftTo(1,y);
}
}
if(g > 0) y.lShiftTo(g,y);
return y;
}
// (protected) this % n, n < 2^26
function bnpModInt(n) {
if(n <= 0) return 0;
var d = this.DV%n, r = (this.s<0)?n-1:0;
if(this.t > 0)
if(d == 0) r = this[0]%n;
else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;
return r;
}
// (public) 1/this % m (HAC 14.61)
function bnModInverse(m) {
var ac = m.isEven();
if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
var u = m.clone(), v = this.clone();
var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
while(u.signum() != 0) {
while(u.isEven()) {
u.rShiftTo(1,u);
if(ac) {
if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
a.rShiftTo(1,a);
}
else if(!b.isEven()) b.subTo(m,b);
b.rShiftTo(1,b);
}
while(v.isEven()) {
v.rShiftTo(1,v);
if(ac) {
if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
c.rShiftTo(1,c);
}
else if(!d.isEven()) d.subTo(m,d);
d.rShiftTo(1,d);
}
if(u.compareTo(v) >= 0) {
u.subTo(v,u);
if(ac) a.subTo(c,a);
b.subTo(d,b);
}
else {
v.subTo(u,v);
if(ac) c.subTo(a,c);
d.subTo(b,d);
}
}
if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
if(d.compareTo(m) >= 0) return d.subtract(m);
if(d.signum() < 0) d.addTo(m,d); else return d;
if(d.signum() < 0) return d.add(m); else return d;
}
var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997];
var lplim = (1<<26)/lowprimes[lowprimes.length-1];
// (public) test primality with certainty >= 1-.5^t
function bnIsProbablePrime(t) {
var i, x = this.abs();
if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {
for(i = 0; i < lowprimes.length; ++i)
if(x[0] == lowprimes[i]) return true;
return false;
}
if(x.isEven()) return false;
i = 1;
while(i < lowprimes.length) {
var m = lowprimes[i], j = i+1;
while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];
m = x.modInt(m);
while(i < j) if(m%lowprimes[i++] == 0) return false;
}
return x.millerRabin(t);
}
// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
function bnpMillerRabin(t) {
var n1 = this.subtract(BigInteger.ONE);
var k = n1.getLowestSetBit();
if(k <= 0) return false;
var r = n1.shiftRight(k);
t = (t+1)>>1;
if(t > lowprimes.length) t = lowprimes.length;
var a = nbi();
for(var i = 0; i < t; ++i) {
//Pick bases at random, instead of starting at 2
a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]);
var y = a.modPow(r,this);
if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
var j = 1;
while(j++ < k && y.compareTo(n1) != 0) {
y = y.modPowInt(2,this);
if(y.compareTo(BigInteger.ONE) == 0) return false;
}
if(y.compareTo(n1) != 0) return false;
}
}
return true;
}
// protected
BigInteger.prototype.chunkSize = bnpChunkSize;
BigInteger.prototype.toRadix = bnpToRadix;
BigInteger.prototype.fromRadix = bnpFromRadix;
BigInteger.prototype.fromNumber = bnpFromNumber;
BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
BigInteger.prototype.changeBit = bnpChangeBit;
BigInteger.prototype.addTo = bnpAddTo;
BigInteger.prototype.dMultiply = bnpDMultiply;
BigInteger.prototype.dAddOffset = bnpDAddOffset;
BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
BigInteger.prototype.modInt = bnpModInt;
BigInteger.prototype.millerRabin = bnpMillerRabin;
// public
BigInteger.prototype.clone = bnClone;
BigInteger.prototype.intValue = bnIntValue;
BigInteger.prototype.byteValue = bnByteValue;
BigInteger.prototype.shortValue = bnShortValue;
BigInteger.prototype.signum = bnSigNum;
BigInteger.prototype.toByteArray = bnToByteArray;
BigInteger.prototype.equals = bnEquals;
BigInteger.prototype.min = bnMin;
BigInteger.prototype.max = bnMax;
BigInteger.prototype.and = bnAnd;
BigInteger.prototype.or = bnOr;
BigInteger.prototype.xor = bnXor;
BigInteger.prototype.andNot = bnAndNot;
BigInteger.prototype.not = bnNot;
BigInteger.prototype.shiftLeft = bnShiftLeft;
BigInteger.prototype.shiftRight = bnShiftRight;
BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
BigInteger.prototype.bitCount = bnBitCount;
BigInteger.prototype.testBit = bnTestBit;
BigInteger.prototype.setBit = bnSetBit;
BigInteger.prototype.clearBit = bnClearBit;
BigInteger.prototype.flipBit = bnFlipBit;
BigInteger.prototype.add = bnAdd;
BigInteger.prototype.subtract = bnSubtract;
BigInteger.prototype.multiply = bnMultiply;
BigInteger.prototype.divide = bnDivide;
BigInteger.prototype.remainder = bnRemainder;
BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
BigInteger.prototype.modPow = bnModPow;
BigInteger.prototype.modInverse = bnModInverse;
BigInteger.prototype.pow = bnPow;
BigInteger.prototype.gcd = bnGCD;
BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
// JSBN-specific extension
BigInteger.prototype.square = bnSquare;
// BigInteger interfaces not implemented in jsbn:
// BigInteger(int signum, byte[] magnitude)
// double doubleValue()
// float floatValue()
// int hashCode()
// long longValue()
// static BigInteger valueOf(long val)

45
ayun/jsbn/prng4.js Normal file
View File

@ -0,0 +1,45 @@
// prng4.js - uses Arcfour as a PRNG
function Arcfour() {
this.i = 0;
this.j = 0;
this.S = new Array();
}
// Initialize arcfour context from key, an array of ints, each from [0..255]
function ARC4init(key) {
var i, j, t;
for(i = 0; i < 256; ++i)
this.S[i] = i;
j = 0;
for(i = 0; i < 256; ++i) {
j = (j + this.S[i] + key[i % key.length]) & 255;
t = this.S[i];
this.S[i] = this.S[j];
this.S[j] = t;
}
this.i = 0;
this.j = 0;
}
function ARC4next() {
var t;
this.i = (this.i + 1) & 255;
this.j = (this.j + this.S[this.i]) & 255;
t = this.S[this.i];
this.S[this.i] = this.S[this.j];
this.S[this.j] = t;
return this.S[(t + this.S[this.i]) & 255];
}
Arcfour.prototype.init = ARC4init;
Arcfour.prototype.next = ARC4next;
// Plug in your RNG constructor here
function prng_newstate() {
return new Arcfour();
}
// Pool size must be a multiple of 4 and greater than 32.
// An array of bytes the size of the pool will be passed to init()
var rng_psize = 256;

75
ayun/jsbn/rng.js Normal file
View File

@ -0,0 +1,75 @@
// Random number generator - requires a PRNG backend, e.g. prng4.js
// For best results, put code like
// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
// in your main HTML document.
var rng_state;
var rng_pool;
var rng_pptr;
// Mix in a 32-bit integer into the pool
function rng_seed_int(x) {
rng_pool[rng_pptr++] ^= x & 255;
rng_pool[rng_pptr++] ^= (x >> 8) & 255;
rng_pool[rng_pptr++] ^= (x >> 16) & 255;
rng_pool[rng_pptr++] ^= (x >> 24) & 255;
if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
}
// Mix in the current time (w/milliseconds) into the pool
function rng_seed_time() {
rng_seed_int(new Date().getTime());
}
// Initialize the pool with junk if needed.
if(rng_pool == null) {
rng_pool = new Array();
rng_pptr = 0;
var t;
if(window.crypto && window.crypto.getRandomValues) {
// Use webcrypto if available
var ua = new Uint8Array(32);
window.crypto.getRandomValues(ua);
for(t = 0; t < 32; ++t)
rng_pool[rng_pptr++] = ua[t];
}
if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
// Extract entropy (256 bits) from NS4 RNG if available
var z = window.crypto.random(32);
for(t = 0; t < z.length; ++t)
rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
}
while(rng_pptr < rng_psize) { // extract some randomness from Math.random()
t = Math.floor(65536 * Math.random());
rng_pool[rng_pptr++] = t >>> 8;
rng_pool[rng_pptr++] = t & 255;
}
rng_pptr = 0;
rng_seed_time();
//rng_seed_int(window.screenX);
//rng_seed_int(window.screenY);
}
function rng_get_byte() {
if(rng_state == null) {
rng_seed_time();
rng_state = prng_newstate();
rng_state.init(rng_pool);
for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
rng_pool[rng_pptr] = 0;
rng_pptr = 0;
//rng_pool = null;
}
// TODO: allow reseeding after first request
return rng_state.next();
}
function rng_get_bytes(ba) {
var i;
for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
}
function SecureRandom() {}
SecureRandom.prototype.nextBytes = rng_get_bytes;

118
ayun/jsbn/rsa.js Normal file
View File

@ -0,0 +1,118 @@
// Depends on jsbn.js and rng.js
// Version 1.1: support utf-8 encoding in pkcs1pad2
// convert a (hex) string to a bignum object
function parseBigInt(str,r) {
return new BigInteger(str,r);
}
function linebrk(s,n) {
var ret = "";
var i = 0;
while(i + n < s.length) {
ret += s.substring(i,i+n) + "\n";
i += n;
}
return ret + s.substring(i,s.length);
}
function byte2Hex(b) {
if(b < 0x10)
return "0" + b.toString(16);
else
return b.toString(16);
}
// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
function pkcs1pad2(s,n) {
//var ba = b64toBA(hex2b64(s));
//n -= ba.length;
if(n < s.length + 11) { // TODO: fix for utf-8
alert("Message too long for RSA");
return null;
}
var ba = new Array();
var i = (s.length / 2) - 1;
while(i >= 0 && n > 0) {
ba[--n] = parseInt(s.substring(2*i,2*i+2),16);
i--;
/*
var c = s.charCodeAt(i--);
if(c < 128) { // encode using utf-8
ba[--n] = c;
}
else if((c > 127) && (c < 2048)) {
ba[--n] = (c & 63) | 128;
ba[--n] = (c >> 6) | 192;
}
else {
ba[--n] = (c & 63) | 128;
ba[--n] = ((c >> 6) & 63) | 128;
ba[--n] = (c >> 12) | 224;
}
*/
}
ba[--n] = 0;
var rng = new SecureRandom();
var x = new Array();
while(n > 2) { // random non-zero pad
x[0] = 0;
while(x[0] == 0) rng.nextBytes(x);
ba[--n] = x[0];
}
ba[--n] = 2;
ba[--n] = 0;
return new BigInteger(ba);
}
// "empty" RSA key constructor
function RSAKey() {
this.n = null;
this.e = 0;
this.d = null;
this.p = null;
this.q = null;
this.dmp1 = null;
this.dmq1 = null;
this.coeff = null;
}
// Set the public key fields N and e from hex strings
function RSASetPublic(N,E) {
if(N != null && E != null && N.length > 0 && E.length > 0) {
this.n = parseBigInt(N,16);
this.e = parseInt(E,16);
}
else
alert("Invalid RSA public key");
}
// Perform raw public operation on "x": return x^e (mod n)
function RSADoPublic(x) {
return x.modPowInt(this.e, this.n);
}
// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
function RSAEncrypt(text) {
var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
if(m == null) return null;
var c = this.doPublic(m);
if(c == null) return null;
var h = c.toString(16);
if((h.length & 1) == 0) return h; else return "0" + h;
}
// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
//function RSAEncryptB64(text) {
// var h = this.encrypt(text);
// if(h) return hex2b64(h); else return null;
//}
// protected
RSAKey.prototype.doPublic = RSADoPublic;
// public
RSAKey.prototype.setPublic = RSASetPublic;
RSAKey.prototype.encrypt = RSAEncrypt;
//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;

135
ayun/jsbn/rsa2.js Normal file
View File

@ -0,0 +1,135 @@
// Depends on rsa.js and jsbn2.js
// Version 1.1: support utf-8 decoding in pkcs1unpad2
// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
function pkcs1unpad2(d,n) {
var b = d.toByteArray();
var i = 0;
while(i < b.length && b[i] == 0) ++i;
if(b.length-i != n-1 || b[i] != 2)
return null;
++i;
while(b[i] != 0)
if(++i >= b.length) return null;
var ret = "";
while(++i < b.length) {
ret += byte2Hex(b[i]);
/*
var c = b[i] & 255;
if(c < 128) { // utf-8 decode
ret += String.fromCharCode(c);
}
else if((c > 191) && (c < 224)) {
ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63));
++i;
}
else {
ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63));
i += 2;
}
*/
}
return ret;
}
// Set the private key fields N, e, and d from hex strings
function RSASetPrivate(N,E,D) {
if(N != null && E != null && N.length > 0 && E.length > 0) {
this.n = parseBigInt(N,16);
this.e = parseInt(E,16);
this.d = parseBigInt(D,16);
}
else
alert("Invalid RSA private key");
}
// Set the private key fields N, e, d and CRT params from hex strings
function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) {
if(N != null && E != null && N.length > 0 && E.length > 0) {
this.n = parseBigInt(N,16);
this.e = parseInt(E,16);
this.d = parseBigInt(D,16);
this.p = parseBigInt(P,16);
this.q = parseBigInt(Q,16);
this.dmp1 = parseBigInt(DP,16);
this.dmq1 = parseBigInt(DQ,16);
this.coeff = parseBigInt(C,16);
}
else
alert("Invalid RSA private key");
}
// Generate a new random private key B bits long, using public expt E
function RSAGenerate(B,E) {
var rng = new SecureRandom();
var qs = B>>1;
this.e = parseInt(E,16);
var ee = new BigInteger(E,16);
for(;;) {
for(;;) {
this.p = new BigInteger(B-qs,1,rng);
if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
}
for(;;) {
this.q = new BigInteger(qs,1,rng);
if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
}
if(this.p.compareTo(this.q) <= 0) {
var t = this.p;
this.p = this.q;
this.q = t;
}
var p1 = this.p.subtract(BigInteger.ONE);
var q1 = this.q.subtract(BigInteger.ONE);
var phi = p1.multiply(q1);
if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
this.n = this.p.multiply(this.q);
this.d = ee.modInverse(phi);
this.dmp1 = this.d.mod(p1);
this.dmq1 = this.d.mod(q1);
this.coeff = this.q.modInverse(this.p);
break;
}
}
}
// Perform raw private operation on "x": return x^d (mod n)
function RSADoPrivate(x) {
if(this.p == null || this.q == null)
return x.modPow(this.d, this.n);
// TODO: re-calculate any missing CRT params
var xp = x.mod(this.p).modPow(this.dmp1, this.p);
var xq = x.mod(this.q).modPow(this.dmq1, this.q);
while(xp.compareTo(xq) < 0)
xp = xp.add(this.p);
return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
}
// Return the PKCS#1 RSA decryption of "ctext".
// "ctext" is an even-length hex string and the output is a plain string.
function RSADecrypt(ctext) {
var c = parseBigInt(ctext, 16);
var m = this.doPrivate(c);
if(m == null) return null;
return pkcs1unpad2(m, (this.n.bitLength()+7)>>3);
}
// Return the PKCS#1 RSA decryption of "ctext".
// "ctext" is a Base64-encoded string and the output is a plain string.
//function RSAB64Decrypt(ctext) {
// var h = b64tohex(ctext);
// if(h) return this.decrypt(h); else return null;
//}
// protected
RSAKey.prototype.doPrivate = RSADoPrivate;
// public
RSAKey.prototype.setPrivate = RSASetPrivate;
RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
RSAKey.prototype.generate = RSAGenerate;
RSAKey.prototype.decrypt = RSADecrypt;
//RSAKey.prototype.b64_decrypt = RSAB64Decrypt;

118
ayun/music.js Normal file
View File

@ -0,0 +1,118 @@
var aud=new Audio();
var songs=["PkIeYKbzyZY","lv5A5EDvi-g","EyicJOlYOm4","1weATSoaRbA","qSdiecyj6-M","Ugb7GUtiyZ0","1ZFMy48q63w","10RNhMuWR2g","QkVvPD7Xk5U","RUEWIG8zoa0","V6N_rL4fh6I","n02zTn2d3rY","iBZS6ad3Tlk","Mnb2RhXL-nM","lidx_2d4YOA","ETQJZHYlc3g","kRpRoTaNni0","ACy5tHoNUoA","yLFX_7SH2tY","io-vPXE9JXY","oP6wOte3wZU","6LwLyIv3yvA","MrD05HVGVIQ","HBYS5mBHie4","5HxGK3DTUBQ","_9qUu8IeabE","r76yldhXSrw","OqJi_n3AcV4","WFFF-jMyFaQ","D8CwzhM7O6I","FD56t_0B9ig","5OcsWd949w4","jrnNzNT11aU","VLbMXG8lvjI","4aNDoqt9kEQ","_ZMfQ0Aj7h8","ZCJo8CDyqlQ","A1-fM0s1Yt0","zsLT3JqfTn0","zsGM_sGEako","YZlclPLX1Hw","uT1evbCloAw","HYOth1zARhg","loeGmoYr3s4","0qhoqXTUQlY","FtdPlfZNqVY","uIk_jGypR24","mdAb2xALVm0","5hpBvX0sUuo","RiVZCDq--m4","2k5dqgNT37g","j4Jyev7iTlE","9Ty-qFZZPZk","6EDS01Ipaow","720HcvEvEC8","YbdcrJZBtu8","nZ15jw3NOO8","Ub7y69hg4do","hFal0LKZwnM","g-QdgLe_D5M","CAmHrCvZ8tA","Mr-wV17WFZU","EdFyQOngYJs","3RyqONKuRzk","jBPqr_IsWvY","LcyCREQL7w8","dAalyaoVGfE","RM9O1HO4FLE","tUx4SfdoyUI","qFjaDnnPbA4","NrlhbIzjO04","eDBAdAzCqr4","UqVW7-q7fTA","3I-WJ6UgmOA","m8wcDiahBjg","NmzrLZajTLU","EPT3dIWBbDA","tf4dBTlz25g","FuMtDXkuxVw","PkmKM_OXNZM","KbC46oJmLh4","mRJSIYmHuNI","GmLsIivtcIM","rDBbaGCCIhk","Ig5v4jhLLWI","XZcG2esvW7I","_qpgIOzaI0E","TTJBevUIp0s","V4oiuY02dTo","agIayif-oi0","plm3DVsX7Jg","HA0Mk5BXX44","2RLq_paK3-g","h2EgfSvOuPc","HbtwR1REaFk","-tUJJXWXdXk","h-b8Xs7sNI0","xt2DGLoEmW0","eyp-YuzhTN4","xrawoRF4lN0","6xVHpgJbuc8","qsy-14oAXGc","fYSUV33ZPfw","qnSHJlRJ2cM","Ytt1_ErIV34","05TnpE0x4wI","-jcOtAuGZC4","XbuqB3uB6DI","x-42Zkcw4Cs","kXjA7eRZchc","_zceCigOTwo","Qg83cniiYEY","F7gwcgmoREg","aZFe4K1HmPE","e1Ve4Xa9ftQ","p-dVxnR-vLw","PD1a3mfmY8M","-cJFVNZC4h8","Jfs7Lo8CC0Q","zz3F5j8qWNw","CQLvggJFxuM","wf93JAZR3gU","XLQbs59Pn7E","phrpiLpaiLs","Md2xOKFTvSU","_Ci0Kgdpgsw","iBjZshhpipg","j15tAxxc38Y","LwKbsK6E-DI","9J8cD8-LHy4","7ZQlWCsHG7k","UBIsi3xWa64","GWYkh1IX4PE","YYjDFXJ6Wdo","5YDiUcc3emA","s0G4qOrDOgM","9zibDnOOj3w","rQMd3b1BF50","xeM40-FkRLI","wVOFnTrSOOA","CbziO8vuBR8","msUarvc4Sx8","GB9kBLre96M","UMwmB0ZK3yE","SLFMiEAjSoA","K5F-RLzLH6Q","ziAK1OLeeEE","--I54YPKsLU","33zGN7vENog","pTv51QwN57E","zD8TxUBkjGA","A09BhpgfGKQ","cvBQq1yJH-A","YZrIQardsz8","CUHYQ-FN3P8","GLGjqtgCKY8","bLagC2wX3Ak","fW128GHFJIE","e15qP676Zhg","B5L0AMO2HA8","oFFFzMkGNrk","1RQQLwnaw80","byUipqLQ_Hc","WtF6Z13HD_w","pkkIqT9LpDY","gMGEyl5TRa4","oxoqm05c7yA","yTP8tK2OzFQ"];
var insturl="https://invidious.zapashcanon.fr";
var loading=false;
var usealt=0;
function shuffle(array) {
for (let i = 0; i < array.length; i++) {
let j = Math.floor(Math.random() * (array.length-i)) + i;
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
function fixfard(url){
if(!url)return insturl;
return url.endsWith("/")?url.slice(0,url.length-1):url;
}
var updinsturl=async ()=>{
try{
var json=await (await fetch("https://api.invidious.io/instances.json?sort_by=health")).json();
var out=shuffle(json).map(entry => {
const healthKnown = !!entry[1].monitor
return {
name: entry[0],
details: entry[1],
health: +(healthKnown ? entry[1].monitor.dailyRatios[0].ratio : 95),
healthKnown
}
}).filter(entry => {
return entry.details.type === "https" && entry.health > 0
}).sort((a, b) => {
return b.health - a.health
});
insturl=fixfard(out.find(e=>e.details.cors).details.uri);
}catch(e){aud.onerror();}
};
var updint=setInterval(updinsturl,3600000);
updinsturl();
aud.onended=function(e){
loading=true;
window.startmusic();
};
aud.oncanplay=function(e){
aud.play();
};
aud.onplay=function(e){
aud.playing=true;
loading=false;
};
aud.onerror=function(e){
if(usealt==2){
aud=null;
return;
}
if(usealt==0){
usealt=1;
}else if(usealt==1){
loading=true;
usealt=2;
}
window.stopmusic();
//todo: make attempt 2 more times with diff urls and if those fail then stop trying
clearInterval(updint);
};
window.startmusic=function(v){
if(v!=null&&v==0)return;
loading=true;
var url="";
if(usealt==0){
songs=shuffle(songs);
url=insturl+"/latest_version?id="+songs[0]+"&itag=251";
}else if(usealt==1){
url="https://nightride.fm/stream/chillsynth.m4a";
}else if(usealt==2){
return;
}
if(v!=null)aud.volume=v;
aud.src=url;
aud.currentTime=0;
};
window.stopmusic=function(){
if(usealt==2)return;
aud.pause();
loading=false;
};
window.volmusic=function(v){
if(usealt==2)return;
if(v==0){
window.startmusic();
}else{
if(aud.playing){
aud.volume=v;
}else{
window.startmusic(v);
}
}
};
window.playingmusic=function(){
return usealt==2||aud.playing||loading;
};
navigator.mediaSession.setActionHandler('play', function() {});
navigator.mediaSession.setActionHandler('pause', function() {});
navigator.mediaSession.setActionHandler('seekbackward', function() {});
navigator.mediaSession.setActionHandler('seekforward', function() {});
navigator.mediaSession.setActionHandler('previoustrack', function() {});
navigator.mediaSession.setActionHandler('nexttrack', function() {});

3
drag/cover.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 67 KiB

32219
drag/index.html Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,47 @@
[ [
{ {
"name": "π Client",
"image": "cover.svg",
"directory": "pi",
"recommended": "1"
},
{
"name": "Precision Client",
"image": "cover.svg",
"directory": "pre",
"recommended": "1"
},
{
"name": "Shadow Client",
"image": "cover.svg",
"directory": "shadow",
"recommended": "1"
},
{
"name": "Windows XP",
"image": "cover.svg",
"directory": "xp",
"recommended": "1"
},
{
"name": "Dragon Client",
"image": "cover.svg",
"directory": "drag",
"recommended": "1"
},
{
"name": "Ayuncraft 1.5.2",
"image": "cover.svg",
"directory": "ayun",
"recommended": "1"
},
{
"name": "Minecraft Infdev",
"image": "cover.svg",
"directory": "inf",
"recommended": "1"
},
{
"name": "Minesweeper", "name": "Minesweeper",
"image": "cover.svg", "image": "cover.svg",
"directory": "minesweeper", "directory": "minesweeper",

View File

@ -43,6 +43,13 @@ app.get('/ad', (req, res) => {
res.sendFile(path.join(__dirname, 'ad.html')); res.sendFile(path.join(__dirname, 'ad.html'));
}); });
app.get('/blank', (req, res) => {
res.sendFile(path.join(__dirname, 'blank.html'));
});
app.get('/backgrounds', (req, res) => {
res.sendFile(path.join(__dirname, 'backgrounds.html'));
});
app.listen(port, () => { app.listen(port, () => {
console.log(`Selenite is running on port ${port}`); console.log(`Selenite is running on port ${port}`);
}); });

5405
inf/app.js Normal file

File diff suppressed because one or more lines are too long

3
inf/cover.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

84
inf/favicon.ico Normal file
View File

@ -0,0 +1,84 @@
<!DOCTYPE html>
<html>
<head>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-261780635-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-261780635-1');
</script>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-TG85STRS');</script>
<!-- End Google Tag Manager -->
<title>Play Minecraft Online! | Online mc</title>
<link rel="icon" href="/icon.png">
<meta name="description" content="Play Minecraft (eaglercraft) Online For Free!" />
<meta name="keywords" content="free minecraft online, eaglercraft, minecraft, onlinemc, Onlinemc, ayuncraft, Ayuncraft, mc, eaglercraftx, eaglercraft shaders, eaglercraft download,eaglercraft, eaglercraftx, minecraft, 1.8, 1.8.8, eaglercraft, eaglercraft minecraft, eaglercraft 3kh0, eaglercraft github, eaglercraft singleplayer, eaglercraft hacks, eaglercraft 1.8, eaglercraft server, eaglecraft game, eaglercraft alternative, eaglercraft alt links, eaglercraft asspixel, eaglercraft anarchy server, eaglercraft aeon, eaglercraft asspixel server ip, eaglercraft all links, eaglercraft aeon server, eaglercraft beta, eaglecraft boats, eaglecraft boats for sale, eaglecraft boats for sale bc, eaglecraft bedwars server, eaglecraft boats inc, eaglercraft beta servers, eaglercraft blocked, eaglercraft client, eaglecraft custom boats, eaglecraft campbell river, eaglercraft creative, eaglercraft commands, eaglercraft code, eaglercraft controls, eaglercraft com, eaglercraft download, eaglercraft discord, eaglercraft dupe glitch, eaglercraft download file, eaglercraft download google drive, eaglercraft dmca, eaglercraft deleted, eaglercraft down, eaglercraft embed, eaglercraft epk file download, eaglercraft end of stream, eaglecraft apk download, eaglecraft eagtek, eaglercraft exploit, eaglecraft eggs, eaglercraft epk world file download, eaglercraft file, eaglercraft file download, eaglercraft free, eaglercraft forums, eaglercraft fork, eaglercraft faq, eaglercraft fps, eaglecraft free download, eaglercraft github servers, eaglercraft google drive, eaglercraft github lax1dude, eaglercraft github download, eaglercraft github.io, eaglercraft google sites, minecraft, applet, singleplayer, replit, html5, chromebook, lax1dude, games, eaglercraft singleplayer, eagler, minecraft for free, free minecraft">
<meta property="og:title" content="Online mc" />
<meta property="og:image" content="/icon.png" />
<meta property="og:description" content="Online Minecraft" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css">
<link href="/style.css" rel="stylesheet" />
<link href="/darkmode.css" rel="stylesheet" />
</head>
<body class="diff-bg">
<div id="loading"></div>
<div class="container container-table">
<div class="row vertical-center-row">
<div class="col-12">
</a>
<div class="d-flex justify-content-center">
</div>
<div class="col-12">
<div class="button-area d-block">
<h1 class="dark-text">404 Not Found!</h1>
<div class="splash-404">...</div>
<h3>&nbsp;</h3>
<a href="/">click here to go back to the main page!</a>
<img class="creeper ms-auto d-block" src="creeper.webp" alt=""/>
</div>
<div class="mc-footer d-flex justify-content-between">
<div class="footer-copyright text-end text-white">This website is not affiliated with Mojang.</div>
<div class="mc-dd">
</div>
</div>
</div>
</div>
</div>
</div>
<script defer src="/_vercel/insights/script.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
<script>
window.onload = function () {
//display loader on page load
$('#loading').fadeOut();
}
setTimeout(function () {
//display loader on page load
$('#loading').fadeOut();
}, 12 * 1000);
</script>
<script src="/darkmode.js"></script>
<script src="/splash-404.js"></script>
</body>
</html>

16
inf/index.html Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<title>Infdev</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<script type="text/javascript" charset="utf-8" src="app.js"></script>
<script type = text/javascript>
window.addEventListener("load", function() {
window.minecraftOpts = ["game","resources.epk"];
main();
});
</script>
</head>
<body style="margin:0px;width:100vw;height:100vh;" id="game">
</body>
</html>

BIN
inf/resources.epk Normal file

Binary file not shown.

3
pi/cover.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<image href="data:image/png;base64,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" height="200" width="200" />
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

31933
pi/index.html Normal file

File diff suppressed because one or more lines are too long

BIN
pre/ProductSans.ttf Normal file

Binary file not shown.

View File

@ -0,0 +1,54 @@
§fPrecision Client is a custom eaglercraft client with QOL §ffeatures, custom texture packs, and more.§r
§9This was created by LAX1DUDE and forked by EtcherFX§r
§4Ingame voice chat service created by ayunami2000§r
§2Click the Github or Discord button on the main menu for §2more information§r
§fScroll down for the detailed license statements
§fAll graphical assets in this project were ripped from §fMojang's official Minecraft.jar for Minecraft version §f1.5.2 §fand they are Mojang's intellectual property. Assets ommitted §finclude the Minecraft soundtrack and music disks and all §fsoftware references to the Mojang/Minecraft api.
§f========================================
§fCopyright (c) 2022 Calder Young.
§fThis work is licensed under a Creative Commons
§fAttribution-NonCommercial 4.0 International License
§f§nhttp://creativecommons.org/licenses/by-nc/4.0/§r
§f========================================
§fTeaVM Copyright 2016 Alexey Andreev.
§fLicensed under the Apache License, Version 2.0 (the §f"License"); you may not use this file except in compliance §fwith the License. You may obtain a copy of the License at
§f§nhttp://www.apache.org/licenses/LICENSE-2.0§r
§fUnless required by applicable law or agreed to in writing, §fsoftware distributed under the License is distributed on an §f"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY §fKIND, either express or implied. See the License for the §fspecific language governing permissions and limitations §funder the License.
§f========================================
§fNVIDIA FXAA 3.11 by TIMOTHY LOTTES
§fCopyright (c) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS §fRESERVED.
§fTO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, §fTHIS SOFTWARE IS PROVIDED *AS IS* AND NVIDIA AND ITS §fSUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR §fIMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES §fOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. §fIN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR §fANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL §fDAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, §fDAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS §fINTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER §fPECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO §fUSE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE §fPOSSIBILITY OF SUCH DAMAGES.
§f========================================
§fJZlib Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights §freserved.
§fRedistribution and use in source and binary forms, with or §fwithout modification, are permitted provided that the following §fconditions are met:
§f1. Redistributions of source code must retain the above §fcopyright notice, this list of conditions and the following §fdisclaimer.
§f2. Redistributions in binary form must reproduce the §fabove copyright notice, this list of conditions and the §ffollowing disclaimer in the documentation and/or other §fmaterials provided with the distribution.
§f3. The names of the authors may not be used to endorse §for promote products derived from this software without §fspecific prior written permission.
§fTHIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR §fIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE §fIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A §fPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL §fJCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE §fLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, §fEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT §fLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; §fLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) §fHOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER §fIN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING §fNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE §fUSE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY §fOF SUCH DAMAGE.
§f========================================

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
pre/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 KiB

19499
pre/classes.js Normal file

File diff suppressed because one or more lines are too long

16300
pre/classes_server.js Normal file

File diff suppressed because it is too large Load Diff

3
pre/cover.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 31 KiB

798
pre/eagswebrtc.js Normal file
View File

@ -0,0 +1,798 @@
"use strict";
/*
This is the backend for voice channels and LAN servers in eaglercraft
it links with TeaVM EaglerAdapter at runtime
Copyright 2022 ayunami2000 & lax1dude. All rights reserved.
*/
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%% VOICE CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
window.initializeVoiceClient = (() => {
const READYSTATE_NONE = 0;
const READYSTATE_ABORTED = -1;
const READYSTATE_DEVICE_INITIALIZED = 1;
const PEERSTATE_FAILED = 0;
const PEERSTATE_SUCCESS = 1;
const PEERSTATE_LOADING = 2;
class EaglercraftVoicePeer {
constructor(client, peerId, peerConnection, offer) {
this.client = client;
this.peerId = peerId;
this.peerConnection = peerConnection;
this.stream = null;
const self = this;
this.peerConnection.addEventListener("icecandidate", (evt) => {
if (evt.candidate) {
self.client.iceCandidateHandler(self.peerId, JSON.stringify({
sdpMLineIndex: evt.candidate.sdpMLineIndex,
candidate: evt.candidate.candidate
}));
}
});
this.peerConnection.addEventListener("track", (evt) => {
self.rawStream = evt.streams[0];
const aud = new Audio();
aud.autoplay = true;
aud.muted = true;
aud.onended = function () {
aud.remove();
};
aud.srcObject = self.rawStream;
self.client.peerTrackHandler(self.peerId, self.rawStream);
});
this.peerConnection.addStream(this.client.localMediaStream.stream);
if (offer) {
this.peerConnection.createOffer((desc) => {
const selfDesc = desc;
self.peerConnection.setLocalDescription(selfDesc, () => {
self.client.descriptionHandler(self.peerId, JSON.stringify(selfDesc));
if (self.client.peerStateInitial != PEERSTATE_SUCCESS) self.client.peerStateInitial = PEERSTATE_SUCCESS;
}, (err) => {
console.error("Failed to set local description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateInitial == PEERSTATE_LOADING) self.client.peerStateInitial = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
});
}, (err) => {
console.error("Failed to set create offer for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateInitial == PEERSTATE_LOADING) self.client.peerStateInitial = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
});
}
this.peerConnection.addEventListener("connectionstatechange", (evt) => {
if (self.peerConnection.connectionState === 'disconnected') {
self.client.signalDisconnect(self.peerId);
} else if (self.peerConnection.connectionState === 'connected') {
if (self.client.peerState != PEERSTATE_SUCCESS) self.client.peerState = PEERSTATE_SUCCESS;
} else if (self.peerConnection.connectionState === 'failed') {
if (self.client.peerState == PEERSTATE_LOADING) self.client.peerState = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
}
});
}
disconnect() {
this.peerConnection.close();
}
mute(muted) {
this.rawStream.getAudioTracks()[0].enabled = !muted;
}
setRemoteDescription(descJSON) {
const self = this;
try {
const remoteDesc = JSON.parse(descJSON);
this.peerConnection.setRemoteDescription(remoteDesc, () => {
if (remoteDesc.type == 'offer') {
self.peerConnection.createAnswer((desc) => {
const selfDesc = desc;
self.peerConnection.setLocalDescription(selfDesc, () => {
self.client.descriptionHandler(self.peerId, JSON.stringify(selfDesc));
if (self.client.peerStateDesc != PEERSTATE_SUCCESS) self.client.peerStateDesc = PEERSTATE_SUCCESS;
}, (err) => {
console.error("Failed to set local description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
});
}, (err) => {
console.error("Failed to create answer for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
});
}
}, (err) => {
console.error("Failed to set remote description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
});
} catch (err) {
console.error("Failed to parse remote description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalDisconnect(self.peerId);
}
}
addICECandidate(candidate) {
try {
this.peerConnection.addIceCandidate(new RTCIceCandidate(JSON.parse(candidate)));
if (this.client.peerStateIce != PEERSTATE_SUCCESS) this.client.peerStateIce = PEERSTATE_SUCCESS;
} catch (err) {
console.error("Failed to parse ice candidate for \"" + this.peerId + "\"! " + err);
if (this.client.peerStateIce == PEERSTATE_LOADING) this.client.peerStateIce = PEERSTATE_FAILED;
this.client.signalDisconnect(this.peerId);
}
}
}
class EaglercraftVoiceClient {
constructor() {
this.ICEServers = [];
this.hasInit = false;
this.peerList = new Map();
this.readyState = READYSTATE_NONE;
this.peerState = PEERSTATE_LOADING;
this.peerStateConnect = PEERSTATE_LOADING;
this.peerStateInitial = PEERSTATE_LOADING;
this.peerStateDesc = PEERSTATE_LOADING;
this.peerStateIce = PEERSTATE_LOADING;
this.iceCandidateHandler = null;
this.descriptionHandler = null;
this.peerTrackHandler = null;
this.peerDisconnectHandler = null;
this.microphoneVolumeAudioContext = null;
}
voiceClientSupported() {
return typeof window.RTCPeerConnection !== "undefined" && typeof navigator.mediaDevices !== "undefined" &&
typeof navigator.mediaDevices.getUserMedia !== "undefined";
}
setICEServers(urls) {
this.ICEServers.length = 0;
for (var i = 0; i < urls.length; ++i) {
var etr = urls[i].split(";");
if (etr.length == 1) {
this.ICEServers.push({urls: etr[0]});
} else if (etr.length == 3) {
this.ICEServers.push({urls: etr[0], username: etr[1], credential: etr[2]});
}
}
}
setICECandidateHandler(cb) {
this.iceCandidateHandler = cb;
}
setDescriptionHandler(cb) {
this.descriptionHandler = cb;
}
setPeerTrackHandler(cb) {
this.peerTrackHandler = cb;
}
setPeerDisconnectHandler(cb) {
this.peerDisconnectHandler = cb;
}
activateVoice(tk) {
if (this.hasInit) this.localRawMediaStream.getAudioTracks()[0].enabled = tk;
}
initializeDevices() {
if (!this.hasInit) {
const self = this;
navigator.mediaDevices.getUserMedia({audio: true, video: false}).then((stream) => {
self.microphoneVolumeAudioContext = new AudioContext();
self.localRawMediaStream = stream;
self.localRawMediaStream.getAudioTracks()[0].enabled = false;
self.localMediaStream = self.microphoneVolumeAudioContext.createMediaStreamDestination();
self.localMediaStreamGain = self.microphoneVolumeAudioContext.createGain();
var localStreamIn = self.microphoneVolumeAudioContext.createMediaStreamSource(stream);
localStreamIn.connect(self.localMediaStreamGain);
self.localMediaStreamGain.connect(self.localMediaStream);
self.localMediaStreamGain.gain.value = 1.0;
self.readyState = READYSTATE_DEVICE_INITIALIZED;
this.hasInit = true;
}).catch((err) => {
self.readyState = READYSTATE_ABORTED;
});
} else {
this.readyState = READYSTATE_DEVICE_INITIALIZED;
}
}
setMicVolume(val) {
if (this.hasInit) {
if (val > 0.5) val = 0.5 + (val - 0.5) * 2.0;
if (val > 1.5) val = 1.5;
if (val < 0.0) val = 0.0;
this.localMediaStreamGain.gain.value = val * 2.0;
}
}
resetPeerStates() {
this.peerState = this.peerStateConnect = this.peerStateInitial = this.peerStateDesc = this.peerStateIce = PEERSTATE_LOADING;
}
getPeerState() {
return this.peerState;
}
getPeerStateConnect() {
return this.peerStateConnect;
}
getPeerStateInitial() {
return this.peerStateInitial;
}
getPeerStateDesc() {
return this.peerStateDesc;
}
getPeerStateIce() {
return this.peerStateIce;
}
getReadyState() {
return this.readyState;
}
signalConnect(peerId, offer) {
if (!this.hasInit) this.initializeDevices();
try {
const peerConnection = new RTCPeerConnection({
iceServers: this.ICEServers,
optional: [{DtlsSrtpKeyAgreement: true}]
});
const peerInstance = new EaglercraftVoicePeer(this, peerId, peerConnection, offer);
this.peerList.set(peerId, peerInstance);
if (this.peerStateConnect != PEERSTATE_SUCCESS) this.peerStateConnect = PEERSTATE_SUCCESS;
} catch (e) {
if (this.peerStateConnect == PEERSTATE_LOADING) this.peerStateConnect = PEERSTATE_FAILED;
}
}
signalDescription(peerId, descJSON) {
var thePeer = this.peerList.get(peerId);
if ((typeof thePeer !== "undefined") && thePeer !== null) {
thePeer.setRemoteDescription(descJSON);
}
}
signalDisconnect(peerId, quiet) {
var thePeer = this.peerList.get(peerId);
if ((typeof thePeer !== "undefined") && thePeer !== null) {
this.peerList.delete(thePeer);
try {
thePeer.disconnect();
} catch (e) {
}
this.peerDisconnectHandler(peerId, quiet);
}
}
mutePeer(peerId, muted) {
var thePeer = this.peerList.get(peerId);
if ((typeof thePeer !== "undefined") && thePeer !== null) {
thePeer.mute(muted);
}
}
signalICECandidate(peerId, candidate) {
var thePeer = this.peerList.get(peerId);
if ((typeof thePeer !== "undefined") && thePeer !== null) {
thePeer.addICECandidate(candidate);
}
}
}
window.constructVoiceClient = () => new EaglercraftVoiceClient();
});
window.startVoiceClient = () => {
if (typeof window.constructVoiceClient !== "function") {
window.initializeVoiceClient();
}
return window.constructVoiceClient();
};
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%% LAN CLIENT CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
window.initializeLANClient = (() => {
const READYSTATE_INIT_FAILED = -2;
const READYSTATE_FAILED = -1;
const READYSTATE_DISCONNECTED = 0;
const READYSTATE_CONNECTING = 1;
const READYSTATE_CONNECTED = 2;
class EaglercraftLANClient {
constructor() {
this.ICEServers = [];
this.peerConnection = null;
this.dataChannel = null;
this.readyState = READYSTATE_CONNECTING;
this.iceCandidateHandler = null;
this.descriptionHandler = null;
this.remoteDataChannelHandler = null;
this.remoteDisconnectHandler = null;
this.remotePacketHandler = null;
}
LANClientSupported() {
return typeof window.RTCPeerConnection !== "undefined";
}
initializeClient() {
try {
if (this.dataChannel != null) {
this.dataChannel.close();
this.dataChannel = null;
}
if (this.peerConnection != null) {
this.peerConnection.close();
}
this.peerConnection = new RTCPeerConnection({
iceServers: this.ICEServers,
optional: [{DtlsSrtpKeyAgreement: true}]
});
this.readyState = READYSTATE_CONNECTING;
} catch (e) {
this.readyState = READYSTATE_INIT_FAILED;
}
}
setICEServers(urls) {
this.ICEServers.length = 0;
for (var i = 0; i < urls.length; ++i) {
var etr = urls[i].split(";");
if (etr.length == 1) {
this.ICEServers.push({urls: etr[0]});
} else if (etr.length == 3) {
this.ICEServers.push({urls: etr[0], username: etr[1], credential: etr[2]});
}
}
}
setICECandidateHandler(cb) {
this.iceCandidateHandler = cb;
}
setDescriptionHandler(cb) {
this.descriptionHandler = cb;
}
setRemoteDataChannelHandler(cb) {
this.remoteDataChannelHandler = cb;
}
setRemoteDisconnectHandler(cb) {
this.remoteDisconnectHandler = cb;
}
setRemotePacketHandler(cb) {
this.remotePacketHandler = cb;
}
getReadyState() {
return this.readyState;
}
sendPacketToServer(buffer) {
if (this.dataChannel != null && this.dataChannel.readyState == "open") {
this.dataChannel.send(buffer);
} else {
this.signalRemoteDisconnect(false);
}
}
signalRemoteConnect() {
const self = this;
const iceCandidates = [];
this.peerConnection.addEventListener("icecandidate", (evt) => {
if (evt.candidate) {
if (iceCandidates.length == 0) setTimeout(() => {
if (self.peerConnection != null && self.peerConnection.connectionState != "disconnected") {
self.iceCandidateHandler(JSON.stringify(iceCandidates));
iceCandidates.length = 0;
}
}, 3000);
iceCandidates.push({
sdpMLineIndex: evt.candidate.sdpMLineIndex,
candidate: evt.candidate.candidate
});
}
});
this.dataChannel = this.peerConnection.createDataChannel("lan");
this.dataChannel.binaryType = "arraybuffer";
this.dataChannel.addEventListener("open", async (evt) => {
while (iceCandidates.length > 0) {
await new Promise(resolve => setTimeout(resolve, 0));
}
self.remoteDataChannelHandler(self.dataChannel);
});
this.dataChannel.addEventListener("message", (evt) => {
self.remotePacketHandler(evt.data);
}, false);
this.peerConnection.createOffer((desc) => {
const selfDesc = desc;
self.peerConnection.setLocalDescription(selfDesc, () => {
self.descriptionHandler(JSON.stringify(selfDesc));
}, (err) => {
console.error("Failed to set local description! " + err);
self.readyState = READYSTATE_FAILED;
self.signalRemoteDisconnect(false);
});
}, (err) => {
console.error("Failed to set create offer! " + err);
self.readyState = READYSTATE_FAILED;
self.signalRemoteDisconnect(false);
});
this.peerConnection.addEventListener("connectionstatechange", (evt) => {
if (self.peerConnection.connectionState === 'disconnected') {
self.signalRemoteDisconnect(false);
} else if (self.peerConnection.connectionState === 'connected') {
self.readyState = READYSTATE_CONNECTED;
} else if (self.peerConnection.connectionState === 'failed') {
self.readyState = READYSTATE_FAILED;
self.signalRemoteDisconnect(false);
}
});
}
signalRemoteDescription(descJSON) {
try {
this.peerConnection.setRemoteDescription(JSON.parse(descJSON));
} catch (e) {
console.error(e);
this.readyState = READYSTATE_FAILED;
this.signalRemoteDisconnect(false);
}
}
signalRemoteICECandidate(candidates) {
try {
const candidateList = JSON.parse(candidates);
for (let candidate of candidateList) {
this.peerConnection.addIceCandidate(candidate);
}
} catch (e) {
console.error(e);
this.readyState = READYSTATE_FAILED;
this.signalRemoteDisconnect(false);
}
}
signalRemoteDisconnect(quiet) {
if (this.dataChannel != null) {
this.dataChannel.close();
this.dataChannel = null;
}
if (this.peerConnection != null) {
this.peerConnection.close();
}
if (!quiet) this.remoteDisconnectHandler();
this.readyState = READYSTATE_DISCONNECTED;
}
};
window.constructLANClient = () => new EaglercraftLANClient();
});
window.startLANClient = () => {
if (typeof window.constructLANClient !== "function") {
window.initializeLANClient();
}
return window.constructLANClient();
};
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%% LAN SERVER CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
window.initializeLANServer = (() => {
const PEERSTATE_FAILED = 0;
const PEERSTATE_SUCCESS = 1;
const PEERSTATE_LOADING = 2;
class EaglercraftLANPeer {
constructor(client, peerId, peerConnection) {
this.client = client;
this.peerId = peerId;
this.peerConnection = peerConnection;
this.dataChannel = null;
const self = this;
const iceCandidates = [];
this.peerConnection.addEventListener("icecandidate", (evt) => {
if (evt.candidate) {
if (iceCandidates.length == 0) setTimeout(() => {
if (self.peerConnection != null && self.peerConnection.connectionState != "disconnected") {
self.client.iceCandidateHandler(self.peerId, JSON.stringify(iceCandidates));
iceCandidates.length = 0;
}
}, 3000);
iceCandidates.push({
sdpMLineIndex: evt.candidate.sdpMLineIndex,
candidate: evt.candidate.candidate
});
}
});
this.peerConnection.addEventListener("datachannel", async (evt) => {
while (iceCandidates.length > 0) {
await new Promise(resolve => setTimeout(resolve, 0));
}
self.dataChannel = evt.channel;
self.client.remoteClientDataChannelHandler(self.peerId, self.dataChannel);
self.dataChannel.addEventListener("message", (evt) => {
self.client.remoteClientPacketHandler(self.peerId, evt.data);
}, false);
}, false);
this.peerConnection.addEventListener("connectionstatechange", (evt) => {
if (self.peerConnection.connectionState === 'disconnected') {
self.client.signalRemoteDisconnect(self.peerId);
} else if (self.peerConnection.connectionState === 'connected') {
if (self.client.peerState != PEERSTATE_SUCCESS) self.client.peerState = PEERSTATE_SUCCESS;
} else if (self.peerConnection.connectionState === 'failed') {
if (self.client.peerState == PEERSTATE_LOADING) self.client.peerState = PEERSTATE_FAILED;
self.client.signalRemoteDisconnect(self.peerId);
}
});
}
disconnect() {
if (this.dataChannel != null) {
this.dataChannel.close();
this.dataChannel = null;
}
this.peerConnection.close();
}
setRemoteDescription(descJSON) {
const self = this;
try {
const remoteDesc = JSON.parse(descJSON);
this.peerConnection.setRemoteDescription(remoteDesc, () => {
if (remoteDesc.type == 'offer') {
self.peerConnection.createAnswer((desc) => {
const selfDesc = desc;
self.peerConnection.setLocalDescription(selfDesc, () => {
self.client.descriptionHandler(self.peerId, JSON.stringify(selfDesc));
if (self.client.peerStateDesc != PEERSTATE_SUCCESS) self.client.peerStateDesc = PEERSTATE_SUCCESS;
}, (err) => {
console.error("Failed to set local description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalRemoteDisconnect(self.peerId);
});
}, (err) => {
console.error("Failed to create answer for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalRemoteDisconnect(self.peerId);
});
}
}, (err) => {
console.error("Failed to set remote description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalRemoteDisconnect(self.peerId);
});
} catch (err) {
console.error("Failed to parse remote description for \"" + self.peerId + "\"! " + err);
if (self.client.peerStateDesc == PEERSTATE_LOADING) self.client.peerStateDesc = PEERSTATE_FAILED;
self.client.signalRemoteDisconnect(self.peerId);
}
}
addICECandidate(candidates) {
try {
const candidateList = JSON.parse(candidates);
for (let candidate of candidateList) {
this.peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
}
if (this.client.peerStateIce != PEERSTATE_SUCCESS) this.client.peerStateIce = PEERSTATE_SUCCESS;
} catch (err) {
console.error("Failed to parse ice candidate for \"" + this.peerId + "\"! " + err);
if (this.client.peerStateIce == PEERSTATE_LOADING) this.client.peerStateIce = PEERSTATE_FAILED;
this.client.signalRemoteDisconnect(this.peerId);
}
}
}
class EaglercraftLANServer {
constructor() {
this.ICEServers = [];
this.hasInit = false;
this.peerList = new Map();
this.peerState = PEERSTATE_LOADING;
this.peerStateConnect = PEERSTATE_LOADING;
this.peerStateInitial = PEERSTATE_LOADING;
this.peerStateDesc = PEERSTATE_LOADING;
this.peerStateIce = PEERSTATE_LOADING;
this.iceCandidateHandler = null;
this.descriptionHandler = null;
this.remoteClientDataChannelHandler = null;
this.remoteClientDisconnectHandler = null;
this.remoteClientPacketHandler = null;
}
LANServerSupported() {
return typeof window.RTCPeerConnection !== "undefined";
}
initializeServer() {
// nothing to do!
}
setICEServers(urls) {
this.ICEServers.length = 0;
for (var i = 0; i < urls.length; ++i) {
var etr = urls[i].split(";");
if (etr.length == 1) {
this.ICEServers.push({urls: etr[0]});
} else if (etr.length == 3) {
this.ICEServers.push({urls: etr[0], username: etr[1], credential: etr[2]});
}
}
}
setICECandidateHandler(cb) {
this.iceCandidateHandler = cb;
}
setDescriptionHandler(cb) {
this.descriptionHandler = cb;
}
setRemoteClientDataChannelHandler(cb) {
this.remoteClientDataChannelHandler = cb;
}
setRemoteClientDisconnectHandler(cb) {
this.remoteClientDisconnectHandler = cb;
}
setRemoteClientPacketHandler(cb) {
this.remoteClientPacketHandler = cb;
}
sendPacketToRemoteClient(peerId, buffer) {
var thePeer = this.peerList.get(peerId);
if ((typeof thePeer !== "undefined") && thePeer !== null) {
if (thePeer.dataChannel != null && thePeer.dataChannel.readyState == "open") {
thePeer.dataChannel.send(buffer);
} else {
this.signalRemoteDisconnect(peerId);
}
}
}
resetPeerStates() {
this.peerState = this.peerStateConnect = this.peerStateInitial = this.peerStateDesc = this.peerStateIce = PEERSTATE_LOADING;
}
getPeerState() {
return this.peerState;
}
getPeerStateConnect() {
return this.peerStateConnect;
}
getPeerStateInitial() {
return this.peerStateInitial;
}
getPeerStateDesc() {
return this.peerStateDesc;
}
getPeerStateIce() {
return this.peerStateIce;
}
signalRemoteConnect(peerId) {
try {
const peerConnection = new RTCPeerConnection({
iceServers: this.ICEServers,
optional: [{DtlsSrtpKeyAgreement: true}]
});
const peerInstance = new EaglercraftLANPeer(this, peerId, peerConnection);
this.peerList.set(peerId, peerInstance);
if (this.peerStateConnect != PEERSTATE_SUCCESS) this.peerStateConnect = PEERSTATE_SUCCESS;
} catch (e) {
if (this.peerStateConnect == PEERSTATE_LOADING) this.peerStateConnect = PEERSTATE_FAILED;
}
}
signalRemoteDescription(peerId, descJSON) {
var thePeer = this.peerList.get(peerId);
if ((typeof thePeer !== "undefined") && thePeer !== null) {
thePeer.setRemoteDescription(descJSON);
}
}
signalRemoteICECandidate(peerId, candidate) {
var thePeer = this.peerList.get(peerId);
if ((typeof thePeer !== "undefined") && thePeer !== null) {
thePeer.addICECandidate(candidate);
}
}
signalRemoteDisconnect(peerId) {
if (peerId.length == 0) {
for (const thePeer of this.peerList.values()) {
if ((typeof thePeer !== "undefined") && thePeer !== null) {
this.peerList.delete(peerId);
try {
thePeer.disconnect();
} catch (e) {
}
this.remoteClientDisconnectHandler(peerId);
}
}
this.peerList.clear();
return;
}
var thePeer = this.peerList.get(peerId);
if ((typeof thePeer !== "undefined") && thePeer !== null) {
this.peerList.delete(peerId);
try {
thePeer.disconnect();
} catch (e) {
}
this.remoteClientDisconnectHandler(peerId);
}
}
countPeers() {
return this.peerList.size;
}
};
window.constructLANServer = () => new EaglercraftLANServer();
});
window.startLANServer = () => {
if (typeof window.constructLANServer !== "function") {
window.initializeLANServer();
}
return window.constructLANServer();
};

77
pre/favicon.ico Normal file
View File

@ -0,0 +1,77 @@
<!DOCTYPE html>
<html>
<head>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-261780635-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-261780635-1');
</script>
<title>Play Minecraft Online! | Online mc</title>
<link rel="icon" href="/icon.png">
<meta name="description" content="Play Minecraft Online For Free!" />
<meta name="keywords" content="free minecraft online, eaglercraft, minecraft, onlinemc, Onlinemc, ayuncraft, Ayuncraft, mc, eaglercraftx, eaglercraft shaders, eaglercraft download,eaglercraft, eaglercraftx, minecraft, 1.8, 1.8.8, eaglercraft, eaglercraft minecraft, eaglercraft 3kh0, eaglercraft github, eaglercraft singleplayer, eaglercraft hacks, eaglercraft 1.8, eaglercraft server, eaglecraft game, eaglercraft alternative, eaglercraft alt links, eaglercraft asspixel, eaglercraft anarchy server, eaglercraft aeon, eaglercraft asspixel server ip, eaglercraft all links, eaglercraft aeon server, eaglercraft beta, eaglecraft boats, eaglecraft boats for sale, eaglecraft boats for sale bc, eaglecraft bedwars server, eaglecraft boats inc, eaglercraft beta servers, eaglercraft blocked, eaglercraft client, eaglecraft custom boats, eaglecraft campbell river, eaglercraft creative, eaglercraft commands, eaglercraft code, eaglercraft controls, eaglercraft com, eaglercraft download, eaglercraft discord, eaglercraft dupe glitch, eaglercraft download file, eaglercraft download google drive, eaglercraft dmca, eaglercraft deleted, eaglercraft down, eaglercraft embed, eaglercraft epk file download, eaglercraft end of stream, eaglecraft apk download, eaglecraft eagtek, eaglercraft exploit, eaglecraft eggs, eaglercraft epk world file download, eaglercraft file, eaglercraft file download, eaglercraft free, eaglercraft forums, eaglercraft fork, eaglercraft faq, eaglercraft fps, eaglecraft free download, eaglercraft github servers, eaglercraft google drive, eaglercraft github lax1dude, eaglercraft github download, eaglercraft github.io, eaglercraft google sites, minecraft, applet, singleplayer, replit, html5, chromebook, lax1dude, games, eaglercraft singleplayer, eagler, minecraft for free, free minecraft">
<meta property="og:title" content="Online mc" />
<meta property="og:image" content="/icon.png" />
<meta property="og:description" content="Online Minecraft" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css">
<link href="/style.css" rel="stylesheet" />
<link href="/darkmode.css" rel="stylesheet" />
</head>
<body class="diff-bg">
<div id="loading"></div>
<div class="container container-table">
<div class="row vertical-center-row">
<div class="col-12">
</a>
<div class="d-flex justify-content-center">
</div>
<div class="col-12">
<div class="button-area d-block">
<h1 class="dark-text">404 Not Found!</h1>
<div class="splash-404">...</div>
<h3>&nbsp;</h3>
<a href="/">click here to go back to the main page!</a>
<img class="creeper ms-auto d-block" src="creeper.webp" alt=""/>
</div>
<div class="mc-footer d-flex justify-content-between">
<div class="footer-copyright text-end text-white">This website is not affiliated with Mojang.</div>
<div class="mc-dd">
</div>
</div>
</div>
</div>
</div>
</div>
<script defer src="/_vercel/insights/script.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
<script>
window.onload = function () {
//display loader on page load
$('#loading').fadeOut();
}
setTimeout(function () {
//display loader on page load
$('#loading').fadeOut();
}, 12 * 1000);
</script>
<script src="/darkmode.js"></script>
<script src="/splash-404.js"></script>
</body>
</html>

160
pre/index.html Normal file
View File

@ -0,0 +1,160 @@
<!DOCTYPE html>
<html>
<head>
<title>Precision Client (1.5.2-beta_0.2)</title>
<meta charset="UTF-8" />
<meta content="Precision Client is a custom eaglercraft client with QOL features, custom texture packs, and more."
name="description" />
<meta content="//precisionclient.vercel.app" name="url" />
<meta content="EtcherFX" name="author" />
<meta content="Precision Client" property="og:title" />
<meta content="en-US" property="og:locale" />
<meta content="website" property="og:type" />
<meta content="//precisionclient.vercel.app" property="og:url" />
<!--meta content="IMAGE" property="og:image"/>-->
<meta content="Precision Client is a custom eaglercraft client with QOL features, custom texture packs, and more."
property="og:description" />
<script type="text/javascript" src="eagswebrtc.js"></script>
<script type="text/javascript" src="classes.js"></script>
<script async src="https://arc.io/widget.min.js#pchPqjfw"></script>
<style>
@font-face {
font-family: "Product Sans";
src: url(ProductSans.ttf);
}
</style>
</head>
<body style="margin: 0; width: 100vw; height: 100vh; font-family:
'Product Sans'" id="game_frame" class="gameframe">
<div id="Selection"
style="display: inline-block; position: absolute; top:50%; left: 50%; transform: translate(-50%, -50%)">
<style>
html {
color: #fff;
}
.starter {
border-radius: 5px;
border: 1px solid #fff;
background-color: #0d0c0c;
color: #fff;
}
.dropdown {
position: relative;
display: inline-block;
border-radius: 5px;
border: 1px solid #fff;
background-color: #0d0c0c;
color: #fff;
}
.gameframe {
background-image: url("bg.png");
background-size: cover;
background-repeat: no-repeat;
}
</style>
<h1>Precision Client</h1>
<h3>Select a texture pack:</h3>
<select id="Packs" class="dropdown">
<option>-- Choose one --</option>
<option value="defaultold">Default Old</option>
<option value="defaultnew">Default 1.17+</option>
<option value="bombies">Bombies 180k</option>
<option value="bones">Bare Bones</option>
<option value="modifiednew">Modified 1.17+</option>
<option value="miamiprivate">Miami Private</option>
<option value="nebula">Nebula</option>
<option value="rhedd">Rhedd</option>
<option value="ricefault">Ricefault</option>
<option value="tightfault">Tightfault</option>
<option value="walifault">Walifault</option>
</select>
<br /><br />
<input class="starter" type="button" value="Launch" onclick="Start();" />
</div>
<script type="text/javascript">
if (document.location.href.startsWith("file:")) {
alert("You cannot 'open' this file in your browser, the code doesn't work. Upload this folder to your HTTP(s) server and access it via the internet to launch the stable-download game. This is not a bug, please read the documentation.");
} else {
var PackSelect = document.getElementById("Packs");
function Start() {
if (PackSelect.selectedIndex !== 0) {
var Selected = PackSelect.options[PackSelect.selectedIndex].value;
document.getElementById("Selection").style.display = "none";
localStorage.LastPack = Selected;
const relayId = Math.floor(Math.random() * 3);
window.eaglercraftOpts = {
container: "game_frame",
assetsURI: `packs/${Selected}.epk`,
serverWorkerURI: "worker_bootstrap.js",
worldsFolder: "MAIN",
assetOverrides: {
"records/wait.mp3": "wait.mp3",
"records/mellohi.mp3": "https://stream.nightride.fm/chillsynth.m4a",
"records/far.mp3": "https://stream.nightride.fm/nightride.m4a",
"records/cat.mp3": "http://usa9.fastcast4u.com/proxy/jamz?mp=/1",
"records/ward.mp3": "http://fr4.1mix.co.uk:8000/192h",
"records/strad.mp3": "http://listen.011fm.com:8028/stream15",
"records/blocks.mp3": "https://www.ophanim.net:8444/s/9780",
"records/13.mp3": "https://s2.radio.co/s2b2b68744/listen",
//"records/ward.mp3": wardUrl,
"credits.txt": "assetoverrides/credits.txt",
"precision/gui.png": "assetoverrides/precision/gui.png",
"precision/gui2.png": "assetoverrides/precision/gui2.png",
"precision/guismall.png": "assetoverrides/precision/guismall.png",
"precision/logo.png": "assetoverrides/precision/logo.png",
"precision/precision.png": "assetoverrides/precision/precision.png",
"precision/precision2.png": "assetoverrides/precision/precision2.png",
"lang/en_US.lang": "assetoverrides/lang/en_US.lang",
"gui/demo_bg.png": "assetoverrides/gui/demo_bg.png",
"title/bg/panorama0.png": "assetoverrides/title/bg/panorama0.png",
"title/bg/panorama1.png": "assetoverrides/title/bg/panorama1.png",
"title/bg/panorama2.png": "assetoverrides/title/bg/panorama2.png",
"title/bg/panorama3.png": "assetoverrides/title/bg/panorama3.png",
"title/bg/panorama4.png": "assetoverrides/title/bg/panorama4.png",
"title/bg/panorama5.png": "assetoverrides/title/bg/panorama5.png"
},
servers: [
{ serverName: "A*spixel", serverAddress: "wss://web.asspixel.net/CAPixel/", hideAddress: true },
{ serverName: "VanillaCraft", serverAddress: "wss://play.vanillacraftsmp.org/", hideAddress: true },
{ serverName: "ArchMC", serverAddress: "wss://web.arch.lol/join", hideAddress: true },
{ serverName: "Ayunboom", serverAddress: "wss://sus.shhnowisnottheti.me", hideAddress: true },
{ serverName: "Aeon Network", serverAddress: "wss://aeon-network.net/aeon", hideAddress: true },
{ serverName: "Sealcraft", serverAddress: "wss://sealcraft.ddns.net:442/servers", hideAddress: true }
],
relays: [
{ addr: "wss://relay.deev.is/", name: "lax1dude relay #1", primary: relayId == 0 },
{ addr: "wss://relay.lax1dude.net/", name: "lax1dude relay #2", primary: relayId == 1 },
{ addr: "wss://relay.shhnowisnottheti.me/", name: "ayunami relay #1", primary: relayId == 2 }
],
mainMenu: {
splashes: [], eaglerLogo: false
}
};
(function () {
var q = window.location.search;
if (typeof q === 'string' && q.startsWith("?")) {
q = new URLSearchParams(q);
var s = q.get("server");
if (s) window.minecraftOpts.push(s);
}
})();
main();
} else
alert("You need to select a pack");
}
}
if (localStorage.LastPack)
for (Pack of PackSelect.children)
if (Pack.value === localStorage.LastPack) {
Pack.selected = "selected";
break;
}
</script>
</body>
</html>

BIN
pre/packs/defaultold.epk Normal file

Binary file not shown.

5
pre/worker_bootstrap.js Normal file
View File

@ -0,0 +1,5 @@
onmessage = function (o) {
importScripts("classes_server.js");
eaglercraftServerOpts = o.data;
main();
};

3
shadow/cover.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

36979
shadow/index.html Normal file

File diff suppressed because one or more lines are too long

BIN
xp/boot/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
xp/boot/assets/progress.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

29
xp/boot/boot.css Normal file
View File

@ -0,0 +1,29 @@
body {
padding: 0;
margin: 0;
}
._ui_boot {
background: #000000;
width: 100%;
height: 100%;
}
._ui_boot_logo {
height: 150px;
width: 126px;
position: absolute;
top: 50%;
left: 50%;
margin: -75px 0 0 -63px;
}
._ui_boot_winlogo {
background-image: url("assets/logo.png");
width: 118px;
height: 104px;
}
._ui_boot_progress {
background-image: url("assets/progress.gif");
width: 126px;
height: 15px;
position: absolute;
bottom: 0;
}

150
xp/boot/load.js Normal file
View File

@ -0,0 +1,150 @@
var scripts = [
'system/core.js',
'system/window-api.js',
'system/contextmenus.js',
'system/filesystem.js',
'system/xp.js',
'system/jquery.terminal-2.0.0.min.js',
'system/unix_formatting.js',
'program/terminal.js',
'system/script.js',
'system/explorer.js',
'system/help.js',
'program/browser.js',
'program/notepad.js',
'program/imageviewer.js',
'program/mediaplayer.js',
'system/config.js',
'system/controlpanel.js',
'system/uac.js',
'system/uac_app.js',
'system/audio.js',
'system/lambda.js',
'program/minesweeper.js',
'program/paint.js',
'//xpstore.glitch.me/appstore.js',
'boot/boot.js'
];
var stylesheets = [
'system/fonts.css',
'system/xp.css',
'system/icons.css',
'system/widgets.css',
'system/window.css',
'system/contextmenus.css',
'system/cursors.css',
'system/desktop.css',
'system/startmenu.css',
'system/explorer.css',
'system/jquery.terminal-2.0.0.min.css'
];
var requiredDirectories = [];
$(function() {
$('windows').html(`
<div class="_ui_boot">
<div class="_ui_boot_copyright"></div>
<div class="_ui_boot_companylogo"></div>
<center class="_ui_boot_logo">
<div class="_ui_boot_winlogo"></div>
<div class="_ui_boot_progress"></div>
<!--<div style="bottom:0;position:absolute;width:100%;" id="loadingstatus"></div>-->
</center>
</div>`);
console.log('Loading scripts and stylesheets...');
$('<link/>', {rel: 'stylesheet', href: 'boot/boot.css'}).appendTo('head');
var scriptsindex = 0;
var stylesindex = 0;
function loadStylesheets() {
$.ajax({
url: stylesheets[stylesindex],
dataType: "script",
success: function(data){
$("head").append("<style>" + data + "</style>");
stylesindex ++;
if (stylesindex < stylesheets.length) {
loadStylesheets();
} else {
loadScripts();
}
}
});
}
function loadScripts() {
$.ajax({
url: scripts[scriptsindex],
dataType: "script",
success: function(data){
scriptsindex ++;
if (scriptsindex < scripts.length) {
loadScripts();
} else {
console.log('Finished loading');
console.log('Checking for necessary directories');
function checkDir(path, callback) {
var times = 0;
xp.filesystem.listDir(path, (e) => {
if (times === 0)
callback(typeof e === 'string');
times ++;
});
}
var i = 0;
function checkNextDir(t) {
var dirToCreate = requiredDirectories[i];
if (dirToCreate !== undefined) {
xp.filesystem.createDir(dirToCreate, (e) => {
i ++;
checkNextDir();
});
} else {
xp.audio.init();
var event = new Event('xpboot');
window.dispatchEvent(event);
console.log('Dispatched boot event');
$('windows').html('<div class="_ui_wallpaper fullscreen"><img class="_ui_wallpaper_image" src="boot/assets/welcome.png"/></div>');
$.getScript('system/login.js');
xp.audio.playURL('boot/assets/startup.wav');
}
}
xp.filesystem.create(512*1024*1024, () => {
xp.filesystem.fs.root.getDirectory('/', {create: false}, function(dirEntry) {
var dirReader = dirEntry.createReader();
var entries = [];
function readEntries() {
dirReader.readEntries (function(results) {
if (results.length === 0) {
$('._ui_boot').remove();
$('windows').html('<div class="_ui_wallpaper fullscreen"><img class="_ui_wallpaper_image" src="boot/assets/welcome.png"/></div>');
$.getScript('setup/setup.js');
} else {
xp.filesystem.createDir('/WINDOWS', (e) => {
requiredDirectories = [
'/WINDOWS',
'/WINDOWS/system32',
'/WINDOWS/startup',
'/Program Files',
'/Documents and Settings'
];
checkNextDir();
});
}
}, console.error);
};
readEntries();
}, console.error);
});
}
}
});
}
loadStylesheets();
});

3
xp/cover.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<image href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAAAAAAAD/4QBCRXhpZgAATU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAkAAAAMAAAABAAAAAEABAAEAAAABAAAAAAAAAAAAAP/bAEMACwkJBwkJBwkJCQkLCQkJCQkJCwkLCwwLCwsMDRAMEQ4NDgwSGRIlGh0lHRkfHCkpFiU3NTYaKjI+LSkwGTshE//bAEMBBwgICwkLFQsLFSwdGR0sLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLP/AABEIADAAMAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/APXKKKwvE1/NZWcKW8rRzXEpXchw4jVcsVI5HJX86yrVVRg6kuh0YXDyxNWNGG7N2ivKmnuWk81ppTKOd7OxfP8AvE5rqtL1q4tbCCS/aacTXEscJODIsMSrubcevJxyfX0rzaGaQqyakreZ6+Y5M8BR9s5pr0t/mdXRWX/b+iYz9pOcZ2+VNn6fdx+tXLO7jvYBcRo6xs7KnmAAsFOC2AT3z+VelGtTm7Rkmz55ST0TLFcj4kgmu76NXuLW3gggAQ3UypudjuYoi5k9B93tXXEhQzMcBQSSegA5zXlV3cNdXV1cnOZ5pJACckBmJC/h0r0sLlccyThUbUVbY4sXntTJXGrRinN3Sv07suHSZ3VmtbmzvGUFmitZSZgoGSwjkVWP4A1av18k2dnjH2O1ijcZyPOkHnSEfi2PwqhpMPn6lYJnCrMsznkYSH963I9ga6Oc2d2zvc2wMjEkSwP5UmCejcFT+K18zxDg8HktSNNTfvq+utkvTXX06HfhM6x/EmEaqQS5JdNL6fp+pz1eiWUAtbS1t8AGKJVbHQvjLH8TmsDT7PTjcwKlqzMGLl7iUybQoJ4VAq/mDXT1lk0qdWMqtN3W3X1628ifqs8O7VN2V72GW5tLq3jdUeeNot7AkKr/ACscD2zisFPB+nBAJLq6aTHLJ5aLn2Uqx/8AHq6aivp6OLrUY8tOVjkxGBw+Jkp1o3a0OWt9Bn0p7+dZBOr2/kw7UIcCRwXLLz0Ax171DXX0wwwFt5ijL/3iilvzxXy+fZXWzivHESqWaVtvxPVyudLLqTo04aXvuZWjwndNOQcbRGhPQ5OTj8hWxRRXoZdgo4HDxoRd7de9xV6zrVHNn//Z" height="200" width="200" />
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

24
xp/index.html Normal file
View File

@ -0,0 +1,24 @@
<html>
<head>
<title>RebornXP</title>
<meta http-equiv="Content-Language" content="en_US"/>
<meta name="google" content="notranslate"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js" integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="boot/load.js"></script>
<link rel="shortcut icon" href="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Ffavicon.png?1521937672120"/>
<meta property="og:image" content="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Ffavicon.png?1521937672120"/>
<meta property="og:site_name" content="RebornXP"/>
<meta property="og:type" content="object"/>
<meta property="og:title" content="reborn-xp.js"/>
<meta property="og:url" content="https://reborn-xp.js.org/"/>
<meta property="og:description" content=" RebornXP is a free and open source project that brings the beloved Windows XP experience to modern web browsers. Built with JavaScript, RebornXP faithfully recreates the iconic interface, apps, and features of Windows XP."/>
</head>
<body style="background-color:#000000;color:#ffffff;">
<windows>
<noscript>
<br/>
<center>RebornXP requires Javascript. Please update your web browser.</center>
</noscript>
</windows>
</body>
</html>

102
xp/program/browser.js Normal file
View File

@ -0,0 +1,102 @@
function browserGo(loc, guid) {
if(!loc){
loc = document.getElementById('url_' + guid).value;
}
if (loc.indexOf('http://') == -1 && loc.indexOf('https://') == -1) {
loc = location.protocol + '//' + loc;
}
document.getElementById('webPage_' + guid).src = loc;
document.getElementById('url_' + guid).value = loc;
document.getElementById('loading_' + guid).style.display = 'block';
document.getElementById('webPage_' + guid).style.display = 'none';
}
function iframeContentUnload(guid) {
document.getElementById('loading_' + guid).style.display = 'block';
document.getElementById('webPage_' + guid).style.display = 'none';
}
function iframeContentLoaded(guid) {
document.getElementById('loading_' + guid).style.display = 'none';
document.getElementById('webPage_' + guid).style.display = 'block';
}
$(window).on('xpboot', function() {
xp.applications.add('browser', (args) => {
var guid = generate_guid();
var el = $.parseHTML(`<window title="Idiot Explorer 6" width="800" height="500">
<style>
.load-overlay {
position: absolute;
top: 24;
left: 0;
width: 100%;
height: calc(100% - 24px);
background: #d6d6ce;
z-index: 9999;
text-align: center;
}
.load-overlay-cell {
position: absolute;
top: calc(50% - 100px);
left: calc(50% - 100px);
}
@keyframes lds-dual-ring{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes lds-dual-ring{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.lds-dual-ring{position:relative}.lds-dual-ring div{position:absolute;width:40px;height:40px;top:80px;left:80px;border-radius:50%;border:4px solid #000;border-color:#51CACC transparent;-webkit-animation:lds-dual-ring 1s linear infinite;animation:lds-dual-ring 1s linear infinite}.lds-dual-ring{width:200px!important;height:200px!important;-webkit-transform:translate(-100px,-100px) scale(1) translate(100px,100px);transform:translate(-100px,-100px) scale(1) translate(100px,100px)}
</style>
<div id="webBrowserContent">
<button align="left" id="homeButton" onclick="browserGo('search.anasdew.com', '` + guid + `')" title="Home">Home</button>
<button align="left" onclick="browserGo('www.google.com/?igu=1', '` + guid + `')" title="Google">Google</button>
<button align="left" onclick="browserGo('www.wikipedia.com', '` + guid + `')" title="Wikipedia">Wikipedia</button>
<button align="left" id="videoButton" onclick="browserGo('www.bing.com/videos', '` + guid + `')" title="Videos">Videos</button>
<button align="left" id="imageButton" onclick="browserGo('www.bing.com/images', '` + guid + `')" title="Images">Images</button>
<input type="text" id="url_` + guid + `" value="` + location.protocol + `//search.anasdew.com" style="width:calc(100% - 600px);"/>
<button id="goButton" onclick="browserGo(undefined, '` + guid + `')" title="Go">Go</button><br>
<div style="width:calc(100% - 5px);height:calc(100% - 27px);">
<div style="display: none" id="loading_` + guid + `" title="Loading..." class="load-overlay">
<div class="load-overlay-cell">
<div class="lds-css ng-scope"><div style="width:100%;height:100%" class="lds-dual-ring"><div></div></div></div>
</div>
</div>
<iframe style="width:calc(100% - 5px);height:calc(100% - 29px);position:absolute;top:24;left:0;" onload="iframeContentLoaded('` + guid + `')" onunload="iframeContentUnload('` + guid + `')" src="` + location.protocol + `//search.anasdew.com" id="webPage_` + guid + `"></iframe>
</div>
</div>
</window>`);
document.body.appendChild(el[0]);
$(el).updateWindow();
var widthOffset = 30;
var heightOffset = 80;
window.iFrameChanges = -1;
});
xp.applications.add('html', (args) => {
var el = $.parseHTML(`<window title="` + args[1] + `" width="800" height="500">
<style>
iframe[seamless]{
background-color: transparent;
border: 0px none transparent;
padding: 0px;
overflow: hidden;
}
.frame-container {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
padding: 0px;
margin: 0px;
}
</style>
<div class="frame-container">
<iframe seamless="seamless" width="100%" height="100%" id="frame" src="` + args[1] + `"></iframe>
</div>
</window>`);
document.body.appendChild(el[0]);
$(el).updateWindow();
});
xp.startmenu.add('browser', 'Idiot Explorer 6', 'program/assets/ie.webp');
});

18
xp/program/imageviewer.js Normal file
View File

@ -0,0 +1,18 @@
$(window).on('xpboot', () => {
xp.applications.add('image-viewer', (args) => {
var image = args.length > 1 ? xp.filesystem.addPaths(args[0], args[1]) : '';
var imagename = xp.filesystem.basename(image);
var win = new Window({
width: 640,
height: 480,
title: image === '' ? 'Image Viewer' : (imagename + ' - Image Viewer')
});
xp.filesystem.toURL(image, (url) => {
win.content('<div style="width:100%;height:100%;background-size:100%;background-repeat:no-repeat;background-position:center;background-image:url(' + url + ')"></div>');
});
});
explorer.fileHandlers.add('png', (f) => openApp('image-viewer', ['', f]));
explorer.fileHandlers.add('jpg', (f) => openApp('image-viewer', ['', f]));
explorer.fileHandlers.add('jpeg', (f) => openApp('image-viewer', ['', f]));
explorer.fileHandlers.add('gif', (f) => openApp('image-viewer', ['', f]));
});

23
xp/program/mediaplayer.js Normal file
View File

@ -0,0 +1,23 @@
$(window).on('xpboot', () => {
xp.applications.add('media-player', (args) => {
var video = args.length > 1 ? xp.filesystem.addPaths(args[0], args[1]) : '';
var videoname = xp.filesystem.basename(video);
var win = new Window({
width: 480,
height: 360,
title: video === '' ? 'Media Player' : (videoname + ' - Media Player')
});
xp.filesystem.toURL(video, (url) => {
win.content(`<video width="100%" height="100%" style="background-color:#000;" controls>
<source src="` + url + `">
</video>`);
});
});
explorer.fileHandlers.add('webm', (f) => openApp('media-player', ['', f]));
explorer.fileHandlers.add('wav', (f) => openApp('media-player', ['', f]));
explorer.fileHandlers.add('ogg', (f) => openApp('media-player', ['', f]));
explorer.fileHandlers.add('ogv', (f) => openApp('media-player', ['', f]));
explorer.fileHandlers.add('mp3', (f) => openApp('media-player', ['', f]));
explorer.fileHandlers.add('mp4', (f) => openApp('media-player', ['', f]));
explorer.fileHandlers.add('flac', (f) => openApp('media-player', ['', f]));
});

30
xp/program/minesweeper.js Normal file
View File

@ -0,0 +1,30 @@
$(window).on('xpboot', () => {
xp.applications.add('minesweeper', () => {
var el = $.parseHTML(`<window width="300" height="410" title="Minesweeper">
<style>
iframe[seamless]{
background-color: transparent;
border: 0px none transparent;
padding: 0px;
overflow: hidden;
}
.frame-container {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
padding: 0px;
margin: 0px;
}
</style>
<div class="frame-container">
<iframe height="100%" seamless="seamless" width="100%" src="https://mines.vercel.app/"></iframe>
</div>
</window>`);
document.body.appendChild(el[0]);
$(el).updateWindow();
});
xp.startmenu.add('minesweeper', 'Minesweeper', 'https://w7.pngwing.com/pngs/337/559/png-transparent-minesweeper-computer-icons-bing-maps-video-game-mines-miscellaneous-game-angle.png');
});

56
xp/program/notepad.js Normal file
View File

@ -0,0 +1,56 @@
$(window).on('xpboot', () => {
xp.applications.add('notepad', (args) => {
var guid = generate_guid();
var el = $.parseHTML(`<window title="Notepad" width="480" height="360">
<textarea style="width: 100%; height: calc(100% - 19px); resize: none" id="notepad_` + guid + `" filename=""></textarea>
</window>`);
document.body.appendChild(el[0]);
$(el).updateWindow();
$(el).addMenu("File", [
["New", function() {
$("#notepad_" + guid).val("");
$("#notepad_" + guid).attr('filename', '');
}],
["Open", function() {
xp.filesystem.openFileDialog((filename) => {
xp.filesystem.readFile(filename, function(e) {
//e = e.split("\0")[0];
$("#notepad_" + guid).val(e);
$("#notepad_" + guid).attr("filename", filename);
});
});
}],
["Save", function() {
var filename = $("#notepad_" + guid).attr("filename");
if (filename === "") {
xp.filesystem.saveFileDialog((filename) => {
xp.filesystem.writeFile(filename, new Blob([$("#notepad_" + guid).val()], {type: 'text/plain'}), (e) => {
if (e) xp.dialog('Error', e);
});
});
} else {
xp.filesystem.writeFile(filename, new Blob([$("#notepad_" + guid).val()], {type: 'text/plain'}), (e) => {
if (e) xp.dialog('Error', e);
});
}
}],
["Save As", function() {
xp.filesystem.saveFileDialog((filename) => {
xp.filesystem.writeFile(filename, new Blob([$("#notepad_" + guid).val()], {type: 'text/plain'}), (e) => {
if (e) xp.dialog('Error', e);
});
});
}]
]);
if (args !== undefined && args[1] !== undefined) {
var filename = xp.filesystem.addPaths(args[0], args[1]);
xp.filesystem.readFile(filename, function(e) {
//e = e.split("\0")[0];
$("#notepad_" + guid).val(e);
$("#notepad_" + guid).attr("filename", filename);
});
}
});
xp.startmenu.add('notepad', 'Notepad', '//cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fnotepad.png?1521328884236');
});

30
xp/program/paint.js Normal file
View File

@ -0,0 +1,30 @@
$(window).on('xpboot', () => {
xp.applications.add('paint', () => {
var el = $.parseHTML(`<window width="800" height="500" title="JS Paint">
<style>
iframe[seamless]{
background-color: transparent;
border: 0px none transparent;
padding: 0px;
overflow: hidden;
}
.frame-container {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
padding: 0px;
margin: 0px;
}
</style>
<div class="frame-container">
<iframe height="100%" seamless="seamless" width="100%" src="https://jspaint.app/"></iframe>
</div>
</window>`);
document.body.appendChild(el[0]);
$(el).updateWindow();
});
xp.startmenu.add('paint', 'Paint', 'https://raw.githubusercontent.com/1j01/jspaint/master/images/icons/512x512.png');
});

94
xp/program/terminal.js Normal file
View File

@ -0,0 +1,94 @@
var terminalicon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACOUlEQVRYhe2Xv2sTYRjHP8/lvSRN27QipUr9UQLFLhVLRVrN4CQ5cKjg6uIgpQgObi6d+0/o0NHBpZCAVQqigw4VC9GAixAbpNGmMUnT/LjXoV4IJk3AXFLBfuG45w6e5/u55+6euxf+U4kTGEdiPzOjWFoyDkiu3ptDzAfjI9MWWqRdbif6sv3uhbGXe+zPbL0NFgM/U6nVgvLJ5dfjE2MycWmym94EzX1Ob47M5zOF+cTGk4WMKqwCBTU+OSYJdYrEx0zHJgN+xcObE6zH08STWRZvhFiPpwl+WuOResYd7vLhcxa/Lfd1pRIHvqpE31kYGurYHACfB0wvDA7Aibp4eBhKXuYC22z09yO71WBVjGnglbp2DsJX+twBAIr8YDYEsyGzFhMKs0KYQeDk5hp5W5uGiBdAhdUWy9cvugbQThdurZAXEWxtwFG9hnU6BmgAiEQiaK1rWyQSaUjSWncPIBqNYlkWIoJlWUSj0aaJzcBcAQCIxWK1vdRNZ+fKW4G5AnCYHBgH0I0uNAVwCjvPQzO51QXVrrBlWbVYa93QBef8YZI2H9gGgD/ve6tiznE7k1b69+bAMcAxQK+l0rtlpqamemaYK9u/B4doAPXyfarI+UVTS6+6UcDQdr7iMfYBVCr+dEFKxduCDoJuGExdUEWQHY/HnwRQYujnVY+8Mcu2F1s8Xbc3dLXis4umLmYB1F5VfT9Tyu2UywUDRrvuD98wdcBOju5X4GCR2NXlWBu592v1t/oFx8vJxHIFQMwAAAAASUVORK5CYII=';
$(window).on('xpboot', () => {
xp.applications.add("terminal", () => {
var guid = generate_guid();
var el = $.parseHTML(`<window title="Terminal" width="720" height="480">
<div class="ui_terminal" id="terminal_` + guid + `"></div>
</window>`);
document.body.appendChild(el[0]);
el = $(el);
el.updateWindow();
$("#terminal_" + guid).terminal(function(command) {
var term = this;
if (command !== '') {
try {
var args = command.split(" ");
if (this.dir === undefined)
this.dir = [""];
if (args[0] === "ls") {
xp.filesystem.listDir(xp.filesystem.getDir(this.dir), function(e){if(e){term.echo(e)}});
} else if (args[0] === "cd") {
if (args[1] === undefined) {
this.error("Not enough arguments");
} else {
let input = args.slice(1).join(' ');
if (input !== ".") {
if (input.charAt(0) === "/") {
this.dir = input.split("/");
} else {
var foo = input.split("/");
var _this = this;
foo.forEach(function(val, i) {
if (val === "..") {
_this.dir.splice(-1,1)
} else {
_this.dir = _this.dir.concat(val);
}
});
}
}
}
} else if (args[0] === "pwd") {
this.echo(xp.filesystem.getDir(this.dir));
} else if (args[0] === "touch") {
xp.filesystem.createFile(xp.filesystem.addPaths(xp.filesystem.getDir(this.dir), args[1]), function(e){if(e){term.echo(e)}});
} else if (args[0] === "rm") {
xp.filesystem.deleteFile(xp.filesystem.addPaths(xp.filesystem.getDir(this.dir), args[1]), function(e){if(e){term.echo(e)}});
} else if (args[0] === "mkdir") {
xp.filesystem.createDir(xp.filesystem.addPaths(xp.filesystem.getDir(this.dir), args[1]), function(e){if(e){term.echo(e)}});
} else if (args[0] === "rmdir") {
xp.filesystem.deleteDir(xp.filesystem.addPaths(xp.filesystem.getDir(this.dir), args[1]), function(e){if(e){term.echo(e)}});
} else if (args[0] === "cat") {
xp.filesystem.readFile(xp.filesystem.addPaths(xp.filesystem.getDir(this.dir), args[1]), function(e){if(e){term.echo(e)}});
} else if (args[0] === "help") {
this.echo("DE: XPerience");
this.echo("Kernel: RXP vOS.2023");
this.echo("Shell: JQuery Terminal");
this.echo("GitHub: github.com/shoaib-jamal/RebornXP");
this.echo("\nInstalled applications:");
var foo = "";
for (var name in xp.applications.apps) {
foo += name + ", ";
}
foo = foo.slice(0, -2);
this.echo(foo);
this.echo("\nSystem commands:");
this.echo("ls, cd, pwd, touch, rm, mkdir, rmdir, cat, help");
} else if (xp.applications.apps[args[0]] !== undefined) {
xp.applications.apps[args[0]]([xp.filesystem.getDir(this.dir)].concat(args.slice(1)));
} else {
var result = window.eval(command);
if (result !== undefined) {
this.echo(new String(result));
}
}
} catch(e) {
this.error(new String(e));
}
} else {
this.echo('');
}
}, {
greetings: `
RebornXP [vOS.2023]
(c) RebornXP Open-Source Project. All rights reserved.
`,
name: 'xpjs_terminal',
width: '100%',
height: '100%',
prompt: '> '
});
});
xp.startmenu.add("terminal", "Terminal", terminalicon);
});

38
xp/system/audio.js Normal file
View File

@ -0,0 +1,38 @@
xp.audio = {
context: null,
cache: {},
init: function() {
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
xp.audio.context = new AudioContext();
}
catch(e) {
console.error('Web Audio API is not supported in this browser');
}
},
playURL: function(url) {
if (xp.audio.cache[url] !== undefined) {
var source = xp.audio.context.createBufferSource();
source.buffer = xp.audio.cache[url];
source.connect(xp.audio.context.destination);
source.start(0);
} else {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function() {
if (xp.audio.context === null) {
xp.audio.init();
}
xp.audio.context.decodeAudioData(request.response, function(buffer) {
var source = xp.audio.context.createBufferSource();
source.buffer = buffer;
xp.audio.cache[url] = buffer;
source.connect(xp.audio.context.destination);
source.start(0);
}, console.error);
}
request.send();
}
}
};

34
xp/system/config.js Normal file
View File

@ -0,0 +1,34 @@
var configFile = '';
var config = {};
var loadingconfig = false;
function saveConfig(callback) {
if (!loadingconfig) {
config.wallpaper = xp.wallpaper.href;
config.profile = xp.profile;
config.theme = xp.theme.name;
xp.filesystem.writeFile(configFile, new Blob([JSON.stringify(config)], {type: 'text/plain'}), (e) => {
if (e) xp.error(e);
else if (callback !== undefined) callback()
});
}
}
function loadConfig(callback) {
loadingconfig = true;
xp.filesystem.readFile(configFile, (text) => {
try {
config = JSON.parse(text);
console.log(config);
xp.wallpaper.set('https://rebornxp.js.org/system/themes/XP.jpg');
xp.profile = config.profile;
xp.theme.set('reborn');
} catch(e) {
xp.wallpaper.set('https://rebornxp.js.org/system/themes/XP.jpg');
loadingconfig = false;
saveConfig();
}
loadingconfig = false;
if (callback !== undefined) callback();
});
}

View File

@ -0,0 +1,19 @@
.contextMenu {
box-shadow: 0px 0px 20px -5px #000;
clip-path: inset(0 -20px -20px 0);
}
.contextMenuItem {
color: #000000;
background-color: transparent;
font-size: 11px;
}
.contextMenuItem:hover {
color: #ffffff;
background-color: #0A246A;
}
.contextMenuItem.hr {
border-top: 1px solid #979797;
}

196
xp/system/contextmenus.js Normal file
View File

@ -0,0 +1,196 @@
var vContextMenu = Array();
var isContextMenu = false;
var CurX;
var CurY;
var tContextMenu;
function fMouseDown(event) {
try {
if(window.event) event = window.event;
CurX = event.clientX;
CurY = event.clientY;
if (document.getElementById('lContextMenu').style.visibility === 'hidden')
tContextMenu = event.target;
} catch(e) {}
}
function rcContextMenu() {
try {
if (vContextMenu.length != 0) {
drawContextMenu();
var targX = CurX; //0; //event.clientX;
var targY = CurY; //0; //event.clientY;
//alert
var testW = document.getElementById('lContextMenu').offsetWidth;
var testH = document.getElementById('lContextMenu').offsetHeight;
var testX = targX + document.getElementById('lContextMenu').offsetWidth;
var testY = targY + document.getElementById('lContextMenu').offsetHeight;
var sW = document.body.clientWidth;//document.body.clientWidth;
var sH = document.body.clientHeight;//document.body.clientHeight;
if (testX >= sW) { targX = targX - testW; }
if (testY >= sH) { targY = targY - testH; }
document.getElementById('lContextMenu').style.left = targX;
document.getElementById('lContextMenu').style.top = targY;
document.getElementById('lContextMenu').style.visibility = 'visible';
}
} catch (e) {}
}
function rcCloseContext() {
try {
document.getElementById('lContextMenu').style.left = 0;
document.getElementById('lContextMenu').style.top = 0;
document.getElementById('lContextMenu').style.visibility = 'hidden';
} catch (e) {}
}
function drawContextMenu() {
try {
var outMsg = '<table cellpadding="0" cellspacing="0" style="border: 1px solid #979797;"><tr><td><table cellpadding="0" cellspacing="0" style="border: 2px solid #f5f5f5;"><tr><td><table cellpadding="4" cellspacing="0" border="0" width="200" bgcolor="#f1f1f1" style="font-size: 10;"><tr><td rowspan="100" width="15" style="border-right: 1px solid #979797;" nowrap><img width="15" height="1"></td>';
var len = vContextMenu.length - 1;
var inMsg = vContextMenu[0];
var inCmd = vContextMenu[1];
if (typeof inCmd !== 'string') {
outMsg = outMsg + '<td class="contextMenuItem" onClick="rcCloseContext();" commandindex="1" nowrap>' + inMsg + '</td></tr>';
} else {
outMsg = outMsg + '<td class="contextMenuItem" onClick="rcCloseContext();' + inCmd + ';" nowrap>' + inMsg + '</td></tr>';
}
for (var i = 2; i <= len; i ++) {
inMsg = vContextMenu[i];
inCmd = vContextMenu[i+1];
if (inMsg != '-HR-') {
if (typeof inCmd !== 'string') {
var outMsg = outMsg + '<td class="contextMenuItem" commandindex="' + (i + 1) + '" nowrap>' + inMsg + '</td></tr>';
} else {
var outMsg = outMsg + '<td class="contextMenuItem" onClick="rcCloseContext();' + inCmd + ';" nowrap>' + inMsg + '</td></tr>';
}
i ++;
} else {
i ++;
inMsg = vContextMenu[i];
inCmd = vContextMenu[i+1];
if (typeof inCmd !== 'string') {
outMsg = outMsg + '<td class="contextMenuItem hr" commandindex="' + (i + 1) + '" nowrap>' + inMsg + '</td></tr>';
} else {
outMsg = outMsg + '<td class="contextMenuItem hr" onClick="rcCloseContext();' + inCmd + ';" nowrap>' + inMsg + '</td></tr>';
}
i ++;
}
}
outMsg = outMsg + '</table></td></tr></table></td></tr></table>';
document.getElementById('lContextMenu').innerHTML = outMsg;
// JQuery magic
$('#lContextMenu').find('td[commandindex]').each(function() {
$(this).on('click', function() {
rcCloseContext();
vContextMenu[parseInt($(this).attr('commandindex'))]();
});
});
} catch(e) {}
}
function desktopContextMenu(e) {
var el = $(e.target);
if (el.closest('windowbutton').length > 0) {
var guid = el.closest('windowbutton').attr('guid');
vContextMenu = Array();
if ($('window[guid=' + guid + ']').attr('maximized') === 'true') {
vContextMenu.push('Restore');
vContextMenu.push('maximizeWindow(\'' + guid + '\')');
} else if ($('window[guid=' + guid + ']').find('.maximize').length > 0 || $('window[guid=' + guid + ']').find('.restore').length > 0) {
vContextMenu.push('Maximize');
vContextMenu.push('maximizeWindow(\'' + guid + '\')');
}
if ($('window[guid=' + guid + ']').attr('minimized') === 'true') {
vContextMenu.push('Restore');
vContextMenu.push('moveWindowToTop(\'' + guid + '\')');
} else if ($('window[guid=' + guid + ']').find('.minimize').length > 0) {
vContextMenu.push('Minimize');
vContextMenu.push('minimizeWindow(\'' + guid + '\')');
}
if ($('window[guid=' + guid + ']').find('.close').length > 0) {
vContextMenu.push('Close');
vContextMenu.push('closeWindow(\'' + guid + '\')');
}
rcContextMenu();
} else if (el.closest('.ui_icon').length > 0) {
el = el.closest('.ui_icon');
vContextMenu = Array('<b>Open</b>', () => eval(el.data('exe')), 'Explore', () => openLocation(el.data('target')), '-HR-', 'Create Shortcut', '', 'Delete',() => el.remove(), 'Rename', () => xp.prompt('Rename', 'Enter the new name:', (t) => {el.find('span').html(t)}), '-HR-');
rcContextMenu();
}
}
function getSelectionText() {
var text = "";
var activeEl = document.activeElement;
var activeElTagName = activeEl ? activeEl.tagName.toLowerCase() : null;
if (
(activeElTagName == "textarea") || (activeElTagName == "input" &&
/^(?:text|search|password|tel|url)$/i.test(activeEl.type)) &&
(typeof activeEl.selectionStart == "number")
) {
text = activeEl.value.slice(activeEl.selectionStart, activeEl.selectionEnd);
} else if (window.getSelection) {
text = window.getSelection().toString();
}
return text;
}
function windowContextMenu(e, guid) {
var el = $('window[guid=' + guid + ']');
var t = e.target.nodeName;
console.log(t);
vContextMenu = Array();
var type = ($(e.target).attr('type') || '').toLowerCase();
if (t === 'TEXTAREA' || (t === 'INPUT' && (type === 'text' || type === 'number'))) {
vContextMenu.push('Copy');
vContextMenu.push('document.execCommand(\'copy\')');
vContextMenu.push('Paste');
vContextMenu.push('document.execCommand(\'paste\')');
vContextMenu.push('-HR-');
}
if (el.attr('maximized') === 'true') {
vContextMenu.push('Restore');
vContextMenu.push('maximizeWindow(\'' + guid + '\')');
} else if (el.find('.maximize').length > 0) {
vContextMenu.push('Maximize');
vContextMenu.push('maximizeWindow(\'' + guid + '\')');
}
if (el.attr('minimized') === 'true') {
vContextMenu.push('Restore');
vContextMenu.push('moveWindowToTop(\'' + guid + '\')');
} else if (el.find('.minimize').length > 0) {
vContextMenu.push('Minimize');
vContextMenu.push('minimizeWindow(\'' + guid + '\')');
}
if (el.find('.close').length > 0) {
vContextMenu.push('Close');
vContextMenu.push('closeWindow(\'' + guid + '\')');
}
rcContextMenu();
}
function startContextMenu(e) {
var el = $(e.target);
if (!(el.is('li.startmenuitem') || el.is('li.startmenuitem>img') || el.is('li.startmenuitem>div') || el.is('li.startmenuitem>div>div') || el.is('li.startmenuitem>div>div>b'))) return;
if (!el.is('li.startmenuitem'))
el = el.closest('li');
vContextMenu = Array('<b>Open</b>', el.attr('onclick'), 'Explore', el.attr('onclick'), '-HR-', 'Create Shortcut', '', 'Delete',() => el.remove(), 'Rename', () => xp.prompt('Rename', 'Enter the new name:', (t) => {el.find('div>div>b').html(t)}), '-HR-');
rcContextMenu();
}

254
xp/system/controlpanel.js Normal file
View File

@ -0,0 +1,254 @@
var configFile = 'config.json';
// Load the config on startup
$(window).on('xpboot', function() {
loadConfig();
});
function saveConfig(callback) {
if (!loadingconfig) {
config.wallpaper = xp.wallpaper.href;
config.profile = xp.profile;
config.theme = xp.theme.name;
xp.filesystem.writeFile(configFile, new Blob([JSON.stringify(config)], {type: 'text/plain'}), (e) => {
if (e) xp.error(e);
else if (callback !== undefined) callback();
});
}
}
function loadConfig(callback) {
loadingconfig = true;
xp.filesystem.readFile(configFile, (text) => {
try {
config = JSON.parse(text);
xp.wallpaper.set(config.wallpaper || 'https://rebornxp.js.org/system/themes/XP.jpg');
xp.profile = config.profile;
xp.theme.set(config.theme || 'reborn');
} catch (e) {
xp.wallpaper.set('https://rebornxp.js.org/system/themes/XP.jpg');
loadingconfig = false;
saveConfig();
}
loadingconfig = false;
if (callback !== undefined) callback();
});
}
// Add theme chooser to Control Panel
xp.controlpanel.add('Themes', () => {
var win = new Window({
width: 400,
height: 200, // Increased height to accommodate the wallpaper change option
title: 'Change Theme',
canResize: false,
});
win.content(`
<div class="content">
<h1>Theme Chooser</h1>
<p>Choose a new theme to apply:</p>
<select id="themeSelect">
${xp.themes.map(theme => `<option value="${theme}">${theme}</option>`).join('')}
</select>
<br/><br/>
<button id="applyThemeBtn">Apply Theme</button>
<button id="changeWallpaperBtn">Change Wallpaper</button> <!-- Added button for wallpaper change -->
</div>
`);
win.el.find('#applyThemeBtn').on('click', function() {
const selectedTheme = win.el.find('#themeSelect').val();
xp.theme.set(selectedTheme);
saveConfig();
win.close();
});
win.el.find('#changeWallpaperBtn').on('click', function() {
const wallpaperDialog = new Window({
width: 400,
height: 250,
title: 'Change Wallpaper',
canResize: false,
});
wallpaperDialog.content(`
<center><div class="content">
<h1>Wallpaper Chooser</h1>
<p>Select a wallpaper:</p>
<div class="wallpaper-thumbnails">
<!-- Thumbnails will be dynamically added here -->
</div>
<br/>
<input type="text" id="wallpaperLink" placeholder="Enter wallpaper link">
<button id="applyWallpaperBtn">Apply Wallpaper</button>
</div></center>
`);
const thumbnailsContainer = wallpaperDialog.el.find('.wallpaper-thumbnails');
// Add your wallpaper thumbnails here using the following format
const wallpaperThumbnails = [
'system/themes/XP.jpg',
'system/themes/wallpapers/anniversary.png',
'system/themes/wallpapers/3.jpg',
'system/themes/wallpapers/4.jpg',
'system/themes/wallpapers/5.jpg',
'system/themes/wallpapers/6.jpg',
];
wallpaperThumbnails.forEach(thumbnail => {
const thumbnailElement = $('<img>')
.attr('src', thumbnail)
.addClass('wallpaper-thumbnail')
.attr('width', "100px")
.attr('height', "60px")
.on('click', function() {
const selectedWallpaper = $(this).attr('src');
xp.wallpaper.set(selectedWallpaper);
saveConfig();
});
thumbnailsContainer.append(thumbnailElement);
});
wallpaperDialog.el.find('#applyWallpaperBtn').on('click', function() {
const wallpaperLink = wallpaperDialog.el.find('#wallpaperLink').val();
if (wallpaperLink) {
xp.wallpaper.set(wallpaperLink);
saveConfig();
}
wallpaperDialog.close();
});
});
// Calculate window position to center it on the screen
const screenWidth = $(window).width();
const screenHeight = $(window).height();
const windowWidth = win.el.outerWidth();
const windowHeight = win.el.outerHeight();
const left = (screenWidth - windowWidth) / 2;
const top = (screenHeight - windowHeight) / 2;
win.el.css({
position: 'absolute',
left: left + 'px',
top: top + 'px',
});
win.el.find('.content').css({
padding: '20px', // Adjust the padding value as needed
});
});
// Add theme chooser as an application
xp.applications.add('themes', () => {
var win = new Window({
width: 400,
height: 200, // Increased height to accommodate the wallpaper change option
title: 'Change Theme',
canResize: false,
});
win.content(`
<div class="content">
<h1>Theme Chooser</h1>
<p>Choose a new theme to apply:</p>
<select id="themeSelect">
${xp.themes.map(theme => `<option value="${theme}">${theme}</option>`).join('')}
</select>
<br/><br/>
<button id="applyThemeBtn">Apply Theme</button>
<button id="changeWallpaperBtn">Change Wallpaper</button> <!-- Added button for wallpaper change -->
</div>
`);
win.el.find('#applyThemeBtn').on('click', function() {
const selectedTheme = win.el.find('#themeSelect').val();
xp.theme.set(selectedTheme);
saveConfig();
win.close();
});
win.el.find('#changeWallpaperBtn').on('click', function() {
const wallpaperDialog = new Window({
width: 400,
height: 250,
title: 'Change Wallpaper',
canResize: false,
});
wallpaperDialog.content(`
<center><div class="content">
<h1>Wallpaper Chooser</h1>
<p>Select a wallpaper:</p>
<div class="wallpaper-thumbnails">
<!-- Thumbnails will be dynamically added here -->
</div>
<br/>
<input type="text" id="wallpaperLink" placeholder="Enter wallpaper link">
<button id="applyWallpaperBtn">Apply Wallpaper</button>
</div></center>
`);
const thumbnailsContainer = wallpaperDialog.el.find('.wallpaper-thumbnails');
// Add your wallpaper thumbnails here using the following format
const wallpaperThumbnails = [
'system/themes/XP.jpg',
'system/themes/wallpapers/anniversary.png',
'system/themes/wallpapers/3.jpg',
'system/themes/wallpapers/4.jpg',
'system/themes/wallpapers/5.jpg',
'system/themes/wallpapers/6.jpg',
];
wallpaperThumbnails.forEach(thumbnail => {
const thumbnailElement = $('<img>')
.attr('src', thumbnail)
.addClass('wallpaper-thumbnail')
.attr('width', "100px")
.attr('height', "60px")
.on('click', function() {
const selectedWallpaper = $(this).attr('src');
xp.wallpaper.set(selectedWallpaper);
saveConfig();
});
thumbnailsContainer.append(thumbnailElement);
});
wallpaperDialog.el.find('#applyWallpaperBtn').on('click', function() {
const wallpaperLink = wallpaperDialog.el.find('#wallpaperLink').val();
if (wallpaperLink) {
xp.wallpaper.set(wallpaperLink);
saveConfig();
}
wallpaperDialog.close();
});
});
// Calculate window position to center it on the screen
const screenWidth = $(window).width();
const screenHeight = $(window).height();
const windowWidth = win.el.outerWidth();
const windowHeight = win.el.outerHeight();
const left = (screenWidth - windowWidth) / 2;
const top = (screenHeight - windowHeight) / 2;
win.el.css({
position: 'absolute',
left: left + 'px',
top: top + 'px',
});
win.el.find('.content').css({
padding: '20px', // Adjust the padding value as needed
});
});

620
xp/system/core.js Normal file
View File

@ -0,0 +1,620 @@
var xp = {
post: true,
version: "2.0-beta",
openFileHandler: (path) => {},
applications: {
apps: {},
add: function(name, func) {
xp.applications.apps[name] = func;
},
remove: function(name) {
delete xp.applications.apps[name];
}
},
themes: ['reborn', 'classic', 'luna', 'silver', 'vista'],
theme: {
name: 'luna',
set: function(name) {
xp.theme.name = name;
if (xp.theme.name !== 'default') {
$('#theme').attr('href', 'system/themes/' + xp.theme.name + '.css');
} else {
$('#theme').attr('href', '');
}
if (saveConfig) saveConfig();
}
},
wallpaper: {
href: "",
set: function(name) {
if (name === undefined) {
xp.wallpaper.set(xp.wallpaper.href);
} else if (name === "") {
$("._ui_wallpaper_image").attr("src", "");
xp.wallpaper.href = "";
} else {
$("._ui_wallpaper_image").attr("src", name);
xp.wallpaper.href = name;
}
if (saveConfig) saveConfig();
},
setLocal: function(path) {
xp.filesystem.toURL(path, (url) => {
xp.wallpaper.set(url);
});
}
},
icons: {
error: 'data:image/png;base64,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',
warning: 'data:image/png;base64,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',
info: 'data:image/png;base64,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'
},
dialog: function(title, text, callback, isyesno, type, nocallback) {
if (type === undefined) type = 'info';
var icon = undefined;
if (type === 'info') icon = xp.icons.info;
if (type === 'warning') icon = xp.icons.warning;
if (type === 'error') icon = xp.icons.error;
if (type === 'info') xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Ding.wav?1522624603096');
if (type === 'warning') xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Error.wav?1522624607974');
if (type === 'error') xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Critical%20Stop.wav?1522624592867');
var win = new Window({
width: 340,
height: 154,
title: title,
canResize: false,
canMinimize: false
});
if (isyesno) {
win.content(`<img draggable="false" style="position: absolute;left:11px;top:17px;" src="` + icon + `"/>
<p style="position:absolute;left:54px;top:8px;width:calc(100% - 54px);word-wrap:break-word;height:calc(100% - 68px);overflow-y:auto;">` + text + `</p>
<center style="position:absolute;bottom:17px;right:16.7px;">
<button class="yes">Yes</button>
<button class="no">No</button>
</center>`);
} else {
win.content(`<img draggable="false" style="position: absolute;left:11px;top:17px;" src="` + icon + `"/>
<p style="position:absolute;left:54px;top:8px;width:calc(100% - 54px);word-wrap:break-word;height:calc(100% - 68px);overflow-y:auto;">` + text + `</p>
<center style="position:absolute;bottom:17px;right:16.7px;">
<button class="ok">OK</button>
</center>`);
}
if (isyesno) {
win.el.find('.no').on('click', function() {
win.close();
if (nocallback !== undefined) nocallback();
});
win.el.find('.yes').on('click', function() {
win.close();
if (callback !== undefined) callback();
}).focus();
} else {
win.el.find('.ok').on('click', function() {
win.close();
if (callback !== undefined) callback();
}).focus();
}
},
alert: function(msg, callback, nocallback) {
xp.dialog('Alert', msg, callback, false, 'info', nocallback);
},
error: function(msg, callback, nocallback) {
xp.dialog('Error', msg, callback, false, 'error', nocallback);
},
prompt: function(title, text, callback, defaulttext, nocallback) {
xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Ding.wav?1522624603096');
var guid = generate_guid();
var temp = document.createElement('div');
if (defaulttext === undefined) defaulttext = "";
var win = new Window({
width: 340,
height: 154,
title: title,
canResize: false,
canMinimize: false
});
win.content(`<p style="position:relative;left:8px;width:calc(100% - 8px);">` + text + `</p>
<input type="text" class="prompttext" style="width:calc(100% - 16px);position:relative;left:8px;"/>
<center style="position:absolute;bottom:17px;right:16.7px;">
<button class="ok">OK</button>
<button class="cancel">Cancel</button>
</center>`);
win.el.find('.prompttext').val(defaulttext);
win.el.find('.cancel').on('click', function() {
win.close();
if (nocallback !== undefined) nocallback();
});
win.el.find('.ok').on('click', function() {
win.close();
callback(win.el.find('.prompttext').val());
});
},
chooser: function(title, text, options, callback, nocallback) {
xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Ding.wav?1522624603096');
var guid = generate_guid();
var optionstext = '';
for (var i = 0; i < options.length; i ++) {
optionstext += '<option>' + options[i] + '</option>';
}
var win = new Window({
width: 340,
height: 154,
title: title,
canResize: false,
canMinimize: false
});
win.content(`<p style="position:relative;left:8px;width:calc(100% - 8px);">` + text + `</p>
<select class="select" style="width:calc(100% - 16px);position:relative;left:8px;">` + optionstext + `</select>
<center style="position:absolute;bottom:17px;right:16.7px;">
<button class="ok">OK</button>
<button class="cancel">Cancel</button>
</center>`);
win.el.find('.cancel').on('click', function() {
win.close();
if (nocallback !== undefined) nocallback();
});
win.el.find('.ok').on('click', function() {
win.close();
callback(win.el.find('.select').val());
});
}
};
$.fn.closeWindow = function() {
closeWindow($(this).attr('guid'));
}
$.fn.setTitle = function(title) {
var guid = $(this).attr('guid');
if (title === '') title = ' ';
title = title.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
$('window[guid=' + guid + ']').attr('title', title);
$('window[guid=' + guid + ']').find('.windowTitle').html(title.replace(/ /g,'&nbsp;'));
$('windowbutton[guid=' + guid + '] div').html(title);
};
function maximizeWindow(guid, force) {
var el = $('window[guid=' + guid + ']');
if (el.attr('maximized') === 'true' && force !== true) {
el.attr('maximized', 'false');
el.attr('width', el.attr('prevwidth'));
el.attr('height', el.attr('prevheight'));
el.css('left', el.attr('prevleft'));
el.css('top', el.attr('prevtop'));
} else {
el.attr('maximized', 'true');
if (!force) {
el.attr('prevwidth', el.attr('width'));
el.attr('prevheight', el.attr('height'));
el.attr('prevleft', el.css('left'));
el.attr('prevtop', el.css('top'));
}
el.attr('width', $(window).width());
el.attr('height', $(window).height() - (el.find('.windowTitle').closest('table').height() + $('taskbar').height()) + parseInt(el.find('.windowBody').css("border-bottom-width")));
el.css('left', -parseInt(el.find('.windowBody').css("border-left-width")));
el.css('top', -parseInt(el.find('.windowBody').css("border-right-width")));
}
el.updateWindow();
var event = new Event('resize');
el[0].dispatchEvent(event);
}
// Generate GUID
function generate_guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
// Window control
function closeWindow(guid) {
var el = $('[guid=' + guid + ']');
$('window[guid=' + guid + ']')[0].dispatchEvent(new Event('close'));
setTimeout(function() {
el.remove();
}, 50);
}
function minimizeWindow(guid) {
var el = $('[guid=' + guid + ']');
el.attr("minimized", "true");
el.attr("inactive", "true");
updateAllWindows();
}
function sortProperties(obj) {
// convert object into array
var sortable=[];
for(var key in obj)
if(obj.hasOwnProperty(key))
sortable.push([key, obj[key]]); // each item is an array in format [key, value]
// sort items by value
sortable.sort(function(a, b) {
return a[1]-b[1]; // compare numbers
});
return sortable; // array in format [ [ key1, val1 ], [ key2, val2 ], ... ]
}
var createdIndexes = 0;
function updateIndexes(topGuid) {
var newIndexes = {};
var maxIndex = 0;
$("window").each(function(index) {
var el = $(this);
var index = parseInt(el.attr("index"));
var guid = el.attr("guid");
newIndexes[guid] = index;
if (index > maxIndex)
maxIndex = index;
});
if (topGuid === undefined) {
topGuid = Object.keys(newIndexes).find(key => newIndexes[key] === maxIndex);
}
newIndexes[topGuid] = maxIndex + 1;
newIndexes = sortProperties(newIndexes);
var index = 0;
for (var i = 0, len = newIndexes.length; i < len; i++) {
var guid = newIndexes[i][0];
var inactive = i === len - 1 ? "false" : "true"
index ++;
$("window[guid=" + guid + "]").attr("index", index);
$("window[guid=" + guid + "]").attr("inactive", inactive);
}
createdIndexes = index;
}
$.fn.updateWindow = function() {
updateWindow(this, true);
updateIndexes();
updateAllWindows();
}
function hideMenu(name, guid) {
$("#" + name.replace(/ /g,"_") + "_menu_" + guid).css("display", "none");
$("#" + name.replace(/ /g,"_") + "_menubutton_" + guid).removeClass('_ui_menu_item_active');
}
$.fn.addMenu = function(name, items) {
var guid = generate_guid();
var el = `<div class="_ui_menu">
<span class="_ui_menu_item" id="` + name.replace(/ /g,"_") + `_menubutton_` + guid + `">
` + name + `
</span><div id="` + name.replace(/ /g,"_") + `_menu_` + guid + `" style="display:none;position:absolute;z-index:32767;">
<table cellpadding="0" cellspacing="0" style="border: 1px solid #979797;"><tbody><tr><td>
<table cellpadding="0" cellspacing="0" style="border: 2px solid #f5f5f5;"><tbody><tr><td>
<table cellpadding="4" cellspacing="0" border="0" width="200" bgcolor="#f1f1f1" style="font-size: 10;"><tbody>`;
for (var i = 0; i < items.length; i ++) {
el += '<tr>';
if (i === 0) {
el += '<td rowspan="100" width="15" style="border-right: 1px solid #979797;" nowrap=""><img width="15" height="1"></td>';
}
el += '<td class="contextMenuItem" onclick="rcCloseContext();" nowrap id="' + items[i][0].replace(/ /g,"_") + '_' + guid + '">' + items[i][0] + '</td></tr>';
}
el += '</div></span></div>';
this.find(".menuContainer").append(el);
function createMenuCallback(name, guid, callback) {
return function() {
hideMenu(name, guid);
callback();
};
}
for (var i = 0; i < items.length; i ++) {
$("#" + items[i][0].replace(/ /g,"_") + "_" + guid).on('click', createMenuCallback(name, guid, items[i][1]));
}
$("#" + name.replace(/ /g,"_") + "_menubutton_" + guid).on('click', function(e) {
$("#" + name.replace(/ /g,"_") + "_menu_" + guid).css("display", "inline");
$(this).addClass('_ui_menu_item_active');
});
this.find(".windowBody").on('click', function(e) {
var el = $(e.target);
var canClose = !(el.is("span._ui_menu_item#" + name.replace(/ /g,"_") + "_menubutton_" + guid) || el.is("li.menuitem"));
if (canClose) {
hideMenu(name, guid);
}
});
}
jQuery.fn.tagName = function() {
return this.prop("tagName");
};
function getRandomArbitrary(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
function updateWindow(el, doUpdate) {
if (el.attr("guid") === undefined) {
var html = el.html();
var guid = generate_guid();
el.attr("guid", guid);
var width = el.attr("width");
var height = el.attr("height");
var tstyle2 = "";
if (width !== undefined) tstyle2 += "width: " + width + "; ";
if (height !== undefined) tstyle2 += "height: " + height + "; ";
var newHtml = "";
var inactive = el.attr("inactive") === "true" ? "inactive" : "";
var index = el.attr("index");
var title = (el.attr("title") === '' || el.attr("title") === undefined) ? '&nbsp;' : el.attr("title");
/*
var posx = (Math.random() * ($(window).width() - (parseInt(width) - 40)) + 20).toFixed();
var posy = (Math.random() * ($(window).height() - (parseInt(height) - 40)) + 20).toFixed();
el.css({'left': posx + 'px', 'top': posy + 'px'});
*/
if (index === undefined) {
index = createdIndexes ++;
el.attr("index", index);
}
newHtml = `
<table cellspacing="0" class="titlebar"><tbody>
<tr>
<td class="titleBar_left"></td>
<td class="titleBar_middle">
<div class="windowTitleBg ` + inactive + `">
<table cellspacing="0" style="width: 100%; height: 100%;">
<tr style="width: 100%; height: 100%;">
<td style="max-width: 100%; height: 100%; padding: 0;">
<div class="windowTitle ` + inactive + ` ">` + title + `</div>
</td>
<td style="height: 100%; padding: 0;">
<button tabindex="-1" class="close" title="Close" onclick="closeWindow('` + guid + `')"></button>
<button tabindex="-1" class="maximize" title="Maximize" onclick="maximizeWindow('` + guid + `')"></button>
<button tabindex="-1" class="minimize" title="Minimize" onclick="minimizeWindow('` + guid + `')"></button>
</td>
</table>
</div>
</td>
<td class="titleBar_right"></td>
</tr>
</tbody></table>
<div style="` + tstyle2 + `" class="windowBody" title=""><div class="menuContainer"></div>` + html + `</div>
<div class="resize resize-se"></div><div class="resize resize-sw"></div>
<div class="resize resize-ne"></div><div class="resize resize-nw"></div>
<div class="resize resize-n"></div><div class="resize resize-s"></div>
<div class="resize resize-e"></div></div><div class="resize resize-w"></div>
`;
el.html(newHtml);
var posx = getRandomArbitrary(0, $(window).width() - parseInt(width) - parseInt(el.find('.windowBody').css('border-left-width')) - parseInt(el.find('.windowBody').css('border-right-width')));
var posy = getRandomArbitrary(0, $(window).height() - parseInt(height) - el.find('.titlebar').height() - parseInt(el.find('.windowBody').css('border-top-width')) - parseInt(el.find('.windowBody').css('border-bottom-width')));
el.css({'left': posx + 'px', 'top': posy + 'px'});
console.log({'left': posx + 'px', 'top': posy + 'px'});
el.find('table.titlebar').css('width', (el.find('.windowBody').width() + parseInt(el.find('.windowBody').css('border-left-width')) + parseInt(el.find('.windowBody').css('border-right-width'))) + 'px');
if (el.attr('minimized') === undefined)
el.attr('minimized', "false");
el.css('zIndex', index);
el.ui_draggable();
el.children('.resize-se')[0].addEventListener('mousedown', function(e) {
initDrag(e, el[0], 'se');
}, false);
el.children('.resize-sw')[0].addEventListener('mousedown', function(e) {
initDrag(e, el[0], 'sw');
}, false);
el.children('.resize-ne')[0].addEventListener('mousedown', function(e) {
initDrag(e, el[0], 'ne');
}, false);
el.children('.resize-nw')[0].addEventListener('mousedown', function(e) {
initDrag(e, el[0], 'nw');
}, false);
el.children('.resize-n')[0].addEventListener('mousedown', function(e) {
initDrag(e, el[0], 'n');
}, false);
el.children('.resize-s')[0].addEventListener('mousedown', function(e) {
initDrag(e, el[0], 's');
}, false);
el.children('.resize-e')[0].addEventListener('mousedown', function(e) {
initDrag(e, el[0], 'e');
}, false);
el.children('.resize-w')[0].addEventListener('mousedown', function(e) {
initDrag(e, el[0], 'w');
}, false);
$("taskbar").append('<windowbutton guid="' + guid + '" inactive="' + el.attr("inactive") + '"><div>' + title + '</div></windowbutton>');
el.on('click', function() {
rcCloseContext();
closeStartMenu();
});
el.on('mousedown', function(e) {
var t = e.target.nodeName;
fMouseDown(this);
e.stopPropagation();
return true;
});
el.on('contextmenu', function(e) {
fMouseDown(this);
windowContextMenu(e, guid);
return false;
});
if (el.attr('maximized') === 'true') {
el.find('button.maximize').attr('class', 'restore').attr('title', 'Restore');
}
updateIndexes(guid);
} else {
var isActive = el.attr("inactive") === 'false' ? true : false;
var guid = el.attr("guid");
var width = el.attr("width");
var height = el.attr("height");
var tstyle2 = "";
if (width !== undefined) tstyle2 += "width: " + width + "; ";
if (height !== undefined) tstyle2 += "height: " + height + "; ";
var newHtml = "";
var inactive = el.attr("inactive") === "true" ? "inactive" : "";
var index = el.attr("index");
if (index === undefined) {
index = createdIndexes ++;
el.attr("index", index);
}
el.find('table.titlebar').css('width', (el.find('.windowBody').width() + parseInt(el.find('.windowBody').css("border-left-width")) + parseInt(el.find('.windowBody').css("border-right-width"))) + 'px');
var title = (el.attr("title") === '' || el.attr("title") === undefined) ? '&nbsp;' : el.attr("title");
el.children("div.windowBody").attr("style", tstyle2);
if (doUpdate) {
el.children("div.windowBody").html(html);
el.children("div.windowTitle").html(title);
}
el.find("div.windowTitleBg").attr("class", "windowTitleBg " + inactive);
el.find("div.windowTitle").attr("class", "windowTitle " + inactive);
el.css("z-index", index);
$("windowbutton[guid=" + guid + "] div").html(title);
$("windowbutton[guid=" + guid + "]").attr("inactive", el.attr("inactive"));
$("windowbutton[guid=" + guid + "]").attr("onclick", "handleTaskbarButton('" + guid + "')");
if (el.attr('maximized') === 'true') {
el.find('button.maximize').attr('class', 'restore').attr('title', 'Restore');
} else {
el.find('button.restore').attr('class', 'maximize').attr('title', 'Maximize');
}
}
}
var startX, startY, startWidth, startHeight, resizeEl, dragType;
function initDrag(e, el, type) {
startX = e.clientX;
startY = e.clientY;
resizeEl = el;
dragType = type;
startWidth = parseInt(document.defaultView.getComputedStyle(resizeEl).width, 10);
startHeight = parseInt(document.defaultView.getComputedStyle(resizeEl).height, 10);
document.documentElement.addEventListener('mousemove', doDrag, false);
document.documentElement.addEventListener('mouseup', stopDrag, false);
}
function doDrag(e) {
e.preventDefault();
e.stopPropagation();
var el = $(resizeEl);
if (dragType === 'w' || dragType === 'sw') {
var width = startWidth - e.clientX + startX;
var height = startHeight + e.clientY - startY;
} else if (dragType === 'nw') {
var width = startWidth - e.clientX + startX;
var height = startHeight - e.clientY + startY;
} else if (dragType === 'n' || dragType === 'ne') {
var width = startWidth + e.clientX - startX;
var height = startHeight - e.clientY + startY;
} else {
var width = startWidth + e.clientX - startX;
var height = startHeight + e.clientY - startY;
}
if (width < 125)
width = 125;
if (height < 125)
height = 125;
width -= parseInt(el.find('.windowBody').css("border-left-width")) + parseInt(el.find('.windowBody').css("border-right-width"));
height -= 34;
if (dragType === 'se') {
el.attr("width", width);
el.attr("height", height);
} else if (dragType === 'e') {
el.attr("width", width);
} else if (dragType === 's') {
el.attr("height", height);
} else if (dragType === 'w') {
el.css("left", parseInt(el.css("left")) + parseInt(el.attr("width")) - width);
el.attr("width", width);
} else if (dragType === 'sw') {
el.css("left", parseInt(el.css("left")) + parseInt(el.attr("width")) - width);
el.attr("width", width);
el.attr("height", height);
} else if (dragType === 'nw') {
el.css("left", parseInt(el.css("left")) + parseInt(el.attr("width")) - width);
el.attr("width", width);
el.css("top", parseInt(el.css("top")) + parseInt(el.attr("height")) - height);
el.attr("height", height);
} else if (dragType === 'n') {
el.css("top", parseInt(el.css("top")) + parseInt(el.attr("height")) - height);
el.attr("height", height);
} else if (dragType === 'ne') {
el.attr("width", width);
el.css("top", parseInt(el.css("top")) + parseInt(el.attr("height")) - height);
el.attr("height", height);
} else {
el.attr("width", width);
el.attr("height", height);
}
updateWindow($(el));
el.find('table.titlebar').css('width', (el.find('.windowBody').width() + parseInt(el.find('.windowBody').css("border-left-width")) + parseInt(el.find('.windowBody').css("border-right-width"))) + 'px');
}
function stopDrag(e) {
document.documentElement.removeEventListener('mousemove', doDrag, false);
document.documentElement.removeEventListener('mouseup', stopDrag, false);
resizeEl.dispatchEvent(new Event('resize'));
}
$.fn.ui_draggable = function() {
var $this = this,
ns = 'draggable_'+(Math.random()+'').replace('.',''),
mm = 'mousemove.'+ns,
mu = 'mouseup.'+ns,
$w = $(window),
isFixed = ($this.css('position') === 'fixed'),
adjX = 0, adjY = 0;
$this.mousedown(function(ev) {
moveWindowToTop($this.attr("guid"));
var pos = $this.offset();
if (isFixed) {
adjX = $w.scrollLeft(); adjY = $w.scrollTop();
}
var ox = (ev.pageX - pos.left), oy = (ev.pageY - pos.top);
if (oy > $this.find('.windowTitleBg').height() || ($this.attr('maximized') || 'false').toLowerCase() !== 'false') {
return;
}
$this.data(ns,{ x : ox, y: oy });
$w.on(mm, function(ev){
ev.preventDefault();
ev.stopPropagation();
if (isFixed) {
adjX = $w.scrollLeft(); adjY = $w.scrollTop();
}
var offset = $this.data(ns);
$this.css({left: ev.pageX - adjX - offset.x, top: ev.pageY - adjY - offset.y});
});
$w.on(mu, function(){
$w.off(mm + ' ' + mu).removeData(ns);
});
});
return this;
};
function moveWindowToTop(guid) {
var el = $('window[guid=' + guid + ']');
el.attr("minimized", "false");
updateIndexes(guid);
updateAllWindows();
}
function updateAllWindows() {
$("window").each(function(index) {
updateWindow($(this));
});
}
$(function() {
window.addEventListener('resize', (e) => {
console.log(e);
$('window[maximized=true]').each(function() {
maximizeWindow($(this).attr('guid'), true);
});
}, true);
});

19
xp/system/cursors.css Normal file
View File

@ -0,0 +1,19 @@
*, .arrow {
cursor: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fdefault.cur?1522440134277), default;
}
.pointer, a {
cursor: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fpointer.cur?1522440855074), pointer;
}
.text {
cursor: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Ftext.cur?1522441235513), text;
}
.terminal, .ui_terminal, .terminal *, textarea, input:not([type=button]):not([type=submit]) {
cursor: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Ftext.cur?1522441235513), text !important;
}
._ui_boot, ._ui_boot * {
cursor: none;
}

79
xp/system/desktop.css Normal file
View File

@ -0,0 +1,79 @@
.ui_desktop {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
padding: 8px;
}
.ui_icon {
position: relative;
text-align: center;
display: inline-block;
vertical-align: top;
height: 60px;
width: 72px;
z-index: 0;
line-height: 12px;
margin-bottom: 2px;
padding-top: 5px;
padding-left: 1px;
color: #000;
pointer-events: none;
}
.ui_icon>.icon {
width: 32px;
height: 32px;
display: block;
margin: auto;
border: 0;
border-bottom: 1px solid transparent;
box-sizing: content-box;
/*image-rendering: optimizeSpeed;
image-rendering: -moz-crisp-edges;
image-rendering: -o-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
-ms-interpolation-mode: nearest-neighbor;*/
pointer-events: auto;
}
.ui_icon.ui_icon_large>.icon {
width: 48px;
height: 48px;
display: block;
margin: auto;
border: 0;
border-bottom: 1px solid transparent;
box-sizing: content-box;
pointer-events: auto;
}
.ui_icon>span {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
padding: 1px 2px;
padding-left: 2px;
max-width: 100%;
max-height: 26px;
pointer-events: auto;
box-sizing: border-box;
color: white;
text-shadow: 1px 1px 4px black;
}
.ui_icon.ui_selected:not(.ui_is_dragging)>.icon {
filter: brightness(.5) sepia(100%) hue-rotate(180deg) saturate(8);
}
.ui_icon.ui_selected>span {
outline-color: rgba(255,255,255,.8);
background: #0090e4;
color: #fff;
text-shadow: 0 0 transparent;
}

97
xp/system/explorer.css Normal file

File diff suppressed because one or more lines are too long

690
xp/system/explorer.js Normal file
View File

@ -0,0 +1,690 @@
function openLocation(path) {
openApp('explorer', [path]);
}
function DnDFileController(selector, onDropCallback) {
var el_ = document.querySelector(selector);
this.dragenter = function(e) {
e.stopPropagation();
e.preventDefault();
el_.classList.add('dropping');
};
this.dragover = function(e) {
e.stopPropagation();
e.preventDefault();
};
this.dragleave = function(e) {
e.stopPropagation();
e.preventDefault();
};
this.drop = function(e) {
e.stopPropagation();
e.preventDefault();
el_.classList.remove('dropping');
onDropCallback(e.dataTransfer.files)
};
el_.addEventListener('dragenter', this.dragenter, false);
el_.addEventListener('dragover', this.dragover, false);
el_.addEventListener('dragleave', this.dragleave, false);
el_.addEventListener('drop', this.drop, false);
};
function getIconURL(iconName) {
var el = $(`<span class="icon_${iconName}"/>`);
$('body').append(el);
var res = el.css('background-image');
el.remove();
return res.slice(4, -1).replace(/"/g, "");
}
$(window).on('xpboot', function() {
explorer.register();
xp.openFileHandler = explorer.fileHandlers.open;
xp.startmenu.add("explorer", "Explorer", getIconURL('folder'));
explorer.specialLocations = {
'My Computer': [['dir', 'hardDrive', 'Local Disk (C:)', '/']],
'Control Panel': []
};
let temp = [];
for (let i = 0; i < scripts.length; i ++) {
temp.push(['file', 'file', scripts[i].replace(/^.*[\\\/]/, ''), '/WINDOWS/system32/' + scripts[i].replace(/^.*[\\\/]/, '')]);
}
for (let i = 0; i < stylesheets.length; i ++) {
temp.push(['file', 'file', stylesheets[i].replace(/^.*[\\\/]/, ''), '/WINDOWS/system32/' + stylesheets[i].replace(/^.*[\\\/]/, '')]);
}
explorer.specialLocations['/WINDOWS/system32'] = temp;
});
var explorer = {
specialLocations: {},
hiddenLocations: ['/WINDOWS', '/WINDOWS/system32', '/Program Files'],
clipboard: '',
lastRename: '',
icons: {
back: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAEiklEQVRIx7WWWWxUVRjHf7cd24GRTmW1tAXFQjGlY7CNCqLEGDWt0cRAwhokkR1cogblhfhEgCcbJSxiNAYxxOADmlSjYiwgiyDdCNu0QDfazgww271z7z2LD1OmNC2LGs/bOffe/++733rgf17GnR42hxr016FvOHz9CE03moiKKIaAcl85E3InUD22itVla41/DGgKNegt7Vs5EPmeZ/NmMdX7MH6Pj9HZXkKpTtoSrbTGr9Ac7cZ1c1hdsopNMzYb9wTYe3mPXhNcR/WoKpY8uBAlEsTdXmJOiKjdTcIJEXN6caQJQJeV5HBnFwXeEhoWNhp3BGwPbtMftG5gy+RNlOSMJ+FGiDpXiTlhonY3STdCwgkP6YqDl9vJ0UXUvz4QktkcuVqnZ52azc5Hayi4L5+400vMDRG1e0g6YbKNLF4qfoOI3UXtlR1DQ4LtjPaUUbfkkDEIEDgY0E/5A7w4cmbaHU43cTtEzL7KKG8hbwd2M8wzAoCaxmUEoyeHhHz750U+fm4XCx5fbABkAWy/sE13W508k1dGj9lCd/ICoWSQsNUySBzgut01pLirJRWPjGHtD+syZ1kAO1p38PIDM+gxWwiZQcJWKzGnl4LhkweJ77mwkUhqIEChsbQgpSX+vFzIsthe96kGyHKlO6kp2kyBJ4uwdYmwdRlHmhT6SocUP95zILPXgKMlpnKxlcCSLrYWFI7zUXu2FgDPT221LWMMH0m7C6ldgCHFO5LnGekdT9XEVZkzoSUKUFrReP0Yp6/9gaMkw3we2i61pQEAOdq4ozhAka+UIl/pbSvWVIKj4UM4WqK8muarzX0ABcj/3nOkVlhKIFG4WRJS9AE04Pa/2Jk8T03jskF/8Vf4V64kziK0QgNCKxQapTUCxelrR0lpgaskiRsufo+fCDfwTPAW0hlLDLBmKMjU/CfYd6mGYPwMtpIIrXC1wtESoTW2FkitcXQaMG10gN85QlagqMKY6C0mbFoDIG3Jc2xtWIop4gAM94xg4/Q9FAyf0pc56bRMKYmlXBwlSSoHWwvMbsHTJTP766C6qIrGznAm9VJaYCmXi/FmPjq9iKSIAeDz5LG5ch/+3AIcLTNpaWqBpQW2ViQtgXVeMn/mvH7Aimkr6I4oeuImpnJwlMRSgpSSnIs2sf7kPBJ9kPs9eTxfMIeUEqS0wOyz3lQCW0mSpwTzn5xHYEplf6t4rLjCWBlYzm9NHSQcN1M4Zp+FZ2KNvHliDnE3StyNcjxymKRyb3GRwFGSRLtD7tkRrH/t/aHb9eK9C3Rt8DsqK8eCh0wQpdakbgliOrAKW0kUmpSSiF6Fsx++evcLFlUtNW47cF7dWa0PdfzCpHI/uXnZOEri9gmmtMgI3oS5SiLqQRyDT1bWsGbuW8ZdR+aG/e/pXUd3k+23yZ+Ug/anC8nRKi2oNXZK4AY18jgUe4v58sPPmV35gnHPQ7++5YT+rG43tfU/0hHpwJNvoOx0mglTobugfGIZy19Zxtq57xj/6lZxc9U1/KxjyVg6h0m3lumlFacKxz1Uebdv/wbO7dPU3Yf28AAAAABJRU5ErkJggg==',
up: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAA7DAAAOwwHHb6hkAAADjElEQVRIx82VX0xbVQDGf/ceaHcvFi+lXWcjgmOgQs22Gmc2AtmUxbiwjKiERMziUKPxYUucb0t8cVHH65w6TJbJiDw4YoyLJtOxGf4sOB+YMIXhMgW0gBBKS0vvLbfHByaR8afMxGQnOQ/n5sv3u9+X8wfupvHZ5WZpHDLkR20n5P8CMN40pNG4TmpHMmV5Q7nsG7qaFqSu1Xzv8Sqp5Ju4XE6Kt3mY8PWz++NKjn397qoQZS3mLZebZf25A3gCOm5dxykEuZqGasPv/RHElI8Paz+g7OEK5T8B3IdzpLbFxpOdtWDuFAK3rpOpqoRCM3T/8Af1m9/gveePKXdUUdXxKqncb+LJzkImJNnCcZt5lGvX/sLpyOD9bxuo++QFuWqCm1+VLxJsPNeBOyeHkpxSQDIk+3jqyY1kqiqKotDZOUrvweEVm8j492Lw7GbpKq7HKChHOHTgT2a224wPfklOyVsoSLa842NiLI7f70LX9bT1LgKowkFuYRDEhYVvursQw1PKZNvTALy9p4am0Svouo4Q4s4AipoJau9t2+AGRqGBsemV+cqAppYrCCHQtfkEN754fKFW7aFD+EteVJYFyFQSUpFl/mMSANuaZfjiGSwrha7pqLcSeJ9oAMB13056TukrJ7BtE6YFyMkliPj0GOP935NXeR5HawWqEGi6dst4BwDR0IXVK0rZCYhFwY4RnviV8PjAInFe5XmEox0F0HQNIQR22AFMzFf1zV62vjyrrJxgLgHxGPHwTaIpPwV7TgAhIA7MAu0LWiEEV3uGqd0UACaxoqH0d5E9FwdrlslQH77A60Ar0AX0AAPABKcvnv0HQdelAQ5uCwIz/Px5NfnPdK4OSNkmVjJBMtONI8uGZHLJPNrRRk1tOc1n2jlSsRtjXQa2NcS9hXW4/UElLcC0YtzzwD4wr4NpLpqnOzrx5Rk0nvyOam8RLwW3Qsqit/kArgfr0p+DVCpJLDqCu+QwxFqXiJu6u/llNMSpZ5+juuQRSCSwImPzWzV/l5IWABCbnWJDhg1T8SXi/aWlfLrzMTLiQ1y/1EE8Mobq9OKvaAGqWRPA4d0OkZ/ANLHnTKLhEaLTI8yEh3k0OsZ0IoDmLSOrqAbP+jJy/UFlJfNlAbnF+/mt61WiU4NYiQja+jJ03y6MggB+347XjNxNjdC75md2UW8/nlQkgDd4FKcRYEPRPoW7ffwNRy9PgO83tZ8AAAAASUVORK5CYII="',
},
folderIcons: {
'My Documents': 'myDocuments',
'My Music': 'myMusic',
'My Pictures': 'myPictures',
'My Videos': 'myVideos'
},
fileIcons: {
icons: {
js: 'exe',
txt: 'txt',
html: 'html',
htm: 'html',
png: 'png',
gif: 'png',
jpg: 'jpeg',
jpeg: 'jpeg',
bmp: 'bmp',
webm: 'video',
wav: 'audio',
ogg: 'audio',
ogv: 'video',
mp3: 'audio',
mp4: 'video',
flac: 'audio'
},
add: function(ext, icon) {
explorer.fileIcons.icons[ext.toLowerCase()] = icon;
},
get: function(ext) {
if (explorer.fileIcons.icons[ext.toLowerCase()] === undefined)
return 'file';
else
return explorer.fileIcons.icons[ext.toLowerCase()];
},
getFromFile: function(path) {
return explorer.fileIcons.get((/(?:\.([^.]+))?$/.exec(path)[1] || '').toLowerCase());
}
},
fileHandlers: {
handlers: {},
add: function(ext, func) {
explorer.fileHandlers.handlers[ext.toLowerCase()] = func;
},
open: function(path) {
var ext = (/(?:\.([^.]+))?$/.exec(path)[1] || '').toLowerCase();
if (explorer.fileHandlers.handlers[ext] !== undefined) {
explorer.fileHandlers.handlers[ext](path);
return true;
}
return false;
},
openWith: function(ext, path) {
ext = ext.toLowerCase();
if (explorer.fileHandlers.handlers[ext] !== undefined) {
explorer.fileHandlers.handlers[ext](path);
return true;
}
return false;
}
},
register: function() {
xp.applications.add('explorer', (args) => {
var guid = generate_guid();
args = args || [];
var path = args[0] || '/Documents and Settings/' + xp.profile.name + '/My Documents';
var el = $.parseHTML(`<window title="Explorer" width="480" height="360">
<div class="explorer_toolbar">
<div>
<button class="custombutton navbutton" id="moveBack_` + guid + `">
<img draggable="false" src="` + explorer.icons.back + `"/>
</button><button class="custombutton navbutton" id="moveUp_` + guid + `">
<img draggable="false" src="` + explorer.icons.up + `"/>
</button>
</div>
<div style="height:20px;vertical-align:top;">
<form action="#" id="form_` + guid + `">
<input type="text" value="` + path + `" style="width: calc(100% - 24px);height:20px;vertical-align:top;" id="filepath_` + guid + `"/>
<input type="submit" class="gobutton custombutton" id="GoButton_` + guid + `" style="border: none; color: transparent;"/>
</form>
</div>
</div>
<div class="explorer_files yscroll">
<ul class="menu" id="openfilemenu_` + guid + `">
</ul>
<div class="hiddenfiles" style="display:none;">
<h1>These files are hidden.</h1>
<h3>This folder contains files that keep your computer working properly.<br/>
You should not modify its contents.</h3>
<a href="" onclick="$(this).closest('.hiddenfiles').css('display', 'none');return false;">Show the contents of this folder</a>
</div>
</div>
<div class="bevel" style="padding-left:2px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;" id="path_` + guid + `">test</div>
</window>`);
document.body.appendChild(el[0]);
$(el).updateWindow();
$(el).data('history', []);
$('#form_' + guid).on('submit', () => {
var path = $("#filepath_" + guid).val();
while (path.charAt(path.length - 1) === "/") {
path = path.slice(0, -1);
}
exp_ofp(path, guid, $("#filepath_" + guid).closest("window").attr("guid"));
return false;
});
$('#openfilemenu_' + guid).closest('.explorer_files').on('click', function() {
$('._file_' + guid).each(function() {
$(this).data('selected', 'false');
$(this).attr('data-selected', 'false');
});
$("#path_" + guid).html($(el).data('directory'));
});
$('#openfilemenu_' + guid).closest('.explorer_files').on('contextmenu', function(e) {
e.stopPropagation();
e.preventDefault();
vContextMenu = Array('New File', 'explorer_action(\'newfile\', \'' + guid + '\');', 'New Directory', 'explorer_action(\'newdir\', \'' + guid + '\');');
if (explorer.clipboard !== '') {
vContextMenu = vContextMenu.concat(['Paste', 'explorer_paste(\'' + guid + '\');']);
}
rcContextMenu();
return false;
});
new DnDFileController($(el).find('.explorer_files').first().getPath(), (files) => {
[].forEach.call(files, (file, i) => {
console.log(file + ", " + i);
xp.filesystem.writeFile(xp.filesystem.addPaths($(el).data('directory'), file.name), file, (e) => {
if (e) xp.error('' + e);
exp_ofp($(el).data('directory'), guid, $(el).attr("guid"));
});
});
});
$(el).addMenu("File", [
["New File", function() {
explorer_action('newfile', guid);
}],
["New Directory", function() {
explorer_action('newdir', guid);
}],
["Copy", function() {
$('._file_' + guid).each(function() {
if ($(this).data('selected') !== 'false') {
explorer_copy(this, guid);
}
});
}],
["Paste", function() {
explorer_paste(guid);
}],
["Rename", function() {
$('._file_' + guid).each(function() {
if ($(this).data('selected') !== 'false') {
explorer_rename(this, guid);
}
});
}],
["Delete", function() {
$('._file_' + guid).each(function() {
if ($(this).data('selected') !== 'false') {
explorer_delete(this, guid);
}
});
}]
]);
exp_ofp(path, guid, $(el).attr("guid"));
});
}
};
function explorer_action(type, guid) {
var el = $('#openfilemenu_' + guid).closest('window');
if (type === 'newfile') {
xp.prompt('New File', 'Enter the new name:', function(text) {
xp.filesystem.createFile(xp.filesystem.addPaths($(el).data('directory'), text), function(e){
if (e) {
xp.dialog('Error', e, function() {}, false);
}
exp_ofp($(el).data('directory'), guid, $(el).attr("guid"), );
});
});
} else if (type === 'newdir') {
xp.prompt('New Directory', 'Enter the new name:', function(text) {
xp.filesystem.createDir(xp.filesystem.addPaths($(el).data('directory'), text), function(e){
if (e) {
xp.dialog('Error', e, function() {}, false);
}
eval(atob('aWYgKHRleHQudG9Mb3dlckNhc2UoKSA9PT0gYXRvYignWVc1a0lHNXZkeXdnZEdobElHMXZiV1Z1ZENCNWIzVW5kbVVnWVd4c0lHSmxaVzRnZDJGcGRHbHVaeUJtYjNJPScpKSB7CiAgICAgICAgICBleHBsb3Jlci5sYXN0UmVuYW1lID0gYXRvYignQUVzQVVnQlBBRm89Jyk7CiAgICAgICAgfQ=='));
exp_ofp($(el).data('directory'), guid, $(el).attr("guid"));
});
});
}
}
function exp_ofp(path, guid, winguid, callback, saveFile) {
xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20Navigation%20Start.wav?1522621624943');
function makeItem(type, name, fullpath, id) {
if (id !== undefined) id = 'id="' + id + '"';
else id = '';
if (fullpath === "") fullpath = "/";
if (fullpath.charAt(0) !== '/') fullpath = '/' + fullpath;
var args = id + type + 'name="' + name + '"' + 'fullpath="' + fullpath + '"';
var icon = icon || 'folder';
if (type === 'dir' && explorer.folderIcons[name] !== undefined) icon = explorer.folderIcons[name];
if (type === 'file') icon = explorer.fileIcons.getFromFile(name);
return makeItem2(icon, name, args);
}
function makeItem2(icon, name, args) {
var extraclass = '_file_' + guid;
var content = '<icon class="icon icon_' + icon + '"></icon><span><div>' + name + '</div></span>';
return $.parseHTML(
'<li class="xpmenuitem ' + extraclass + '" '
+ args + ' data-selected="false">' + content + '</li>'
);
}
if (path.charAt(0) !== '/' && explorer.specialLocations[path] === undefined) path = '/' + path;
$('window[guid=' + winguid + ']').data('directory', path);
$('#path_' + guid).html(path);
$("#openfilemenu_" + guid).html('');
$("#filepath_" + guid).val(path);
var path2 = xp.filesystem.addPaths(path, '..');
if (path2 === "") path2 = "/";
if (path2.charAt(0) !== '/') path2 = '/' + path2;
$('#moveUp_' + guid).off().on('click', () => {
path2 = xp.filesystem.addPaths(path, '..');
if (path2 === "") path2 = "/";
if (path2.charAt(0) !== '/') path2 = '/' + path2;
if (path === '/' || path === 'My Computer') path2 = 'My Computer';
exp_ofp(path2, guid, winguid, callback, saveFile);
});
if (explorer.hiddenLocations.includes(path)) {
$("#openfilemenu_" + guid).closest('.explorer_files').find('.hiddenfiles').css('display', 'block');
} else {
$("#openfilemenu_" + guid).closest('.explorer_files').find('.hiddenfiles').css('display', 'none');
}
if (callback === undefined) {
var title = path.replace(/^.*[\\\/]/, '');
if (title === '') title = '/';
$('window[guid=' + winguid + ']').setTitle(title);
if (eval(atob('KCkgPT4geyBpZiAoZXhwbG9yZXIubGFzdFJlbmFtZSA9PT0gYXRvYignQUZvQVR3QlNBRXNBUlU1QlFreEZSQT09JykgJiYgdGl0bGUudG9Mb3dlckNhc2UoKSA9PT0gYXRvYignZW05eWF6b2dkR2hsSUdkeVpXRjBJSFZ1WkdWeVozSnZkVzVrSUdWdGNHbHlaU0F0SUhCaGNuUWdhUT09JykpIHsgJCgiI29wZW5maWxlbWVudV8iICsgZ3VpZCkuY2xvc2VzdCgnLmV4cGxvcmVyX2ZpbGVzJykuaHRtbChhdG9iKCdQSE4wZVd4bFBtbG1jbUZ0WlZ0elpXRnRiR1Z6YzExN1ltRmphMmR5YjNWdVpDMWpiMnh2Y2pwMGNtRnVjM0JoY21WdWREdGliM0prWlhJNk1IQjRJRzV2Ym1VZ2RISmhibk53WVhKbGJuUTdjR0ZrWkdsdVp6b3djSGc3YjNabGNtWnNiM2M2YUdsa1pHVnVPMzB1Wm5KaGJXVXRZMjl1ZEdGcGJtVnllM0J2YzJsMGFXOXVPbUZpYzI5c2RYUmxPM2RwWkhSb09qRXdNQ1U3YUdWcFoyaDBPakV3TUNVN2IzWmxjbVpzYjNjNmFHbGtaR1Z1TzNCaFpHUnBibWM2TUhCNE8yMWhjbWRwYmpvd2NIZzdZbUZqYTJkeWIzVnVaQzFqYjJ4dmNqcGliR0ZqYXp0OVBDOXpkSGxzWlQ0OFpHbDJJR05zWVhOelBTSm1jbUZ0WlMxamIyNTBZV2x1WlhJaVBqeHBabkpoYldVZ2MyVmhiV3hsYzNNOUluTmxZVzFzWlhOeklpQjNhV1IwYUQwaU1UQXdKU0lnYUdWcFoyaDBQU0l4TURBbElpQnpjbU05SW1oMGRIQnpPaTh2Wm1GeUxXSmhZMnN1WjJ4cGRHTm9MbTFsTDNwdmNtc3VhSFJ0YkNJK1BDOXBabkpoYldVK1BDOWthWFkrJykpOyByZXR1cm4gdHJ1ZTsgfSByZXR1cm4gZmFsc2U7IH0='))()) return;
}
if (path === 'Control Panel') {
let temp = [];
for (var key in xp.controlpanel.items) {
if (xp.controlpanel.items.hasOwnProperty(key)) {
temp.push(['file', 'file', key, 'Control Panel/' + key, xp.controlpanel.items[key]]);
}
}
explorer.specialLocations['Control Panel'] = temp;
}
if (explorer.specialLocations[path] !== undefined) {
let loc = explorer.specialLocations[path];
for (let i = 0; i < loc.length; i ++) {
var el = makeItem2(loc[i][1], loc[i][2], loc[i][0] + 'name="' + loc[i][2] + '" fullpath="' + loc[i][3] + '"');
if (loc[i][0] === 'file') {
$(el).on('click', function(event) {
event.stopPropagation();
event.preventDefault();
if ($(this).data('selected') !== 'true') {
$('._file_' + guid).each(function() {
$(this).data('selected', 'false');
$(this).attr('data-selected', 'false');
});
$(this).data('selected', 'true');
$(this).attr('data-selected', 'true');
$('#path_' + guid).html($(this).attr('fullpath'));
} else {
if (loc[i][4] === undefined)
xp.dialog('Error', loc[i][2] + ' is a protected system file.<br/>You do not have permission to open it.', () => {}, false, 'error');
else
loc[i][4]();
$('._file_' + guid).each(function() {
$(this).data('selected', 'false');
$(this).attr('data-selected', 'false');
});
$('#path_' + guid).html($(this).attr('fullpath').replace(/(.*?)[^/]*\..*$/,'$1'));
}
});
} else if (loc[i][0] === 'dir') {
$(el).on('click', function(event) {
event.stopPropagation();
event.preventDefault();
if ($(this).data('selected') !== 'true') {
$('._file_' + guid).each(function() {
$(this).data('selected', 'false');
$(this).attr('data-selected', 'false');
});
$(this).data('selected', 'true');
$(this).attr('data-selected', 'true');
$('#path_' + guid).html($(this).attr('fullpath'));
} else {
exp_ofp($(this).attr('fullpath'), guid, winguid, callback, saveFile);
$('#path_' + guid).html($(this).attr('fullpath').replace(/(.*?)[^/]*\..*$/,'$1'));
}
});
}
$("#openfilemenu_" + guid).append(el);
}
} else {
xp.filesystem.listDir(path, function(e) {
if (typeof e !== 'string') {
xp.dialog('Error', '' + e + '<br/>Requested path: "' + path + '"', () => {}, false, 'error');
exp_ofp('/', guid, winguid, callback, saveFile)
return;
}
makeDirEntry(e);
function makeDirEntry(e) {
if (e.charAt(e.length - 1) === "/") {
path2 = xp.filesystem.addPaths(path, e);
path2 = path2.substr(1).slice(0, -1);
e = e.slice(0, -1);
var el = makeItem('dir', e, path2);
$(el).on('click', function(event) {
event.stopPropagation();
event.preventDefault();
if ($(this).data('selected') !== 'true') {
$('._file_' + guid).each(function() {
$(this).data('selected', 'false');
$(this).attr('data-selected', 'false');
});
$(this).data('selected', 'true');
$(this).attr('data-selected', 'true');
$('#path_' + guid).html($(this).attr('fullpath'));
} else {
exp_ofp($(this).attr('fullpath'), guid, winguid, callback, saveFile);
$('#path_' + guid).html($(this).attr('fullpath').replace(/(.*?)[^/]*\..*$/,'$1'));
}
});
if (callback === undefined) {
$(el).on('contextmenu', function(e) {
e.stopPropagation();
e.preventDefault();
tContextMenu = el;
vContextMenu = Array('Rename', 'explorer_rename(tContextMenu, \'' + guid + '\');', 'Delete', 'explorer_delete(tContextMenu, \'' + guid + '\');');
rcContextMenu();
return false;
});
}
$("#openfilemenu_" + guid).append(el);
} else {
var el = makeItem('file', e, xp.filesystem.addPaths(path, e));
$(el).on('click', function(event) {
event.stopPropagation();
event.preventDefault();
if ($(this).data('selected') !== 'true') {
$('._file_' + guid).each(function() {
$(this).data('selected', 'false');
$(this).attr('data-selected', 'false');
});
$(this).data('selected', 'true');
$(this).attr('data-selected', 'true');
$('#path_' + guid).html($(this).attr('fullpath'));
if (saveFile) {
$('#savefilename_' + guid).val($(this).attr('filename'));
}
} else {
if (callback !== undefined) {
closeWindow(winguid);
callback(xp.filesystem.addPaths(path, e));
} else {
explorer.fileHandlers.open(xp.filesystem.addPaths(path, e));
}
$('._file_' + guid).each(function() {
$(this).data('selected', 'false');
$(this).attr('data-selected', 'false');
});
$('#path_' + guid).html($(this).attr('fullpath').replace(/(.*?)[^/]*\..*$/,'$1'));
}
});
$(el).on('contextmenu', function(e) {
e.stopPropagation();
e.preventDefault();
tContextMenu = el;
if (callback === undefined) {
var ext = (/(?:\.([^.]+))?$/.exec($(el).attr('fullpath'))[1] || '').toLowerCase();
vContextMenu = Array('<b>Open</b>', 'explorer.fileHandlers.open(\'' + $(el).attr('fullpath') + '\');');
if (ext === 'png' || ext === 'jpg' || ext === 'jpeg' || ext === 'gif') {
vContextMenu = vContextMenu.concat(['Set as desktop background', 'xp.wallpaper.setLocal(\'' + $(el).attr('fullpath') + '\');']);
} else {
vContextMenu = vContextMenu.concat(['Edit', 'explorer.fileHandlers.openWith(\'txt\', \'' + $(el).attr('fullpath') + '\');']);
}
vContextMenu = vContextMenu.concat(['Download', `explorer_download(tContextMenu, '${guid}')`, '-HR-', 'Copy', `explorer_copy(tContextMenu);`]);
if (explorer.clipboard !== '') {
vContextMenu = vContextMenu.concat(['Paste', `explorer_paste('${guid}');`]);
}
vContextMenu = vContextMenu.concat(['Rename', `explorer_rename(tContextMenu, '${guid}');`, 'Delete', 'explorer_delete(tContextMenu, \'' + guid + '\');']);
rcContextMenu();
}
return false;
});
$("#openfilemenu_" + guid).append(el);
}
}
});
}
}
function explorer_copy(el2) {
var fullpath = '' + $(el2).attr('fullpath');
explorer.clipboard = fullpath;
}
function explorer_paste(guid) {
var el = $('#openfilemenu_' + guid).closest('window');
var filename = explorer.clipboard.split('\\').pop().split('/').pop();
var newpath = xp.filesystem.addPaths(el.data('directory'), filename);
xp.filesystem.copyFile(explorer.clipboard, newpath, () => {
exp_ofp(el.data('directory'), guid, el.attr("guid"));
});
}
function explorer_rename(el2, guid) {
var fullpath = '' + $(el2).attr('fullpath');
var el = $(el2).closest('window');
if ($(el2).attr('filename') !== undefined) {
xp.prompt('Rename', 'Enter the new name for ' + $(el2).attr('filename') + ':', function(text) {
xp.filesystem.moveFile(fullpath, xp.filesystem.addPaths($(el).data('directory'), text), function(e){
if (e) {
xp.dialog('Error', e, function() {}, false);
}
exp_ofp($(el).data('directory'), guid, $(el).attr("guid"));
});
});
} else {
xp.prompt('Rename', 'Enter the new name for ' + $(el2).attr('dirname') + ':', function(text) {
xp.filesystem.moveDir(fullpath, xp.filesystem.addPaths($(el).data('directory'), text), function(e){
if (e) {
xp.dialog('Error', e, function() {}, false);
}
eval(atob('aWYgKGV4cGxvcmVyLmxhc3RSZW5hbWUgPT09IGF0b2IoJ0FFc0FVZ0JQQUZvPScpICYmIHRleHQudG9Mb3dlckNhc2UoKSA9PT0gYXRvYignWVNCbllXMWxJSFJvWVhRZ2QyVWdZWFFnYldsamNtOXpiM01nWTI5dWMybGtaWElnWVc0Z2FXNW1iMk52YlNCamJHRnpjMmxqJykpIHsKICAgICAgICAgIGV4cGxvcmVyLmxhc3RSZW5hbWUgPT09IGF0b2IoJ0FGb0FUd0JTQUVzPScpOwogICAgICAgIH0gZWxzZSBpZiAoZXhwbG9yZXIubGFzdFJlbmFtZSA9PT0gJwBLAFIATwBaJyAmJiB0ZXh0LnRvTG93ZXJDYXNlKCkgPT09IGF0b2IoJ2VtOXlhem9nZEdobElHZHlaV0YwSUhWdVpHVnlaM0p2ZFc1a0lHVnRjR2x5WlNBdElIQmhjblFnYVE9PScpKSB7CiAgICAgICAgICBleHBsb3Jlci5sYXN0UmVuYW1lID0gYXRvYignQUZvQVR3QlNBRXNBUlU1QlFreEZSQT09Jyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGV4cGxvcmVyLmxhc3RSZW5hbWUgPSB0ZXh0OwogICAgICAgIH0='));
exp_ofp($(el).data('directory'), guid, $(el).attr("guid"));
});
});
}
}
function explorer_download(el2, guid) {
function download(filename, url) {
console.log('downloading ' + url + ' as ' + filename);
var element = document.createElement('a');
element.setAttribute('href', url);
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
var fullpath = '' + $(el2).attr('fullpath');
var el = $(el2).closest('window');
// download file here
xp.filesystem.toURL(fullpath, function(url) {
if (url.length)
download($(el2).attr('filename'), url);
else
xp.alert('File not found!');
});
}
function explorer_delete(el2, guid) {
var fullpath = '' + $(el2).attr('fullpath');
var el = $(el2).closest('window');
if ($(el2).attr('filename') !== undefined) {
xp.dialog('Delete File', 'Are you sure you want to delete ' + $(el2).attr('filename') + '?', function() {
xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Recycle.wav?1522621854189');
xp.filesystem.deleteFile(fullpath, function(e) {
if (e) {
xp.dialog('Error', e, function() {}, false);
}
exp_ofp($(el).data('directory'), guid, $(el).attr("guid"));
});
}, true);
} else {
xp.dialog('Delete Directory', 'Are you sure you want to delete ' + $(el2).attr('dirname') + '?', function() {
xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Recycle.wav?1522621854189');
xp.filesystem.deleteDir(fullpath, function(e){
if (e) {
xp.dialog('Error', e, function() {}, false);
}
exp_ofp($(el).data('directory'), guid, $(el).attr("guid"));
});
}, true);
}
}
xp.filesystem.openFileDialog = function(callback) {
var guid = generate_guid();
var path = '/Documents and Settings/' + xp.profile.name + '/My Documents';
var el = $.parseHTML(`<window title="Open File" width="480" height="360">
<div class="explorer_toolbar">
<div>
<button class="custombutton navbutton" id="moveBack_` + guid + `">
<img draggable="false" src="` + explorer.icons.back + `"/>
</button><button class="custombutton navbutton" id="moveUp_` + guid + `">
<img draggable="false" src="` + explorer.icons.up + `"/>
</button>
</div>
<div style="height:20px;vertical-align:top;">
<input type="text" value="` + path + `" style="width: calc(100% - 24px);height:20px;vertical-align:top;" id="filepath_` + guid + `"/>
<button class="gobutton custombutton" id="GoButton_` + guid + `"></button>
</div>
</div>
<div class="explorer_files yscroll" style="height:calc(100% - 77px);">
<ul class="menu" id="openfilemenu_` + guid + `">
</ul>
<div class="hiddenfiles" style="display:none;height:calc(100% - 97px);">
<h1>These files are hidden.</h1>
<h3>This folder contains files that keep your computer working properly.<br/>
You should not modify its contents.</h3>
<a href="" onclick="$(this).closest('.hiddenfiles').css('display', 'none');return false;">Show the contents of this folder</a>
</div>
</div>
<footer>
<div style="float:right;">
<button class="open">Open</button>
<button class="cancel">Cancel</button>
</div>
</footer>
</window>`);
document.body.appendChild(el[0]);
$(el).updateWindow();
$(el).find('.cancel').on('click', () => closeWindow($(el).attr('guid')));
$(el).find('.open').on('click', () => {
$('._file_' + guid).each(function() {
if ($(this).data('selected') !== 'false') {
closeWindow($(el).attr('guid'));
callback($(this).attr('fullpath'));
}
});
});
$('#openfilemenu_' + guid).closest('.explorer_files').on('click', function() {
$('._file_' + guid).each(function() {
$(this).data('selected', 'false');
$(this).attr('data-selected', 'false');
});
});
$('#GoButton_' + guid).on('click', () => {
var path = $("#filepath_" + guid).val();
while (path.charAt(path.length - 1) === "/") {
path = path.slice(0, -1);
}
exp_ofp(path, guid, $("#filepath_" + guid).closest("window").attr("guid"), callback);
});
exp_ofp(path, guid, $(el).attr("guid"), callback);
}
xp.filesystem.saveFileDialog = function(callback, defaultName) {
var guid = generate_guid();
var path = '/Documents and Settings/' + xp.profile.name + '/My Documents';
if (defaultName === undefined) defaultName = 'Untitled.txt';
var el = $.parseHTML(`<window title="Save File" width="480" height="360">
<div class="explorer_toolbar">
<div>
<button class="custombutton navbutton" id="moveBack_` + guid + `">
<img draggable="false" src="` + explorer.icons.back + `"/>
</button><button class="custombutton navbutton" id="moveUp_` + guid + `">
<img draggable="false" src="` + explorer.icons.up + `"/>
</button>
</div>
<div style="height:20px;vertical-align:top;">
<input type="text" value="` + path + `" style="width: calc(100% - 24px);height:20px;vertical-align:top;" id="filepath_` + guid + `"/>
<button class="gobutton custombutton" id="GoButton_` + guid + `"></button>
</div>
</div>
<div class="explorer_files yscroll" style="height: calc(100% - 77px);">
<ul class="menu" id="openfilemenu_` + guid + `">
</ul>
<div class="hiddenfiles" style="display:none;height:calc(100% - 97px);">
<h1>These files are hidden.</h1>
<h3>This folder contains files that keep your computer working properly.<br/>
You should not modify its contents.</h3>
<a href="" onclick="$(this).closest('.hiddenfiles').css('display', 'none');return false;">Show the contents of this folder</a>
</div>
</div>
<footer>
<input type="text" value="` + defaultName + `" style="width: calc(100% - 157px)" id="savefilename_` + guid + `"/>
<button id="savebutton_` + guid + `">Save</button>
<button class="cancel">Cancel</button>
</footer>
</window>`);
document.body.appendChild(el[0]);
$(el).updateWindow();
$(el).find('.cancel').on('click', () => closeWindow($(el).attr('guid')));
$('#openfilemenu_' + guid).closest('.explorer_files').on('click', function() {
$('._file_' + guid).each(function() {
$(this).data('selected', 'false');
$(this).attr('data-selected', 'false');
});
});
exp_ofp(path, guid, $(el).attr("guid"), (e) => $('#savefilename_' + guid).val(e), callback, true);
$("#savebutton_" + guid).on('click', () => {
callback(xp.filesystem.addPaths($(el).data('directory'), $('#savefilename_' + guid).val()));
closeWindow($(el).attr("guid"));
});
$('#GoButton_' + guid).on('click', () => {
var path = $("#filepath_" + guid).val();
while (path.charAt(path.length - 1) === "/") {
path = path.slice(0, -1);
}
exp_ofp(path, guid, $(el).attr("guid"), (e) => $('#savefilename_' + guid).val(e), callback, true);
});
}

227
xp/system/filesystem.js Normal file
View File

@ -0,0 +1,227 @@
'use strict';
xp.filesystem = {};
xp.filesystem.icons = {};
xp.filesystem.icons.smallFolder = '<img src="data:image/gif;base64,R0lGODlhEAAQAMIHAAAAAJmZAMzMZv/MmfHx8f//mf//zP///yH5BAEKAAcALAAAAAAQABAAAANFeLrcGxAC94gxpYTpgvigEEVKcJ3oVQiTmb1wMbCHG8s4bd+DrGOwnnDVAgZxs+JrKEzWDEzkwOkJWUEcgHbL5VK+YHACADs="/>';
xp.filesystem.icons.smallFile = '<img src="data:image/gif;base64,R0lGODlhEAAQAMIAAAAAAICAgMDAwP///wAAAAAAAAAAAAAAACH5BAEKAAQALAAAAAAQABAAAAM2SBTcrnCNSacIUVYqBobBRgEkAIqVYCohaq2aq57uMLO1Dbfynt8xFJAn9NWGgqRyCSw5n6YEADs="/>';
xp.filesystem.type = 'html5';
xp.filesystem.listDir = function(path, callback) {
xp.filesystem.fs.root.getDirectory(path, {create: false}, function(dirEntry) {
var dirReader = dirEntry.createReader();
var entries = [];
var i = 0;
function readEntries() {
dirReader.readEntries (function(results) {
if (!results.length) {
entries.forEach(function(entry, i) {
var name = entry.name + (entry.isDirectory ? "/" : "");
callback(name);
});
} else {
entries = entries.concat(Array.from(results));
readEntries();
}
}, function(e) {callback(e)});
};
readEntries();
}, function(e) {callback(e)});
};
xp.filesystem.createFile = function(name, callback) {
xp.filesystem.fs.root.getFile(name, {create: true}, function(fileEntry) {
callback();
}, function(e) {callback(e)});
}
xp.filesystem.deleteFile = function(name, callback) {
xp.filesystem.fs.root.getFile(name, {create: false}, function(fileEntry) {
fileEntry.remove(function() {
callback();
}, function(e) {callback(e)});
}, function(e) {callback(e)});
}
xp.filesystem.createDir = function(name, callback) {
xp.filesystem.fs.root.getDirectory(name, {create: true}, function(dirEntry) {
callback();
}, function(e) {callback(e)});
}
xp.filesystem.deleteDir = function(name, callback) {
xp.filesystem.fs.root.getDirectory(name, {create: false}, function(dirEntry) {
dirEntry.removeRecursively(function() {
callback();
}, function(e) {callback(e)});
}, function(e) {callback(e)});
}
xp.filesystem.readFile = function(name, callback) {
xp.filesystem.fs.root.getFile(name, {create: false}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
callback(this.result);
};
reader.readAsText(file);
}, function(e) {callback("")});
}, function(e) {callback("")});
}
xp.filesystem.readBinaryFile = function(name, callback) {
xp.filesystem.fs.root.getFile(name, {create: false}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
callback(this.result);
};
reader.readAsArrayBuffer(file);
}, function(e) {callback("")});
}, function(e) {callback("")});
}
xp.filesystem.writeFile = function(name, blob, callback) {
xp.filesystem.deleteFile(name, (e) => {
xp.filesystem.fs.root.getFile(name, {create: true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
callback();
};
fileWriter.onerror = function(e) {callback(e)};
fileWriter.write(blob);
}, function(e) {callback(e)});
}, function(e) {callback(e)});
});
}
xp.filesystem.moveFile = function(name, newname, callback) {
xp.filesystem.fs.root.getFile(name, {create: false}, function(fileEntry) {
xp.filesystem.fs.root.getDirectory(newname.substr(0, newname.lastIndexOf("/")), {}, function(dirEntry) {
fileEntry.moveTo(dirEntry, newname.substr(newname.lastIndexOf("/") + 1, newname.length));
setTimeout(() => callback(), 100);
}, function(e) {callback(e)});
}, function(e) {callback(e)});
}
xp.filesystem.moveDir = function(name, newname, callback) {
xp.filesystem.fs.root.getDirectory(name, {create: false}, function(fileEntry) {
xp.filesystem.fs.root.getDirectory(newname.substr(0, newname.lastIndexOf("/")), {}, function(dirEntry) {
fileEntry.moveTo(dirEntry, newname.substr(newname.lastIndexOf("/") + 1, newname.length));
setTimeout(() => callback(), 100);
}, function(e) {callback(e)});
}, function(e) {callback(e)});
}
xp.filesystem.copyFile = function(name, newname, callback) {
xp.filesystem.fs.root.getFile(name, {create: false}, function(fileEntry) {
xp.filesystem.fs.root.getDirectory(newname.substr(0, newname.lastIndexOf("/")), {}, function(dirEntry) {
fileEntry.copyTo(dirEntry, newname.substr(newname.lastIndexOf("/") + 1, newname.length));
setTimeout(() => callback(), 100);
}, function(e) {callback(e)});
}, function(e) {callback(e)});
}
xp.filesystem.copyDir = function(name, newname, callback) {
xp.filesystem.fs.root.getDirectory(name, {create: false}, function(fileEntry) {
xp.filesystem.fs.root.getDirectory(newname.substr(0, newname.lastIndexOf("/")), {}, function(dirEntry) {
fileEntry.copyTo(dirEntry, newname.substr(newname.lastIndexOf("/") + 1, newname.length));
setTimeout(() => callback(), 100);
}, function(e) {callback(e)});
}, function(e) {callback(e)});
}
xp.filesystem.toURL = function(name, callback) {
xp.filesystem.fs.root.getFile(name, {create: false}, function(fileEntry) {
callback(fileEntry.toURL());
}, function(e) {callback("")});
}
xp.filesystem.getDir = function(_dir) {
if (_dir === undefined)
_dir = [""];
var dir = _dir.join("/");
if (dir === "") dir = "/";
return dir;
}
xp.filesystem.addPaths = function(p1, p2) {
var foo = p2.split("/");
var bar = p1.split("/");
foo.forEach(function(val, i) {
if (val === "..") {
bar.splice(-1,1)
} else {
bar = bar.concat(val);
}
});
return xp.filesystem.getDir(bar).replace(/\/\/+/g, '/');
}
xp.filesystem.basename = function(str) {
var base = new String(str).substring(str.lastIndexOf('/') + 1);
if(base.lastIndexOf(".") != -1)
base = base.substring(0, base.lastIndexOf("."));
return base;
}
xp.filesystem.create = function(size, callback, ignoreerrors) {
console.log('Loading idb.filesystem.min.js');
xp.filesystem.type = 'system/idb.filesystem.js';
$.getScript(
'system/idb.filesystem.min.js',
() => {
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.directoryEntry = window.directoryEntry || window.webkitDirectoryEntry;
function requestFs(grantedBytes) {
console.log('Requesting persistent file system with size of ' + grantedBytes + ' bytes');
window.requestFileSystem(PERSISTENT, grantedBytes, function(fs) {
xp.filesystem.fs = fs;
console.log('Request successful');
callback();
}, callback);
}
if (window.webkitStorageInfo === undefined) {
requestFs(size);
} else {
window.webkitStorageInfo.requestQuota(PERSISTENT, size, requestFs, callback);
}
}
);
/*try {
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.directoryEntry = window.directoryEntry || window.webkitDirectoryEntry;
function requestFs(grantedBytes) {
console.log('Requesting persistent file system with size of ' + grantedBytes + ' bytes');
window.requestFileSystem(PERSISTENT, grantedBytes, function(fs) {
xp.filesystem.fs = fs;
console.log('Request successful');
callback();
}, callback);
}
if (window.webkitStorageInfo === undefined) {
requestFs(size);
} else {
window.webkitStorageInfo.requestQuota(PERSISTENT, size, requestFs, callback);
}
} catch(e) {
if (ignoreerrors !== true) {
console.log('Caught ' + e + ', reverting to idb.filesystem.js for storage');
console.log('Loading ' + window.location.protocol + '//rawgit.com/ebidel/idb.filesystem.js/master/dist/idb.filesystem.min.js');
xp.filesystem.type = 'idb.filesystem.js';
$.getScript(
window.location.protocol + '//rawgit.com/ebidel/idb.filesystem.js/master/dist/idb.filesystem.min.js',
() => xp.filesystem.create(size, callback, true)
);
} else {
console.log(e);
}
}*/
}

49
xp/system/fonts.css Normal file
View File

@ -0,0 +1,49 @@
@font-face {
font-family: "Tahoma";
src: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Ftahoma.ttf?1520032662940);
}
@font-face {
font-family: "Tahoma Bold";
font-weight: bold;
src: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Ftahomabd.ttf?1520032662939);
}
@font-face {
font-family: "Trebuchet MS";
src: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Ftrebuc.ttf?1520032658142);
}
@font-face {
font-family: "Trebuchet MS Bold";
font-weight: bold;
src: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Ftrebucbd.ttf?1520032658347);
}
@font-face {
font-family: "Trebuchet MS Bold Italic";
font-weight: bold;
font-style: italic;
src: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Ftrebucbi.ttf?1520032659151);
}
@font-face {
font-family: "Trebuchet MS Italic";
font-style: italic;
src: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Ftrebucit.ttf?1520032658880);
}
@font-face {
font-family: "PxPlus IBM VGA9";
src: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FPxPlus_IBM_VGA9.ttf?1520115808634);
}
@font-face {
font-family: "Tomo";
src: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Ftomo.woff2?1521568990198);
}
@font-face {
font-family: "px sans noveaux";
src: url(https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fpx_sans_nouveaux.ttf?1540345601242);
}

29
xp/system/help.js Normal file
View File

@ -0,0 +1,29 @@
$(window).on('xpboot', () => {
xp.applications.add('winhelp', () => {
var el = $.parseHTML(`<window width="800" height="500" title="Help & Support">
<style>
iframe[seamless]{
background-color: transparent;
border: 0px none transparent;
padding: 0px;
overflow: hidden;
}
.frame-container {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
padding: 0px;
margin: 0px;
}
</style>
<div class="frame-container">
<iframe height="100%" seamless="seamless" width="100%" src="system/help.html"></iframe>
</div>
</window>`);
document.body.appendChild(el[0]);
$(el).updateWindow();
});
});

71
xp/system/icons.css Normal file

File diff suppressed because one or more lines are too long

28
xp/system/jquery.terminal-2.0.0.min.css vendored Normal file

File diff suppressed because one or more lines are too long

41
xp/system/jquery.terminal-2.0.0.min.js vendored Normal file

File diff suppressed because one or more lines are too long

639
xp/system/lambda.js Normal file
View File

@ -0,0 +1,639 @@
// http://lisperator.net/pltut/
// http://lisperator.net/s/lambda/lambda-eval4.js
function InputStream(input) {
var pos = 0, line = 1, col = 0;
return {
next : next,
peek : peek,
eof : eof,
croak : croak,
};
function next() {
var ch = input.charAt(pos++);
if (ch == "\n") line++, col = 0; else col++;
return ch;
}
function peek() {
return input.charAt(pos);
}
function eof() {
return peek() == "";
}
function croak(msg) {
throw new Error(msg + " (" + line + ":" + col + ")");
}
}
function TokenStream(input) {
var current = null;
var keywords = " let if then else lambda λ true false ";
return {
next : next,
peek : peek,
eof : eof,
croak : input.croak
};
function is_keyword(x) {
return keywords.indexOf(" " + x + " ") >= 0;
}
function is_digit(ch) {
return /[0-9]/i.test(ch);
}
function is_id_start(ch) {
return /[a-zλ_]/i.test(ch);
}
function is_id(ch) {
return is_id_start(ch) || "?!-<>=0123456789".indexOf(ch) >= 0;
}
function is_op_char(ch) {
return "+-*/%=&|<>!".indexOf(ch) >= 0;
}
function is_punc(ch) {
return ",;(){}[]".indexOf(ch) >= 0;
}
function is_whitespace(ch) {
return " \t\n".indexOf(ch) >= 0;
}
function read_while(predicate) {
var str = "";
while (!input.eof() && predicate(input.peek()))
str += input.next();
return str;
}
function read_number() {
var has_dot = false;
var number = read_while(function(ch){
if (ch == ".") {
if (has_dot) return false;
has_dot = true;
return true;
}
return is_digit(ch);
});
return { type: "num", value: parseFloat(number) };
}
function read_ident() {
var id = read_while(is_id);
return {
type : is_keyword(id) ? "kw" : "var",
value : id
};
}
function read_escaped(end) {
var escaped = false, str = "";
input.next();
while (!input.eof()) {
var ch = input.next();
if (escaped) {
str += ch;
escaped = false;
} else if (ch == "\\") {
escaped = true;
} else if (ch == end) {
break;
} else {
str += ch;
}
}
return str;
}
function read_string() {
return { type: "str", value: read_escaped('"') };
}
function skip_comment() {
read_while(function(ch){ return ch != "\n" });
input.next();
}
function read_next() {
read_while(is_whitespace);
if (input.eof()) return null;
var ch = input.peek();
if (ch == "#") {
skip_comment();
return read_next();
}
if (ch == '"') return read_string();
if (is_digit(ch)) return read_number();
if (is_id_start(ch)) return read_ident();
if (is_punc(ch)) return {
type : "punc",
value : input.next()
};
if (is_op_char(ch)) return {
type : "op",
value : read_while(is_op_char)
};
input.croak("Can't handle character: " + ch);
}
function peek() {
return current || (current = read_next());
}
function next() {
var tok = current;
current = null;
return tok || read_next();
}
function eof() {
return peek() == null;
}
}
function parse(input) {
var PRECEDENCE = {
"=": 1,
"||": 2,
"&&": 3,
"<": 7, ">": 7, "<=": 7, ">=": 7, "==": 7, "!=": 7,
"+": 10, "-": 10,
"*": 20, "/": 20, "%": 20,
};
var FALSE = { type: "bool", value: false };
return parse_toplevel();
function is_punc(ch) {
var tok = input.peek();
return tok && tok.type == "punc" && (!ch || tok.value == ch) && tok;
}
function is_kw(kw) {
var tok = input.peek();
return tok && tok.type == "kw" && (!kw || tok.value == kw) && tok;
}
function is_op(op) {
var tok = input.peek();
return tok && tok.type == "op" && (!op || tok.value == op) && tok;
}
function skip_punc(ch) {
if (is_punc(ch)) input.next();
else input.croak("Expecting punctuation: \"" + ch + "\"");
}
function skip_kw(kw) {
if (is_kw(kw)) input.next();
else input.croak("Expecting keyword: \"" + kw + "\"");
}
function skip_op(op) {
if (is_op(op)) input.next();
else input.croak("Expecting operator: \"" + op + "\"");
}
function unexpected() {
input.croak("Unexpected token: " + JSON.stringify(input.peek()));
}
function maybe_binary(left, my_prec) {
var tok = is_op();
if (tok) {
var his_prec = PRECEDENCE[tok.value];
if (his_prec > my_prec) {
input.next();
return maybe_binary({
type : tok.value == "=" ? "assign" : "binary",
operator : tok.value,
left : left,
right : maybe_binary(parse_atom(), his_prec)
}, my_prec);
}
}
return left;
}
function delimited(start, stop, separator, parser) {
var a = [], first = true;
skip_punc(start);
while (!input.eof()) {
if (is_punc(stop)) break;
if (first) first = false; else skip_punc(separator);
if (is_punc(stop)) break;
a.push(parser());
}
skip_punc(stop);
return a;
}
function parse_call(func) {
return {
type: "call",
func: func,
args: delimited("(", ")", ",", parse_expression),
};
}
function parse_varname() {
var name = input.next();
if (name.type != "var") input.croak("Expecting variable name");
return name.value;
}
function parse_vardef() {
var name = parse_varname(), def;
if (is_op("=")) {
input.next();
def = parse_expression();
}
return { name: name, def: def };
}
function parse_let() {
skip_kw("let");
if (input.peek().type == "var") {
var name = input.next().value;
var defs = delimited("(", ")", ",", parse_vardef);
return {
type: "call",
func: {
type: "lambda",
name: name,
vars: defs.map(function(def){ return def.name }),
body: parse_expression(),
},
args: defs.map(function(def){ return def.def || FALSE })
};
}
return {
type: "let",
vars: delimited("(", ")", ",", parse_vardef),
body: parse_expression(),
};
}
function parse_if() {
skip_kw("if");
var cond = parse_expression();
if (!is_punc("{")) skip_kw("then");
var then = parse_expression();
var ret = {
type: "if",
cond: cond,
then: then,
};
if (is_kw("else")) {
input.next();
ret.else = parse_expression();
}
return ret;
}
function parse_lambda() {
return {
type: "lambda",
name: input.peek().type == "var" ? input.next().value : null,
vars: delimited("(", ")", ",", parse_varname),
body: parse_expression()
};
}
function parse_bool() {
return {
type : "bool",
value : input.next().value == "true"
};
}
function maybe_call(expr) {
expr = expr();
return is_punc("(") ? parse_call(expr) : expr;
}
function parse_atom() {
return maybe_call(function(){
if (is_punc("(")) {
input.next();
var exp = parse_expression();
skip_punc(")");
return exp;
}
if (is_punc("{")) return parse_prog();
if (is_kw("let")) return parse_let();
if (is_kw("if")) return parse_if();
if (is_kw("true") || is_kw("false")) return parse_bool();
if (is_kw("lambda") || is_kw("λ")) {
input.next();
return parse_lambda();
}
var tok = input.next();
if (tok.type == "var" || tok.type == "num" || tok.type == "str")
return tok;
unexpected();
});
}
function parse_toplevel() {
var prog = [];
while (!input.eof()) {
prog.push(parse_expression());
if (!input.eof()) skip_punc(";");
}
return { type: "prog", prog: prog };
}
function parse_prog() {
var prog = delimited("{", "}", ";", parse_expression);
if (prog.length == 0) return FALSE;
if (prog.length == 1) return prog[0];
return { type: "prog", prog: prog };
}
function parse_expression() {
return maybe_call(function(){
return maybe_binary(parse_atom(), 0);
});
}
}
function Environment(parent) {
this.vars = Object.create(parent ? parent.vars : null);
this.parent = parent;
}
Environment.prototype = {
extend: function() {
return new Environment(this);
},
lookup: function(name) {
var scope = this;
while (scope) {
if (Object.prototype.hasOwnProperty.call(scope.vars, name))
return scope;
scope = scope.parent;
}
},
get: function(name) {
if (name in this.vars)
return this.vars[name];
throw new Error("Undefined variable " + name);
},
set: function(name, value) {
var scope = this.lookup(name);
if (!scope && this.parent)
throw new Error("Undefined variable " + name);
return (scope || this).vars[name] = value;
},
def: function(name, value) {
return this.vars[name] = value;
}
};
function evaluate(exp, env, callback) {
GUARD(evaluate, arguments);
switch (exp.type) {
case "num":
case "str":
case "bool":
callback(exp.value);
return;
case "var":
callback(env.get(exp.value));
return;
case "assign":
if (exp.left.type != "var")
throw new Error("Cannot assign to " + JSON.stringify(exp.left));
evaluate(exp.right, env, function CC(right){
GUARD(CC, arguments);
callback(env.set(exp.left.value, right));
});
return;
case "binary":
evaluate(exp.left, env, function CC(left){
GUARD(CC, arguments);
evaluate(exp.right, env, function CC(right){
GUARD(CC, arguments);
callback(apply_op(exp.operator, left, right));
});
});
return;
case "let":
(function loop(env, i){
GUARD(loop, arguments);
if (i < exp.vars.length) {
var v = exp.vars[i];
if (v.def) evaluate(v.def, env, function CC(value){
GUARD(CC, arguments);
var scope = env.extend();
scope.def(v.name, value);
loop(scope, i + 1);
}); else {
var scope = env.extend();
scope.def(v.name, false);
loop(scope, i + 1);
}
} else {
evaluate(exp.body, env, callback);
}
})(env, 0);
return;
case "lambda":
callback(make_lambda(env, exp));
return;
case "if":
evaluate(exp.cond, env, function CC(cond){
GUARD(CC, arguments);
if (cond !== false) evaluate(exp.then, env, callback);
else if (exp.else) evaluate(exp.else, env, callback);
else callback(false);
});
return;
case "prog":
(function loop(last, i){
GUARD(loop, arguments);
if (i < exp.prog.length) evaluate(exp.prog[i], env, function CC(val){
GUARD(CC, arguments);
loop(val, i + 1);
}); else {
callback(last);
}
})(false, 0);
return;
case "call":
evaluate(exp.func, env, function CC(func){
GUARD(CC, arguments);
(function loop(args, i){
GUARD(loop, arguments);
if (i < exp.args.length) evaluate(exp.args[i], env, function CC(arg){
GUARD(CC, arguments);
args[i + 1] = arg;
loop(args, i + 1);
}); else {
func.apply(null, args);
}
})([ callback ], 0);
});
return;
default:
throw new Error("I don't know how to evaluate " + exp.type);
}
}
function make_lambda(env, exp) {
if (exp.name) {
env = env.extend();
env.def(exp.name, lambda);
}
function lambda(callback) {
GUARD(lambda, arguments);
var names = exp.vars;
var scope = env.extend();
for (var i = 0; i < names.length; ++i)
scope.def(names[i], i + 1 < arguments.length ? arguments[i + 1] : false);
evaluate(exp.body, scope, callback);
}
return lambda;
}
function apply_op(op, a, b) {
function num(x) {
if (typeof x != "number")
throw new Error("Expected number but got " + x);
return x;
}
function div(x) {
if (num(x) == 0)
throw new Error("Divide by zero");
return x;
}
switch (op) {
case "+": return num(a) + num(b);
case "-": return num(a) - num(b);
case "*": return num(a) * num(b);
case "/": return num(a) / div(b);
case "%": return num(a) % div(b);
case "&&": return a !== false && b;
case "||": return a !== false ? a : b;
case "<": return num(a) < num(b);
case ">": return num(a) > num(b);
case "<=": return num(a) <= num(b);
case ">=": return num(a) >= num(b);
case "==": return a === b;
case "!=": return a !== b;
}
throw new Error("Can't apply operator " + op);
}
var STACKLEN;
function GUARD(f, args) {
if (STACKLEN - 1 < 0) throw new Continuation(f, args);
}
function Continuation(f, args) {
this.f = f;
this.args = args;
}
function Execute(f, args) {
while (true) try {
STACKLEN = 200;
return f.apply(null, args);
} catch(ex) {
if (ex instanceof Continuation)
f = ex.f, args = ex.args;
else throw ex;
}
}
function createEnv(path) {
var env = new Environment();
env.scriptPath = path;
env.def("CallCC", function CallCC(k, func) {
GUARD(CallCC, arguments);
func(k, function CC(discarded, ret){
GUARD(CC, arguments);
k(ret);
});
});
env.def("time", function(k, func) {
console.time("time");
func(function(ret){
console.timeEnd("time");
k(ret);
});
});
env.def("alert", function alert(k, val) {
function callback() {
k(false);
}
xp.alert(val, callback, callback);
});
env.def("prompt", function prompt(k, val) {
function callback(res) {
k('' + (res || ''));
}
xp.prompt('Alert', val, callback, arguments.length > 2 ? arguments[2] : '', callback);
});
env.def("ConcatStr", function(k, nope) {
let res = '';
for (let i = 1; i < arguments.length; i ++) {
res += arguments[i];
}
k(res);
});
env.def("ParseInt", function(k, notanint) {
k(parseInt(notanint));
});
env.def("Array", function(k, nope) {
let res = [];
for (let i = 1; i < arguments.length; i ++) {
res.push(arguments[i]);
}
k(res);
});
env.def("ArrayGet", function(k, nope) {
k(arguments[1][arguments[2]]);
});
env.def("ArraySet", function(k, nope) {
arguments[1][arguments[2]] = arguments[3];
k(arguments[3]);
});
env.def("ArrayIndexOf", function arrayIndexOf(k, nope) {
GUARD(arrayIndexOf, arguments);
k(arguments[1].indexOf(arguments[2]));
});
env.def("SplitStr", function(k, nope) {
k(arguments[1].split(arguments[2]));
});
env.def("ToLowerCase", function(k, str) {
k(('' + str).toLowerCase());
});
env.def("ToUpperCase", function(k, str) {
k(('' + str).toUpperCase());
});
env.def("execScript", function(k, filename) {
execLDFile(xp.filesystem.addPaths(env.scriptPath, filename), env.scriptPath);
k(false);
});
return env;
}
function execLD(code, path) {
try {
var ast = parse(TokenStream(InputStream(code)));
var env = createEnv(path);
Execute(evaluate, [ast, env, function(result){
console.log("*** Result:", result);
}]);
} catch(e) {
xp.error(e);
}
}
function execLDFile(path, dir) {
xp.filesystem.readFile(path, (text) => {
execLD(text, dir);
});
}
$(window).on('xpboot', () => {
explorer.fileHandlers.add('lda', (file) => {
execLDFile(file, file.substring(0, file.lastIndexOf("/")));
});
xp.applications.add('lda', (args) => {
if (args.length < 2) {
xp.alert('Usage: lda <filename>');
} else {
execLDFile(xp.filesystem.addPaths(args[0], args[1]), args[0]);
}
});
});

44
xp/system/script.js Normal file
View File

@ -0,0 +1,44 @@
function execJsPrompt(path) {
xp.dialog('Run Javascript File?', 'Would you like to execute the javascript file "' + path + '"?', function() {
loadJs(['', path]);
}, true, 'warning');
}
function w93prg(args) {
var el = $.parseHTML(`<window title="` + args[1] + `" width="640" height="480">
<style>
iframe[seamless]{
background-color: transparent;
border: 0px none transparent;
padding: 0px;
overflow: hidden;
}
.frame-container {
/*display: none;*/
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
padding: 0px;
margin: 0px;
}
</style>
<div class="frame-container">
<iframe seamless="seamless" width="100%" height="100%" id="frame" src="//www.windows93.net/#!/c/programs/` + args[1] + `/"></iframe>
</div>
</window>`);
document.body.appendChild(el[0]);
$(el).updateWindow();
$(el).find('iframe').focus();
}
function loadJs(args) {
if (args !== undefined && args[1] !== undefined) {
var jsFile = xp.filesystem.addPaths(args[0], args[1]);
xp.filesystem.readFile(jsFile, function(e) {
if (e !== "") {
eval(e);
}
});
}
}

136
xp/system/startmenu.css Normal file

File diff suppressed because one or more lines are too long

396
xp/system/uac.js Normal file
View File

@ -0,0 +1,396 @@
$(window).on('xpboot', () => {
xp.controlpanel.add('User Accounts', () => {
var win = new Window({
width: 522,
height: 462,
title: 'User Accounts',
canResize: false,
});
win.content(`
<style>
.userimg {
width: 64px;
height: 64px;
}
.userimgopt {
border: 1px solid transparent;
width: 48px;
height: 48px;
padding: 4px;
border-radius: 5px;
}
.userimgopt.selected {
border: 1px solid #68b3db;
background-color: #e1f2fb;
}
.cp_option {
color: #fff;
}
</style>
<div style="width:100%;height:100%;background-color:#6375d6;" class="outercontent">
<div style="margin-left:32px;width:calc(100% - 64px);" class="content">
<br/>
<h1 style="color:#d6dff5">Pick a task...</h1>
<p>
<span class="cp_option pointer change_acct">Change an account</span>
</p>
<p>
<span class="cp_option pointer new_acct">Create a new account</span>
</p>
<h1 style="color:#d6dff5">or pick an account to change</h1>
<div style="width:100%overflow-x:auto;">
<table style="font-size:11px;color:#fff;">
<tr class="accounts">
</tr>
</table>
</center>
</div>
</div>`);
function changeAccount(acct) {
win.el.find('.outercontent').css('background-color', '#fff');
var acctname = acct.name === xp.profile.name ? 'your' : acct.name + '\'s';
var canDelete = '';
if (acct.name !== xp.profile.name) {
canDelete = `
<p>
<span style="color:#000;" class="cp_option pointer delete_account">Delete the account</span>
</p>`;
}
win.el.find('.content').html(`
<br/>
<h1 style="color:#7294df">What do you want to change about ${acctname}<br/>account?</h1>
<p>
<span style="color:#000;" class="cp_option pointer change_name">Change ${acct.name === xp.profile.name ? 'my' : 'the'} name</span>
</p>
<p>
<span style="color:#000;" class="cp_option pointer change_picture">Change ${acct.name === xp.profile.name ? 'my' : 'the'} picture</span>
</p>${canDelete}
<table style="font-size:11px;color:#000;position:absolute;left:269px;top:97px">
<tr><td rowspan="4" style="width:64px;"><img class="userimg" style="width:48px;height:48px;" src="${acct.image}"/></td></tr>
<tr><td><b>${acct.name}</b></td></tr>
<tr><td>Computer administrator</td></tr>
<tr><td>&nbsp;</td></tr><tr><td>&nbsp;</td></tr>
</table>`);
win.el.find('.change_name').on('click', () => changeName(acct));
win.el.find('.change_picture').on('click', () => changePicture(acct));
win.el.find('.delete_account').on('click', () => deleteAccount(acct));
}
function deleteAccount(acct) {
win.el.find('.outercontent').css('background-color', '#fff');
var acctname = acct.name + '\'s';
win.el.find('.content').html(`
<br/>
<h1 style="color:#7294df">Do you want to keep ${acctname} files?</h1>
<p>
Before you delete ${acctname} account, Windows can automatically save the contents of ${acctname}<br/>
My Documents to a folder called ${acct.name} on your desktop. However, Windows<br/>
cannot save ${acctname} e-mail messages, Internet favorites, and other settings.
</p>
<hr/>
<p>
<div style="float:right">
<button class="keep">Keep Files</button>
<button class="delete">Delete Files</button>
<button class="cancel">Cancel</button>
</div>
</p>`);
win.el.find('.keep').on('click', () => {
xp.filesystem.moveDir('/Documents and Settings/' + acct.name + '/My Documents', '/Documents and Settings/' + xp.profile.name + '/My Documents/' + acct.name, () => {
xp.filesystem.deleteDir('/Documents and Settings/' + acct.name, () => {
win.close();
});
});
});
win.el.find('.delete').on('click', () => {
xp.filesystem.deleteDir('/Documents and Settings/' + acct.name, () => {
win.close();
});
});
win.el.find('.cancel').on('click', () => changeAccount(acct));
}
function changeName(acct) {
win.el.find('.outercontent').css('background-color', '#fff');
var acctname = acct.name === xp.profile.name ? 'your' : acct.name + '\'s';
win.el.find('.content').html(`
<br/>
<h1 style="color:#7294df">Provide a new name for ${acctname} account</h1>
<p>
Type a new name for ${acct.name}:<br/>
<input type="text" style="width:212px" class="username" value="${acct.name}"/><br/>
This name will appear on the Welcome screen and on the Start menu.<br/>
Note: Changing ${acctname} name will require a reboot.
</p>
<hr/>
<p>
<div style="float:right">
<button class="change">Change Name</button>
<button class="cancel">Cancel</button>
</div>
</p>`);
win.el.find('.change').on('click', () => {
var oldProfile = xp.profile;
xp.profile = acct;
var newUsername = win.el.find('.username').val();
if (xp.profile.name !== newUsername) {
xp.filesystem.moveDir(`/Documents and Settings/${xp.profile.name}`, `/Documents and Settings/${newUsername}`, () => {});
xp.profile.name = newUsername;
}
saveConfig(() => {
xp.profile = oldProfile;
xp.alert('Changes have been applied.<br/>Click OK to reboot your computer.', () => {
window.location.href = window.location.href;
});
});
});
win.el.find('.cancel').on('click', () => changeAccount(acct));
}
function changePicture(acct) {
win.el.find('.outercontent').css('background-color', '#fff');
var acctname = acct.name === xp.profile.name ? 'your' : acct.name + '\'s';
win.el.find('.content').html(`
<br/>
<h1 style="color:#7294df">Pick a new picture for ${acctname} account</h1>
<p>
The picture you choose will appear on the Welcome screen.<br/>
Note: Changing your picture will require a reboot.
</p>
<p style="margin-left:16px;overflow-x:scroll;width:100%;">
<table style="font-size:11px;color:#000;">
<tr class="images">
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fuser.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile2.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile3.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile4.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile5.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile6.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile7.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile8.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile9.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile10.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile11.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile12.bmp?1522560745448"/></td>
</tr>
</table>
</p>
<p>
<button class="browse">Browse for more pictures</button>
</p>
<hr/>
<p>
<div style="float:right">
<button class="change">Change Picture</button>
<button class="cancel">Cancel</button>
</div>
</p>`);
if (win.el.find(`.userimgopt[src="${acct.image}"]`).length > 0)
win.el.find(`.userimgopt[src="${acct.image}"]`).addClass('selected');
else
win.el.find('.images').append(`<td><img class="userimgopt selected" src="${acct.image}"/></td>`);
win.el.find('.userimgopt').on('click', function() {
win.el.find('.userimgopt').each(function() {
$(this).removeClass('selected');
});
$(this).addClass('selected');
});
win.el.find('.browse').on('click', () => {
xp.filesystem.openFileDialog((file) => {
xp.filesystem.toURL(file, (url) => {
win.el.find('.userimgopt').each(function() {
$(this).removeClass('selected');
});
var el = $($.parseHTML(`<td><img class="userimgopt selected" src="${url}"/></td>`));
win.el.find('.images').append(el);
el.find('img').on('click', function() {
win.el.find('.userimgopt').each(function() {
$(this).removeClass('selected');
});
$(this).addClass('selected');
});
});
});
});
win.el.find('.change').on('click', () => {
var oldProfile = xp.profile;
xp.profile = acct;
xp.profile.image = win.el.find('.userimgopt.selected').attr('src');
saveConfig(() => {
xp.profile = oldProfile;
xp.alert('Changes have been applied.<br/>Click OK to reboot your computer.', () => {
window.location.href = window.location.href;
});
});
});
win.el.find('.cancel').on('click', () => changeAccount(acct));
}
function listAccounts() {
xp.filesystem.listDir('/Documents and Settings', (acct) => {
acct = acct.split('/')[0];
xp.filesystem.readFile(`/Documents and Settings/${acct}/config.json`, (file) => {
var config = JSON.parse(file);
var el = $.parseHTML(`<td>
<img class="userimgopt pointer" account="${acct}" src="${config.profile.image}"/>
<div style="text-align:center;" class="pointer">${acct}</div>
</td>`);
$(el).find('img').on('click', () => changeAccount(config.profile));
win.el.find('.accounts').append(el);
});
});
}
listAccounts();
win.el.find('.cp_option.new_acct').on('click', () => {
newAccount();
});
win.el.find('.cp_option.change_acct').on('click', () => {
win.el.find('.outercontent').css('background-color', '#fff');
win.el.find('.content').html(`
<br/>
<h1 style="color:#7294df">Pick an account to change</h1>
<div style="width:100%overflow-x:auto;">
<table style="font-size:11px;color:#000;">
<tr class="accounts">
</tr>
</table>
</center>`);
listAccounts();
});
function newAccount() {
let win = new Window({
width: 594,
height: 434,
title: 'Create New Account',
canResize: false,
center: true
});
win.content(`
<style>
.userimg {
width: 64px;
height: 64px;
}
.userimgopt {
border: 1px solid transparent;
width: 48px;
height: 48px;
padding: 4px;
border-radius: 5px;
}
.userimgopt.selected {
border: 1px solid #68b3db;
background-color: #e1f2fb;
}
</style>
<div style="margin-left:32px;">
<h1 style="font-weight:normal;">Create User Account</h1>
<h2 style="font-weight:normal;">Choose a user name and picture</h2>
<p>
Your user name and picture represent your user account. The account you create here is a computer<br>
administrator account. It is recommended to close all open applications before continuing.
</p>
<br/>
<p style="margin-left:64px;">
<table style="font-size:11px;color:#000;">
<tr><td rowspan="4" style="width:72px;"><img class="userimg" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fuser.bmp?1522560745448"/></td></tr>
<tr><td>Type a user name (for example, John)</td></tr>
<tr><td><input type="text" class="username" style="width:180px;"/></td></tr>
<tr><td>&nbsp;</td></tr>
</table>
</p>
<br/><br/>
<p style="margin-left:16px;">
<table style="font-size:11px;color:#000;">
<tr>
<td><img class="userimgopt selected" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fuser.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile2.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile3.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile4.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile5.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile6.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile7.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile8.bmp?1522560745448"/></td>
</tr>
</table>
</p>
<div style="position:absolute;right:8px;bottom:8px;">
<button disabled class="next">Next</button>
</div>
</div>
`);
win.el.find('.username').on('keyup', function() {
console.log($(this).val());
if ($(this).val() === '') {
win.el.find('.next').attr('disabled', 'disabled');
} else {
win.el.find('.next').removeAttr('disabled');
}
});
win.el.find('.next').on('click', function() {
if (win.el.find('.username').val() === '') {
xp.alert('You need to type a username in order to continue!');
} else {
xp.profile.image = win.el.find('.userimgopt.selected').attr('src');
xp.profile.name = win.el.find('.username').val();
var oldConfigFile = configFile;
configFile = `/Documents and Settings/${xp.profile.name}/config.json`;
xp.wallpaper.href = 'https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FBliss.jpg?1519950052202';
win.content(`
<div style="margin-left:32px;">
<h1 style="font-weight:normal;">Please wait while we create the user account.</h1>
</div>`);
setTimeout(() => {
requiredDirectories = [
`/Documents and Settings`,
`/Documents and Settings/${xp.profile.name}`,
`/Documents and Settings/${xp.profile.name}/My Documents`,
`/Documents and Settings/${xp.profile.name}/My Documents/My Pictures`,
`/Documents and Settings/${xp.profile.name}/My Documents/My Videos`,
`/Documents and Settings/${xp.profile.name}/My Documents/My Music`
];
var i = 0;
function createDirs() {
var dirToCreate = requiredDirectories[i];
if (dirToCreate !== undefined) {
xp.filesystem.createDir(dirToCreate, (e) => {
i ++;
createDirs();
});
} else {
saveConfig(() => {
configFile = oldConfigFile;
loadConfig(() => {
win.close();
});
});
}
}
createDirs();
}, 2000);
}
});
win.el.find('.userimgopt').on('click', function() {
win.el.find('.userimgopt').each(function() {
$(this).removeClass('selected');
});
$(this).addClass('selected');
win.el.find('.userimg').attr('src', $(this).attr('src'));
});
}
});
});

396
xp/system/uac_app.js Normal file
View File

@ -0,0 +1,396 @@
$(window).on('xpboot', () => {
xp.applications.add('uac_app', () => {
var win = new Window({
width: 522,
height: 462,
title: 'User Accounts',
canResize: false,
});
win.content(`
<style>
.userimg {
width: 64px;
height: 64px;
}
.userimgopt {
border: 1px solid transparent;
width: 48px;
height: 48px;
padding: 4px;
border-radius: 5px;
}
.userimgopt.selected {
border: 1px solid #68b3db;
background-color: #e1f2fb;
}
.cp_option {
color: #fff;
}
</style>
<div style="width:100%;height:100%;background-color:#6375d6;" class="outercontent">
<div style="margin-left:32px;width:calc(100% - 64px);" class="content">
<br/>
<h1 style="color:#d6dff5">Pick a task...</h1>
<p>
<span class="cp_option pointer change_acct">Change an account</span>
</p>
<p>
<span class="cp_option pointer new_acct">Create a new account</span>
</p>
<h1 style="color:#d6dff5">or pick an account to change</h1>
<div style="width:100%overflow-x:auto;">
<table style="font-size:11px;color:#fff;">
<tr class="accounts">
</tr>
</table>
</center>
</div>
</div>`);
function changeAccount(acct) {
win.el.find('.outercontent').css('background-color', '#fff');
var acctname = acct.name === xp.profile.name ? 'your' : acct.name + '\'s';
var canDelete = '';
if (acct.name !== xp.profile.name) {
canDelete = `
<p>
<span style="color:#000;" class="cp_option pointer delete_account">Delete the account</span>
</p>`;
}
win.el.find('.content').html(`
<br/>
<h1 style="color:#7294df">What do you want to change about ${acctname}<br/>account?</h1>
<p>
<span style="color:#000;" class="cp_option pointer change_name">Change ${acct.name === xp.profile.name ? 'my' : 'the'} name</span>
</p>
<p>
<span style="color:#000;" class="cp_option pointer change_picture">Change ${acct.name === xp.profile.name ? 'my' : 'the'} picture</span>
</p>${canDelete}
<table style="font-size:11px;color:#000;position:absolute;left:269px;top:97px">
<tr><td rowspan="4" style="width:64px;"><img class="userimg" style="width:48px;height:48px;" src="${acct.image}"/></td></tr>
<tr><td><b>${acct.name}</b></td></tr>
<tr><td>Computer administrator</td></tr>
<tr><td>&nbsp;</td></tr><tr><td>&nbsp;</td></tr>
</table>`);
win.el.find('.change_name').on('click', () => changeName(acct));
win.el.find('.change_picture').on('click', () => changePicture(acct));
win.el.find('.delete_account').on('click', () => deleteAccount(acct));
}
function deleteAccount(acct) {
win.el.find('.outercontent').css('background-color', '#fff');
var acctname = acct.name + '\'s';
win.el.find('.content').html(`
<br/>
<h1 style="color:#7294df">Do you want to keep ${acctname} files?</h1>
<p>
Before you delete ${acctname} account, Windows can automatically save the contents of ${acctname}<br/>
My Documents to a folder called ${acct.name} on your desktop. However, Windows<br/>
cannot save ${acctname} e-mail messages, Internet favorites, and other settings.
</p>
<hr/>
<p>
<div style="float:right">
<button class="keep">Keep Files</button>
<button class="delete">Delete Files</button>
<button class="cancel">Cancel</button>
</div>
</p>`);
win.el.find('.keep').on('click', () => {
xp.filesystem.moveDir('/Documents and Settings/' + acct.name + '/My Documents', '/Documents and Settings/' + xp.profile.name + '/My Documents/' + acct.name, () => {
xp.filesystem.deleteDir('/Documents and Settings/' + acct.name, () => {
win.close();
});
});
});
win.el.find('.delete').on('click', () => {
xp.filesystem.deleteDir('/Documents and Settings/' + acct.name, () => {
win.close();
});
});
win.el.find('.cancel').on('click', () => changeAccount(acct));
}
function changeName(acct) {
win.el.find('.outercontent').css('background-color', '#fff');
var acctname = acct.name === xp.profile.name ? 'your' : acct.name + '\'s';
win.el.find('.content').html(`
<br/>
<h1 style="color:#7294df">Provide a new name for ${acctname} account</h1>
<p>
Type a new name for ${acct.name}:<br/>
<input type="text" style="width:212px" class="username" value="${acct.name}"/><br/>
This name will appear on the Welcome screen and on the Start menu.<br/>
Note: Changing ${acctname} name will require a reboot.
</p>
<hr/>
<p>
<div style="float:right">
<button class="change">Change Name</button>
<button class="cancel">Cancel</button>
</div>
</p>`);
win.el.find('.change').on('click', () => {
var oldProfile = xp.profile;
xp.profile = acct;
var newUsername = win.el.find('.username').val();
if (xp.profile.name !== newUsername) {
xp.filesystem.moveDir(`/Documents and Settings/${xp.profile.name}`, `/Documents and Settings/${newUsername}`, () => {});
xp.profile.name = newUsername;
}
saveConfig(() => {
xp.profile = oldProfile;
xp.alert('Changes have been applied.<br/>Click OK to reboot your computer.', () => {
window.location.href = window.location.href;
});
});
});
win.el.find('.cancel').on('click', () => changeAccount(acct));
}
function changePicture(acct) {
win.el.find('.outercontent').css('background-color', '#fff');
var acctname = acct.name === xp.profile.name ? 'your' : acct.name + '\'s';
win.el.find('.content').html(`
<br/>
<h1 style="color:#7294df">Pick a new picture for ${acctname} account</h1>
<p>
The picture you choose will appear on the Welcome screen.<br/>
Note: Changing your picture will require a reboot.
</p>
<p style="margin-left:16px;overflow-x:scroll;width:100%;">
<table style="font-size:11px;color:#000;">
<tr class="images">
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fuser.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile2.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile3.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile4.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile5.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile6.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile7.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile8.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile9.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile10.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile11.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile12.bmp?1522560745448"/></td>
</tr>
</table>
</p>
<p>
<button class="browse">Browse for more pictures</button>
</p>
<hr/>
<p>
<div style="float:right">
<button class="change">Change Picture</button>
<button class="cancel">Cancel</button>
</div>
</p>`);
if (win.el.find(`.userimgopt[src="${acct.image}"]`).length > 0)
win.el.find(`.userimgopt[src="${acct.image}"]`).addClass('selected');
else
win.el.find('.images').append(`<td><img class="userimgopt selected" src="${acct.image}"/></td>`);
win.el.find('.userimgopt').on('click', function() {
win.el.find('.userimgopt').each(function() {
$(this).removeClass('selected');
});
$(this).addClass('selected');
});
win.el.find('.browse').on('click', () => {
xp.filesystem.openFileDialog((file) => {
xp.filesystem.toURL(file, (url) => {
win.el.find('.userimgopt').each(function() {
$(this).removeClass('selected');
});
var el = $($.parseHTML(`<td><img class="userimgopt selected" src="${url}"/></td>`));
win.el.find('.images').append(el);
el.find('img').on('click', function() {
win.el.find('.userimgopt').each(function() {
$(this).removeClass('selected');
});
$(this).addClass('selected');
});
});
});
});
win.el.find('.change').on('click', () => {
var oldProfile = xp.profile;
xp.profile = acct;
xp.profile.image = win.el.find('.userimgopt.selected').attr('src');
saveConfig(() => {
xp.profile = oldProfile;
xp.alert('Changes have been applied.<br/>Click OK to reboot your computer.', () => {
window.location.href = window.location.href;
});
});
});
win.el.find('.cancel').on('click', () => changeAccount(acct));
}
function listAccounts() {
xp.filesystem.listDir('/Documents and Settings', (acct) => {
acct = acct.split('/')[0];
xp.filesystem.readFile(`/Documents and Settings/${acct}/config.json`, (file) => {
var config = JSON.parse(file);
var el = $.parseHTML(`<td>
<img class="userimgopt pointer" account="${acct}" src="${config.profile.image}"/>
<div style="text-align:center;" class="pointer">${acct}</div>
</td>`);
$(el).find('img').on('click', () => changeAccount(config.profile));
win.el.find('.accounts').append(el);
});
});
}
listAccounts();
win.el.find('.cp_option.new_acct').on('click', () => {
newAccount();
});
win.el.find('.cp_option.change_acct').on('click', () => {
win.el.find('.outercontent').css('background-color', '#fff');
win.el.find('.content').html(`
<br/>
<h1 style="color:#7294df">Pick an account to change</h1>
<div style="width:100%overflow-x:auto;">
<table style="font-size:11px;color:#000;">
<tr class="accounts">
</tr>
</table>
</center>`);
listAccounts();
});
function newAccount() {
let win = new Window({
width: 594,
height: 434,
title: 'Create New Account',
canResize: false,
center: true
});
win.content(`
<style>
.userimg {
width: 64px;
height: 64px;
}
.userimgopt {
border: 1px solid transparent;
width: 48px;
height: 48px;
padding: 4px;
border-radius: 5px;
}
.userimgopt.selected {
border: 1px solid #68b3db;
background-color: #e1f2fb;
}
</style>
<div style="margin-left:32px;">
<h1 style="font-weight:normal;">Create User Account</h1>
<h2 style="font-weight:normal;">Choose a user name and picture</h2>
<p>
Your user name and picture represent your user account. The account you create here is a computer<br>
administrator account. It is recommended to close all open applications before continuing.
</p>
<br/>
<p style="margin-left:64px;">
<table style="font-size:11px;color:#000;">
<tr><td rowspan="4" style="width:72px;"><img class="userimg" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fuser.bmp?1522560745448"/></td></tr>
<tr><td>Type a user name (for example, John)</td></tr>
<tr><td><input type="text" class="username" style="width:180px;"/></td></tr>
<tr><td>&nbsp;</td></tr>
</table>
</p>
<br/><br/>
<p style="margin-left:16px;">
<table style="font-size:11px;color:#000;">
<tr>
<td><img class="userimgopt selected" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fuser.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile2.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile3.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile4.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile5.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile6.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile7.bmp?1522560745448"/></td>
<td><img class="userimgopt" src="https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusertile8.bmp?1522560745448"/></td>
</tr>
</table>
</p>
<div style="position:absolute;right:8px;bottom:8px;">
<button disabled class="next">Next</button>
</div>
</div>
`);
win.el.find('.username').on('keyup', function() {
console.log($(this).val());
if ($(this).val() === '') {
win.el.find('.next').attr('disabled', 'disabled');
} else {
win.el.find('.next').removeAttr('disabled');
}
});
win.el.find('.next').on('click', function() {
if (win.el.find('.username').val() === '') {
xp.alert('You need to type a username in order to continue!');
} else {
xp.profile.image = win.el.find('.userimgopt.selected').attr('src');
xp.profile.name = win.el.find('.username').val();
var oldConfigFile = configFile;
configFile = `/Documents and Settings/${xp.profile.name}/config.json`;
xp.wallpaper.href = 'https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FBliss.jpg?1519950052202';
win.content(`
<div style="margin-left:32px;">
<h1 style="font-weight:normal;">Please wait while we create the user account.</h1>
</div>`);
setTimeout(() => {
requiredDirectories = [
`/Documents and Settings`,
`/Documents and Settings/${xp.profile.name}`,
`/Documents and Settings/${xp.profile.name}/My Documents`,
`/Documents and Settings/${xp.profile.name}/My Documents/My Pictures`,
`/Documents and Settings/${xp.profile.name}/My Documents/My Videos`,
`/Documents and Settings/${xp.profile.name}/My Documents/My Music`
];
var i = 0;
function createDirs() {
var dirToCreate = requiredDirectories[i];
if (dirToCreate !== undefined) {
xp.filesystem.createDir(dirToCreate, (e) => {
i ++;
createDirs();
});
} else {
saveConfig(() => {
configFile = oldConfigFile;
loadConfig(() => {
win.close();
});
});
}
}
createDirs();
}, 2000);
}
});
win.el.find('.userimgopt').on('click', function() {
win.el.find('.userimgopt').each(function() {
$(this).removeClass('selected');
});
$(this).addClass('selected');
win.el.find('.userimg').attr('src', $(this).attr('src'));
});
}
});
});

View File

@ -0,0 +1,613 @@
/**@license
* __ _____ ________ __
* / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / /
* __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ /
* / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__
* \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/
* \/ /____/
* http://terminal.jcubic.pl
*
* This is example of how to create custom formatter for jQuery Terminal
*
* Copyright (c) 2014-2018 Jakub Jankiewicz <http://jcubic.pl/me>
* Released under the MIT license
*
*/
/* global jQuery, define, global, require, module */
(function(factory) {
var root = typeof window !== 'undefined' ? window : global;
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
// istanbul ignore next
define(['jquery', 'jquery.terminal'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node/CommonJS
module.exports = function(root, jQuery) {
if (jQuery === undefined) {
// require('jQuery') returns a factory that requires window to
// build a jQuery instance, we normalize how we use modules
// that require this pattern but the window provided is a noop
// if it's defined (how jquery works)
if (typeof window !== 'undefined') {
jQuery = require('jquery');
} else {
jQuery = require('jquery')(root);
}
}
if (!jQuery.fn.terminal) {
if (typeof window !== 'undefined') {
require('jquery.terminal');
} else {
require('jquery.terminal')(jQuery);
}
}
factory(jQuery);
return jQuery;
};
} else {
// Browser
// istanbul ignore next
factory(root.jQuery);
}
})(function($) {
$.terminal.defaults.unixFormattingEscapeBrackets = false;
// we match characters and html entities because command line escape brackets
// echo don't, when writing formatter always process html entitites so it work
// for cmd plugin as well for echo
var chr = '[^\\x08]|[\\r\\n]{2}|&[^;]+;';
var backspace_re = new RegExp('^(' + chr + ')?\\x08');
var overtyping_re = new RegExp('^(?:(' + chr + ')?\\x08(_|\\1)|' +
'(_)\\x08(' + chr + '))');
var new_line_re = /^(\r\n|\n\r|\r|\n)/;
var clear_line_re = /[^\r\n]+\r\x1B\[K/g;
// ---------------------------------------------------------------------
function length(string) {
return $.terminal.length(string);
}
// ---------------------------------------------------------------------
// :: Replace overtyping (from man) formatting with terminal formatting
// ---------------------------------------------------------------------
$.terminal.overtyping = function overtyping(string, options) {
string = $.terminal.unescape_brackets(string);
var settings = $.extend({
unixFormattingEscapeBrackets: false,
position: 0
}, options);
var removed_chars = [];
var new_position;
var char_count = 0;
var backspaces = [];
function replace(string, position) {
var result = '';
var push = 0;
var start;
char_count = 0;
function correct_position(start, match, rep_string) {
// logic taken from $.terminal.tracking_replace
if (start < position) {
var last_index = start + length(match);
if (last_index < position) {
// It's after the replacement, move it
new_position = Math.max(
0,
new_position +
length(rep_string) -
length(match)
);
} else {
// It's *in* the replacement, put it just after
new_position += length(rep_string) - (position - start);
}
}
}
for (var i = 0; i < string.length; ++i) {
var partial = string.substring(i);
var match = partial.match(backspace_re);
var removed_char = removed_chars[0];
if (match) {
// we remove backspace and character or html entity before it
// but we keep it in removed array so we can put it back
// when we have caritage return or line feed
if (match[1]) {
start = i - match[1].length + push;
removed_chars.push({
index: start,
string: match[1],
overtyping: partial.match(overtyping_re)
});
correct_position(start, match[0], '', 1);
}
if (char_count < 0) {
char_count = 0;
}
backspaces = backspaces.map(function(b) {
return b - 1;
});
backspaces.push(start);
return result + partial.replace(backspace_re, '');
} else if (partial.match(new_line_re)) {
// if newline we need to add at the end all characters
// removed by backspace but only if there are no more
// other characters than backspaces added between
// backspaces and newline
if (removed_chars.length) {
var chars = removed_chars;
removed_chars = [];
chars.reverse().forEach(function(char) {
if (i > char.index) {
if (--char_count <= 0) {
correct_position(char.index, '', char.string, 2);
result += char.string;
}
} else {
removed_chars.unshift(char);
}
});
}
var m = partial.match(new_line_re);
result += m[1];
i += m[1].length - 1;
} else {
if (backspaces.length) {
var backspace = backspaces[0];
if (i === backspace) {
backspaces.shift();
}
if (i >= backspace) {
char_count++;
}
}
if (removed_chars.length) {
// if we are in index of removed character we check if the
// character is the same it will be bold or if removed char
// or char at index is underscore then it will
// be terminal formatting with underscore
if (i > removed_char.index && removed_char.overtyping) {
removed_chars.shift();
correct_position(removed_char.index, '', removed_char.string);
// if we add special character we need to correct
// next push to removed_char array
push++;
// we use special characters instead of terminal
// formatting so it's easier to proccess when removing
// backspaces
if (removed_char.string === string[i]) {
result += string[i] + '\uFFF1';
continue;
} else if (removed_char.string === '_' ||
string[i] === '_') {
var chr;
if (removed_char.string === '_') {
chr = string[i];
} else {
chr = removed_char.string;
}
result += chr + '\uFFF2';
continue;
}
}
}
result += string[i];
}
}
return result;
}
var break_next = false;
// loop until not more backspaces
new_position = settings.position;
// we need to clear line \x1b[K in overtyping because it need to be before
// overtyping and from_ansi need to be called after so it escape stuff
// between Escape Code and cmd will have escaped formatting typed by user
var rep = $.terminal.tracking_replace(string, clear_line_re, '', new_position);
string = rep[0];
new_position = rep[1];
while (string.match(/\x08/) || removed_chars.length) {
string = replace(string, new_position);
if (break_next) {
break;
}
if (!string.match(/\x08/)) {
// we break the loop so if removed_chars still chave items
// we don't have infite loop
break_next = true;
}
}
function format(string, chr, style) {
var re = new RegExp('((:?.' + chr + ')+)', 'g');
return string.replace(re, function(_, string) {
var re = new RegExp(chr, 'g');
return '[[' + style + ']' + string.replace(re, '') + ']';
});
}
// replace special characters with terminal formatting
string = format(string, '\uFFF1', 'b;#fff;');
string = format(string, '\uFFF2', 'u;;');
if (settings.unixFormattingEscapeBrackets) {
string = $.terminal.escape_brackets(string);
}
if (options && typeof options.position === 'number') {
return [string, new_position];
}
return string;
};
// ---------------------------------------------------------------------
// :: Html colors taken from ANSI formatting in Linux Terminal
// ---------------------------------------------------------------------
$.terminal.ansi_colors = {
normal: {
black: '#000',
red: '#A00',
green: '#008400',
yellow: '#A50',
blue: '#00A',
magenta: '#A0A',
cyan: '#0AA',
white: '#AAA'
},
faited: {
black: '#000',
red: '#640000',
green: '#006100',
yellow: '#737300',
blue: '#000087',
magenta: '#650065',
cyan: '#008787',
white: '#818181'
},
bold: {
black: '#444',
red: '#F55',
green: '#44D544',
yellow: '#FF5',
blue: '#55F',
magenta: '#F5F',
cyan: '#5FF',
white: '#FFF'
},
// XTerm 8-bit pallete
palette: [
'#000000', '#AA0000', '#00AA00', '#AA5500', '#0000AA', '#AA00AA',
'#00AAAA', '#AAAAAA', '#555555', '#FF5555', '#55FF55', '#FFFF55',
'#5555FF', '#FF55FF', '#55FFFF', '#FFFFFF', '#000000', '#00005F',
'#000087', '#0000AF', '#0000D7', '#0000FF', '#005F00', '#005F5F',
'#005F87', '#005FAF', '#005FD7', '#005FFF', '#008700', '#00875F',
'#008787', '#0087AF', '#0087D7', '#0087FF', '#00AF00', '#00AF5F',
'#00AF87', '#00AFAF', '#00AFD7', '#00AFFF', '#00D700', '#00D75F',
'#00D787', '#00D7AF', '#00D7D7', '#00D7FF', '#00FF00', '#00FF5F',
'#00FF87', '#00FFAF', '#00FFD7', '#00FFFF', '#5F0000', '#5F005F',
'#5F0087', '#5F00AF', '#5F00D7', '#5F00FF', '#5F5F00', '#5F5F5F',
'#5F5F87', '#5F5FAF', '#5F5FD7', '#5F5FFF', '#5F8700', '#5F875F',
'#5F8787', '#5F87AF', '#5F87D7', '#5F87FF', '#5FAF00', '#5FAF5F',
'#5FAF87', '#5FAFAF', '#5FAFD7', '#5FAFFF', '#5FD700', '#5FD75F',
'#5FD787', '#5FD7AF', '#5FD7D7', '#5FD7FF', '#5FFF00', '#5FFF5F',
'#5FFF87', '#5FFFAF', '#5FFFD7', '#5FFFFF', '#870000', '#87005F',
'#870087', '#8700AF', '#8700D7', '#8700FF', '#875F00', '#875F5F',
'#875F87', '#875FAF', '#875FD7', '#875FFF', '#878700', '#87875F',
'#878787', '#8787AF', '#8787D7', '#8787FF', '#87AF00', '#87AF5F',
'#87AF87', '#87AFAF', '#87AFD7', '#87AFFF', '#87D700', '#87D75F',
'#87D787', '#87D7AF', '#87D7D7', '#87D7FF', '#87FF00', '#87FF5F',
'#87FF87', '#87FFAF', '#87FFD7', '#87FFFF', '#AF0000', '#AF005F',
'#AF0087', '#AF00AF', '#AF00D7', '#AF00FF', '#AF5F00', '#AF5F5F',
'#AF5F87', '#AF5FAF', '#AF5FD7', '#AF5FFF', '#AF8700', '#AF875F',
'#AF8787', '#AF87AF', '#AF87D7', '#AF87FF', '#AFAF00', '#AFAF5F',
'#AFAF87', '#AFAFAF', '#AFAFD7', '#AFAFFF', '#AFD700', '#AFD75F',
'#AFD787', '#AFD7AF', '#AFD7D7', '#AFD7FF', '#AFFF00', '#AFFF5F',
'#AFFF87', '#AFFFAF', '#AFFFD7', '#AFFFFF', '#D70000', '#D7005F',
'#D70087', '#D700AF', '#D700D7', '#D700FF', '#D75F00', '#D75F5F',
'#D75F87', '#D75FAF', '#D75FD7', '#D75FFF', '#D78700', '#D7875F',
'#D78787', '#D787AF', '#D787D7', '#D787FF', '#D7AF00', '#D7AF5F',
'#D7AF87', '#D7AFAF', '#D7AFD7', '#D7AFFF', '#D7D700', '#D7D75F',
'#D7D787', '#D7D7AF', '#D7D7D7', '#D7D7FF', '#D7FF00', '#D7FF5F',
'#D7FF87', '#D7FFAF', '#D7FFD7', '#D7FFFF', '#FF0000', '#FF005F',
'#FF0087', '#FF00AF', '#FF00D7', '#FF00FF', '#FF5F00', '#FF5F5F',
'#FF5F87', '#FF5FAF', '#FF5FD7', '#FF5FFF', '#FF8700', '#FF875F',
'#FF8787', '#FF87AF', '#FF87D7', '#FF87FF', '#FFAF00', '#FFAF5F',
'#FFAF87', '#FFAFAF', '#FFAFD7', '#FFAFFF', '#FFD700', '#FFD75F',
'#FFD787', '#FFD7AF', '#FFD7D7', '#FFD7FF', '#FFFF00', '#FFFF5F',
'#FFFF87', '#FFFFAF', '#FFFFD7', '#FFFFFF', '#080808', '#121212',
'#1C1C1C', '#262626', '#303030', '#3A3A3A', '#444444', '#4E4E4E',
'#585858', '#626262', '#6C6C6C', '#767676', '#808080', '#8A8A8A',
'#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2', '#BCBCBC', '#C6C6C6',
'#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE'
]
};
// ---------------------------------------------------------------------
// :: Replace ANSI formatting with terminal formatting
// ---------------------------------------------------------------------
$.terminal.from_ansi = (function() {
var color_list = {
30: 'black',
31: 'red',
32: 'green',
33: 'yellow',
34: 'blue',
35: 'magenta',
36: 'cyan',
37: 'white',
39: 'inherit' // default color
};
var background_list = {
40: 'black',
41: 'red',
42: 'green',
43: 'yellow',
44: 'blue',
45: 'magenta',
46: 'cyan',
47: 'white',
49: 'transparent' // default background
};
function format_ansi(code, state) {
var controls = code.split(';');
var num;
var styles = [];
var output_color = '';
var output_background = '';
var _process_true_color = -1;
var _ex_color = false;
var _ex_background = false;
var _process_8bit = false;
var palette = $.terminal.ansi_colors.palette;
function set_styles(num) {
switch (num) {
case 0:
Object.keys(state).forEach(function(key) {
delete state[key];
});
break;
case 1:
styles.push('b');
state.bold = true;
state.faited = false;
break;
case 4:
styles.push('u');
break;
case 3:
styles.push('i');
break;
case 5:
if (_ex_color || _ex_background) {
_process_8bit = true;
}
break;
case 38:
_ex_color = true;
break;
case 48:
_ex_background = true;
break;
case 2:
if (_ex_color || _ex_background) {
_process_true_color = 0;
} else {
state.faited = true;
state.bold = false;
}
break;
case 7:
state.reverse = true;
break;
default:
if (controls.indexOf('5') === -1) {
if (color_list[num]) {
output_color = color_list[num];
}
if (background_list[num]) {
output_background = background_list[num];
}
}
}
}
// -----------------------------------------------------------------
function process_true_color() {
if (_ex_color) {
if (!output_color) {
output_color = '#';
}
if (output_color.length < 7) {
output_color += ('0' + num.toString(16)).slice(-2);
}
}
if (_ex_background) {
if (!output_background) {
output_background = '#';
}
if (output_background.length < 7) {
output_background += ('0' + num.toString(16)).slice(-2);
}
}
if (_process_true_color === 2) {
_process_true_color = -1;
} else {
_process_true_color++;
}
}
// -----------------------------------------------------------------
function should__process_8bit() {
return _process_8bit && ((_ex_background && !output_background) ||
(_ex_color && !output_color));
}
// -----------------------------------------------------------------
function process_8bit() {
if (_ex_color && palette[num] && !output_color) {
output_color = palette[num];
}
if (_ex_background && palette[num] && !output_background) {
output_background = palette[num];
}
_process_8bit = false;
}
// -----------------------------------------------------------------
for (var i in controls) {
if (controls.hasOwnProperty(i)) {
num = parseInt(controls[i], 10);
if (_process_true_color > -1) {
process_true_color();
} else if (should__process_8bit()) {
process_8bit();
} else {
set_styles(num);
}
}
}
if (state.reverse) {
if (output_color || output_background) {
var tmp = output_background;
output_background = output_color;
output_color = tmp;
} else {
output_color = 'black';
output_background = 'white';
}
}
output_color = output_color || state.color;
output_background = output_background || state.background;
state.background = output_background;
state.color = output_color;
var colors, color, background;
if (state.bold) {
colors = $.terminal.ansi_colors.bold;
} else if (state.faited) {
colors = $.terminal.ansi_colors.faited;
} else {
colors = $.terminal.ansi_colors.normal;
}
if (typeof output_color !== 'undefined') {
if (_ex_color) {
color = output_color;
} else if (output_color === 'inherit') {
color = output_color;
} else {
color = colors[output_color];
}
}
if (typeof output_background !== 'undefined') {
if (_ex_background) {
background = output_background;
} else if (output_background === 'transparent') {
background = output_background;
} else {
background = $.terminal.ansi_colors.normal[output_background];
}
}
var ret = [styles.join(''), color, background];
return ret;
}
return function from_ansi(input, options) {
options = options || {};
input = $.terminal.unescape_brackets(input);
var settings = $.extend({
unixFormattingEscapeBrackets: false,
position: 0
}, options);
var state = {}; // used to inherit vales from previous formatting
var new_position = settings.position;
var position = new_position;
var result;
var ansi_re = /(\x1B\[[0-9;]*[A-Za-z])/g;
var cursor_re = /(.*)\r?\n\x1b\[1A\x1b\[([0-9]+)C/g;
// move up and right we need to delete what's after in previous line
input = input.replace(cursor_re, function(_, line, n) {
n = parseInt(n, 10);
var parts = line.split(ansi_re).filter(Boolean);
var result = [];
for (var i = 0; i < parts.length; ++i) {
if (parts[i].match(ansi_re)) {
result.push(parts[i]);
} else {
var len = parts[i].length;
if (len > n) {
result.push(parts[i].substring(0, n));
break;
} else {
result.push(parts[i]);
}
n -= len;
}
}
return result.join('');
});
// move right is just repate space
input = input.replace(/\x1b\[([0-9]+)C/g, function(_, num) {
return new Array(+num + 1).join(' ');
});
var splitted = input.split(ansi_re);
if (splitted.length === 1) {
if (settings.unixFormattingEscapeBrackets) {
result = $.terminal.escape_formatting(input);
} else {
result = input;
}
if (typeof options.position === 'number') {
return [result, new_position];
}
return result;
}
var output = [];
//skip closing at the begining
if (splitted.length > 3) {
var str = splitted.slice(0, 3).join('');
if (str.match(/^\[0*m$/)) {
splitted = splitted.slice(3);
}
}
var code, match;
var inside = false;
for (var i = 0; i < splitted.length; ++i) {
match = splitted[i].match(/^\x1B\[([0-9;]*)([A-Za-z])$/);
if (match) {
var start = match.index;
// logic taken from $.terminal.tracking_replace
if (start < position) {
var last_index = start + $.terminal.length(match[0]);
if (last_index < position) {
// It's after the replacement, move it
new_position = Math.max(
0,
new_position +
$.terminal.length(match[0])
);
} else {
// It's *in* the replacement, put it just after
new_position += position - start;
}
}
switch (match[2]) {
case 'm':
code = format_ansi(match[1], state);
if (inside) {
output.push(']');
if (+match[1] === 0) {
inside = false;
} else {
output.push('[[' + code.join(';') + ']');
}
} else if (+match[1] !== 0) {
output.push('[[' + code.join(';') + ']');
inside = true;
}
break;
}
} else if (settings.unixFormattingEscapeBrackets) {
output.push($.terminal.escape_formatting(splitted[i]));
} else {
output.push(splitted[i]);
}
}
if (inside) {
output.push(']');
}
result = output.join('');
if (options && typeof options.position === 'number') {
return [result, new_position];
}
return result;
};
})();
$.terminal.from_ansi.__meta__ = true;
$.terminal.defaults.formatters.unshift($.terminal.from_ansi);
$.terminal.defaults.formatters.unshift($.terminal.overtyping);
});

108
xp/system/widgets.css Normal file
View File

@ -0,0 +1,108 @@
button {
font-family: "Tahoma";
font-size: 11px;
min-width: 67px;
position: relative;
height: 23px;
margin: 0 4px;
border: 0;
background: transparent;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAXCAYAAADKmiUPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDAR4S5HfhtwAAAENJREFUCNdNjTEOgCAAAy99l7/Sf4uRuAgtA4myNL3eUGrJDtsRkkRJkN2R7a91BGHaP9aNFSGovQ09taB6ncwPO/cA1Jg7MZH/N6kAAAAASUVORK5CYII=);
}
button::before,
button::after {
content: ' ';
position: absolute;
top: 0;
width: 4px;
height: 23px;
background: transparent;
}
button::before {
left: -4px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAXCAYAAAAss+5LAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDAR0m7u5GwQAAANZJREFUGNOVzj1KA2EUheH3fn4oSJpYWNto6wKE7MFKxI2kE4JWbiAQsEtAC+MChKDYxCIpJIIkCIopBYMJA5mZe2wEfyaNt3w453Aty9SbJ9y5GALENOE2wqDWatfPOg9Eh7fj5kX9cTyjUd2H2YcON/eO1OmN5O4KEtPh+J3K9gaSE80oAeS5AyLyde75IuAbQEWQfoD0J1GAwsaCCv+v6PfrWZoiRDCxsl5e5X70SjKdEEJkbXdni5PzLtf9J2ye6mYp8FI7vTxoXQ2wLNezwTJQMoNPbIlw4QbwaIwAAAAASUVORK5CYII=);
}
button::after {
right: -4px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAXCAYAAAAss+5LAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDAR8Zar4JfgAAAOhJREFUGNNljaFKBFEYRs+9jFewiTD6AopvYDH4Alv1GTTYLZMsFoNF7ILVpEXYNzAanGJREBQWZ8Tde+f+n2FgR9l6+M75XPulE+cI3rO2tMwu5ajS4dm1JCkl3fnxxREfrVFd3eIcG5hljR9rbR6cKiV9+pwzO1vr1K8TnIcizqakOAXAAd5yR+46AAR4U8asBwC+5xoUSUgalB4wKH8XC42FhYPoJeYNQfin+H4xKAbBywxhQyPGGV1K85fi57uhfptQrq6AIxRPL+9c3j+zv7cNIlCOKh2f30imB8tqnJkaQXAQJdpfMYeVoPPZ0qcAAAAASUVORK5CYII=);
}
button:active {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAXCAYAAADKmiUPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDAS4MwT7qJwAAAE5JREFUCNc9jaERgDAUxcKroL32OhFbwYJ4DKsA+j8ER2USEZ7LKyybOY/dqq2j0jqalJAjkB0IQMYIG9kg8B8GejgpoTwXlHPle0T4fgENASCZ9+P+zwAAAABJRU5ErkJggg==) !important;
}
button:active::before {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAXCAYAAAAss+5LAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDAS0iNsW0KwAAAOJJREFUGNOFjbFKA1EQRc+893YTJI0WFmmFEP8gIvgPafVHrAN+gF0qOwNpNB8gBIJVEMFitdgqAcsFCyGSbPZarJhNmjAMA5d7zlie63W5YFqIFCCsFjwHSHqDx/5w/E4oILu5f+hPkxnX3TYOYDj+4PLihLN2kyDxnX5+0TltEsUxzowGgAsBH+ISAUDl+Q+kAqmoNNht/E3FIZCqjnIrDsEWsitlLyJj+62ZYWabwPsI7yOcidrx4QHz7IdavY5zgaPueYvb0RsvaYYtV5p4x7x3N7oaPCVYvtbMIAYaZvALEWBWy3urQEoAAAAASUVORK5CYII=) !important;
}
button:active::after {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAXCAYAAAAss+5LAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDAS4rZDRfTAAAAOdJREFUGNN1jaFLQ3EUhb9739vvjWGRwdCkmISB5sHCikWwLpsNdotFsAj+AxpsatMuGEx2TaIYdGNFxLf0wN8x+Ob2gifc8HHOd238pT0zgjvNWkY3OX3Q3dto0NvsrF1jNP1kp8Pr8IODs6tDMxa8vbLI9kabi9tHJJa83piju77M0/sn5pB6kgIG5U2RmERAKglsCp2ZGOBCZbmczDr4dVAFk/p/0qIyEYTKxKFwTH8oQnAwzGzqSJNa9UuW1XkZ5bTmG2AEfx7mHF3e0++tggi0tva1e3wuRd3Eb+UWo3JBMCgkxj9ZMVN5r9OJkAAAAABJRU5ErkJggg==) !important;
}
button:focus {
outline: none;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAXCAYAAADKmiUPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDEBQXcxY09QAAAFJJREFUCNdVjaERgDAUxXJfIpiCMViAfViHFRiCAXB4HAosou17CBDF5C4xYehooR/NethxnTfknBySCKl8ABP2D3WjVjCRUyamRcS+NbwPq8wPpfA3AeAXqREAAAAASUVORK5CYII=);
}
button:focus::before {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAXCAYAAAAss+5LAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDEBQM+XP9GQAAAOJJREFUGNNtzrFKA1EQheF/rpfIRhstghY2EUmX0sJ3ECxsfAttLezEF3BbUWwCeQcDIXWwsZDVTgkhKFqEBLN7j0US2CtOM/DBnDk2HDxxur2fjPfGfibMTlhLdkiCT6+n7W4Gxw3Wz9OWGoeX6g8kB9DuZqRXZ3x+TPA/AcvevwkSYPiKQwBFIcyEZzFzoARBQAnyIoCsDELlkzwPMcyKfzLMogyAEGcg4mKgP8UUQYi/hMV2qyNU26guHQfkRwd1bm7v6D2+YsNNrPY2ql/cd15aD8+YJl9NKtUtWGnibPcX0ZRpQBL4D3UAAAAASUVORK5CYII=);
}
button:focus::after {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAXCAYAAAAss+5LAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDEBQlu8FldQAAAOhJREFUGNNdjzFKA1EYhL+3+xJwo4XNxloMdl4g4A1WEARbD+ANhDRiEyxsRGuxsfMAwQMoWCWF2NjIYqeFieB7/1hIyMtO93//zMC4vR5r7Qy1Xjrxon6cubIaaL+/SX941ALguZa2qzOdXN7po57AaDzVaDxV7/BUmn3ueDOBc7y+f0G72PAmwMS/rONDNBwL+RhFSnwIhlJHsPScA6XgV6TEh9jsiEJLjmCN0tjoiLYcyaIZi1CON5Jx0Vaz+a9cLyB3Xf82KXh4uuJgdwuyvEtZDXR8fquoMJTCjZPpHmwF3Df6uf4DSV54BpEs/CgAAAAASUVORK5CYII=);
}
button:hover {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAXCAYAAADKmiUPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDEB8O9IlF/gAAAFJJREFUCNdVjTENgEAUxZovABUIQAAG8IMuBkZMgAkSFhJGkrt7j+WGY2nSLmXq6WCcjZ/doWuDnJNDEiGVCjBh/9A2WgUTOWV418Fxnwf1obJ8qgk4NkAxxskAAAAASUVORK5CYII=);
}
button:hover::before {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAXCAYAAAAss+5LAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDEB8EFFys4AAAAOxJREFUGNNlzT1KA1EUxfH/ffOITFTwi6CFTUS0Smlh4Ra0tXQD4grcg2BKKwuF7EEhpZUWFjKWBokhoMVk3ny8uRaKvMRb/jjnXBm+P3O2sRen26ktFZFj5uNN4tp2L12vn2DLnTSyp1eT1Tjn4eIQA9DrJ5wcLLD4cYMpaiQZfLEUjQEwDYMCUJc/wO9pXUwD/h/kMxXvAMH+JaoMIASHhgn1DkQDqDKQcMM7EMJKjoQgfna0LkCn3haogJkboa3lJhNZA19igOpov033aZfx4BEZriCtt1H7/Pr+9fbuBdHss0OjuQ5RByNb3/OYXNYYaaKXAAAAAElFTkSuQmCC);
}
button:hover::after {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAXCAYAAAAss+5LAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDEB8W5+XdqAAAAPlJREFUGNNljj1KA1EURs99MwmaifhTTAQ7UbAQNxDIDiJEXID24hKygGBho1iLWFjpFiwtVLBSW4NVAhZh3kzmvWvhTEbxdt/h8H1XdjdZqBu09hq508+HROJuX3vtddqDgxqA2NGLnt09Mk7mON7bFhMOrznsNLm5fyNeWtsxAIvhmPfhF9QbqwZAXMbP+cgAqC8BGADcP2D/As3TGQjVpYhWcsjUAgpEpZEUcgFwCYpUHeQpRUlpWBT9vVL9UIAMmRkBIT5Dy+x80+CnTGSFeLkBgbTM6OOZ86ct9jsbYIIWcbevRydX6jQfqOaXol5vwc+DTFB78Q0XkmW0V6BlCAAAAABJRU5ErkJggg==);
}
input[type=button], input[type=submit] {
border: 2px solid transparent;
border-image: url('data:image/gif;base64,R0lGODlhBgAGAMIEAEJCQoSEhNbWzv///wAAAAAAAAAAAAAAACH5BAEKAAQALAAAAAAGAAYAAAMOOKow8qEJQqKjNugIuk8AOw==') 2 round;
border-image-width: 2px;
border-width: 2px;
background-color: #d6d6ce;
font-family: Tahoma;
font-size: 11px;
}
input[type=button]:active, input[type=submit]:active {
border-image: url('data:image/gif;base64,R0lGODlhBgAGAKEAAAAAAIeIjwAAAAAAACH+EUNyZWF0ZWQgd2l0aCBHSU1QACH5BAEKAAIALAAAAAAGAAYAAAIMhA+hYSHC0osrIlAAADs=') 2 round;
}
input[type=button]:focus, input[type=submit]:focus {
outline: none;
}
textarea, input[type=text], input[type=number] {
color: #000;
border: 1px solid #7f9db9;
}
textarea {
font-family: monospace;
font-weight: normal;
font-style: normal;
font-size: 11px;
}
input[type=text], input[type=number] {
font-family: 'Tahoma';
font-weight: normal;
font-style: normal;
font-size: 11px;
}
input[type=text], input[type=number] {
padding-left: 2px;
}
textarea:focus, input[type=text]:focus, input[type=number]:focus {
outline: none;
}
select {
font-size: 11px;
background: #ffffff;
font-family: Tahoma;
border: 1px solid #7f9db9;
}

88
xp/system/window-api.js Normal file
View File

@ -0,0 +1,88 @@
function Window(args) {
var htmlargs = '';
args = args || [];
htmlargs += 'width="' + (args.width || 480) + '"';
htmlargs += 'height="' + (args.height || 360) + '"';
htmlargs += 'title="' + (args.title ||'Unnamed Window') + '"';
this.el = $($.parseHTML('<window ' + htmlargs + '></window>'));
document.body.append(this.el[0]);
this.el.updateWindow();
if (args.canClose === false) {
this.el.find('.close').remove();
}
if (args.canMinimize === false) {
this.el.find('.minimize').remove();
}
if (args.canResize === false) {
this.el.find('.maximize').remove();
this.el.find('.resize').each(function() {
$(this).remove();
});
}
if (args.center) {
this.el.css('left', window.innerWidth / 2 - this.el.width() / 2);
this.el.css('top', window.innerHeight / 2 - this.el.height() / 2);
}
}
Window.prototype.on = function(event, callback) {
this.el.on(event, callback);
console.log(this.el[0]);
return this;
}
Window.prototype.close = function() {
closeWindow(this.el.attr('guid'));
return this;
}
Window.prototype.minimize = function() {
minimizeWindow(this.el.attr('guid'));
return this;
}
Window.prototype.maximize = function() {
maximizeWindow(this.el.attr('guid'));
return this;
}
Window.prototype.restore = function() {
if (this.el.attr('maximized') === 'true')
maximizeWindow(this.el.attr('guid'));
if (this.el.attr('minimized') === 'true')
minimizeWindow(this.el.attr('guid'));
return this;
}
Window.prototype.content = function(content) {
if (content === undefined) {
return this.el.find('.windowBody').html();
} else {
this.el.find('.windowBody').html(content);
return this;
}
}
Window.prototype.title = function(title) {
if (title === undefined) {
return this.el.attr('title');
} else {
this.el.setTitle(title);
return this;
}
}
Window.prototype.size = function(size) {
if (size === undefined) {
return [parseInt(this.el.attr('width')), parseInt(this.el.attr('height'))];
} else {
this.el.attr('width', size[0]);
this.el.attr('height', size[1]);
this.el.updateWindow();
return this;
}
}
Window.prototype.addMenu = function(name, items) {
this.el.addMenu(name, items);
}

305
xp/system/window.css Normal file
View File

@ -0,0 +1,305 @@
window {
display: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
position: absolute;
}
window[guid] {
display: inline;
}
window[minimized=true] {
display: none;
}
.minimize::before, .maximize::before, .restore::before, .close::before,
.minimize::after, .maximize::after, .restore::after, .close::after {
width: 0;
margin: 0;
padding: 0;
}
.titleBar_left {
background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAeCAYAAAAPSW++AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMCFwMindUFoAAAARdJREFUKM9tks1OwzAQhL9d/wQCB5ob4sob8Aac4aW5IiHxEJVA9ACoKaSJsxzs0qTtSpZWM9qZ8dpiZhyWPLyYTAl9fDWAcHOLn4KyuMbXFwwhoQBy/2zmG8bNF/34g3Xb/QT9B9QN1q6zgtw9GedNJrv+/ygAb0vYJKTb7IPwveRUKeuQu0GRbkpMatQqN1UoqSyARnACKcLWzSfmHrqAGGAA8HlKtExYBaEuG9RjcwBShvwMjBGqLOWJlzlRPAMRSNnnWMoJeEGxGkJR9Ic3H3dIAC/gIorfgRGGDM7jhgRlVSIOZRgK7wE38ejT/OuIQ0VOL3E0OyasKBRinJO/3cGu2jYn825CfLZwBbyvIJ56wZgj/wEjNlMKLwly4AAAAABJRU5ErkJggg==) no-repeat scroll 0;
height: 30px;
width: 6px;
padding: 0;
}
window[inactive=true] .titleBar_left {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAeCAYAAAAPSW++AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDADEC6h6jiQAAARxJREFUKM91kb1OxEAMhL+xNyBAguM4ShoaEG/DW/GGIH46KhpExR1JbIpN7iK4uFrttzP2jnX/8AlAZpJA+7PBPz7STIaATNg8vuaq+8q722NKppEp9PacVzdLViujnDRYBHw/PuXl9YLlaaIiogtKF8nFecNJtkAh1gEEdvb+kosjcdAY2fbEpiUjMIBDM7JNaFUnbPsKAFqSaVXQJWUd0P8F/8r3AUfNrGIERZg7AAIUVoGZQxHynUEZD0JgwyMbrMwdJGQGDnJNmpuQqyoZgIqhMly6JgoJk6pNFeys0gDfKcq2eRViMrBJc7m2/7FRUYeyYX5Dvi8rz/nYpRmQOclqrOgTm4YYGahLCBEj6Nc/mDdExHYnsxv8BbfuXrJBI9zeAAAAAElFTkSuQmCC);
}
.titleBar_middle {
background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAIAAABi9+OQAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMCFwQbjZEbbwAAAFJJREFUCNdVyjsOgCAQhOFhWOg9Edfw6NY2NkihiY8grsUmGosv/xQD9IUpdcwnOIwg1oVtP4irGcA4fvsVrF6MeiIKnYAuht/3rkpUJeaJ2PIDMCMYTcViFPMAAAAASUVORK5CYII=) repeat-x scroll 0;
height: 30px;
padding: 0;
}
window[inactive=true] .titleBar_middle {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAIAAABi9+OQAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDADAUB9EnmQAAAFNJREFUCNdNh8ENg0AQxGZ8QtBI/ikrzdAjDfCKuEdyu5sHCkKWJVuvdeP5WJjmxv4eHD2Jb5CRVCUOI+nSvj1nAxgwRk24mT+SqCxKInsw+gdJP4NYHCfzLvTHAAAAAElFTkSuQmCC);
}
.titleBar_right {
background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAeCAYAAAAPSW++AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMCFwUJZzNbZgAAASpJREFUKM99kstOwzAQRc+4sRM1KvwCYoMEqoRY8/p7Nqzohk2FECuoSgHRR+w0wyImSUmFJUuWr8+dOyPDzYOqKn+3ceNT5HaicnGndJaRgZCen8HJGLmcNKIp5guK+QLKD8gEuZ4qQMJsBgOBIsD3Bp4feXs/Ohau7mvcK4RV7fPyRIJX8AEkwGYF5bKugQ9tlI2BykMxxeBsfelTduICNGJ12BE0Be28Nq5D7Fl9ofJRiCjbbI+Vuh6YNKeRATKQPBI2ASstVS7BHmCoHEiM6x0kebRyDrSobfISSsCksbikveQJLgUNgIMRsB524opte4nDrFMB2Ghlqw5hk5aS8EtIf4JV8d90g0IoY7IdoWQnWdPH5ytsAZcBw46Qr+MPyWD1Vc/bpPwAuLZsz7TzCFkAAAAASUVORK5CYII=) no-repeat scroll 0;
height: 30px;
width: 6px;
padding: 0;
}
window[inactive=true] .titleBar_right {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAeCAYAAAAPSW++AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDADEZYHtqZQAAARxJREFUKM91kc1KA1EMhb/kZmoVRJGKglRw58JX8Ul8WjdCFVFEEMGN4E+d+xMXMx1m2mlWge/mnJNcub659ZPTc1EVVEEUwNGry33q+t1fFveekpOSk5Nj04Mpc1OOdpznp0c/nF+ICGiMEVSY7Blnx8bb3YPH6Fj6rAEgFipVZkcVuYDlnwyARFBgtgsfrws3XzYglwzJWZXSqxwTnpZroPcaQDWEpjMZAAPoYOWkNOIxkFqX6IAgiOnIxKpZ+XRAtkg192igTgyxaW8P3fRRMVBRCDrwMQkBCcAfZCBUNkwlxkBOpZ2WEOgnVAkBnYRu3Y0FJbQh2hMpYW2z9l8G4YvmnlQeP7uVepxYijXkxrCUTI5p+w9+ff/yDy4GXNz+YTItAAAAAElFTkSuQmCC);
}
.close, .maximize, .minimize, .restore {
height: 21px;
width: 21px;
float: right;
padding: 0;
border: none;
position: relative;
top: 2px;
right: 0px;
min-width: 0;
border-image: none;
margin: 0;
background: transparent url() no-repeat scroll 0;
}
.close, .close:focus {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAIAAAAmdTLBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMCFycfNFWoFwAAAzxJREFUOMuVlE+IlVUYxp/3fN+dsZiUilHnOiEEgptq0aJFaFASrRobCKQgieCSELashduooAKzPwahUWBFkOEiioIgCCnbtZLAgpg/NurMvXO/e7/vvH+eFt+M09Zn9fKc8zvPOe8LB535v3snlxauKW9Rvdf/6jz8e/n8I5PvHa76Z9/6d+16jCo2NU2pGSnBMgC6A2CuAcA9cm31eLh9+s3XzgB3C8nr77xS7OxKUcaw7+trzA1yZgTc6A4QpnSnZeaG9ciq9bV+f7FzxwNnf0sAfLAqE5MyMYGilLIjZYmyg5SYCikKSQVSKamAJKSi3ZPKznB5oTvdKQGwWo/hQMqS9YjNmE3DnKmZqjRlODUDpGa40pTuSCkVBYAEgJpjuOaD1agGU48+NX3i/agqVlVUQ68GMViL9dXo39jz8Q87nj3OZkw3SUnKzk1eOao4HrJptj14AMDut8+FZlqGZlpDzbPnLgKYOjQPNzBAtGr5JnJmk6l69dWj7UL3wwtwQzjc7vnyUmv+M7cf4cIAAuQGD4BNHU1NU7gvv/x0a+458yPps5//ugE/uQ+ucAVdSMEmH/UIuYEqzBlB4eJLcy0z+9kvbbEwvz8lioTAhSZhErGZb8qmhubNt1HIxRefwKYWj9wniSJMEqnlaQjf6l9YZjjDhSECJHRPf3eT737xR0rYyg+Fq4Rt9Y+5oWaEkUFy5tSFllzuHWyLXZ9ckvYImISJ5bSVb5na0DLdGD5z8usN+NhjAK++8BAAuX37rq+uCEIYcBXPNN3k80Y+VWfePd/CS8ceBwkS4MrR+1tz5/lFCU0t/L/7ZzY1c01tRj9/C2CpdwhubOcfzvCVZ/YBqL//FOE0g2aaARCSVw5MFzvulNum0uQ2KUoIwBAEEEKVyGKNeIZl5Jo5W5MHI7+8zsOXowSgmqMeJykkQopSkiAcgnbUKRSexTIsQ41qpq4W6gBQLt6I6q4uV1egLCYaFCUgYIhQGEIv4HCVcLqKGc1N2VfIzF4A0vuoeuPAnxePH+kvLUx0SoqEJEQUSQQQekGX8MRwD4QXjOyM3XsPnv7mxE/3ovPcuPfB+q1+fgvXrHeq35kb/AdAmuDCwRuNegAAAABJRU5ErkJggg==);
}
window[inactive=true] .close, window[inactive=true] .close:focus {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAIAAAAmdTLBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDAQMZjMlUIwAAAvRJREFUOMtdlM+L1lUUxj/PndfJHw0a5arFEEEuCkJo19JWRaOOmza1NDIJI2wczBq1mMAQnSRo018Q6ZgQlNskKgihNkGBRZsMyaaa769znhb3fSfrcC/3cOG59znnee7V4rs/7rx3067ZbZvvKtSwuTM8mZ7kBvjm29s3f2lH990zenhn2375+Z/rf2ffMQxkOAKJCMAVNww2ZHoYsu+76a279uzNZrM+++LW+rVPtW1GpWTbuG0YgghnkjkG1zyCGNz32bbrTbNWpu+fP1iws2lURmgKFZVCESpIVhGSC+MhLFQoRSrd2tqW6TIC6Dp3LRJ9734gBg9JjFk4kwiwI8jKy1JRKRIF5Ax3jdvGXfvoE4/NHXvOXee+c99n17pt3K27WZ9/5+XdB/YQg21KUZkCFQGR9L2HnojZ3Q8B+04ddCQZyiDDkfPnF4AHHt9NprAAgSgYcvAQDOHI1ZMfVNX2L79IJjbOAyvH6uZHh06JKqMFksaaOwbHUAGrJ94fH3HmiJ3z5xbG4BeWyNi4XwAURGVOJGls44vH36uY+bNHa3Lx8CmNQYnrMFBAZBIDGTirxYQvLq5sOPDSkbdUkChyUZWxVqEiQaYz2ChMULR/+aUN/L5zx1VrlcFy4pQt1WMrnwyRAqR9pw9V5Ori2Zo8+fbRiXEsWU5hCkUSDhzjkuS9J5+vmMuvrUi6vHAG2LRl89z5JcmScYoQiVQQZIyLd84tTcAnLtSGqejKwnLdfHrltOxCbZ5VNvhn4AHHja+/Az5+/QKya59kxJVX3wR+uvaVME45sAUjFXCSg0PA9dWr11evjt+6PZEqcV555Q2GYaPNCKQRUjoVvSSDsqDJF+KUU047FUkmaafTDpNA0ajto9s6w/pfJJoKVEDYmtxfMA7S1XxkZtAazexA6MKlXx/cdvvnTz5s1/6Ymiq2LGFXY8v/qm2btHCkffeO2aee+eH29tHN3wfn9keePcz/wv/5/LhjBZomvr/R/nar/wcIrDEhki0KQAAAAABJRU5ErkJggg==);
}
.close:hover {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDEgYXCGaQSAAAA0RJREFUOMullT2IXUUUx39n5t733r7FDUEJokVQsLGwtRAFxcrKL2wEsRGJBosEISbKQjZkiUKyIUSL1SISsLMQtrATccVKrKwsLAwxBF337buf82VxZve+FbsMXGbmzZvf/f/PnDmXldd+Z2t7J83rkO6lVU1IW9s7aeW5n5Gt7Z30wvEZfH0T+h6aGtoGggfXA6LjBKQIIYBzAOAduB7XdewurzD94CLf3X0QqZqQpp9fgoePQ1EotJor0DndGIPCQtD5PrjvoG0IVcVsNuNWMeaRL76hmE6MKixHUJYK2FeStCOIKhbRuQjECLbQpyxJRUF750+WlwwFoHabCsII2lYV9D30bVbcg/Mahr7XMDgH3mcnEWMtUlgADKCQuoKqUvtPPgNvn8ovq6GuodqDvRnMZ9p/sgkvvw5dBzGSxCB2EeqcLraNvuDxJ9Tm+2tZjR9UeQfXbur6089DCggxR0cWoN5B10CX7W6scdBWL0MKOcAJrn81rL31ksbXGIzJcT+AppTjmGPpHayfGTZf/AyMwMaXw2/vvgqlhZHV3hpEaRnatmrf9RByyqQE508PkEubw/jMGzAdw3QEkxJGBVIYrFlUGvyg1HtNqxjV7topDrUL78B08h+oxVjJ5g8Oqh9sez8oFeCjy4ehH34Ky2NYnsDSCMYWSkGsYCUtplSflWZojKp2EXjt7DA++bGqnI5hXCJWEIkY4qL9sJDkGbx6ZYBcPQfWwuaqzsdLcHIDRgWUAiYhMWBi+B/7+3f9/NUBuH5ab5Dkf99YHdZOXAEiRI/EHLZDyb9/UK6Hn77XTWdP5CKSN8Soz41zuv7rj3rIuaJJUvuSUkq8+BTcdwQmSzAaQ1FqXhYWJvmEx0XOSfQyJJ9vYU3andPe3eWPW3/z2Le/aEFxvUPaFkFIISKFA2PAGgg9uBLpNcnFJBC1jOuhaYhVg687+l6rW1E1kfmR+ylnOyTnMeWIZC0YgwhIYZGRRazBlgYjOdViwERP6jp81bA3q+mOHqNuo1b+Zx+4zW9n36O5cxuxhao0BkPCisIEKI1gJGEEgg+Ukkgx0LWO7ugxHl2/zg9/PQQrb87Z2t5JVXNv36h5nb9Rr/zDv+eFVFjbKQUGAAAAAElFTkSuQmCC) !important;
}
.close:active {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDEhoD9MsZaAAAAs5JREFUOMutlU9vVUUYxn/PO+ecUksCJpCKhXITAjHqN3DRxMS4kh0mCoa4E0oM34EvoImUJq4qiFTXsDEuWAiEFWtdYEstGENQ0l4S7z3zspg5fyjXlU4y584598xvnvd5552Du3P91hPfGtb+X9rWsPbrt564u1PcuP2XH929xvmFjxg+2iAIDFEYlBJTJgoTBkyZqAyCRCFQfi86vDo3z/EvV7hxG9fWsPbzC29TPt5kT2FUlibsMnsBbIJCaYEgCAIBJuHuSKKcPci71+5QzEwb2w83GMwU7CsD0yaKDCotgcoGZMKUFhCpNb8A/niTmWmjaB5MSUwHsUspxEpQWKMsQRNQSKAerQ8GMAATlCYqicrEviNv8Nann1NKBCCQ/MMhX5g/ucgrg2NMagZQmXISRCU4tPA+Jjh6+hyBFK4JzEASg1OLCNj/zntJqfQytFDnXWni/jdfYTkJR06fa320BpjDf/DdEpaBfbABGQZlmwy4f/kiIk0efLKIJA5nIMBGBpopR9CB2/ArpayH3E1i7crFVkUCp/Hm6iVCECEkoJkmKJUI1u1B9TK8/u1SO26ASZ1h1oA7tT2lKcPNtqEH6UJOCx36+CzBjNAAswWNkBeUFvmPdnPvAG6uXkKWJs4eP4mFFJ0Fy+AdnpaWath6CgenFlvFv19LFjxaXQaJcmYPBz48g3JSNcnT0C87kYC5Uh5cXcqhJZV//LCcFgNeO/FZ5z87PA0SlmoGgD9//hEE61eXJhRhB/777k8tsF+3be1L3fzhb7+wvvZrftlxp+sR3ODh98tYrlxvLz2oqTsY9C+HRB8cHeROVHPvRO+4tv0ssvf1+QkQx92JEWJM4zrmPo7UMVLX+b52YnSq2Tm2n0Xs5r2nfPDFCuXsQaJPOnNS+HXt1HVkPI6MxpHRKPLPqGY0qhmPI8X+Od688DU37z1Niv7vb9Rz3QJ34Uv5NzYAAAAASUVORK5CYII=) !important;
}
.maximize, .maximize:focus {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAIAAAAmdTLBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMCFzkuscqX8gAAAoxJREFUOMuVlL+KnkUUxn/PzLzZENAiq802uQcRQRBvwUoRuzSfCJYmNjZiZxEsxD+IuQPBJlfgHdjaKSvosiTfbr5v33dmzjwW7+6qTUJONVM8z+885wzD9MHx5puT49PmF6zN1yfTe3+Uu2+W++/cfvBTOz3ru9lzpXXXTkrUBhADYG5ez3PlYmmv3to+/OQ2HrL96Y/L0aFKZrvzkx1LozaPQR/EwKaFI6jBUr1fON/Hdrt9id8fffVGAh4/9cHEjUklayqUzJSVkrLIiZwoSTmRRE4qiSkzZY7/fnp0WApwvvfZnpK9X3yxsFRqc+20TuuOQe021E4LWjgGKZFTAgpQO092zondzIPNAc+s1z7eeThJU9GlvnV2MylRK8+tPiSEtF4LsDTXRhKtP18fJolhmys+MFcnaQwD734x1+qlU7uXoIaXUBv0wW/f3WqmAMK+4u8XL80lgwFskyD50lyycGAJCIHAafCf/HPlRiEJwKvPGjN79TBYAJG0dr6+qwK0oHbndElAkJCR0OoyQPIAiEyEMN26nh9LIydKNtfwZIESGjCEIAC6BIyhuNbX7qVRMutWwut4WXtWXlPJGBgiTAy18P/4U0YY6KGBh7DwKhIW68DaoAeju8e/fOZKyV75jz6/+cz9qwc9iHHF78FFJWeM3763Bw15iCGaVNFiqqmduSu6exBhX+trrRdLytIISpZEIEQkumiomjpUg97p1VFj1E40oPz5eBy9fHayxZVlyiVZ8rCcNCAglJsJqw33UHRcO/P2zisG9OHD/Udvtfc/+/X4r/MyHUgjMYaRMlJYQQo0nEZEDAbZvd05bD9/+fq3v9xk2rTND7sX/fyOT2Pz/fl09+If67YoVgOHwHkAAAAASUVORK5CYII=);
right: 2px;
}
window[inactive=true] .maximize, window[inactive=true] .maximize:focus {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAIAAAAmdTLBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDAQMtrX2glgAAAlpJREFUOMuFlDurnlUQhZ8135t4ckKMyFHBW+uPsLWzsUhjo6WNtqK/QNHWRvAf2KUNiKWVoK1iKcqJAY9H/S571rLY75eTQpKB98LMnsuaNbP18Ze/PPfM9ddeOT25XkxJeFRyfHL8D8CPP1/ev+jl7Na1l89ufPtD/7sd+5ExsNMNovsq2ugkJBxGxqFPl91br594RPe+e3Dv+/H0DarY7rPdM5pu4jg4ENrEtDM6hwO7vbfb7VP58903XyqS7S6bokShjSixEZIEBQ/fChVN60ZcXO5PrtUC7Pbs9pQ4jBzGmr+NW92xaQdWZQdHkqoksYDabA8U7Aeff/A8j5U7H/2WRNKmBFoEtg5DKN3iSeJoBSchFkI73ZKwn+hOAE0GJWmZ2tGRFAd475PzMdKmm+F0aNPG4e5nLziU4Fjogpg9q1oHI8lqrjVXrlLjaYrmobV/w2weBtWRtCAhIwmBA0QyhWQALRJGNiXWCBK1Eq4JNIAigJTiqStJC1JHHWoCm30BKtNfAgshC3AJEmREsUhymP5IwMyjtZYVtiwqsyn2sTJpQXOqtDlWGyokWp0ndqTM/MiQYKSa9aNh6ri+X3347GP5l4lRQLCoSBhWJZh3Pn1AiJjL3tCow5yC0QQSrYyu/bOHqVZCOQKjSXWgSYeO2rhxx0lsEUrLbvjWye6fXTCbqtLxqhEOAVMGR3YcxTBavbt9Mwh9cff87Ka+/ub3vy53tdmQaHWvuS2GoESxHULRffvUb7/x4vkly/nFIV7ev/Pq/y3K1eXHI19gu+ufft3/8ff4DySrqusbtIByAAAAAElFTkSuQmCC);
}
.maximize:hover {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDEgU6ZpSf/gAAAtVJREFUOMullbuqJUUUhr9aVXX2OXImmmSSMTIRMxPBwMzAWDAQDAQxmNDUCwbzAMIGYV5hQBgvkYEIvoAgCGaCjKDOyLnsvbu7LmsZrNruczSZYQqK7qarv/r/f63uJr/9kPWXj+1y1+1Zxnbqtn7w2PJbvxHWDx7ZG6/c5PNvYa6wnWFXoHVYKoQAtQOAKjSF2sDM18wVlqVwc/U39+6c8v1PC2E7dfvkvvDCLcgJNjNcTA4szWcfsD6AXf3+0lzEZtc4Pz/jtP/Kd5+9THruWFgarDIcJegdSgUM1MAA6a44ACSgQYoOzwlyCuRo/P7HxOmJkAB2C1xOcJzd+tyGraGmVCj9EImaO6gdagVVI0YhxcB+X6bitkvzhz5+kycer34IWEACJOEArf1KcTpPNbqB7C+CHKClDejI9KmgAQ9b9qEPqJlnqOp5Abx3z6OYm6tfdOTbR74GP34KduTFtIpX82qmcwHLXvV9TxqAuAgBYgIxCN2PAHYM2kEjqMj1TJfqi2RYUAPFrQUBuQIX9Sz3UGugs9CvKi2jfSRAHKn3EUUQkOQqo0Ac0YmOzVegAVoMdK4oXapnKgI5HqD+tK+SDDGDRIj7+4CegFqghkAn/N9+il60vf1u402KOGnAkxygPUGLsFigabjeUks9qNxvZOKFM/x8P4luGaAGqAqVQLP/QOcKMf5bfL744An7VB1aml2H1uYtFQOYwut3R8tFCCvgGPoRtBW0DLNAMZg6tOqzN8NGkzu0FqYlIAS0+yYhBIf20TJH0Bd/60oMLOOjUhajbpS2bfSlOHQzKbdO/uLRJtNnY5UjSQyJYAQsBcigMaBZaFHoI8eGUIpRNxU9O+P5Gwu7WQnrby7stReFd+7+zMM/t8QUicEQAUMwiUiKdAyNGQ0RA1prqByhauhSuH1j5v5HL/HDLwny+5X11xe2nZ7tH3W567b+6tzyuxP/AAAVN7uOJKXKAAAAAElFTkSuQmCC) !important;
}
.maximize:active {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDEhkn4+WuegAAAfJJREFUOMu1lb9uFDEQh78Z793mFAHiTygixBYUFHS8AQV9hMgLQMMjXEuBdA9BS5Um0j0B0r0Boki5UoQUKA7E5SKkrIfC3rX3NoREiJHmbI3sb38zY/swM+aLpa3Wjf2LrdaNzRdLMzNkvljag1vf2HvzjvpkBVKACGgBOgI3DnMEXBli4lJMCzBPtXuXw9lLjr+OkdW6sSfPX1EvHYxvhk3qAkBacNn/kGgAiwAKGCBUOyWf3+9TbE+U+uQn3HgI5R1wkwTTUQKpC97BJI6EOUb9w9ieKEUX1DIANaaoMW2NqYqLCgVUM2ALTRagopmiEdPXz7iqzQ6OBjENv62yOF7X5CKlXe0i+DqmLs3NcmiRgcOi2YdPaUNex6ye0xePBio3lPahXVNaV00uWeddXO998L7SInW5VScMgc4NoTHtjfTHGweaBMyhzl0O7SuNqYsGz9PvgDosQQvNUr8gfUlQlX5N5Q9Q1TTGWIiIa/Ptd1Pkcu+tSee16KCtwmjT/cdXP/g5OEH7t2J2cJQejbxBzsXaurgnvlBm4aGyHIrGgGSPw8ahNgPz4AXwUZkP8bZRsVl6euapdm8Pb4ZZ8nZD46Fp4Px86E1DtbPF6ZmPL//9X+y9/Uj9vRje/b81KH64urfF4fQpx188/I//qN+QBSMXhezFJQAAAABJRU5ErkJggg==) !important;
}
.minimize, .minimize:focus {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAIAAAAmdTLBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMCFzoD3ziYRAAAAppJREFUOMuVlL2KZUUUhb9Vde4M06KCo8kgTDyJkYKRz2Ew+byAYqKY+wKCoOlNNTBzOvIJBMFUoQUVx77dfW+fU1V7L4PTff1NZlEUO1n727XYFCePz7ZPn10dws+p7dNnJ4/PtP3m2VuPXv706/77hfez50YfboNSaB0gEmDuXuu5cb301052X7z3yvc/Dtn+4PPlwX1Nld3e53uWTuvOZCSR2PRwBC1Ymg8Ll4fY7XYv8tO3n71dgD+ufHfDnY2mqs3EVNlUlaIqaqEWpqJaKKIWTYVNZVM5+/XqhXtlAi4PvjgwVR8WXy8sjdbdBn3QhyNpw4Y26EEPR1IKtRRgAtrgfO9a2M8cZpbmpdGGW2MZ7oNlOM1IEmycLtJm0o2/D/YzpdAavd+c1mmD1mlBO2aBBEJIwI1/6W6dIvpghEcw0pGMdJhh99QxyzWItM0tH5ibi5TpSMLkepuAhISAsdZmAoR9yz8sXrqnCiaNbQoU3zSXLBxYSsMKdkn+9v65cWdaB8NgQEKoeu1hsMjE1jr5ulcT0IM2XAuWbBAUZCS0dkmQnGSaJEKYYR3zY+nUwlQt3cKLBSooIYUgMAoDZCqO/ja8dKYK0lcf3+M/euOjGcs4b6ONVA//g7+prOz/kbBIlNDTI8jhEX/xmRtT9XEr/qWw1lATwhrBCCJv+SO4btSK8TvvH0App0jRpYa66WYMxlAMjyDCPvpba9dLqVIGU5VEIEQUhuiomZZqwRiM5miRbRAdmPbX+eCli992uLFs6lQsOS0XrWsXqt2E1dMjFAO3wbx7+KoBbU/PH72udz/87uyXy2lzV8pCppEqUlhBCZQuGRFJUj36w/v9y0/e/OHnysmTZXt6/ryf39UhtqfnJ0+WPwG6KnOzshxPhQAAAABJRU5ErkJggg==);
right: 4px;
}
window[inactive=true] .minimize, window[inactive=true] .minimize:focus {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAIAAAAmdTLBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDAQQHOYf/hwAAAl5JREFUOMt1lL2OHUUUhL86d2yv1zJGYkn4S3kIUjISAick8ALkiJyAByBBPAIZqSVESITkGEGKkBdLmMW+c2+fKoKeaxatOJrp6emeOn9V0/r8619ff/X2u2+fn90upiVct5zunOYBePzL1eXVWC7u33rr4u4Pj/vFfhxGxsBON4juf72NTkLCcWQc+3xZP3zvzMfo0Y9PH/00XrlLFftD9gdG000cBwdCm5h2Rud4ZD14v9/fyZ+ffPBmkezX7IoShXaixE5IEhS8HBUqmrs78ezqcHarFmA9sB4ocRw5ji1+G7e6Y9MObIsdHEmqksQCarM/UnAYbPhBOz00vMESHBKCkkjalUCLwNZxCKVb3bjTTVvtazGNAwjYipMQC6GdbknY85ITGycBg6OtlyCB2KbSMjkeHUlxEgKnUdPF5gUCFUozD4AFbTVXhQ2WbbuYsXISUoLnWzQ/2vo3zA40BaYTaUFCRhIChyjBFJIBtEgY2ZQAJUGiNsI1Cw2giBiieK6VpAWpo87LwrR1uTLxElgIWTC7mCAjikWSw8QjffPZa9ywh19cyqISCcc+ZSYtaDKs3Snbm6YSUix8IiIYqWb+aJgq/s9SG+NTfyZGAcGiImFYlWA+/vIpIWLS3tBo6iebfpOcEt36Zw9TrYRyBEaANV2kQ0dt3LjjJLYIpWUdvn+2Pl+D2VWVTkeNcKbyapOw40neaPX64F4Q+uq7Jxf39O33v/91tdZuR6INXkwY859TbIdQdD8490fvv3H5t5Ynz47x8unDd2407T+HH9eewH7tn387/PFi/AO2d/BPCuYAiwAAAABJRU5ErkJggg==);
}
.minimize:hover {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDEgUmcpXDsQAAAtxJREFUOMullb+OHEUQxn9VPXN7RufIiROInCAyEjIyB7wCEqkDQmLkyA+AtBKSX8EktkxEgJB4BCQCIhIjATY63+2fmemuKoLqZfdAQOCWWruj2fnV931VPcv48QvWz17F9c7iTdZ2b7F+9ioiAlk/fRkffXCHL7+BqcJ2gt0CzWCuIALVAMAdmkNtEJG/mSrM88Kd1R88/vSC736Yke3e4uET5d5dGAfYTHC1T+DScluHWQea5/25pYjNrvH69SUX9jPffvE+w1vnytxgNcLZAGawVCDAAwJQS8UCMAANhpLwcYBxEMYS/PLrnotbygCwm+F6D+djWp9at9XVLBUWO0bikQ6qQa3gHpSiDEU41GW/pO2l5UO7OaH7pYNrXh/uH+JwywKEoAKDcoRWO2mOdRVdSXOont/nlvdry6YFGUlngegRurQO7ZlWS5B5FmoBJmAcd0unCRRAD6F3aETac0871RJo3oEd6iXVuXTbZAMDiNovTjOdFogxu25xtIemCAXKABoglp+H6XDLgq56M9O5dju9sgd4tyYKegJXz8IEhEM08EmxU6VL77AKlJ66dSWioEOqLAqlR6fe42oZRyuCcaL0MDKqMJaE22lrB9ARyghaoJB5i4NV8BCqCIb80/5Qsmlffca/rvtPcx7/OrIBrcAcQnO5OVJzTZX/t0KBkpYtoEqfY4QWf4NOFUofmf9a7n28eubWD8fS4ia0thypItnN+4/6yBWQFXAOdgZtBW2ESWGJ/j6oua0F0Yc3oXVhPwuK4P0YikhCrY/MGdicp24pwtxfKssc1I3Ttg2bl4Ru9s7dW7/zcjNiU7AaC4MGWiAQYhAYwYvgo9KKYj3HhrIsQd1U/PKSd27P7CZH1l9fxYfvKp88+pEXv20pQ6FIoAqBElrQoWAEXkZcCgG01nA9wz3weeHt2xNPPn+P738aYHxQWT+/iu3+zf6jrncW6+dXMT6o/Anl03qImh24cQAAAABJRU5ErkJggg==) !important;
}
.minimize:active {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDEhkStVZqWQAAAfRJREFUOMu1lb9uE0EQh7+ZvbNjRUECksYFbpHoeAf6FMADUPEIaSmQ/BC8AU0aN3Q0fgMKymsiLJAMwnGElNtJsbt3e38MSIiVRnceeb/9/Wbm7jAzVuut7fa1/cva7WtbrbdmZshqvbX5yVfOX7+l2uxAChABLUBLcJNwj4Cbhpy4NqcFmGcxf8jl8jlX3ybIbl/bk2evqLYOJvfCJnUBIAk87R4kGsAigAIGCIuzKZ/evaA4ninV5iecPILpA3CzFqZlC1IXooFJvBLuMaofxvFMKZqkTgNQo0WNtjVaFRcVCqhmwARtl4acZopKkDLWNgYa91nYZRbiwApKG2XxKkVUF5uBtnZFQbvKEOkckkGLFtxAo80Umv8e2k7gCC0ycK92SYmO1LOncERpBsWNq0whWecT1PsQXaVF1uU0MgyBzg2hZmP2J72BzoA51LnfQ7tKy6wxqY7aA+p4CZLtCByxH0bm4uXjgzO4/LAZ1hU6DYzD7+J49P44tvLmdYIRaLL9t0t6dW9mN9nPTgFYvv/cNixvkHOhtibg6ygkNsrap7hoXgFGWwIOPC3mwQvgozIf8r1m6fWNZzG/P6xlGpV8U+2hruH2dhh1zeLsiOsbH9/8p784f/OR6nt8XP/UmDwfD16cHnF58ZSrLx7+xzfqDlm7M0y3wYJVAAAAAElFTkSuQmCC) !important;
}
.restore, .restore:focus {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMEASEHTKMX2QAAAwBJREFUOMulkzGIXVUQhr8557zNZiEWrjbbpLRLo1hpncLSxtLKKJguqEQRtBJBsdIqqzaCYhELewttLEUQW2EDKiZ5u/vuu/ecMzMWc9/LRkyaHBjuvYfLP///zz/sXu1+5XDwo9vqj3pePTz1nVdWXl6+dMq1yxf4+NvGP8fOanTGCq07tUNKUBsAqMVzbL79Hiusp8aTe0sOrz2O94a4u795Y+JgXygZlivn7gqmBrU5ZtAtANyhqaMKVWGqzjDByaAsl0su8Afff/IsCeDOqXNuATsLoWRhUaBkWGQhJSEL5BRVkpATJIGchJJgkaOO/jrlYL9QAE4G53iAkp1hctYTTDWY1g6thx1qULvjEPc6M7ewKacEEKC1w92VkxOsRhjGkDZV+Or6Lg86T19d4Q5uThJhUeQeaOsBlhLUCq3dq4edqoIAgoDI9r4ATM2pLXxqHbo6XaGb88L1NdOchEmdSYVu8OunezRl66+545xhCjDWkGDmfPnGgyVfen1A5/cGmM8gEunYgg6TMzWnZMAfLtkL+IxqeUYSwBPGfzwdK+yUkALw4vtr2pzHalDN+fGDPciy7WsJ3GUre7McAaoRlZzAN4YLkEA8ZiDzvRT4/aPzAVoAA1UBh+5ydlBROUVW2bggAil4SNqMVnjqrZGm4EnQmbaZoGdBa3emFlu0iYb6ZqLRwDeJSfHhOOZgFv+qCW3ucB/TRYaNY9+9e/7/JyXRwBAMaBbxs+50lfs3aqyzdBEuvz3gCCZgAl0iPpWQuGFvgLpEphXUzjDtCusKOYPjlBwdTXwL3ESoQHOnOfQOvQvag6mq42dBa62sp0QWwRRKFkRAERDQtGErVIdqQtUZuDpaFasdNPa63LpjHDx2zN9L8ArTIlOSI+KYC57COwVUMs1DcngpaAevHcYlF58IpnLlxuCvPd946Z1fOPrzhLI4h4iRMMxBJIOEl0pCEcwTpooaGBnvjYv7jZsfPsNnP+xSvvg5gxu/ff0cj3Ju3Tbe+2bg85+EfwHQoDlA+htxlwAAAABJRU5ErkJggg==);
right: 2px;
}
window[inactive=true] .restore, window[inactive=true] .restore:focus {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMEASICF+SwlQAAAsRJREFUOMt1lbGrHkUUxX9ndsN7vmDS5EVQEPw7bC0tAmphJbGwsg6xktiE9IqFvY0ogmVAWyuxs7BVSPKMaF4wu983c4/Fnd39ML6B2Z1l5p45c+6Zu7r79QNfuQSvnR5xdEmszea55vWR08t3X/rLb894UmE8juD08hE//Fx5NpldNbVChGkNEPk+2Kc2Y+f3vpq6b5yMMzdeP2aeGrr/45++/1PlygtQCkw7M+2gtgRzmDBEZ9YCHNDC1Gb2e5h3wTRNHPlv3nvzFQo202yGAkVQEINyPAgkIaAk6fUtQ7HWdYPgydMdx2NhBJh32YvyOPu6MW0B0URrJjpD2OaaISwkUYqQYATRAqZ9sthVNtAKn9++zkXtndsPMMI2khiKADEKiBD7KpBpTbQG0bwm6KLWnG4RyRQJBGOKn2ASRCxdhM3NO49yPqBGlyPgm3svEU4ctLgqwcdl19ryCA7z2a3TC9m99dFDYmEKFGcuOLD4iDYNS9mMfFFz2aItEUuAhTvymqgaMBxs+MHdR5ndnuFm+PLj62jQtqgIG4ICUj+BGCUIREQ/xhIhQdk8qU5IBb795LSz7gwj40zpmko0i+YDfTqoSNEOQSnixp0/iMhx9PtvRJBERiknFtBMJ3ghvDJfQEEhKMYShIlIPd3JjGjRTQwHjL64de1/E6WSfnQIAoLsqa1QWY6PqJEFBeD9e4+7RltQdAu5rKbMSkU6IPp6AaNKTtYQJbej9ED3eHfAhtaKtZQ+Y2xtTlwTFZFMW1qkRDouupChBdjdXuqFJq9z2Dg61yLGuQYvHs/8MyfLoRSKDqq7OjPSj0FWpQgTi51qQ23m6mWDQJ9+d+ZrJ+Kr7x9y/nSmDAM4c5mYKXQ4zZ1VSTiib1agNa6eBO++8TJn5zCe/bXHbeTDt1+94F4+/3/iP0OAaW78+vuOx+eVfwHSwtGIVS3C5gAAAABJRU5ErkJggg==);
}
.restore:hover {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMEASInXOBk0gAAAu5JREFUOMullbtuJFUQhr86p9tjGy8EEGwCJEQgAiIk4BV4AAKkJSDZhBfYCDkhIIBgBQ8ARisRkphLDhHRBkSbgMSuF83Yc+lzqyKo450xYJI9Uqs13X3++i9VZwA4+fHM5hfVnmYtLqqdnD40APnq9JG9+foL3D2FqcBqgnWG2iAVEIHSAEAVqkKpYObfTAVSyjw/+4svbx/x629rZLGs9vG3kVduwjjAcoLzjQPm6lfrYK0DNvX3qTqJ5bqyWMw5ag/4/tM3GJ59JpIqzEbYG6A1yAUwUAMDQnPGAjAAFYbo4OMA4yCM0fjjzw3PHUUGgHWCiw3sjy59ql1WZ5ML5La1RM0VlAalgKoRY2CIwmVdNtll5+qb1slBNxm++JBr1zt3vAAmBIEhsAUtbSec1lnUbUDXraxuSbh8IGELmmsH7Z6WBqUH895nMDW3Ycp+LxV+OYYqHVCAcGl6BzVzuaou5/MPrmf31jFo36yjB2iAFfzHrqdTBhs99f9b4RDk0pYD/1wbaAQN4aqnqfRNncWtu+5ZMZeZA3x3G8IBBO2gh2AKVkGnQNtlmnv7BIHYXW/dCgkQBoiDP48H8POtLVOtbkeNQmOHaSruaQgwxi3ok2gHCONW/tv3evKH0AqoCUWEhvxb/hA9NHCWzfokRaAXC3vej09G1qBGSCZUlastlcqWJcA3H/13UBa8gIoDFvH2KwjV/gE6FYjR03z3k94qEWQfbB9sBnXmbdTElah1xgq52lXQ0hs7iqc59v5D+5AEaH6OUBWmANn6eVD8atUwtR3QktkkISBo8yIiAtF70iroHrTkU5ejkPqhkpNRlkpdVVrKDnq+atw8eMTZcqRNxmyMDMEIEQzBBoERNAo6BmoMtO5jJZCzUZYFnc956UbifNWQk58e26svz3j/+D6/P1wRh0gUIwQwAhYiYYg0DI0jKhEDaq1o2EPV0JR58cbEvTuvcf9Bn4yTHx7bYvl0/1Hzi2pfn54ZwN8wflBlW3piCAAAAABJRU5ErkJggg==) !important;
}
.restore:active {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMEASMQ/UbwnAAAAiJJREFUOMullb9rFEEUxz/vzW7uIir4I00ETxAVLGOppZVVkKRMY+WfsK2FcP2ltNZChIhX2Qn5E6IQsLnysIiXy91ZZGcsZnZn1ttTIQNvZ3nLfOb7fswsAIPhqZvOS3eRMVuUbn84cQCy/+nEPb7zg+2XrxmNz0AyEAHNQHMwa/4dAdPxPjHRpxk4S2/zBgf9HQ6Pc2S2KN3Dpy8YnRhYu+oXqfEAqcCd5kaiHiwCKOAAobfR4ejNLtmlrjIaT+HKbehcB7MeYZpHkBpvNUzCjH/HMZo4Lq8rWe3UjgdqCFFD2BpCFRMUCqgmwAoah4eKJopykDzkNqPYe8Sq0X9/3OpX/6yUpbOH/teQNqV17gJQsgBV+m+/+kVp2CIUO/d8atLhXArNErCh2NtaHfKH71GZag1aoTRC/zqMiVBjItRab02lWawy0H/3DVRCEb0Vz++2QytwM/y1Pxo6dEmaS9UaVDy71Q5tKs3rwiBhcdqTqmC0zmP/89h/y7IYdgC2hC8RqhKVSurXRhfE5owHIjS/qeKtPxS7D1b3ZKvRAq2UVCdFkiIZ07QazjK4PlGyfCrqai6Z9bMtwTp/QznnLyqX5hQNDkkuB2nZwIIVwAZl1QbNYunZwtLbvLasNFVXLSgtlCWcny9bWdLb6DL/ZZHB8NQ9uT9n+9UXRj/Dcf1XYVJ/2Lh3s8tBscXhUfg+GE7cbHGxf9R0XrrBR/+P+g3drjnilUkuFQAAAABJRU5ErkJggg==) !important;
}
.resize {
position: absolute;
}
.resize-se {
cursor: nwse-resize;
bottom: 0;
right: 0;
width: 5px;
height: 5px;
}
.resize-sw {
cursor: nesw-resize;
bottom: 0;
left: 0;
width: 5px;
height: 5px;
}
.resize-ne {
cursor: nesw-resize;
top: 0;
right: 0;
width: 5px;
height: 5px;
}
.resize-nw {
cursor: nwse-resize;
top: 0;
left: 0;
width: 5px;
height: 5px;
}
.resize-n {
cursor: ns-resize;
top: 0;
right: 5px;
width: calc(100% - 10px);
height: 5px;
}
.resize-s {
cursor: ns-resize;
bottom: 0;
right: 5px;
width: calc(100% - 10px);
height: 5px;
}
.resize-e {
cursor: ew-resize;
bottom: 5px;
right: 0;
width: 5px;
height: calc(100% - 10px);
}
.resize-w {
cursor: ew-resize;
bottom: 5px;
left: 0;
width: 5px;
height: calc(100% - 10px);
}
.windowBody {
background-color: #f3f4f5;
color: #000;
margin: 0;
padding: 0;
overflow: hidden;
border: 4px solid transparent;
border-top-width: 0px;
border-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDAQszn6sX/QAAAKJJREFUKM+1jz0KwkAQRt+qhRgICAZi5SksBC/gQTyfpZ2VvUcQrcRNUKKDYTW7NiEkBn9S+LqZ4Q3fpxhu6IY9/ElAok+kqwUVxnMQDbs1SESHV7yAT9SF0bSh4A2+Cq68cEtflWc1Syr3Fg35v1CUfhxu+GG/lhnRcN4XTQvhLoI9GhBbfWmu4Cyodi5kW9I4IY0B1JvUFjKTC1aDXH7u8ARCtTVoTVankgAAAABJRU5ErkJggg==) 4 round;
border-image-width: 0 4px 4px 4px;
position: relative;
}
window[inactive=true] .windowBody {
border-top-width: 0px;
border-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDAQ4we9WyAgAAAJlJREFUKM9jZJA8z8AhwcXAZynK8On1e4Yf+9YzoADTVAaGr68ZGB4eYWD4+oaBhQEdcIsy4AOYGuRtSNTALYJfQ7T/v/+SEswMjDzvGRiU/jN0FfMxIisoa7/7n4GRkeHHW12GR/ffMzAxkAhorwHh6b+MDAzMUDcjA0ZGhn+//+AIpd8QBQRt+PnlIwPDFxKc9Oj+e6L9AABFaylSbHBdvwAAAABJRU5ErkJggg==) 4 round;
}
.windowTitleBg {
width: 100%;
height: 30px;
line-height: 24px;
}
.windowTitleBg.img {
width: 16px;
height: 16px;
float: left;
margin-top: 7px;
}
.windowTitle {
float: left;
padding: 4px 4px 2px 2px;
white-space: nowrap;
color: #ffffff;
font-family: 'Trebuchet MS Bold';
font-weight: normal;
font-style: normal;
font-size: 13px;
position: relative;
top: 0px;
left: 2px;
text-shadow: 1px 1px rgba(0, 0, 0, 0.5);
}
.windowTitle.inactive {
text-shadow: none;
color: #d8e4f8;
}
windowbutton {
border: 0;
max-width: 140px;
min-width: 140px;
width: 140px;
height: 25px;
display: inline-block;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAZCAIAAAB/8tMoAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDFzE623Wu4gAAADtJREFUCNdjkEm6xMzCo83ExivExMguzMTAwMDEwMDAxMj4n4nhHwOcTwpmZmZgYmJiYGJi/M/0+tl3AE9qB9CxoTXnAAAAAElFTkSuQmCC) repeat-x scroll 0;
position: relative;
top: 0px;
padding-left: 4px;
line-height: 25px;
margin-right: 4px;
margin: 0 10px;
color: #FFFFFF;
}
windowbutton * {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 140px;
vertical-align: top;
}
windowbutton::before,
windowbutton::after {
content: ' ';
position: absolute;
top: 0;
width: 10px;
height: 25px;
}
windowbutton::before {
left: -10px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAZCAIAAACHEijfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDFzEmz3TyrQAAAOBJREFUKM+dkU1KA0EQhV/9dM10fshGAjmAe6/giTyAd/FgASEiySYg7iSMU+UiM5h2JpHk0YumHl+9qm56eN7u9hV9vU+zYSB926ivX6SqPwEQd+VwACAWfDd5sdI6a70Qy/2ZiE3EsgIAU1SzoLuirwAt+m5/vF6Mc2oBQDv4OMsVNDqajviNdCkftX28nQKAB2SQHXQpmygg/45GTAV0evfQYfV3ab56754rH3VgFDSfCWEgLmWH+8gfRcdwun8KNOQNmZBJSpwSJ5OkZMa6nDf79vHw8QocTnAHWiD9AE80M+EwBCb8AAAAAElFTkSuQmCC);
}
windowbutton::after {
right: -10px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAZCAIAAACHEijfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDFzIcIlV43AAAALhJREFUKM+lkTsKwlAURGfuu/EHElGChal0Ae7JpboEWwsLxUKxsImfvORaKX4eCcRpDzPMMEwXK3wqzwt/8+wl6STSbL18Z6SzMgfFX7PNYa6t/hAhaTw4n7bK9iiIKQbsBJWqwUqz5u5KLGzqFgEpjd00ABq0OEIFMPlnGGuGFY3CX5UC2BEAosgAFxhmYsLnoc79fgw6AgZA1X3/rYJISwBmeSC8IAvPuzd2p3rcX8Ll41ky7jwA6wYu6UwIbSwAAAAASUVORK5CYII=);
}
windowbutton[inactive=true] {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAZCAIAAAB/8tMoAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDFy8lgjycyAAAAEZJREFUCNeNw7ENgDAMRcHvZzEDFRIrsBrDUrAADQVNJJKAzQqcdFrWnXGeGGqjdKc/QplEGBGJuchXyA1J/yIU4j4vyrF9UqEXZO62m7oAAAAASUVORK5CYII=);
}
windowbutton[inactive=true]::before {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAZCAIAAACHEijfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDFy4yGPQoTgAAARxJREFUKM+Fkb1Sw0AMhL/7cRwYamZSUdHnBfJkvCMVPAFQUTApHN/5ThKFHU/iJLBzlVa7Wunc9uVLckv+bteBC8TDT7uiPm+fVtgV+l72u90mrGISGUt9UkAzviUC0dOL9ElLnjpKNatGIs6KQ1eB1AMUnNQIR7pkST0FB0gNagIiYnF2K7hTAjAXIlCV1JPU482LFwUHoIpfbKIBC27kptmqFNeAqjrAio0XkDnaMKgppsvLeCDlZnbjqJOZXkBOjwrUOCyqI+yq+ny2D+M+l3CTemgkAz7A/MCD/8c8AmrlmNmfR9MIpFoH7m5EA6v2lznqfK43aJU6iGuDTd94Tu+79v3182HzeF3trbNm3X284RTAPIBTUCz+Agi9oqKb73KqAAAAAElFTkSuQmCC);
}
windowbutton[inactive=true]::after {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAZCAIAAACHEijfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMDFy86DzSRPQAAANFJREFUKM+lkjFOA0EMRd/MepWQIgUVDWm4ADfLZdPQUAANCIGCkgjGY5uCUMyy2iDFnf39vi3PpNv1HW2Ye/2qMbucL5Grm1UjljhoqMbHw+th+ySUGNALMaOz5WJ7/yyleOsMZLdjUVQb2oIw0F/ZWu+wJpVB3rQGmcmQ1P2B7H/mgNClYc2CPlNA0thsTz9j4dRqk7Klc+g8TSc/x3xUdjKeqEHkU0/i2nTk3nPv6PFqknsfIgo4NTCTz/fd2L3q7uWN+bXsHzfjX+ViFcy+AdYLXsVStetyAAAAAElFTkSuQmCC);
}
windowbutton[inactive=true]:hover {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAZCAIAAAB/8tMoAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMEAAw6NSNrEAAAAD5JREFUCNdj0InfxNB94D/Tq08MTF9+MjB9+sPA9O8vA9Of/wxMDAxQ/BeJTQRm/M/A9OI9A9ObzwzMHIziAODAEzc3pGP3AAAAAElFTkSuQmCC);
}
windowbutton[inactive=true]:hover::before {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAZCAIAAACHEijfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMEAAwgyEGSagAAASxJREFUKM+NkTFOAzEQRd/Y3hWRoKBAos0NECdBAhoaWu7AQbgOBWeAjo4qRRZCsontsSnWuxtpA2IaF8//+VsjF48fYbHS77e6dkzGfb431Xl9f3c1q7F2gvP69eH2pgOqAOoBNhHAiabTmqWn9cRIUGJ3qcODZ7UBRxMBxAN47XHrAZowgqB76RhpApJGUKp1R1DE42VkmgAM4CNR2Zgc61xZkpAEICkuWzOocisBcgJQwFKYRsxOkhRn94LmHocMkLU4OzZWq4TQh7CFFbwVQkYUEfLAtG/+xxhwvu2bTzc2TVgBUPs/+YEZmpth84DooXTQX+UOiMrOl792Akk9FvXbwDawbll+ESrMnkzm1y+czI7nl0kwuawSCJHK4czRWVotmuen6cMt/AD3ip1TAxRXIQAAAABJRU5ErkJggg==);
}
windowbutton[inactive=true]:hover::after {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAZCAIAAACHEijfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMEAA0c/jXfrAAAAOBJREFUKM/Nkb1KA1EQhb+Jo0iwCmwQxC6VBN/BJ/GB0ucxLCxSpxesUsYqQVQEIUaze+f+WETC7mY3tk514eOcOXOPDG/vKY23AORrf5INuud9GU1TGX97No7cmEzn7mmmbyv25/mV7GKweLzTdVEBLgA4I3cAuvJ1aUcAiAAaQx3H0lt9qmOVkhNNY9KOUwRwWyf2dv9KQot6F1bkqHk3wHF7tD+S/1cc4kGctt9iLbgAZ7v2qoV+GRaxBAKgLx/VKgNAXkAipaDvn3VzHwBs+SBnV3J5M248SXvXndPsB5RLU4IQEm/+AAAAAElFTkSuQmCC);
}
windowbutton[inactive=false]:hover {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAZCAIAAAB/8tMoAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMEABglloWxsAAAADNJREFUCNdjkEm6xPTv/QcmFh5BJhEhcSYGBgYI/v8fwSYRM7H8Z2Jm/Mv09RcD8zc2GwBviwvoZG3RuQAAAABJRU5ErkJggg==);
}
windowbutton[inactive=false]:hover::before {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAZCAIAAACHEijfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMEABQj01NbiQAAAOZJREFUKM+dkU1Ow0AMhT+PZ5KGEUJsUi7AHk7GATggHIIFCJVNVQkJpIo2M2bRpjBplQi89NPz+7Hc3C/elrWsX2NTcTT+5dmffTyg8esTSwFATegAwyvdNra3ohXNpdQzqWcSGkIkRAmNB1Dm7dWGi+KuAjiAxBA7aA8Xegwrgu0XqYAdo+NBAJydhKfZ5aSTcBpxniDk4ZnsJrRFbcqaOCkYfUBxhvXWpIytQgaH/TG3yqEv+ylVhf+U6sDGtC2XfQXIONtzfLi+0+pp3SXb6W/6s84A355vl+/z1eIR8i83efeJb5JFPYaBDT0sAAAAAElFTkSuQmCC);
}
windowbutton[inactive=false]:hover::after {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAZCAIAAACHEijfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMEABUVBfL/UQAAAMNJREFUKM+lkc9qwmAQxGf3mwTbBmzF0IM51dfwafqAfZWAnnrq3YMtgoh+f9ZLKDZ8jRDntPBjdmdYad7X+CvvYzgFeaybRcH0/dPDRHCg7DZf25KsXq6ZSDeU+rT/bDmfvSKnow9AqxjUDUyYjXcPYpU73CI61l249A92UJqKwfSeYpIrpmYA6BSIo5b/Rhp2u9xtotDYPVTZf6hYBFCWCQCdxP5GJrrCx2TmeTj3opp6BKbgKQ9vUq0+8uGny/p5cgHVvzWzWeZRsAAAAABJRU5ErkJggg==);
}

369
xp/system/xp.css Normal file
View File

@ -0,0 +1,369 @@
/* Styles */
body {
font-family: 'Tahoma';
font-weight: normal;
font-style: normal;
font-size: 11;
overflow: hidden;
margin: 0px;
}
.scroll {
overflow: scroll;
}
pre {
font-family: monospace;
}
a {
font-family: 'Tahoma';
font-size: 11px;
}
windows {
position: relative;
top: 0px;
bottom: 0px;
width: 100%;
height: 100%;
display: block;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
._ui_ellipsis_overflow {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
taskbar {
background-color: #d6d6ce;
width: 100%;
position: fixed;
left: 0;
bottom: 0;
height: 30px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAIAAABi9+OQAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMCFjAx7MJLeQAAAFpJREFUCNdNyTEKg0AARNGZ31hYCR4gV/BWuXAOYKVgISEExNUdGwurVzwN7w/Nq6drT6Y5bOvG8dvJEVKDJCQTGSNksJ8aJcjGFrbR/dL9EqmVuhfKf6F8xwvt2yA6OsEE7AAAAABJRU5ErkJggg==);
z-index: 16777214;
}
taskbar * {
vertical-align: middle;
}
taskbar separator {
width: 2px;
height: 22px;
display: inline-block;
background: url('data:image/gif;base64,R0lGODdhAgABAIACAISEhP///ywAAAAAAgABAAACAkQKADs=') repeat scroll 0;
}
.bevelinset {
border: 2px solid transparent;
border-image: url('data:image/gif;base64,R0lGODlhBgAGAMIEAEJCQoSEhNbWzv///wAAAAAAAAAAAAAAACH5BAEKAAQALAAAAAAGAAYAAAMOGKoT8KIBQqKjVug4uk8AOw==') 2 round;
border-image-width: 2px;
background-color: #FFFFFF;
}
.vertical-text {
writing-mode: tb-rl;
transform: rotate(-180deg);
float: left;
color: #FFFFFF;
font-family: Arial;
font-weight: bold;
font-style: normal;
font-size: 16px;
position: absolute;
bottom: 0px;
left: 0px;
}
._ui_grad_btb {
background: linear-gradient(0deg, #0000FF 0, #000000 100%);
width: 17px;
}
ul.menu {
list-style-type: none;
font-family: 'Tahoma';
font-weight: normal;
font-style: normal;
font-size: 11;
padding: 0px;
margin: 0;
position: relative;
bottom: 0;
}
li.menuitem {
color: #000000;
padding-left: 4px;
padding-right: 12px;
padding-top: 2px;
height: 18px;
min-width: 134px;
}
li.menuitem:hover {
background-color: #316ac5;
color: #FFFFFF;
}
li.menuitem[data-selected=true] {
background-color: #316ac5;
color: #FFFFFF;
}
td._ui_td {
font-size: 11;
}
.ui_terminal {
background-color: #000;
color: #c3ff00;
font-family: "Tomo",Ubuntu Mono,Consolas,Andale Mono WT,Andale Mono,Lucida Console,Lucida Sans Typewriter,DejaVu Sans Mono,Bitstream Vera Sans Mono,Liberation Mono,Nimbus Mono L,Monaco,Menlo,source-code-pro,Courier New,Courier,monospace;
font-size: 8px;
white-space: pre-wrap;
word-break: break-word;
word-wrap: break-word;
padding: 5px;
overflow-x: hidden;
overflow-y: scroll;
width: calc(100% - 10px);
height: calc(100% - 10px);
}
.ui_terminal, .ui_terminal * {
font-family: "Tomo",monospace;
font-size: 8px;
line-height: 1;
color:#c3ff00;
}
.fillspace, .fullscreen {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
display: block;
margin: 0;
}
.noscroll {
overflow: hidden!important;
}
._ui_postlogo {
background: url('data:image/gif;base64,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') no-repeat scroll 0;
width: 278px;
height: 116px;
position: relative;
top: 5px;
left: 5px;
}
._ui_wallpaper {
background: linear-gradient(135deg, #316ac5 0, #a5c6f7 100%);
z-index: -2;
}
._ui_wallpaper_image {
width:100%;
height:100%;
z-index: -2;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.hidden {
width: 0px;
height: 0;
border: none!important;
padding: 0;
}
._ui_menu {
padding: 1px;
height: 16px;
display: inline-block;
padding-top: 2px;
}
._ui_menu_item {
height: 15px!important;
line-height: 15px;
padding-left: 5px;
padding-right: 5px;
padding-top: 1px;
padding-bottom: 2px;
color: #000000;
}
._ui_menu_item_active {
background-color: #316ac5;
color: #FFFFFF;
}
.beveledmenu {
position: absolute;
border: 2px solid transparent;
border-image: url('data:image/gif;base64,R0lGODlhBgAGAMIEAEJCQoSEhNbWzv///wAAAAAAAAAAAAAAACH5BAEKAAQALAAAAAAGAAYAAAMOOKow8qEJQqKjNugIuk8AOw==') 2 round;
border-image-width: 2px;
border-width: 2px;
background-color: #d6d6ce;
z-index: 16777215;
width: 150px;
}
.ContextMenu {
position: absolute;
top: 0;
left: 0;
cursor: default;
visibility: hidden;
z-index: 2147483647;
/*box-shadow: 0 0 25px 1px rgba(0,0,0,.5);*/
}
.startmenuitem {
padding: 4px;
width: 178px;
height: 24px;
color: #0a246a;
}
.startmenuitem.large {
width: 172px;
height: 32px;
padding: 8px;
color: #373738;
}
.startmenuitem:hover {
background-color: #316ac5;
color: #FFFFFF;
}
.startmenuitem[data-selected=true] {
background-color: #316ac5;
color: #FFFFFF;
}
.startmenuitem div {
vertical-align: top;
width: calc(100% - 44px);
display: inline-block;
padding-left: 4px;
height: 100%;
}
.startmenuitem.large div {
padding-left: 8px;
}
.startmenuitem div div {
position: relative;
top: 50%;
transform: translateY(-50%);
padding: 0;
height: auto;
width: 100%;
}
.startmenuitem.large div div {
padding: 0;
}
.startmenuitem:hover div.startmenuitem {
background-color: transparent;
}
.startmenuitem.expand {
background-image: url(data:image/gif;base64,R0lGODdhlAAgAIACAAAAANbWziwAAAAAlAAgAAACV4yPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCoczAPFoARiRTIhy2YwqnlCp9WnNGpRabbULDovH5LL5jE6r1+y2+w2Py+eUAgA7);
}
.startmenuitem.expand:hover {
background-image: url(data:image/gif;base64,R0lGODdhlAAgAIABAAgha////ywAAAAAlAAgAAACV4SPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCoezAPFoCRiRTIhy2YwqnlCp9WnNGpRabbULDovH5LL5jE6r1+y2+w2Py+eUAgA7);
}
.startmenuitem img {
width: 24px;
height: 24px;
}
.startmenuitem.large img {
width: 32px;
height: 32px;
}
hr {
border-top-color: #848484;
border-bottom-color: #FFFFFF;
border-style: solid;
border-left-color: transparent;
border-right-color: transparent;
}
.clock {
float: right;
height: 30px;
line-height: 30px;
text-align: right;
padding-right: 10px;
padding-left: 12px;
}
.clock::before {
content: ' ';
width: 30px;
position: absolute;
top: 0;
height: 30px;
background: transparent;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMLACYxlflu5gAAAotJREFUSMfNV9Fu1DAQnFn7WlqdVH6AL+OHeOUD+CD+AgnxhqgoUErj3eEhTuJLk2uqVhyRIsX22bs7s7Pe48Xbj8IJnvzmy3vcvvuAkoD4fF+nW1842/KInxvDyK/ODbcAsgNxlfu98UQQ4umg5a/Xf2B1UL4XRAegrByk2XwZLc+cYA2d64ZvfnV43W4qALoNEUQ15oBafEMN3uvnZE/E7uc17PIKpXPEHfvNscydpP5bqm9dauc3PAYAdEEtKvEPspqVB6oNjlOYmkVdxxkGEHCpCXK7x7Y0yUc0kcXnR9xmLI0gBRnAQSIcOOy/6QZvDnABUExZvyYIHlaGTNOiUtbqQdBmY82oePwgAciKyvEKepwZN8VM2poiRqxK97+J2HCiJ0eDnAcgEYq+hljj5hBIkc2g9oeS26zjVF/vS15UQlrUpJe9PU8H9Ui2gADh3sjyIEX5soY1Oz5yQpQAjIt3LeMZ2MZC5RInMdOAMYdGB+rvdg52ad1AOoJMWiqZjWeqF8BB9UjTt5VGCTNdb82ajLZXyIS6ao0L1Kqf8IvAzm2EysOadW3qwfJw9lCAmHn8dlPvZjEhgzAAfh8TKs4n6HjgOAGMAOwYXr1jUqCg71R4bv3VrRk9R1qvvla7QAE6tz6/jkVcovJtIANRZhnftlzQlJxLUP/YE9wn8KZ3YNGwq1IhRCHIAD3GJG4dGI2SqyRn+iXO9ntoZ/CzumXWZYYTyQJR217LAu6mdkCuPpm97QqbxEk2dqTD4kM5/XZY+BghACQnwks9XOOa7pvE93ovD5ymI42+Edm6AtwV2G0H//QNdlNw0NtUT4d0U4nlIhoCgrX2DkQngGXqMmrTARN4qj9tfwFF3WbxoYSOLwAAAABJRU5ErkJggg==);
left: calc(100% - 68px);
z-index: -1;
}
.clock::after {
content: '';
z-index: -2;
position: absolute;
top: 0;
right: 0;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAIAAABi9+OQAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gMLACYnYS3btwAAAFhJREFUCNdNijEKg1AUwPLyXQrOvVzP6EE8QU/gWHAQCt/6XgcdHEIghMdr5jmttrG5L93a0/oeAkIIWGBmqGXm2bK4nhstpHl6CBk0xCD1+Gnv+tnc3usfcTkdk/RJajkAAAAASUVORK5CYII=);
height: inherit;
width: inherit;
min-width: 38px;
}
.bevel {
border: 1px solid;
border-bottom-color: #FFFFFF;
border-right-color: #FFFFFF;
border-top-color: #848484;
border-left-color: #848484;
}
img.menuicon {
width: 16px;
height: 16px;
padding-right: 4px;
}
li.menuitem span.menuitemtext {
position: relative;
top: -4px;
}

482
xp/system/xp.js Normal file
View File

@ -0,0 +1,482 @@
'use strict';
xp.startmenu = {
icons: {
programs: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA7DAAAOwwHHb6hkAAADLklEQVRYw+2XTYscVRSGn3PqVvVH7Nag8QPGaERBIQguxJXgT3BA3LjLH3CjS/+AK1F0I2QnrkQUwYULs3GhuHETQwgYBiWBOOhMJd1dXXXPcVHV3WWnZ3Q+erLJoYvqrnvrvO897znn3ob7do9NePfqhVM6/fSRQVfHpfvEHDcwBwdUIRqIQ0gE6g9BweF2dCijIwJmEN2ZFhGATidQTCtAodsDTVXcMt+58QkfvfwekAcm+QdPbQz1/NnT3BglYg5BYGJCFZ0HOsLfkwgOvVRxwNwQFGAwLp0iQlAhxsg0Qj9L6AbYmUQe7KVomqDjnOdHV7jGGX6qhm+Xw8evsHvzs0CxM7i8ZVz+fVwvO4F67QIOGgSROlzqThmb2Lk1dwWtp4PBFF578VGeefgUF7/fYvOVJ8mlz/SXb7gYPuT97uv8EDc5+1D26tYu3wbyO5DfgmkBMdbOGnwMbCEW0ZvvKjXZ5jnSEtWcS9czLvUz2M758vqvtb8icLrzFrv6GAxvMR6Pe0AaNp49x9cXuvw1MqoZwmzJvuQcwL1+5i1mi0FcwConmhFCgpnXUzVlJBlP9Eve+WrE1e9qumHY6/PS0+dONPPPb9zkx7wCIEyLojVUrhE2qasB8OkCR6mWQdPm8v9w6M2Vskicu6t8oWPVXE2yNhbUbcnpdIW27OGcfebLfMX16g0I9S9fkA1isQV+uF62d4TiSmnFbY4XknkEpMW2TciPpeG2/WhcRF3/LYE0rL1V4HJsXX8WEWlhBolxKWwztvY/c+EgZkBSE7AZAY8H1PaoUZhFwJoyvFeWDVNAVM1O/gxQR12Aju4twToJzCUQDR5XlJ2vl4C1k9Cq1pC2km99RJJWGarMm4K3upefgAR3dUJvbSrrItAqwwYiZOqtFuz79AI/NgKdxBERHAiiuk/zKRtJwnwnO3onVAqUkHWTcoyGa79t88Ibn1NVRnRb4uv1Eewoe4IsDrCqQhoSigrw0oEQkjL/eCe/82asysxa2qw8cK5GODAznfxxuxr9uQ2UAgyATeA5IDug2ClwprkfxEbAz8AXM/aDBvwwlh7yvRGQ3/9z+g/E/lvy1FW2PwAAAABJRU5ErkJggg==',
documents: 'data:image/png;base64,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',
recentdocuments: 'data:image/png;base64,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',
controlpanel: 'data:image/png;base64,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',
search: 'data:image/png;base64,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',
help: 'data:image/png;base64,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',
run: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAD9klEQVRYw+2WTUwcZRjH/8+7M7uuiwtZ2OWrpRQUESQQY9JLQ4mJxgPG9qa1VHrwYg+W2Ium9uQBQyKeTIwxTTSaGiWaqAdjrZDYVhoq0C7hUz6EaWFnYReW/Zhh5n08NBQKLB+Fm/wvk0xm8jzv7/2/z/sH9rWv/7toW19VNxUS8j8BqASwFTARIB+pIJOam5vtCYR0/Svnwu8Xle39dqCNDzx5pOSZg1AUB/x+765WfW18Ec6b1xpETLYpAzPJSHwxBisZg5WIwUgtwIzHMDnw94m3mj5oR3VrDdyZR/B0OUYlABMY0sxtFfrsZBkuXA7iw9eexYXLQYSWziCgXgIAmG4vHmeuVDqv/JA1PDQAljZYSjDbkNJGwOOsA9BOMtnkq3oOOdUFO17px32L8FUVP3iW4w/4AOiXfsJjE9+NELFHefONk5v6IDuQ3/DrWS9KCrQ9MV04aqLy0wUoS1pICjUiNjdf63FmppIC9565/turIXDkdoKIQkRSUwZmUpHFaARGLAwjEYEVnw/39fz5YtN7H40Tp84cf+kwAMAwTXR2dT9S0dLiIhQW5AMAvvhZg2qM6gzSAJpW/vrt+8zhoUFiaUHaFkzDyDroy8gCgGx/3itvv3wIANDZ1Y3rN3beQMPrr6Kyug5RfRDhqAlNT8Jpz2lSqOMkEVIaT50SO8Hf3NyKlpYWNDY2AgD8fn/a4n297aisrkNyMbSCP9obZ6YZYp6ULKNpPXAfvw8AEE8kHry3LAvBYBAA4PWmnwdSrgwqM7Wwgj81FiZBdyFoxulwxZWeyTjHZ6eQmLuHPF/GSFXN80+txX+r5w6u3+hGc3Mrvvz6G9TX12+6cgCY1SdXph/bG+HX59kwlCttn2MuHIK0l5Drzyncyv1up4ra2tot9z40PYbi0pqH3b8GP6ZcS8r5c+doY/z33S+ZUFpchNLiIvT1tqOizI/wdD/C0/1bNuHJyEJUH1qHnwXNOOGKJ9EhN7wLVuP3BcrgC5Tt4uRzWvwAWLk9pnNooh93+26eOH32/I9r8Uf1wb0ZPhvgB8Aiog1ysLcLnpy8i8v43z1duKd3/gp+oS27H+iQAKAcO3r0oaPIwvXCIZ8HAxPxPSm+kLCh6Umo1uy/TMo4VuEHgHUeINvobXj/6mGC6QWzCjDtrgViJTU8DeEYIeH4RzLNYVJZStuAO/HLO2ThGKRdzgTvtlNTeg9aEDQnHY6gIIwm3CK2jH9tA4SKCpWSzilms4MUcQe2cO6agJCSQAlyOHWHod5DkZHCqjxH6zJiRYUKO8uVmRSKtFxi16FTxJkcLjlvPmGiLGaio8Nexp8ulNKOAutONmNV4X3ta1n/AZedFNtvtQ31AAAAAElFTkSuQmCC',
shutdown: 'data:image/png;base64,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',
pictures: 'data:image/png;base64,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',
music: 'data:image/png;base64,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',
computer: 'data:image/png;base64,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'
},
appIcons: {},
menuItems: {},
add: function(appName, menuItemTxt, appIcon) {
xp.startmenu.menuItems[appName] = menuItemTxt;
xp.startmenu.appIcons[appName] = appIcon || 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAjElEQVRYw+2XMQ7EIAwEh4iHcS/DTzMv4woUiShKESkxKXYbLAo8trcwsFjJzPqq5GZGBiilhCd3d4ABMCB6cPXj3N6pLuGegN9lvGtbbcL8xqOzp67iE8BozWNDuG/C/SJCcycOI6i1hgC01r5jQgEIQAACEIAABCCAPK9J86YSChC5D57+hkBHWqg/W2onU5GesFMAAAAASUVORK5CYII=';
xp.startmenu.update();
},
remove: function(appName) {
delete xp.startmenu.menuItems[appName];
xp.startmenu.update();
},
update: function() {
$("#_ui_programsmenu").find('ul').html('');
for (var key in xp.startmenu.menuItems) {
$("#_ui_programsmenu").find('ul').append('<li class="menuitem" onclick="openApp(\'' + key + '\')"><img class="menuicon" src="' + xp.startmenu.appIcons[key] + '"/><span class="menuitemtext">' + xp.startmenu.menuItems[key] + '</span></li>');
}
}
};
xp.controlpanel = {
items: {},
add: function(name, func) {
xp.controlpanel.items[name] = func;
},
remove: function(name) {
delete xp.controlpanel.items[name];
}
}
xp.profile = {
image: 'https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2Fusericon.png?1520129931353',
name: 'User'
};
jQuery.fn.extend({
getPath: function () {
var path, node = this;
while (node.length) {
var realNode = node[0], name = realNode.localName;
if (!name) break;
name = name.toLowerCase();
var parent = node.parent();
var sameTagSiblings = parent.children(name);
if (sameTagSiblings.length > 1) {
var allSiblings = parent.children();
var index = allSiblings.index(realNode) + 1;
if (index > 1) {
name += ':nth-child(' + index + ')';
}
}
path = name + (path ? '>' + path : '');
node = parent;
}
return path;
}
});
document.onclick = function (e) {
e = e || window.event;
var element = e.target || e.srcElement;
if (element.tagName == 'A') {
if ($(element).attr('download') !== undefined) return true; // allow browser to download file
if ($(element).attr('href') !== '' && element.href !== undefined) {
var temp = document.createElement('div');
temp.innerHTML = `<window title="` + element.href + `" width="640" height="480">
<style>
iframe[seamless]{
background-color: transparent;
border: 0px none transparent;
padding: 0px;
overflow: hidden;
}
.frame-container {
/*display: none;*/
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
padding: 0px;
margin: 0px;
}
</style>
<div class="frame-container">
<iframe seamless="seamless" width="100%" height="100%" id="frame" src="` + element.href + `"></iframe>
</div>
</window>`;
var el = temp.firstChild;
document.body.appendChild(el);
$(el).updateWindow();
}
return false; // prevent default action and stop event propagation
}
};
$(function() {
xp.applications.add('winver', function() {
var guid = generate_guid();
var temp = document.createElement('div');
temp.innerHTML = `<window title="About RebornXP" width="418" height="400">
<center>
<img src="boot/assets/logo.png" width="100" height="100">
<br>
<h2>Reborn XP</h2>
<p> Version ` + xp.version + `</p>
<p> Registered to: ` + xp.profile.name + `</p>
<p>Powered by <a href="https://jquery.com/" target="_blank">JQuery</a></p>
<p> © 2023 - Shoaib Khan<br>
RebornXP is <a href="https://github.com/shoaib-jamal/rebornxp" target="_blank">Open Source</a> under the GPL v3.0 License</p>
<br>
<a href="https://www.buymeacoffee.com/shoaibify" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 50px !important;width: 200px !important;" ></a>
<br><br>
<a href="https://opensource.org/license/gpl-3-0/"><img src="https://img.shields.io/badge/License-GPL-yellow.svg"></a>
<a href="https://github.com/shoaib-jamal/rebornxp/stargazers"><img src="https://img.shields.io/github/stars/shoaib-jamal/rebornxp?label=GitHub%20Stars&style=social"></a>
<a href="https://github.com/shoaib-jamal/rebornxp/network/members"><img src="https://img.shields.io/github/forks/shoaib-jamal/rebornxp?style=social"></a>
<br>
</center>
<center style="position:absolute;bottom:4.5px;right:4.5px;">
<button id="OKButton_` + guid + `">OK</button>
</center>
</window>`;
var el = temp.firstChild;
document.body.appendChild(el);
$(el).updateWindow();
$("#OKButton_" + guid).attr("onclick", "closeWindow('" + $(el).attr("guid") + "')");
});
});
window.onerror = function (msg, url, lineNo, columnNo, error) {
xp.dialog('Error', `An error has occurred!<br/>
&nbsp;&nbsp` + msg + `<br/>
&nbsp;&nbsp;&nbsp;&nbsp;in ` + url + ` line ` + lineNo + ` column ` + columnNo, () => {}, false, 'error');
};
function openApp(name, args) {
closeStartMenu();
if (xp.applications.apps[name] !== undefined) {
xp.applications.apps[name](args);
return true;
} else {
return false;
}
}
// Start menu control
function openStartMenu() {
$("taskbar div.startmenu").css("display", "inline");
$("taskbar button.start").attr("isopen", "true");
xp.audio.playURL('https://cdn.glitch.com/01d2e04f-e49d-4304-aa9e-55b9849b4cce%2FWindows%20XP%20Start.wav?1522621401979');
}
function closeStartMenu() {
$("taskbar div.startmenu").css("display", "none");
$("taskbar button.start").attr("isopen", "false");
$('#_ui_programsmenu').css('display', 'none');
$('#_ui_programsmenu').data('isopen', false);
}
function toggleStartMenu() {
var el = $("taskbar button.start");
if (el.attr("isopen") === "true")
closeStartMenu();
else
openStartMenu();
}
function handleTaskbarButton(guid) {
var el = $('window[guid=' + guid + ']');
if (el.attr("inactive") === "false")
minimizeWindow(guid);
else
moveWindowToTop(guid);
}
function updateTaskbar() {
var el = $("taskbar");
}
var width = 0;
var windowsEl;
function getClockTime() {
var date = new Date().getTime();
var d = new Date(date);
var hh = d.getHours();
var m = d.getMinutes();
var s = d.getSeconds();
var dd = "AM";
var h = hh;
if (h >= 12) {
h = hh - 12;
dd = "PM";
}
if (h == 0) {
h = 12;
}
m = m < 10 ? "0" + m : m;
s = s < 10 ? "0" + s : s;
var result = h + ":" + m + " " + dd;
document.getElementById('_ui_clock').innerHTML = result;
}
function updateClock() {
var interval = (60 - (new Date()).getSeconds()) * 1000 + 5;
getClockTime();
setTimeout(updateClock, interval);
}
$.fn.initWindows = function() {
windowsEl = this;
windowsEl.append(`
<div class="ui_desktop" id="_ui_desktop">
<div tabindex="0" data-exe="openLocation('My Computer')" data-target="My Computer" class="ui_icon" style="position:absolute;left:0px;top:0px;">
<div class="icon icon_computer"></div>
<span>My Computer</span>
</div>
</div>
<taskbar id="_ui_taskbar" class="shadow" onmousedown="return false;" oncontextmenu="return false;">
<button class="start" onmousedown="toggleStartMenu()" isopen="false">Start</button>
<div class="startmenu shadow" style="display: none">
<div class="startmenu_top">
<img class="startmenu_usericon" src="` + xp.profile.image + `"/>
<div class="startmenu_username">` + xp.profile.name + `</div>
</div>
<div class="startmenu_middle">
<ul class="menu startmenu_programs">
<li class="startmenuitem large" onclick="openApp('browser')">
<img src="https://www.freeiconspng.com/uploads/internet-explorer-logo-icon-10.png"/>
<div><div>
<b>Internet</b><br/>
Web Browser
</div></div>
</li>
<li class="startmenuitem large" onclick="openApp('terminal')">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACOUlEQVRYhe2Xv2sTYRjHP8/lvSRN27QipUr9UQLFLhVLRVrN4CQ5cKjg6uIgpQgObi6d+0/o0NHBpZCAVQqigw4VC9GAixAbpNGmMUnT/LjXoV4IJk3AXFLBfuG45w6e5/u55+6euxf+U4kTGEdiPzOjWFoyDkiu3ptDzAfjI9MWWqRdbif6sv3uhbGXe+zPbL0NFgM/U6nVgvLJ5dfjE2MycWmym94EzX1Ob47M5zOF+cTGk4WMKqwCBTU+OSYJdYrEx0zHJgN+xcObE6zH08STWRZvhFiPpwl+WuOResYd7vLhcxa/Lfd1pRIHvqpE31kYGurYHACfB0wvDA7Aibp4eBhKXuYC22z09yO71WBVjGnglbp2DsJX+twBAIr8YDYEsyGzFhMKs0KYQeDk5hp5W5uGiBdAhdUWy9cvugbQThdurZAXEWxtwFG9hnU6BmgAiEQiaK1rWyQSaUjSWncPIBqNYlkWIoJlWUSj0aaJzcBcAQCIxWK1vdRNZ+fKW4G5AnCYHBgH0I0uNAVwCjvPQzO51QXVrrBlWbVYa93QBef8YZI2H9gGgD/ve6tiznE7k1b69+bAMcAxQK+l0rtlpqamemaYK9u/B4doAPXyfarI+UVTS6+6UcDQdr7iMfYBVCr+dEFKxduCDoJuGExdUEWQHY/HnwRQYujnVY+8Mcu2F1s8Xbc3dLXis4umLmYB1F5VfT9Tyu2UywUDRrvuD98wdcBOju5X4GCR2NXlWBu592v1t/oFx8vJxHIFQMwAAAAASUVORK5CYII="/>
<div><div>
<b>Shell</b><br/>
JQuery Terminal
</div></div>
</li>
<li class="startmenuitem large" onclick="window.open('https://www.buymeacoffee.com/shoaibify', '_blank');">
<img src="https://media.giphy.com/media/TDQOtnWgsBx99cNoyH/giphy.gif"/>
<div><div>
<b>Support</b><br/>
Buy me a coffee
</div></div>
</li>
</ul>
<ul class="menu startmenu_allprograms">
<li class="startmenuitem">
<div><div style="padding-left:32px;line-height:24px;">
<b>All Programs</b>
<span class="allprograms_arrow"></span>
</div></div>
</li>
<div id="_ui_programsmenu" class="programsmenu" style="display:none;" data-isopen="false">
<ul class="menu">
<li class="menuitem">Test</li>
</ul>
</div>
</ul>
<ul class="menu startmenu_shortcuts">
<li class="startmenuitem" onclick="openLocation('/Documents and Settings/' + xp.profile.name + '/My Documents')">
<img src="` + xp.startmenu.icons.documents + `"/>
<div><div>
<b>My Documents</b>
</div></div>
</li>
<li class="startmenuitem" onclick="openLocation('/Documents and Settings/' + xp.profile.name + '/My Documents')">
<img src="` + xp.startmenu.icons.recentdocuments + `"/>
<div><div>
<b>My Recent Documents</b>
</div></div>
</li>
<li class="startmenuitem" onclick="openLocation('/Documents and Settings/' + xp.profile.name + '/My Documents/My Pictures')">
<img src="` + xp.startmenu.icons.pictures + `"/>
<div><div>
<b>My Pictures</b>
</div></div>
</li>
<li class="startmenuitem" onclick="openLocation('/Documents and Settings/' + xp.profile.name + '/My Documents/My Music')">
<img src="` + xp.startmenu.icons.music + `"/>
<div><div>
<b>My Music</b>
</div></div>
</li>
<li class="startmenuitem" onclick="openLocation('My Computer')">
<img src="` + xp.startmenu.icons.computer + `"/>
<div><div>
<b>My Computer</b>
</div></div>
</li>
<li class="startmenuseparator"></li>
<li class="startmenuitem" onclick="openLocation('Control Panel')">
<img src="` + xp.startmenu.icons.controlpanel + `"/>
<div><div>
<b>Control Panel</b>
</div></div>
</li>
<li class="startmenuitem" onclick="openApp('uac_app')">
<img src="` + xp.startmenu.icons.controlpanel + `"/>
<div><div>
<b>User Accounts and Control</b>
</div></div>
</li>
<li class="startmenuitem" onclick="openApp('themes')">
<img src="` + xp.startmenu.icons.controlpanel + `"/>
<div><div>
<b>Personalize RebornXP</b>
</div></div>
</li>
<li class="startmenuseparator"></li>
<li class="startmenuitem" onclick="openApp('winhelp')">
<img src="` + xp.startmenu.icons.help + `"/>
<div><div>
<b>Help & Support</b>
</div></div>
</li>
<!--Search is under Development-->
<li class="startmenuitem" onclick="">
<img src="` + xp.startmenu.icons.search + `"/>
<div><div>
<b>Search</b>
</div></div>
</li>
<!--Feel free to contribute to this Section-->
<li class="startmenuitem" onclick="runAppDialog()">
<img src="` + xp.startmenu.icons.run + `"/>
<div><div>
<b>Run...</b>
</div></div>
</li>
</ul>
</div>
<div class="startmenu_bottom">
</div>
</div>
<div class="clock" id="_ui_clock">0:00</div>
</taskbar>
<div id="lContextMenu" class="ContextMenu" onselectstart="return false;" oncontextmenu="return false;" style="left: 0px; top: 0px; visibility: hidden;">
Uh oh! Something went wrong!<br>You should <b>not</b> be seeing this!
</div>
`);
$("#_ui_taskbar").css("display", "none");
$("#_ui_boot").css("display", "none");
//$('#_ui_programsmenu').closest('ul').find('li.startmenuitem').on('click', function() {
// $('#_ui_programsmenu').css('display', 'inline');
// $('#_ui_programsmenu').data('isopen', true);
//});
/*$("#_ui_programsmenu").closest("li.startmenuitem").on("mouseleave", function() {
$('#_ui_programsmenu').css('display', 'none');
});*/
$('#_ui_desktop').on('click', function(e) {
var el = $(e.target).closest('.ui_icon');
if (el.hasClass('ui_selected')) {
el.removeClass('ui_selected');
eval(el.data('exe'));
} else {
$('#_ui_desktop .ui_icon').each(function() {
$(this).removeClass('ui_selected');
});
el.addClass('ui_selected');
}
});
$("#_ui_taskbar").css("display", "inline");
$("#_ui_boot").remove();
updateAllWindows();
updateIndexes();
updateAllWindows();
updateTaskbar();
windowsEl.on("mousedown", function(e) {
//var canClose = !(el.is("button.start") || el.is("li.menuitem") || el.is("li.startmenuitem") || el.is("li.startmenuitem img") || el.is("li.startmenuitem div") || el.is("li.startmenuitem div div") || el.is("li.startmenuitem div div b"));
var canClose = !$.contains($('#_ui_taskbar').find('.startmenu')[0], e.target);
if (canClose && !$(e.target).is('button.start')) {
closeStartMenu();
} else {
if ($('#_ui_programsmenu').is(e.target) || $('#_ui_programsmenu').has(e.target).length) return;
if ($('#_ui_programsmenu').closest('ul').find('li.startmenuitem').is(e.target) || $('#_ui_programsmenu').closest('ul').find('li.startmenuitem').has(e.target).length) {
$('#_ui_programsmenu').css('display', $('#_ui_programsmenu').data('isopen') ? 'none ' : 'inline');
$('#_ui_programsmenu').data('isopen', !$('#_ui_programsmenu').data('isopen'));
} else {
$('#_ui_programsmenu').css('display', 'none');
$('#_ui_programsmenu').data('isopen', false);
}
}
});
windowsEl.on('mousedown', function() {
fMouseDown(this);
return false;
});
windowsEl.on('contextmenu', function(e) {
desktopContextMenu(e);
return false;
});
windowsEl.on('click', function() {
rcCloseContext();
});
$('#_ui_taskbar').find('div.startmenu').on('contextmenu', startContextMenu);
updateClock();
};
function runAppDialog() {
closeStartMenu();
var win = new Window({
width: 340,
height: 154,
title: 'Run',
canResize: false,
canMinimize: false
});
win.content(`<form action="#">
<span class="icon icon_run" draggable="false" style="position: absolute; left: 11px; top: 17px;"></span>
<p style="position: absolute; left: 54px; top: 8px;">
Type the name of a program, document, or<br>
Internet resource, and RebornXP will open it for you.
</p>
<p style="position: absolute; top: 54px; left: 12px; line-height: 16px;">Open:</p>
<input type="text" class="prompttext" style="width: 275px; position: absolute; top: 70px; left: 54px;">
<center style="position: absolute; bottom: 17px; right: 16.7px;">
<button class="ok">OK</button>
<button class="cancel">Cancel</button>
<button class="browse">Browse</button>
</center>
</form>`);
win.el.find('.cancel').on('click', function() {
win.close();
});
win.el.find('.ok').on('click', function() {
win.close();
var result = win.el.find('.prompttext').val();
if (!openApp(result)) {
xp.openFileHandler(result);
}
});
win.el.find('.browse').on('click', function() {
xp.filesystem.openFileDialog((file) => {
win.el.find('.prompttext').val(file);
});
});
win.el.find('input[type=text]').focus();
win.el.find('form').on('submit', function() {
return false;
});
}