Compare commits

..

7 Commits
main ... main

Author SHA1 Message Date
Fabian Stamm
35ef2a8ddc Adding earthly and gitea actions 2023-07-13 22:59:14 +02:00
Fabian Stamm
6d482896ba Merge branch 'main' of https://git.stamm.me/hibas123/ScreenSharingThing 2023-07-13 15:17:55 +02:00
Fabian Stamm
11810e8889 Add gitea action support 2023-07-13 15:13:53 +02:00
Fabian Stamm
7ffb691922 Merge branch 'main' of https://git.hibas.dev/hibas123/ScreenSharingThing 2023-07-02 15:57:14 +02:00
Fabian Stamm
8aa6d43483 Working on better thing 2023-07-02 15:51:49 +02:00
012d0fe823 Fixing earthfile 2023-06-08 16:33:34 +02:00
Fabian Stamm
3ab6fc97e9 Switch direction of link sharing 2022-06-20 20:03:55 +02:00
49 changed files with 6293 additions and 1614 deletions

View File

@ -4,7 +4,7 @@ root = true
end_of_line = lf
insert_final_newline = true
[*.{js,json,yml,mjs}]
[*.{js,ts,json,yml,mjs,svelte}]
charset = utf-8
indent_style = space
indent_size = 3

36
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,36 @@
# .github/workflows/ci.yml
name: CI
on:
push:
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
env:
MY_DOCKER_USERNAME: ${{ secrets.MY_DOCKER_USERNAME }}
MY_DOCKER_PASSWORD: ${{ secrets.MY_DOCKER_PASSWORD }}
FORCE_COLOR: 1
steps:
- uses: https://github.com/earthly/actions-setup@v1
with:
version: v0.7.0
- uses: actions/checkout@v2
- name: Put back the git branch into git (Earthly uses it for tagging)
run: |
branch=""
if [ -n "$GITHUB_HEAD_REF" ]; then
branch="$GITHUB_HEAD_REF"
else
branch="${GITHUB_REF##*/}"
fi
git checkout -b "$branch" || true
- name: Docker Login
run: docker login git.hibas.dev --username "$MY_DOCKER_USERNAME" --password "$MY_DOCKER_PASSWORD"
- name: Earthly version
run: earthly --version
- name: Run build
run: earthly --push +docker-multi

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,9 @@
nodeLinker: node-modules
npmRegistryServer: "https://npm.hibas123.de"
nodeLinker: "node-modules"
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
yarnPath: .yarn/releases/yarn-3.1.1.cjs

1
Client/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
dist/

18
Client/.routify/config.js Normal file
View File

@ -0,0 +1,18 @@
module.exports = {
"pages": "src/pages",
"sourceDir": "public",
"routifyDir": ".routify",
"ignore": "",
"dynamicImports": true,
"singleBuild": false,
"noHashScroll": false,
"distDir": "dist",
"hashScroll": true,
"extensions": [
"html",
"svelte",
"md",
"svx"
],
"started": "2022-01-22T20:07:08.621Z"
}

41
Client/.routify/routes.js Normal file
View File

@ -0,0 +1,41 @@
/**
* @roxi/routify 2.18.4
* File generated Sat Jan 22 2022 21:07:08 GMT+0100 (Mitteleuropäische Normalzeit)
*/
export const __version = "2.18.4"
export const __timestamp = "2022-01-22T20:07:08.628Z"
//buildRoutes
import { buildClientTree } from "@roxi/routify/runtime/buildRoutes"
//imports
//options
export const options = {}
//tree
export const _tree = {
"name": "root",
"filepath": "/",
"root": true,
"ownMeta": {},
"absolutePath": "src/pages",
"children": [],
"isLayout": false,
"isReset": false,
"isIndex": false,
"isFallback": false,
"meta": {
"recursive": true,
"preload": false,
"prerender": true
},
"path": "/"
}
export const {tree, routes} = buildClientTree(_tree)

View File

@ -0,0 +1 @@
[]

1
Client/README.md Normal file
View File

@ -0,0 +1 @@
# Client

32
Client/index.html Normal file
View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hibas123 Screen Share</title>
<script defer type="module" src="./src/bootstrap.ts"></script>
<link id="theme" rel="stylesheet" href="/smui.css" />
<!-- <link rel="stylesheet" href="/styles.css" /> -->
<!-- Material Icons -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
<!-- Roboto -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700" />
<!-- Roboto Mono -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Mono" />
<style>
html,
body {
margin: 0;
}
</style>
</head>
<body></body>
</html>

64
Client/package.json Normal file
View File

@ -0,0 +1,64 @@
{
"name": "@hibas123/screen-client",
"packageManager": "yarn@3.1.1",
"scripts": {
"dev": "run-p dev:routify dev:vite",
"dev:vite": "vite --host",
"dev:routify": "routify",
"build": "run-s prepare build:routify build:vite",
"build:routify": "routify -b",
"build:vite": "vite build",
"prepare": "npm run smui-theme-light && npm run smui-theme-dark",
"smui-theme-light": "smui-theme compile public/smui.css -i src/theme",
"smui-theme-dark": "smui-theme compile public/smui-dark.css -i src/theme/dark"
},
"dependencies": {
"@hibas123/utils": "^2.2.18",
"@material/theme": "^14.0.0",
"@rtdb2/sdk": "^3.0.0-beta.7",
"@smui-extra/accordion": "^7.0.0-beta.14",
"@smui-extra/badge": "^7.0.0-beta.14",
"@smui/banner": "^7.0.0-beta.14",
"@smui/button": "^7.0.0-beta.14",
"@smui/card": "^7.0.0-beta.14",
"@smui/checkbox": "^7.0.0-beta.14",
"@smui/circular-progress": "^7.0.0-beta.14",
"@smui/common": "^7.0.0-beta.14",
"@smui/data-table": "^7.0.0-beta.14",
"@smui/dialog": "^7.0.0-beta.14",
"@smui/drawer": "^7.0.0-beta.14",
"@smui/fab": "^7.0.0-beta.14",
"@smui/floating-label": "^7.0.0-beta.14",
"@smui/icon-button": "^7.0.0-beta.14",
"@smui/layout-grid": "^7.0.0-beta.14",
"@smui/line-ripple": "^7.0.0-beta.14",
"@smui/linear-progress": "^7.0.0-beta.14",
"@smui/list": "^7.0.0-beta.14",
"@smui/menu": "^7.0.0-beta.14",
"@smui/menu-surface": "^7.0.0-beta.14",
"@smui/notched-outline": "^7.0.0-beta.14",
"@smui/paper": "^7.0.0-beta.14",
"@smui/radio": "^7.0.0-beta.14",
"@smui/ripple": "^7.0.0-beta.14",
"@smui/select": "^7.0.0-beta.14",
"@smui/snackbar": "^7.0.0-beta.14",
"@smui/tab": "^7.0.0-beta.14",
"@smui/tab-indicator": "^7.0.0-beta.14",
"@smui/tab-scroller": "^7.0.0-beta.14",
"@smui/textfield": "^7.0.0-beta.14",
"@smui/top-app-bar": "^7.0.0-beta.14",
"dayjs": "^1.11.9",
"nanoid": "^3.3.6",
"peerjs": "^1.4.7",
"svelte": "^4.0.5"
},
"devDependencies": {
"@roxi/routify": "^2.18.12",
"@sveltejs/vite-plugin-svelte": "^2.4.2",
"@tsconfig/svelte": "^5.0.0",
"npm-run-all": "^4.1.5",
"smui-theme": "^7.0.0-beta.14",
"svelte-preprocess": "^5.0.4",
"vite": "^4.4.3"
}
}

File diff suppressed because one or more lines are too long

29
Client/public/smui.css Normal file

File diff suppressed because one or more lines are too long

5
Client/routify.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
routifyDir: "src/.routify",
dynamicImports: true,
extensions: ["svelte"],
};

View File

@ -0,0 +1,15 @@
module.exports = {
"pages": "src/pages",
"sourceDir": "public",
"routifyDir": "src/.routify",
"ignore": "",
"dynamicImports": true,
"singleBuild": true,
"noHashScroll": false,
"distDir": "dist",
"hashScroll": true,
"extensions": [
"svelte"
],
"started": "2023-07-13T13:49:48.147Z"
}

View File

@ -0,0 +1,57 @@
/**
* @roxi/routify 2.18.12
* File generated Thu Jul 13 2023 15:49:48 GMT+0200 (Mitteleuropäische Sommerzeit)
*/
export const __version = "2.18.12"
export const __timestamp = "2023-07-13T13:49:48.159Z"
//buildRoutes
import { buildClientTree } from "@roxi/routify/runtime/buildRoutes"
//imports
//options
export const options = {}
//tree
export const _tree = {
"root": true,
"children": [
{
"isIndex": true,
"isPage": true,
"path": "/index",
"id": "_index",
"component": () => import('../pages/index.svelte').then(m => m.default)
},
{
"isDir": true,
"ext": "",
"children": [
{
"isDir": true,
"ext": "",
"children": [
{
"isIndex": true,
"isPage": true,
"path": "/session/:sessionid/index",
"id": "_session__sessionid_index",
"component": () => import('../pages/session/[sessionid]/index.svelte').then(m => m.default)
}
],
"path": "/session/:sessionid"
}
],
"path": "/session"
}
],
"path": "/"
}
export const {tree, routes} = buildClientTree(_tree)

View File

@ -0,0 +1,3 @@
[
"/index"
]

6
Client/src/App.svelte Normal file
View File

@ -0,0 +1,6 @@
<script lang="ts">
import { Router } from "@roxi/routify";
import { routes } from "./.routify/routes";
</script>
<Router {routes} />

105
Client/src/api.ts Normal file
View File

@ -0,0 +1,105 @@
import {
type ICollectionRef,
type IDocumentRef,
UpdateTypes,
} from "@rtdb2/sdk";
import { nanoid } from "nanoid";
import { Peer } from "peerjs";
import {
collectionToStore,
Sessions,
type IMember,
type IMessage,
type ISession,
} from "./db";
import type { Readable } from "svelte/store";
import { Signal } from "@hibas123/utils";
export class Session {
#client_id = nanoid(22);
#peer: Peer;
#session: IDocumentRef<ISession>;
#members: ICollectionRef<IMember>;
#messages: ICollectionRef<IMessage>;
#self: IDocumentRef<IMember>;
#name: string;
#iv: any;
#closeSignal = new Signal();
members: Readable<(IMember & { $id: string })[]>;
messages: Readable<(IMessage & { $id: string })[]>;
get name() {
return this.#name;
}
set name(value) {
this.#name = value;
this.#self.update({ name: UpdateTypes.Value(value) });
}
constructor(id: string, name: string) {
this.#name = name;
this.#peer = new Peer(this.#client_id, {
host: window.location.hostname,
port: window.location.port as any,
path: "/peerjs",
config: {},
});
this.#session = Sessions.doc(id);
this.#members = this.#session.collection("members");
this.#messages = this.#session.collection("messages");
this.#self = this.#members.doc(this.#client_id);
this.members = collectionToStore(this.#members);
this.messages = collectionToStore(this.#messages);
this.registerSelf();
this.#iv = setInterval(() => this.tick(), 5000);
}
tick() {
this.#self.update({ lastActive: UpdateTypes.Value(Date.now()) });
}
registerSelf() {
this.#self.set({
name: this.#name,
lastActive: Date.now(),
offline: false,
});
}
close() {
this.#closeSignal.sendSignal();
clearInterval(this.#iv);
this.#self.update({ offline: UpdateTypes.Value(true) });
this.#peer.destroy();
}
}
let bitrate = new URL(window.location.href).searchParams.get("br") || 50000;
function bitrateTransform(sdp: string) {
var arr = sdp.split("\r\n");
arr.forEach((str, i) => {
if (/^a=fmtp:\d*/.test(str)) {
console.log("found fmtp");
arr[i] =
str +
`;x-google-max-bitrate=${bitrate};x-google-min-bitrate=0;x-google-start-bitrate=12000`;
} else if (/^a=mid:(1|video)/.test(str)) {
console.log("found mid");
arr[i] += "\r\nb=AS:" + bitrate;
}
});
let res = arr.join("\r\n");
console.log(sdp, res);
return res;
}

5
Client/src/bootstrap.ts Normal file
View File

@ -0,0 +1,5 @@
import App from "./App.svelte";
new App({
target: document.body,
});

43
Client/src/db.ts Normal file
View File

@ -0,0 +1,43 @@
import { AwaitStore } from "@hibas123/utils";
import Client, { type ICollectionRef } from "@rtdb2/sdk";
import { readable } from "svelte/store";
const client = new Client(
"https://rtdb.hibas123.de",
"screen_share",
"screen_share"
);
(window as any).db = client;
export const Sessions = client.collection<ISession>("sessions");
export interface ISession {}
export interface IMember {
lastActive: number;
offline: boolean;
name: string;
}
export interface IMessage {
sender: string;
message: string;
}
export function collectionToStore<T>(coll: ICollectionRef<T>) {
return readable<(T & { $id: string })[]>([], (set) => {
const cancel = new AwaitStore(false);
(async () => {
const itr = await coll.onSnapshot();
cancel.awaitValue(true).then(() => itr.close());
for await (const snapshot of itr) {
set(snapshot.docs.map((doc) => ({ ...doc.data(), $id: doc.id })));
}
})();
return () => {
cancel.send(true);
};
});
}

View File

@ -0,0 +1,80 @@
<script lang="ts">
import Button from "@smui/button";
import Textfield from "@smui/textfield";
import Paper, { Title as PTitle, Content as PContent } from "@smui/paper";
import { nanoid } from "nanoid";
import { url } from "@roxi/routify";
import Snackbar, { Actions, Label } from "@smui/snackbar";
import type { SnackbarComponentDev } from "@smui/snackbar";
import IconButton from "@smui/icon-button";
let sessionID = "";
let errorSnack: SnackbarComponentDev;
function create() {
sessionID = nanoid(22);
connect();
}
function connect() {
if (sessionID.length < 22) {
errorSnack.open();
return;
}
window.history.pushState(
undefined,
undefined,
$url(`/session/${sessionID}`)
);
sessionID = "";
}
</script>
<div class="outer">
<div class="inner">
<Paper elevation={6}>
<PContent>
<PTitle>Create Session</PTitle>
<div style="margin-top: 1rem" />
<Button variant="raised" on:click={create}>Create</Button>
</PContent>
</Paper>
<Paper elevation={6}>
<PContent>
<PTitle>Join Session</PTitle>
<Textfield
label="Session ID"
bind:value={sessionID}
style="width: 100%;"
/>
<div style="margin-top: 1rem" />
<Button variant="raised" on:click={connect}>Connect</Button>
</PContent>
</Paper>
</div>
</div>
<Snackbar bind:this={errorSnack}>
<Label>Invalid Session!</Label>
<Actions>
<IconButton class="material-icons" title="Dismiss">close</IconButton>
</Actions>
</Snackbar>
<style>
.outer {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.inner {
display: grid;
grid-template-columns: repeat(2, minmax(150px, 300px));
grid-template-rows: auto;
gap: 1rem;
}
</style>

View File

@ -0,0 +1,42 @@
<script lang="ts">
import { onMount } from "svelte";
import { Session } from "../../../api";
export let sessionid: string;
let session = new Session(sessionid, "");
let members = session.members;
onMount(() => {
return () => {
session.close();
};
});
</script>
<!-- {sessionid} -->
<div class="outer">
<div class="members">
{#each $members as member (member.$id)}
<div class="member">
<div class="name">{member.name || "anon"}</div>
<div class="id">{member.$id}</div>
</div>
{/each}
</div>
<div class="content">Content</div>
</div>
<style>
.outer {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: grid;
grid-template-columns: 200px 1fr;
}
</style>

View File

@ -0,0 +1,28 @@
@use "sass:color";
@use "@material/theme/color-palette";
// Svelte Colors!
@use "@material/theme/index" as theme with
(
$primary: #1e88e5,
$secondary: #d8701b,
$surface: #fff,
$background: #fff,
$error: color-palette.$red-900
);
@import "@material/typography/mdc-typography";
// html,
// body {
// background-color: theme.$surface;
// color: theme.$on-surface;
// }
// a {
// color: #40b3ff;
// }
// a:visited {
// color: color.scale(#40b3ff, $lightness: -35%);
// }

View File

@ -0,0 +1,28 @@
@use "sass:color";
@use "@material/theme/color-palette";
// Svelte Colors! (Dark Theme)
@use "@material/theme/index" as theme with
(
$primary: #1e88e5,
$secondary: #d8701b,
$surface: color.adjust(color-palette.$grey-900, $blue: +4),
$background: #000,
$error: color-palette.$red-700
);
@import "@material/typography/mdc-typography";
// html,
// body {
// background-color: #000;
// color: theme.$on-surface;
// }
// a {
// color: #40b3ff;
// }
// a:visited {
// color: color.scale(#40b3ff, $lightness: -35%);
// }

5
Client/svelte.config.js Normal file
View File

@ -0,0 +1,5 @@
const autoPreprocess = require("svelte-preprocess");
module.exports = {
preprocess: autoPreprocess(),
};

20
Client/tsconfig.json Normal file
View File

@ -0,0 +1,20 @@
{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "Node",
// "resolveJsonModule": true,
"baseUrl": ".",
"outDir": "tout",
/**
* Typecheck JS in `.svelte` and `.js` files by default.
* Disable checkJs if you'd like to use dynamic types in JS.
* Note that setting allowJs false does not prevent the use
* of JS in `.svelte` files.
*/
"allowJs": true,
"checkJs": true
},
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"]
}

80
Client/vite.config.mts Normal file
View File

@ -0,0 +1,80 @@
import { defineConfig } from "vite";
import { svelte } from "@sveltejs/vite-plugin-svelte";
import * as zlib from "zlib";
// https://vitejs.dev/config/
export default defineConfig({
optimizeDeps: {
exclude: ["@roxi/routify"],
},
server: {
proxy: {
"/peerjs": {
target: "http://localhost:5000/",
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(/^\/peerjs/, ""),
},
"*": "/index.html",
},
},
plugins: [svelte()],
build: {
sourcemap: false,
rollupOptions: {
plugins: [
{
name: "pregzip-files",
generateBundle: async function (options, bundle) {
let prms: Promise<any>[] = [];
for (const fileName in bundle) {
const file = bundle[fileName];
// if (fileName.startsWith("assets/")) {
let src;
if (file.type === "asset") {
src = file.source;
} else {
src = file.code;
}
// console.log("Compressing asset:", typeof file.source == "undefined" ? file : undefined)
prms.push(
new Promise<any>((yes, no) =>
zlib.gzip(
src,
{
level: 6,
},
(err, res) => (err ? no(err) : yes(res))
)
).then((gzip) => {
this.emitFile({
type: "asset",
name: file.name + ".gz",
fileName: file.fileName + ".gz",
source: gzip,
});
}),
new Promise((yes, no) =>
zlib.brotliCompress(src, (err, res) =>
err ? no(err) : yes(res)
)
).then((br) => {
this.emitFile({
type: "asset",
name: file.name + ".br",
fileName: file.fileName + ".br",
source: br as Uint8Array,
});
})
);
// }
}
await Promise.all(prms);
},
},
],
},
},
});

View File

@ -1,17 +0,0 @@
FROM node:12
LABEL maintainer="Fabian Stamm <dev@fabianstamm.de>"
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
RUN npm config set registry https://npm.hibas123.de
COPY ["package.json", "tsconfig.json", "/usr/src/app/"]
RUN npm install
COPY src/ /usr/src/app/src
COPY public/ /usr/src/app/public
EXPOSE 3000/tcp
CMD ["npm", "run", "start"]

39
Earthfile Normal file
View File

@ -0,0 +1,39 @@
VERSION 0.7
FROM node:lts-alpine3.18
WORKDIR /build
deps:
COPY .yarnrc.yml .yarnrc.yml
COPY .yarn .yarn
COPY package.json .
COPY Server/package.json Server/
COPY Client/package.json Client/
RUN apk add --no-cache git python3 make g++ gcc
RUN yarn install
build:
FROM +deps
COPY Client ./Client
COPY Server ./Server
RUN yarn install
RUN sh -c "find . -type f -name '*.ts' | grep -v node_modules"
RUN yarn build
SAVE ARTIFACT Client/dist /dist
SAVE ARTIFACT Server/lib /lib
docker-multi:
BUILD +build
BUILD --platform linux/amd64 --platform linux/arm64 +docker
docker:
FROM +deps
COPY +build/lib ./Server/lib
COPY +build/dist ./Server/public
WORKDIR /build/Server
ENTRYPOINT ["node", "lib/index.js"]
ARG EARTHLY_TARGET_TAG
ARG TAG=$EARTHLY_TARGET_TAG
SAVE IMAGE --push git.hibas.dev/hibas123/screenshare:$TAG

1
Server/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
lib/

18
Server/package.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "@hibas123/screen-server",
"packageManager": "yarn@3.1.1",
"scripts": {
"start": "ts-node src/index.ts",
"build": "tsc",
"dev": "nodemon -e ts --exec ts-node src/index.ts"
},
"devDependencies": {
"@types/node": "^20.4.2",
"ts-node": "^10.9.1",
"typescript": "^5.1.6"
},
"dependencies": {
"express": "^4.18.2",
"peer": "^1.0.0"
}
}

21
Server/src/index.ts Normal file
View File

@ -0,0 +1,21 @@
import { ExpressPeerServer } from "peer";
import express = require("express");
import * as path from "path";
const app = express();
const server = app.listen(5000, () => {
console.log("Server is running on port 5000");
});
const peerServer = ExpressPeerServer(server, {
path: "/",
});
app.use("/peerjs", peerServer as any);
app.use("/", express.static("public"));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, "..", "public", "index.html"));
});

13
Server/tsconfig.json Normal file
View File

@ -0,0 +1,13 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "esnext",
"esModuleInterop": true,
"outDir": "lib/",
"sourceMap": true,
"declaration": true,
"noImplicitAny": false
},
"exclude": ["node_modules"],
"include": ["src"]
}

View File

@ -1,25 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIELzCCAxegAwIBAgIUD0BQwjVJXVH/a0mC5Sfjk1WQdQswDQYJKoZIhvcNAQEL
BQAwgaYxCzAJBgNVBAYTAkRFMQ4wDAYDVQQIDAVIZXNzZTEXMBUGA1UEBwwOU3Rh
ZHRhbGxlbmRvcmYxEDAOBgNVBAoMB0ZlcnJlcm8xDDAKBgNVBAsMA0lBTjEkMCIG
A1UEAwwbd2RldTEzNjEwMDAxLmZlcnJlcm9uZXQuY29tMSgwJgYJKoZIhvcNAQkB
FhlnbGFlc2xlb24xQGZlcnJlcm9uZXQuY29tMB4XDTIyMDExMTE0NTIxNFoXDTIz
MDExMTE0NTIxNFowgaYxCzAJBgNVBAYTAkRFMQ4wDAYDVQQIDAVIZXNzZTEXMBUG
A1UEBwwOU3RhZHRhbGxlbmRvcmYxEDAOBgNVBAoMB0ZlcnJlcm8xDDAKBgNVBAsM
A0lBTjEkMCIGA1UEAwwbd2RldTEzNjEwMDAxLmZlcnJlcm9uZXQuY29tMSgwJgYJ
KoZIhvcNAQkBFhlnbGFlc2xlb24xQGZlcnJlcm9uZXQuY29tMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAstunEBtYoA7JcsSfP+zrJOtM4Qm5sKtVohI0
wNrBenjrheYpzX5BaNhMaQHyQZ1P7TnpT0krrRxEhZ3/K2KjN1m6Zym/B0UncTSS
sEzhkSLaB6d+InIr1KPrL1XNlECfXB2CppfWnJzmh+8n7UuWgzXjYiW6A2fmIEru
0wvkscnwA4BuOhtRSNlBonaod7PyjSqrKKSAUJT3IUuL6h1vUoC2vz0xGSQdKLB9
9JtNxD+wCgiZGFVOLACeDjRc4+5aMBn48lJjl18I9rBubpbdXinJ6215w9G/YP03
ZkX2f9iizSSsveEOOtWs4cGAFTSmnNFpGPmf5AuuNb3rN5eyEwIDAQABo1MwUTAd
BgNVHQ4EFgQUOCi4I94CHUpjbiF2pUAJiwLXY8wwHwYDVR0jBBgwFoAUOCi4I94C
HUpjbiF2pUAJiwLXY8wwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
AQEAGVMITcIjBzEzFpBJoLQYFrhUhGcwchYlHZh/VcTf3IJAQjr0+6pHZS6LnXhk
Hn6zPgfJrm6mhdsXZahtx/mMZFGhu/coh4qXzszFiqxdqIZ9zWlNmkP4ylgVQrnD
X6kURNvGNp807aMx05dcEb//O+xUyKjiue4+CIN2y9Jst4aqB7HIC4XQJb+DwHne
UmPFjR0rhExSjntf86RuWAzlNWhQLMdyqF48rdcTqoecFLl8/vsMYWJp+IhLgUHb
3MBpxbOSUVMyYBxdV70fOkxv2LZZwO3EpM6X3id41QQXxHUrDDrlCMhCXiHFbIPR
IdwktLDNZk0gZFXdPUToNXsuTA==
-----END CERTIFICATE-----

View File

@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCy26cQG1igDsly
xJ8/7Osk60zhCbmwq1WiEjTA2sF6eOuF5inNfkFo2ExpAfJBnU/tOelPSSutHESF
nf8rYqM3WbpnKb8HRSdxNJKwTOGRItoHp34icivUo+svVc2UQJ9cHYKml9acnOaH
7yftS5aDNeNiJboDZ+YgSu7TC+SxyfADgG46G1FI2UGidqh3s/KNKqsopIBQlPch
S4vqHW9SgLa/PTEZJB0osH30m03EP7AKCJkYVU4sAJ4ONFzj7lowGfjyUmOXXwj2
sG5ult1eKcnrbXnD0b9g/TdmRfZ/2KLNJKy94Q461azhwYAVNKac0WkY+Z/kC641
ves3l7ITAgMBAAECggEAVSX9As4CAzEG9nxk1CoWSB09HGVk4ZavzdidBLMgKQ4o
Ejbg79OLkD5pIhSrIFGkG2vWhshu4pryhCoTsLPkwBUXiMV3DB8ACATfUM9JE69j
3QEAK6Xu9+yRqpdOp6WcOF5UNLtUkHqhxVU1zOKPZSfieHc9dyGfjQAfcpnW5kxQ
aYMzPEgPP+m9jp1JyVdAEqPxV0Y8xUcaO65+yvOVJk95zZcVM9kRJpDgbVjXVl+/
0ZS4y2WXUIygEYNGcV7ZGahQZirekLEmFT1LL/c9PepAmMpur/PvOQcN+ZJvJVJ3
b377VY5ZPWLgaorEsMBQaLU+2XAxspszTGjSdrQkAQKBgQDoTRlSPKdjSBh//Tay
Km/diKhCW94BjB+X7pHopj1LWG4Ws7hJVfW/sVi9qkk8ENeOPUg2MHdmobBB1nxr
JXmmKkZD0K16BmVnGBgSatR0P57Df0wzhcBmdvcYa7ZJ7odFgcYN7sIOvB1ZJ1x0
cEbfRQ6UjudMT8BC/2W67jXMcQKBgQDFGs3Mb/gq2jarILKAnmPGbgb4uWors+Ka
QJHF+jTyqjce4zVTUvL8DtNch9DZYyKiDSx6ReDFOaylfQINqz7Kqi41q0Q//H9a
ZlAmmvn3QWcQ5mT0Xld1bWK/qbApFzZY0JF4Cys3lmH2JSqhmukLAqTV/obQRjUN
ahn4XUh4wwKBgBRINv/BH/RBJTJ3j0D7B41WEyrIDpgf/dosED051nwvml0ND/gH
M0+rUk4tAfvmlItsulNQ4/vn/hWhfnd0bCyf4Eanf5351PytU9y3yxjjPR9gi+yr
ruLDXEubi+zkkJb2/63TvMnAjudr0lywON/hjaZW28cD54tx9RXfGn9hAoGADzWH
RcwqCRx3dXL7cyNFra0VyqF8CM1DogVzeiRZa5Qo1rBPkBNpfnuiYZR1UCDvLjP4
B6NWucE+ijKAMw/Qs5C4KhoCFTHlndMhQilZOnQIgOxWQ+j3tK7xHLr6ReFtpyLI
5stt1Uc8XeL2TCwI6XmVwJF4U5/nPha+1ERWcEMCgYBoseZo3GW8LRPpzR9WvDgC
bjX2/nwG1S8r/cfyE29oRn/O/WgoFQ8uywQH5jxQKjEcNnCgIp3Jl9bdhuIPsQIO
Yi2UkwSiXNxisMUQR57q8Xcy043giaxW92WZ7R82Ysb8pBf8769TuVi/DB8EUDLG
8srPcKRNcsaUDdMSGM6yRw==
-----END PRIVATE KEY-----

784
package-lock.json generated
View File

@ -1,784 +0,0 @@
{
"name": "ScreenSharingThing",
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"@cspotcode/source-map-consumer": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
"integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
"dev": true
},
"@cspotcode/source-map-support": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz",
"integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==",
"dev": true,
"requires": {
"@cspotcode/source-map-consumer": "0.8.0"
}
},
"@tsconfig/node10": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
"integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
"dev": true
},
"@tsconfig/node12": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
"integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
"dev": true
},
"@tsconfig/node14": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
"integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
"dev": true
},
"@tsconfig/node16": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
"dev": true
},
"@types/body-parser": {
"version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
"integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
"requires": {
"@types/connect": "*",
"@types/node": "*"
}
},
"@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
"integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
"requires": {
"@types/node": "*"
}
},
"@types/cors": {
"version": "2.8.12",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
"integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw=="
},
"@types/express": {
"version": "4.17.13",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz",
"integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==",
"requires": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.18",
"@types/qs": "*",
"@types/serve-static": "*"
}
},
"@types/express-serve-static-core": {
"version": "4.17.27",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz",
"integrity": "sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA==",
"requires": {
"@types/node": "*",
"@types/qs": "*",
"@types/range-parser": "*"
}
},
"@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
},
"@types/node": {
"version": "16.11.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.19.tgz",
"integrity": "sha512-BPAcfDPoHlRQNKktbsbnpACGdypPFBuX4xQlsWDE7B8XXcfII+SpOLay3/qZmCLb39kV5S1RTYwXdkx2lwLYng=="
},
"@types/qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
},
"@types/range-parser": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
},
"@types/serve-static": {
"version": "1.13.10",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz",
"integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==",
"requires": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"@types/ws": {
"version": "7.4.7",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz",
"integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==",
"requires": {
"@types/node": "*"
}
},
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
"requires": {
"mime-types": "~2.1.24",
"negotiator": "0.6.2"
}
},
"acorn": {
"version": "8.7.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
"integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
"dev": true
},
"acorn-walk": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
"dev": true
},
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": {
"color-convert": "^2.0.1"
}
},
"arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"dev": true
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"body-parser": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz",
"integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==",
"requires": {
"bytes": "3.1.1",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "~1.1.2",
"http-errors": "1.8.1",
"iconv-lite": "0.4.24",
"on-finished": "~2.3.0",
"qs": "6.9.6",
"raw-body": "2.4.2",
"type-is": "~1.6.18"
}
},
"bytes": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz",
"integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg=="
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
},
"cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
"requires": {
"safe-buffer": "5.2.1"
}
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
"cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"requires": {
"object-assign": "^4",
"vary": "^1"
}
},
"create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"express": {
"version": "4.17.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz",
"integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==",
"requires": {
"accepts": "~1.3.7",
"array-flatten": "1.1.1",
"body-parser": "1.19.1",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.4.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~1.1.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "~1.1.2",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.7",
"qs": "6.9.6",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
"send": "0.17.2",
"serve-static": "1.14.2",
"setprototypeof": "1.2.0",
"statuses": "~1.5.0",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
}
},
"finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
"requires": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"statuses": "~1.5.0",
"unpipe": "~1.0.0"
}
},
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
},
"http-errors": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
"integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.1"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"requires": {
"p-locate": "^4.1.0"
}
},
"make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
},
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
},
"mime-db": {
"version": "1.51.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
"integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g=="
},
"mime-types": {
"version": "2.1.34",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
"integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
"requires": {
"mime-db": "1.51.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"requires": {
"ee-first": "1.1.1"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"requires": {
"p-limit": "^2.2.0"
}
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
},
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
},
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"peer": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/peer/-/peer-0.6.1.tgz",
"integrity": "sha512-zPJSPoZvo+83sPJNrW8o93QTktx7dKk67965RRDDNAIelWw1ZwE6ZmmhsvRrdNRlK0knQb3rR8GBdZlbWzCYJw==",
"requires": {
"@types/cors": "^2.8.6",
"@types/express": "^4.17.3",
"@types/ws": "^7.2.3",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"uuid": "^3.4.0",
"ws": "^7.2.3",
"yargs": "^15.3.1"
}
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"requires": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
}
},
"qs": {
"version": "6.9.6",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
"integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ=="
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
},
"raw-body": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz",
"integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==",
"requires": {
"bytes": "3.1.1",
"http-errors": "1.8.1",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
}
},
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
},
"require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"send": {
"version": "0.17.2",
"resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
"integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==",
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "1.8.1",
"mime": "1.6.0",
"ms": "2.1.3",
"on-finished": "~2.3.0",
"range-parser": "~1.2.1",
"statuses": "~1.5.0"
},
"dependencies": {
"ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
}
}
},
"serve-static": {
"version": "1.14.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz",
"integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==",
"requires": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.17.2"
}
},
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
}
},
"strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"requires": {
"ansi-regex": "^5.0.1"
}
},
"toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
},
"ts-node": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz",
"integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==",
"dev": true,
"requires": {
"@cspotcode/source-map-support": "0.7.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"yn": "3.1.1"
}
},
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"requires": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
}
},
"typescript": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
"dev": true
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
"which-module": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
},
"wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
}
},
"ws": {
"version": "7.5.6",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz",
"integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA=="
},
"y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
},
"yargs": {
"version": "15.4.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"requires": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
}
},
"yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
},
"yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true
}
}
}

View File

@ -1,16 +1,24 @@
{
"name": "ScreenSharingThing",
"packageManager": "yarn@3.1.1",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "ts-node src/index.ts"
"build:client": "yarn workspace @hibas123/screen-client build",
"build:server": "yarn workspace @hibas123/screen-server build",
"build": "run-s build:server build:client",
"dev:client": "yarn workspace @hibas123/screen-client dev",
"dev:server": "yarn workspace @hibas123/screen-server dev",
"dev": "run-p dev:client dev:server"
},
"workspaces": [
"Server",
"Client"
],
"devDependencies": {
"@types/node": "^16.11.11",
"ts-node": "^10.4.0",
"typescript": "^4.5.2"
"npm-run-all": "^4.1.5"
},
"dependencies": {
"express": "^4.17.1",
"peer": "^0.6.1"
"@hibas123/jrpcgen": "~1.2.13"
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,24 +0,0 @@
/* * {
box-sizing: border-box !important;
margin: 0 !important;
padding: 0 !important;
} */
/* #main {
position: fixed;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
}
*/
body {
margin: 0;
height: 100vh;
width: 100%;
/* overflow: hidden; */
}
video {
width: 100% !important;
height: auto !important;
background-color: black;
}

View File

@ -1,43 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, height= initial-scale=1.0">
<link rel="stylesheet" href="./css/mystyle.css">
<title>SimpleStream</title>
<!-- //asset self hosting for non internet environments
//TODO: improve this later with correct tools like bundeling
-->
<link href="./css/bootstrap.min.css" rel="stylesheet">
<script src="./lib/jquery.min.js"></script>
<script src="./lib/bootstrap.bundle.min.js"></script>
<script src="./lib/peerjs.min.js"></script>
</head>
<body>
<div class="container-fluid vh-100">
<div class="row-fluid">
<div class="col-md-auto">
<h1>SimpleStream (Alpha)</h1>
<h2>Your ID: <span id="streamId"></span></h2>
<div id="streamURLCont">
<h2>Connect URL: <a id="streamURL"></a></h2>
</div>
<div id="connectToCont">
<h2>Connecting to: <span id="connectToID"></span></h2>
<button id="startStramBTN">Start Stream</button>
</div>
</div>
<video id="localVideo" autoplay muted></video>
</div>
</div>
<!-- style="min-width: 100%; min-height: 100%;width: auto; height: auto; z-index: -100; background-color: black;" -->
<script src="main.mjs" type="module">
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,202 +0,0 @@
function simpleFramwork() {
let obj = {};
return new Proxy(obj, {
get(_, prop) {
const [id, param] = prop.split("_");
let elm = document.getElementById(id);
if (!elm) {
console.log(`Element with id ${id} not found`);
return false;
}
switch (param) {
case "value":
return elm.value;
case "href":
return elm.href;
case "style":
return elm.getAttribute("style");
case "text":
return elm.innerText;
case undefined:
return elm;
}
},
set(_, prop, value) {
const [id, param] = prop.split("_");
let elm = document.getElementById(id);
if (!elm) {
console.log(`Element with id ${id} not found`);
return false;
}
switch (param) {
case "value":
elm.value = value;
break;
case "href":
elm.href = value;
break;
case "click":
elm.addEventListener("click", value);
break;
case "style":
elm.setAttribute("style", value);
break;
case "text":
elm.innerText = value;
break;
case undefined:
break;
}
return true;
},
});
}
let sf = simpleFramwork();
sf.streamId_text = "Loading...";
sf.streamURL_text = "Loading...";
sf.localVideo.enableAutosize = true;
let connectToId = new URL(window.location.href).searchParams.get("id");
let ownId = new URL(window.location.href).searchParams.get("own_id");
let autoFullscreen = new URL(window.location.href).searchParams.get("auto_fullscreen");
let bitrate = new URL(window.location.href).searchParams.get("br") || 50000;
//Connect to ID means: Iam the screensharer now.
//no ID Specified = Iam the Viewer
if (connectToId) {
sf.streamURLCont_style = "display:none";
sf.connectToCont_style = "display:block";
sf.connectToID_text = connectToId;
} else {
sf.streamURLCont_style = "display:block";
sf.connectToCont_style = "display:none";
}
if (ownId) {
var peer = new Peer(ownId, {
host: window.location.hostname,
port: window.location.port,
path: "/peerjs",
});
} else {
var peer = new Peer({
host: window.location.hostname,
port: window.location.port,
path: "/peerjs",
});
}
function fullscreenHandler(element, fullscreensetting) {
//main.mjs: 98 Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture.
//if (fullscreensetting) {
let res = element.requestFullscreen();
console.log(res);
//}
}
function bitrateTransform(sdp) {
var arr = sdp.split("\r\n");
arr.forEach((str, i) => {
if (/^a=fmtp:\d*/.test(str)) {
console.log("found fmtp");
arr[i] =
str +
`;x-google-max-bitrate=${bitrate};x-google-min-bitrate=0;x-google-start-bitrate=12000`;
} else if (/^a=mid:(1|video)/.test(str)) {
console.log("found mid");
arr[i] += "\r\nb=AS:" + bitrate;
}
});
let res = arr.join("\r\n");
console.log(sdp, res);
return res;
}
let currentStream = undefined;
peer.on("open", (id) => {
console.log("ID", id);
sf.streamId_text = id;
//clearing the params from the url
let url = new URL(window.location.href.split('?')[0]);
url.searchParams.set("id", id);
sf.streamURL_text = url.href;
sf.streamURL_href = url.href;
let con = peer.connect(connectToId);
con.on("data", console.log);
con.on("open", () => con.send("Hello"));
if (connectToId) {
sf.startStramBTN_click = () => {
navigator.mediaDevices
.getDisplayMedia({
video: true,
})
.then((stream) => {
if (currentStream) {
currentStream.getTracks().forEach(track => track.stop())
}
currentStream = stream;
let v = sf.localVideo;
v.srcObject = stream;
v.play();
const conn = peer.call(connectToId, stream, {
sdpTransform: bitrateTransform,
});
conn.on("stream", console.log);
conn.on("close", console.log);
conn.on("error", console.log);
});
};
}
});
peer.on("connection", (conn) => {
console.log("connection", conn);
conn.on("data", console.log);
});
peer.on("error", console.error);
peer.on("close", console.log);
peer.on("disconnected", console.log);
peer.on("error", console.log);
peer.on("call", (call) => {
console.log("Call", call);
call.answer(undefined);
call.on("stream", console.log);
call.on("close", console.log);
call.on("error", console.log);
call.on("stream", (remoteStream) => {
console.log("stream", remoteStream);
let v = sf.localVideo;
v.srcObject = remoteStream;
//fullscreenHandler(v, autoFullscreen);
v.muted = true;
v.autoplay = true;
//because of https://developer.mozilla.org/de/docs/Web/HTML/Element/video
//because of https://developer.chrome.com/blog/autoplay/ (autoplay / play not possible with sound enabled)
v.play();
});
});
function createEmptyVideoTrack({ width, height }) {
const canvas = Object.assign(document.createElement("canvas"), {
width,
height,
});
canvas.getContext("2d").fillRect(0, 0, width, height);
const stream = canvas.captureStream();
const track = stream.getVideoTracks()[0];
return Object.assign(track, { enabled: false });
}

View File

@ -1,23 +0,0 @@
import { ExpressPeerServer } from "peer";
import * as express from "express";
import * as fs from "fs";
import * as https from "https";
import * as path from "path";
const cert = fs.readFileSync(path.resolve(__dirname, "../cert/selfsigned.crt"), 'utf8');
const key = fs.readFileSync(path.resolve(__dirname, "../cert/selfsigned.key"), 'utf8');
var credentials = { key: key, cert: cert };
const app = express();
const https_server = https.createServer(credentials,app)
let server = https_server.listen(8001);
const peerServer = ExpressPeerServer(server, {
path: "/",
});
console.log("Started server!")
app.use("/peerjs", peerServer as any);
app.use("/", express.static("public"));

View File

@ -1,10 +0,0 @@
{
"compilerOptions": {
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"module": "commonjs" /* Specify what module code is generated. */,
"moduleResolution": "node" /* Specify how the compiler resolves module names. */,
"esModuleInterop": false /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */,
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}

5344
yarn.lock

File diff suppressed because it is too large Load Diff