Initial commit

This commit is contained in:
Serena Ziviani 2022-01-31 21:52:13 +01:00
commit 512332d439
27 changed files with 959 additions and 0 deletions

20
README.md Normal file
View file

@ -0,0 +1,20 @@
Source code for the webvm.io webpage.
Please use github.com/webvm/issues to signal any bug.
This project depends on xterm.js (https://xtermjs.org/) and on its add-on xterm-addon-fit
To update the xterm-related files do:
```
mkdir build
cd build
npm install --save xterm
npm install --save xterm-addon-fit
cd ../xterm
cp ../build/node_modules/xterm/lib/xterm.js .
cp ../build/node_modules/xterm/css/xterm.css .
cp ../build/node_modules/xterm-addon-fit/lib/xterm-addon-fit.js .
cd ..
rm -r build
```

BIN
assets/webvm.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

13
examples/c/Makefile Normal file
View file

@ -0,0 +1,13 @@
SRCS = $(wildcard *.c)
PROGS = $(patsubst %.c,%,$(SRCS))
all: $(PROGS)
%: %.c
$(CC) $(CFLAGS) -o $@ $<
clean:
rm -f $(PROGS)
.PHONY: all clean

12
examples/c/env.c Normal file
View file

@ -0,0 +1,12 @@
#include <stdio.h>
// Most of the C compilers support a third parameter to main which
// store all envorinment variables
int main(int argc, char *argv[], char * envp[])
{
int i;
for (i = 0; envp[i] != NULL; i++)
printf("\n%s", envp[i]);
getchar();
return 0;
}

6
examples/c/helloworld.c Normal file
View file

@ -0,0 +1,6 @@
#include <stdio.h>
int main()
{
printf("Hello, World!\n");
}

7
examples/c/link.c Normal file
View file

@ -0,0 +1,7 @@
#include <unistd.h>
int main()
{
link("env", "env3");
return 0;
}

10
examples/c/openat.c Normal file
View file

@ -0,0 +1,10 @@
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
int main()
{
int ret = openat(AT_FDCWD, "/dev/tty", 0x88102, 0);
printf("return value is %d and errno is %d\n", ret, errno);
}

17
examples/c/waitpid.c Normal file
View file

@ -0,0 +1,17 @@
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
int main()
{
int status;
pid_t p = getpid();
// waitpid takes a children's pid, not the current process one
// if the pid is not a children of the current process, it returns -ECHILD
pid_t res = waitpid(1001, &status, WNOHANG);
printf("res is %d, p is %d and errno is %d\n", res, p, errno);
}

20
examples/lua/fizzbuzz.lua Normal file
View file

@ -0,0 +1,20 @@
#!/usr/bin/env luajit
cfizz,cbuzz=0,0
for i=1,20 do
cfizz=cfizz+1
cbuzz=cbuzz+1
io.write(i .. ": ")
if cfizz~=3 and cbuzz~=5 then
io.write(i)
else
if cfizz==3 then
io.write("Fizz")
cfizz=0
end
if cbuzz==5 then
io.write("Buzz")
cbuzz=0
end
end
io.write("\n")
end

12
examples/lua/sorting.lua Normal file
View file

@ -0,0 +1,12 @@
fruits = {"banana","orange","apple","grapes"}
for k,v in ipairs(fruits) do
print(k,v)
end
table.sort(fruits)
print("sorted table")
for k,v in ipairs(fruits) do
print(k,v)
end

View file

@ -0,0 +1,19 @@
A = { ["John"] = true, ["Bob"] = true, ["Mary"] = true, ["Elena"] = true }
B = { ["Jim"] = true, ["Mary"] = true, ["John"] = true, ["Bob"] = true }
A_B = {}
for a in pairs(A) do
if not B[a] then A_B[a] = true end
end
B_A = {}
for b in pairs(B) do
if not A[b] then B_A[b] = true end
end
for a_b in pairs(A_B) do
print( a_b )
end
for b_a in pairs(B_A) do
print( b_a )
end

View file

@ -0,0 +1,6 @@
console.log("process.uptime = ", global.process.uptime());
console.log("process.title = ", global.process.title);
console.log("process version = ", global.process.version);
console.log("process.platform = ", global.process.platform);
console.log("process.cwd = ", global.process.cwd());
console.log("process.uptime = ", global.process.uptime());

161
examples/nodejs/nbody.js Normal file
View file

@ -0,0 +1,161 @@
const PI = Math.PI;
const SOLAR_MASS = 4 * PI * PI;
const DAYS_PER_YEAR = 365.24;
function Body(x, y, z, vx, vy, vz, mass) {
this.x = x;
this.y = y;
this.z = z;
this.vx = vx;
this.vy = vy;
this.vz = vz;
this.mass = mass;
}
function Jupiter() {
return new Body(
4.84143144246472090e+00,
-1.16032004402742839e+00,
-1.03622044471123109e-01,
1.66007664274403694e-03 * DAYS_PER_YEAR,
7.69901118419740425e-03 * DAYS_PER_YEAR,
-6.90460016972063023e-05 * DAYS_PER_YEAR,
9.54791938424326609e-04 * SOLAR_MASS
);
}
function Saturn() {
return new Body(
8.34336671824457987e+00,
4.12479856412430479e+00,
-4.03523417114321381e-01,
-2.76742510726862411e-03 * DAYS_PER_YEAR,
4.99852801234917238e-03 * DAYS_PER_YEAR,
2.30417297573763929e-05 * DAYS_PER_YEAR,
2.85885980666130812e-04 * SOLAR_MASS
);
}
function Uranus() {
return new Body(
1.28943695621391310e+01,
-1.51111514016986312e+01,
-2.23307578892655734e-01,
2.96460137564761618e-03 * DAYS_PER_YEAR,
2.37847173959480950e-03 * DAYS_PER_YEAR,
-2.96589568540237556e-05 * DAYS_PER_YEAR,
4.36624404335156298e-05 * SOLAR_MASS
);
}
function Neptune() {
return new Body(
1.53796971148509165e+01,
-2.59193146099879641e+01,
1.79258772950371181e-01,
2.68067772490389322e-03 * DAYS_PER_YEAR,
1.62824170038242295e-03 * DAYS_PER_YEAR,
-9.51592254519715870e-05 * DAYS_PER_YEAR,
5.15138902046611451e-05 * SOLAR_MASS
);
}
function Sun() {
return new Body(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS);
}
const bodies = Array(Sun(), Jupiter(), Saturn(), Uranus(), Neptune());
function offsetMomentum() {
let px = 0;
let py = 0;
let pz = 0;
const size = bodies.length;
for (let i = 0; i < size; i++) {
const body = bodies[i];
const mass = body.mass;
px += body.vx * mass;
py += body.vy * mass;
pz += body.vz * mass;
}
const body = bodies[0];
body.vx = -px / SOLAR_MASS;
body.vy = -py / SOLAR_MASS;
body.vz = -pz / SOLAR_MASS;
}
function advance(dt) {
const size = bodies.length;
for (let i = 0; i < size; i++) {
const bodyi = bodies[i];
let vxi = bodyi.vx;
let vyi = bodyi.vy;
let vzi = bodyi.vz;
for (let j = i + 1; j < size; j++) {
const bodyj = bodies[j];
const dx = bodyi.x - bodyj.x;
const dy = bodyi.y - bodyj.y;
const dz = bodyi.z - bodyj.z;
const d2 = dx * dx + dy * dy + dz * dz;
const mag = dt / (d2 * Math.sqrt(d2));
const massj = bodyj.mass;
vxi -= dx * massj * mag;
vyi -= dy * massj * mag;
vzi -= dz * massj * mag;
const massi = bodyi.mass;
bodyj.vx += dx * massi * mag;
bodyj.vy += dy * massi * mag;
bodyj.vz += dz * massi * mag;
}
bodyi.vx = vxi;
bodyi.vy = vyi;
bodyi.vz = vzi;
}
for (let i = 0; i < size; i++) {
const body = bodies[i];
body.x += dt * body.vx;
body.y += dt * body.vy;
body.z += dt * body.vz;
}
}
function energy() {
let e = 0;
const size = bodies.length;
for (let i = 0; i < size; i++) {
const bodyi = bodies[i];
e += 0.5 * bodyi.mass * ( bodyi.vx * bodyi.vx + bodyi.vy * bodyi.vy + bodyi.vz * bodyi.vz );
for (let j = i + 1; j < size; j++) {
const bodyj = bodies[j];
const dx = bodyi.x - bodyj.x;
const dy = bodyi.y - bodyj.y;
const dz = bodyi.z - bodyj.z;
const distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
e -= (bodyi.mass * bodyj.mass) / distance;
}
}
return e;
}
const n = +50000000;
offsetMomentum();
console.log(energy().toFixed(9));
const start = Date.now();
for (let i = 0; i < n; i++) {
advance(0.01);
}
const end = Date.now();
console.log(energy().toFixed(9));
console.log("elapsed:",end-start);

31
examples/nodejs/primes.js Normal file
View file

@ -0,0 +1,31 @@
(function () {
function isPrime(p) {
const upper = Math.sqrt(p);
for(let i = 2; i <= upper; i++) {
if (p % i === 0 ) {
return false;
}
}
return true;
}
// Return n-th prime
function prime(n) {
if (n < 1) {
throw Error("n too small: " + n);
}
let count = 0;
let result = 1;
while(count < n) {
result++;
if (isPrime(result)) {
count++;
}
}
return result;
}
console.log("your prime is ", prime(100000));
}());

16
examples/nodejs/wasm.js Normal file
View file

@ -0,0 +1,16 @@
(function (){
let bytes = new Uint8Array([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01,
0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x07, 0x01,
0x03, 0x73, 0x75, 0x6d, 0x00, 0x00, 0x0a, 0x0a,
0x01, 0x08, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a,
0x0f, 0x0b
]);
console.log(bytes);
let mod = new WebAssembly.Module(bytes);
let instance = new WebAssembly.Instance(mod, {});
console.log(instance.exports);
return instance.exports.sum(2020, 1);
}());

View file

@ -0,0 +1,9 @@
def factorial():
f, n = 1, 1
while True: # First iteration:
yield f # yield 1 to start with and then
f, n = f * n, n+1 # f will now be 1, and n will be 2, ...
for index, factorial_number in zip(range(51), factorial()):
print('{i:3}!= {f:65}'.format(i=index, f=factorial_number))

View file

@ -0,0 +1,9 @@
def fib():
a, b = 0, 1
while True: # First iteration:
yield a # yield 0 to start with and then
a, b = b, a + b # a will now be 1, and b will also be 1, (0 + 1)
for index, fibonacci_number in zip(range(100), fib()):
print('{i:3}: {f:3}'.format(i=index, f=fibonacci_number))

12
examples/python3/pi.py Normal file
View file

@ -0,0 +1,12 @@
from decimal import Decimal, getcontext
getcontext().prec=60
summation = 0
for k in range(50):
summation = summation + 1/Decimal(16)**k * (
Decimal(4)/(8*k+1)
- Decimal(2)/(8*k+4)
- Decimal(1)/(8*k+5)
- Decimal(1)/(8*k+6)
)
print(summation)

View file

@ -0,0 +1,14 @@
=begin
# The famous Hello World
# Program is trivial in
# Ruby. Superfluous:
#
# * A "main" method
# * Newline
# * Semicolons
#
# Here is the Code:
=end
puts "Hello World!"

9
examples/ruby/love.rb Normal file
View file

@ -0,0 +1,9 @@
# Output "I love Ruby"
say = "I love Ruby"; puts say
# Output "I *LOVE* RUBY"
say['love'] = "*love*"; puts say.upcase
# Output "I *love* Ruby", 5 times
5.times { puts say }

6
examples/ruby/powOf2.rb Normal file
View file

@ -0,0 +1,6 @@
puts(2 ** 1)
puts(2 ** 2)
puts(2 ** 3)
puts(2 ** 10)
puts(2 ** 100)
puts(2 ** 1000)

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

295
index.html Normal file
View file

@ -0,0 +1,295 @@
<!DOCTYPE html>
<html lang="en" style="height:100%;">
<head>
<!-- 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-5GBJM42');
</script>
<!-- End Google Tag Manager -->
<meta charset="utf-8">
<title>WebVM</title>
<meta name="description" content="WebVM - a Bash shell, demo of CheerpX x86 emulation technology, completely client side">
<meta name="keywords" content="WebVM, Bash, CheerpX, WebAssembly">
<meta property="og:title" content="WebVM" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="WebVM"/>
<meta property="og:url" content="/">
<meta property="og:image" content="https://webvm.io/assets/webvm.jpeg" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@leaningtech" />
<meta name="twitter:title" content="WebVM" />
<meta name="twitter:description" content="WebVM - a Bash shell, demo of CheerpX x86 emulation technology, completely client side" />
<meta name="twitter:image" content="https://webvm.io/assets/webvm.jpeg" />
<link rel="shortcut icon" href="/favicon.ico">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/xterm/xterm.css" />
<script src="/xterm/xterm.js"></script>
<script src="/xterm/xterm-addon-fit.js"></script>
<script src="https://cheerpxdemos.leaningtech.com/publicdeploy/20220131_600/cx.js"></script>
</head>
<body style="margin:0;height:100%;background:black;color:white;overflow:hidden;">
<!-- Google Tag Manager (noscript) -->
<noscript>
<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5GBJM42" height="0" width="0"
style="display:none;visibility:hidden"></iframe>
</noscript>
<!-- End Google Tag Manager (noscript) -->
<main style="display: flex; flex-direction: row; justify-content: space-between; margin:0; height:100%;">
<div style="flex-grow:1; height:100%;display:inline-block;margin:0;" id="console">
</div>
</main>
<script>
//Utility namespace to group all functionality related to printing (both error and non error) messages
const color= "\x1b[1;35m";
const bold= "\x1b[1;37m";
const underline= "\x1b[94;4m";
const normal= "\x1b[0m";
var printOnTerm = {
getAsciiTitle: function ()
{
var title = [
color + " __ __ _ __ ____ __ " + normal,
color + " \\ \\ / /__| |_\\ \\ / / \\/ | " + normal,
color + " \\ \\/\\/ / -_) '_ \\ V /| |\\/| | " + normal,
color + " \\_/\\_/\\___|_.__/\\_/ |_| |_| " + normal,
];
return title;
},
getAsciiText: function ()
{
var text = [
" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+",
" | |",
" | WebVM is based on Leaning Technologies' virtualization engine, CheerpX. |",
" | |",
" | CheerpX allows safe client-side execution of x86 apps in a WebAssembly |",
" | sandbox. |",
" | |",
" | CheerpX includes a WebAssembly JIT compiler to achieve |",
" | a high level of performance. |",
" | |",
" | WebVM is an headless, serverless Debian environment. It runs unmodified |",
" | binaries from the Debian distribution. |",
" | |",
" | " +
underline + "Medium" + normal + " | " +
underline + "GitHub" + normal + " | " +
underline + "Issues" + normal + " | " +
underline + "Gitter" + normal + " | " +
underline + "Twitter" + normal + " | " +
underline + "CheerpX's site" + normal + " |",
" | |",
" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+",
"",
" Welcome to WebVM! If you don't know what to do, try to create and delete ",
" files, or to compile / execute one of the examples. All the data will be ",
" saved internally to the browser. If you want to reset the state of WebVM, ",
" delete the cache and IndexDB for this page.",
"",
];
return text;
},
getSharedArrayBufferMissingMessage: function ()
{
const text = [
"",
"",
color + "CheerpX could not start" + normal,
"",
"CheerpX depends on JavaScript's SharedArrayBuffer, that your browser",
" does not support.",
"",
"SharedArrayBuffer is currently enabled by default on recent",
" versions of Chrome, Edge and Firefox.",
"",
"Safari and mobile don't support this JavaScript feature, but will do in the future",
"",
"",
"Give it a try from a desktop version / another browser!",
]
return text;
},
getErrorMessage: function (error_message)
{
const text = [
"",
"",
color + "CheerpX could not start" + normal,
"",
"CheerpX internal error message is:",
error_message,
"",
"",
"CheerpX is expected to work with recent desktop versions of Chrome, Edge and Firefox",
"",
"",
"Give it a try from a desktop version / another browser!",
]
return text;
},
printMessage: function (text) {
for (var i=0; i<text.length; i++)
{
term.write(text[i]);
term.write('\n');
}
},
printError: function (message)
{
this.printMessage(message);
term.write("\n\n");
function writeCustom(something)
{
term.write(something);
}
},
};
var consoleDiv = document.getElementById("console");
//xterm.js related logic
var term = new Terminal({cursorBlink:true,convertEol:true, fontFamily:"'Roboto Mono', monospace", fontWeight: 400, fontWeightBold: 700});
var fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);
term.open(consoleDiv);
term.scrollToTop();
fitAddon.fit();
window.addEventListener("resize", function(ev){fitAddon.fit();}, false);
term.focus();
var cxReadFunc = null;
function writeData(buf)
{
term.write(new Uint8Array(buf));
}
function readData(str)
{
if(cxReadFunc == null)
return;
for(var i=0;i<str.length;i++)
cxReadFunc(str.charCodeAt(i));
}
term.onData(readData);
structure = {
name: "bash",
cmd: "/bin/bash",
args: ["--login"],
env: ["HOME=/home/user", "TERM=xterm", "USER=user", "SHELL=/bin/bash", "EDITOR=vim", "LANG=en_US.UTF-8", "LC_ALL=C"],
expectedPrompt: ">",
versionOpt: "--version",
comment_line: "#",
description_line: "The original Bourne Again SHell",
}
//Actual CheerpX and bash specific logic
function runBash(structure)
{
if (typeof SharedArrayBuffer === "undefined")
{
printOnTerm.printError(printOnTerm.getSharedArrayBufferMissingMessage());
return;
}
async function runTest(cx)
{
term.scrollToBottom();
async function cxLogAndRun(cheerpx, cmd, args, env)
{
await cheerpx.run(cmd, args, env);
printOnTerm.printMessage(" ");
}
cxReadFunc = cx.setCustomConsole(writeData, term.cols, term.rows);
function preventDefaults (e) {
e.preventDefault()
e.stopPropagation()
}
consoleDiv.addEventListener("dragover", preventDefaults, false);
consoleDiv.addEventListener("dragenter", preventDefaults, false);
consoleDiv.addEventListener("dragleave", preventDefaults, false);
consoleDiv.addEventListener("drop", preventDefaults, false);
var opts = {env:structure.env, cwd:"/home/user"};
while (true)
{
await cxLogAndRun(cx, structure.cmd, structure.args, opts);
}
}
function failCallback(err)
{
printOnTerm.printError(printOnTerm.getErrorMessage(err));
}
CheerpXApp.create({devices:[{type:"block",url:"https://disks.leaningtech.com/webvm_20220131.ext2",name:"block1"}],mounts:[{type:"ext2",dev:"block1",path:"/"},{type:"cheerpOS",dev:"/app",path:"/bootstrap"},{type:"devs",dev:"",path:"/dev"}]}).then(runTest, failCallback);
}
function initialMessage()
{
printOnTerm.printMessage(printOnTerm.getAsciiTitle());
printOnTerm.printMessage(["\n"]);
printOnTerm.printMessage(printOnTerm.getAsciiText());
const textArray = new Array(6);
const linksArray = new Array(6);
const rangesArray = new Array(6);
var last = 0;
const textLinkLine = " | Medium | GitHub | Issues | Gitter | Twitter | CheerpX's site |";
const lineWithLinks = 20;
function addLink(text, website)
{
var index = textLinkLine.indexOf(text);
const start_x = index+1;
const end_x = index + text.length;
rangesArray[last] = {start: {x:start_x, y:lineWithLinks}, end: {x:end_x, y:lineWithLinks}};
linksArray[last] = website;
last++;
}
addLink("Medium", "https://medium.com/leaningtech");
addLink("GitHub", "https://github.com/leaningtech/webvm");
addLink("Issues", "https://github.com/leaningtech/webvm/issues");
addLink("Gitter", "https://gitter.im/leaningtech/cheerpx");
addLink("Twitter", "https://twitter.com/leaningtech");
addLink("CheerpX's site", "https://leaningtech.com/cheerpx");
var provider = {
provideLinks(bufferLineNum, callback) {
switch(bufferLineNum)
{
case lineWithLinks:
{
callback([
{range: rangesArray[0], activate() {window.open('' + linksArray[0], '_blank');}},
{range: rangesArray[1], activate() {window.open('' + linksArray[1], '_blank');}},
{range: rangesArray[2], activate() {window.open('' + linksArray[2], '_blank');}},
{range: rangesArray[3], activate() {window.open('' + linksArray[3], '_blank');}},
{range: rangesArray[4], activate() {window.open('' + linksArray[4], '_blank');}},
{range: rangesArray[5], activate() {window.open('' + linksArray[5], '_blank');}},
]);
break;
}
}
}
};
term.registerLinkProvider(provider);
console.log("Welcome. We appreciate curiosity, but be warned that keeping the DevTools open causes significant performance degradation and crashes.");
}
initialMessage();
runBash(structure);
</script>
</body>
</html>

76
nginx.conf Normal file
View file

@ -0,0 +1,76 @@
worker_processes 1;
events {
worker_connections 1024;
}
error_log nginx_main_error.log info;
pid nginx_user.pid;
daemon off;
http {
access_log nginx_access.log;
error_log nginx_error.log info;
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
server {
# listen 8080 ssl;
listen 8081;
server_name localhost;
gzip on;
# Enable compression for .wasm, .js and .txt files (used for the runtime chunks)
gzip_types application/javascript application/wasm text/plain application/octet-stream;
charset utf-8;
# ssl_certificate nginx.crt;
# ssl_certificate_key nginx.key;
location / {
root .;
autoindex on;
index index.html index.htm;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Expose-Headers' 'content-length' always;
add_header 'Cross-Origin-Opener-Policy' 'same-origin' always;
add_header 'Cross-Origin-Embedder-Policy' 'require-corp' always;
add_header 'Cross-Origin-Resource-Policy' 'cross-origin' always;
#auth_basic "CX Demo";
#auth_basic_user_file basicauth;
}
location /images/ {
root .;
if ($arg_s != "") {
rewrite ^/images/(.*)$ $1 break;
}
if ($arg_s = "") {
gzip off;
}
error_page 404 =200 /images_slicer/$uri?$args;
}
location /images_slicer/ {
proxy_pass http://localhost:8082/images/;
proxy_http_version 1.0;
proxy_set_header Range bytes=$arg_s-$arg_e;
proxy_hide_header Content-Range;
}
}
server {
listen 127.0.0.1:8082;
server_name localhost;
charset utf-8;
location / {
root .;
}
}
}

2
xterm/xterm-addon-fit.js Normal file
View file

@ -0,0 +1,2 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FitAddon=t():e.FitAddon=t()}(self,(function(){return(()=>{"use strict";var e={775:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.FitAddon=void 0;var r=function(){function e(){}return e.prototype.activate=function(e){this._terminal=e},e.prototype.dispose=function(){},e.prototype.fit=function(){var e=this.proposeDimensions();if(e&&this._terminal){var t=this._terminal._core;this._terminal.rows===e.rows&&this._terminal.cols===e.cols||(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}},e.prototype.proposeDimensions=function(){if(this._terminal&&this._terminal.element&&this._terminal.element.parentElement){var e=this._terminal._core;if(0!==e._renderService.dimensions.actualCellWidth&&0!==e._renderService.dimensions.actualCellHeight){var t=window.getComputedStyle(this._terminal.element.parentElement),r=parseInt(t.getPropertyValue("height")),i=Math.max(0,parseInt(t.getPropertyValue("width"))),n=window.getComputedStyle(this._terminal.element),o=r-(parseInt(n.getPropertyValue("padding-top"))+parseInt(n.getPropertyValue("padding-bottom"))),a=i-(parseInt(n.getPropertyValue("padding-right"))+parseInt(n.getPropertyValue("padding-left")))-e.viewport.scrollBarWidth;return{cols:Math.max(2,Math.floor(a/e._renderService.dimensions.actualCellWidth)),rows:Math.max(1,Math.floor(o/e._renderService.dimensions.actualCellHeight))}}}},e}();t.FitAddon=r}},t={};return function r(i){if(t[i])return t[i].exports;var n=t[i]={exports:{}};return e[i](n,n.exports,r),n.exports}(775)})()}));
//# sourceMappingURL=xterm-addon-fit.js.map

175
xterm/xterm.css Normal file
View file

@ -0,0 +1,175 @@
/**
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
* https://github.com/chjj/term.js
* @license MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Originally forked from (with the author's permission):
* Fabrice Bellard's javascript vt100 for jslinux:
* http://bellard.org/jslinux/
* Copyright (c) 2011 Fabrice Bellard
* The original design remains. The terminal itself
* has been extended to include xterm CSI codes, among
* other features.
*/
/**
* Default styles for xterm.js
*/
.xterm {
position: relative;
user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
}
.xterm.focus,
.xterm:focus {
outline: none;
}
.xterm .xterm-helpers {
position: absolute;
top: 0;
/**
* The z-index of the helpers must be higher than the canvases in order for
* IMEs to appear on top.
*/
z-index: 5;
}
.xterm .xterm-helper-textarea {
padding: 0;
border: 0;
margin: 0;
/* Move textarea out of the screen to the far left, so that the cursor is not visible */
position: absolute;
opacity: 0;
left: -9999em;
top: 0;
width: 0;
height: 0;
z-index: -5;
/** Prevent wrapping so the IME appears against the textarea at the correct position */
white-space: nowrap;
overflow: hidden;
resize: none;
}
.xterm .composition-view {
/* TODO: Composition position got messed up somewhere */
background: #000;
color: #FFF;
display: none;
position: absolute;
white-space: nowrap;
z-index: 1;
}
.xterm .composition-view.active {
display: block;
}
.xterm .xterm-viewport {
/* On OS X this is required in order for the scroll bar to appear fully opaque */
background-color: #000;
overflow-y: scroll;
cursor: default;
position: absolute;
right: 0;
left: 0;
top: 0;
bottom: 0;
}
.xterm .xterm-screen {
position: relative;
}
.xterm .xterm-screen canvas {
position: absolute;
left: 0;
top: 0;
}
.xterm .xterm-scroll-area {
visibility: hidden;
}
.xterm-char-measure-element {
display: inline-block;
visibility: hidden;
position: absolute;
top: 0;
left: -9999em;
line-height: normal;
}
.xterm {
cursor: text;
}
.xterm.enable-mouse-events {
/* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
cursor: default;
}
.xterm.xterm-cursor-pointer,
.xterm .xterm-cursor-pointer {
cursor: pointer;
}
.xterm.column-select.focus {
/* Column selection mode */
cursor: crosshair;
}
.xterm .xterm-accessibility,
.xterm .xterm-message {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 10;
color: transparent;
}
.xterm .live-region {
position: absolute;
left: -9999px;
width: 1px;
height: 1px;
overflow: hidden;
}
.xterm-dim {
opacity: 0.5;
}
.xterm-underline {
text-decoration: underline;
}
.xterm-strikethrough {
text-decoration: line-through;
}

2
xterm/xterm.js Normal file

File diff suppressed because one or more lines are too long