This commit is contained in:
jusax23 2023-06-22 17:47:04 +02:00
parent 806baf0043
commit 6156fac496
Signed by: jusax23
GPG key ID: 499E2AA870C1CD41
16 changed files with 827 additions and 329 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
dist/
build/
node_modules/

View file

@ -1,166 +0,0 @@
class Tragable {
initTrag(element, cb) {
let selected = false;
element.addEventListener('mousedown', () => {
selected = true;
});
svg.addEventListener('mousemove', event => {
if (selected) cb(event.x, event.y);
});
svg.addEventListener('mouseup', () => {
selected = false;
});
svg.addEventListener('mouseleave', event => {
selected = false;
});
}
}
class SVGNode extends Tragable {
group;
circle;
circleText;
aboveText;
constructor(node) {
super();
// Create the group element
this.group = document.createElementNS(svgNamespace, 'g');
this.group.classList.add("PNode");
this.group.setAttribute('transform', `translate(${node.x}, ${node.y})`);
// Create the circle
this.circle = document.createElementNS(svgNamespace, 'circle');
this.circle.setAttribute('cx', '0');
this.circle.setAttribute('cy', '0');
this.circle.setAttribute('r', '25');
// Create the text inside the circle
this.circleText = document.createElementNS(svgNamespace, 'text');
this.circleText.classList.add("circleText");
this.circleText.setAttribute('x', '0');
this.circleText.setAttribute('y', '5');
this.circleText.textContent = '0/1';
// Create the text above the circle
this.aboveText = document.createElementNS(svgNamespace, 'text');
this.aboveText.classList.add("aboveText");
this.aboveText.setAttribute('x', '0');
this.aboveText.setAttribute('y', '-35');
this.aboveText.textContent = node.name;
// Append the circle and texts to the group
this.group.appendChild(this.circle);
this.group.appendChild(this.circleText);
this.group.appendChild(this.aboveText);
this.initTrag(this.group, (x, y) => node.updatePosition(x, y));
}
appendIt(svg) {
svg.appendChild(this.group);
}
translate(x, y) {
this.group.setAttribute('transform', `translate(${x}, ${y})`);
}
setName(name) {
this.aboveText.textContent = name;
}
setMarks(amount, max) {
this.circleText.textContent = `${amount}/${max}`;
}
}
class SVGTRansition extends Tragable {
group;
rect;
rectText;
constructor(trans) {
super();
// Create the group element
this.group = document.createElementNS(svgNamespace, 'g');
this.group.classList.add("PTransition");
this.group.setAttribute('transform', `translate(${trans.x}, ${trans.y})`);
// Create the circle
this.rect = document.createElementNS(svgNamespace, 'rect');
this.rect.setAttribute('x', '-12.5');
this.rect.setAttribute('y', '-25');
this.rect.setAttribute('height', '50');
this.rect.setAttribute('width', '25');
// Create the text inside the circle
this.rectText = document.createElementNS(svgNamespace, 'text');
this.rectText.classList.add("rectText");
this.rectText.setAttribute('x', '-5');
this.rectText.setAttribute('y', '-35');
this.rectText.textContent = trans.name;
// Append the circle and texts to the group
this.group.appendChild(this.rect);
this.group.appendChild(this.rectText);
this.initTrag(this.group, (x, y) => trans.updatePosition(x, y));
}
appendIt(svg) {
svg.appendChild(this.group);
}
translate(x, y) {
this.group.setAttribute('transform', `translate(${x}, ${y})`);
}
setName(name) {
this.aboveText.textContent = name;
}
setCanFire(can){
if (can)this.group.classList.add("canFire");
else this.group.classList.remove("canFire");
}
}
class SVGArrow {
group;
lineText;
line;
from;
to;
constructor(from, to) {
this.from = from;
this.to = to;
this.group = document.createElementNS(svgNamespace, 'g');
this.group.classList.add("PEdge");
this.line = document.createElementNS(svgNamespace, 'line');
this.line.setAttribute('marker-end', "url(#arrowhead)");
this.group.setAttribute('transform', `translate(0, 0)`);
// Create the text inside the circle
this.lineText = document.createElementNS(svgNamespace, 'text');
this.lineText.classList.add("lineText");
this.lineText.setAttribute('x', '0');
this.lineText.setAttribute('y', '0');
this.lineText.textContent = "";
this.group.appendChild(this.line);
this.group.appendChild(this.lineText);
this.updatePosition();
}
updatePosition() {
let dx = this.to.x - this.from.x;
let dy = this.to.y - this.from.y;
let l = Math.sqrt(dx * dx + dy * dy);
dx /= l;
dy /= l;
this.line.setAttribute('x1', this.from.x + dx * 30);
this.line.setAttribute('y1', this.from.y + dy * 30);
this.line.setAttribute('x2', this.to.x - dx * 40);
this.line.setAttribute('y2', this.to.y - dy * 40);
}
appendIt(svg) {
svg.appendChild(this.group);
}
}

View file

@ -83,9 +83,7 @@
</marker>
</defs>
</svg>
<script>const svgNamespace = 'http://www.w3.org/2000/svg';</script>
<script src="graphics.js"></script>
<script src="main.js"></script>
<script src="index.js"></script>
</body>
</html>

37
js/PElems/Edge.ts Normal file
View file

@ -0,0 +1,37 @@
import { svgArrows } from "..";
import { SVGArrow } from "../graphics/SVGArrow";
import { Node } from "./Node";
import { Transition } from "./Transition";
export class Edge {
renderedElement: SVGArrow;
end: Node;
trans: Transition;
inEdge: boolean;
dimension = 1;
constructor(end: Node, trans: Transition, inEdge = true) {
this.end = end;
this.trans = trans;
this.inEdge = inEdge;
this.renderedElement = inEdge ? new SVGArrow(end, trans) : new SVGArrow(trans, end);
this.renderedElement.appendIt(svgArrows);
end.updateList.push(this);
}
canSuck() {
return this.end.marks >= this.dimension;
}
suck() {
this.end.marks -= this.dimension;
this.end.updatePoints();
}
canPush() {
return this.end.capacity >= this.end.marks + this.dimension;
}
push() {
this.end.marks += this.dimension;
this.end.updatePoints();
}
updatePosition() {
this.renderedElement.updatePosition();
}
}

37
js/PElems/Node.ts Normal file
View file

@ -0,0 +1,37 @@
import { svgNodes } from "..";
import { SVGNode } from "../graphics/SVGNode";
import { Positionable } from "../types";
import { Edge } from "./Edge";
export class Node implements Positionable {
renderedElement: SVGNode;
x: number = 0;
y: number = 0;
name: string;
capacity = 1;
marks = 0;
updateList: Edge[] = [];
constructor(name, x, y) {
this.name = name;
this.x = x;
this.y = y;
this.renderedElement = new SVGNode(this);
this.renderedElement.appendIt(svgNodes);
this.renderedElement.onMove((event) => this.updatePosition(event.x, event.y));
}
updatePoints() {
this.renderedElement.setMarks(this.marks, this.capacity);
}
updatePosition(x: number, y: number) {
this.x = x;
this.y = y;
this.renderedElement.translate(x, y);
for (const elem of this.updateList) {
elem.updatePosition();
}
}
}

58
js/PElems/Transition.ts Normal file
View file

@ -0,0 +1,58 @@
import { svgNodes } from "..";
import { SVGTRansition } from "../graphics/SVGTransition";
import { Positionable } from "../types";
import { Edge } from "./Edge";
export class Transition implements Positionable {
renderedElement: SVGTRansition;
name = "noname";
inEdges: Edge[] = [];
outEdges: Edge[] = [];
x: number;
y: number;
constructor(name: string, x: number, y: number) {
this.name = name;
this.x = x;
this.y = y;
this.renderedElement = new SVGTRansition(this);
this.renderedElement.appendIt(svgNodes);
this.renderedElement.onMove((event) => this.updatePosition(event.x, event.y));
}
canFire() {
for (const inE of this.inEdges) {
if (!inE.canSuck()) {
this.renderedElement.setCanFire(false);
return false;
}
}
for (const outE of this.outEdges) {
if (!outE.canPush()) {
this.renderedElement.setCanFire(false);
return false;
}
}
this.renderedElement.setCanFire(true);
return true;
}
fire() {
if (!this.canFire()) return false;
for (const inE of this.inEdges) {
inE.suck();
}
for (const outE of this.outEdges) {
outE.push();
}
return true;
}
updatePosition(x: number, y: number) {
this.x = x;
this.y = y;
this.renderedElement.translate(x, y);
for (const inE of this.inEdges) {
inE.updatePosition();
}
for (const outE of this.outEdges) {
outE.updatePosition();
}
}
}

46
js/graphics/SVGArrow.ts Normal file
View file

@ -0,0 +1,46 @@
import { HTMLappendIt, Positionable, svgNamespace } from "../types";
export class SVGArrow implements HTMLappendIt {
group;
lineText;
line;
from: Positionable;
to: Positionable;
constructor(from: Positionable, to: Positionable) {
this.from = from;
this.to = to;
this.group = document.createElementNS(svgNamespace, 'g');
this.group.classList.add("PEdge");
this.line = document.createElementNS(svgNamespace, 'line');
this.line.setAttribute('marker-end', "url(#arrowhead)");
this.group.setAttribute('transform', `translate(0, 0)`);
// Create the text inside the circle
this.lineText = document.createElementNS(svgNamespace, 'text');
this.lineText.classList.add("lineText");
this.lineText.setAttribute('x', '0');
this.lineText.setAttribute('y', '0');
this.lineText.textContent = "";
this.group.appendChild(this.line);
this.group.appendChild(this.lineText);
this.updatePosition();
}
updatePosition() {
let dx = this.to.x - this.from.x;
let dy = this.to.y - this.from.y;
let l = Math.sqrt(dx * dx + dy * dy);
dx /= l;
dy /= l;
this.line.setAttribute('x1', this.from.x + dx * 30);
this.line.setAttribute('y1', this.from.y + dy * 30);
this.line.setAttribute('x2', this.to.x - dx * 40);
this.line.setAttribute('y2', this.to.y - dy * 40);
}
appendIt(svg) {
svg.appendChild(this.group);
}
}

56
js/graphics/SVGNode.ts Normal file
View file

@ -0,0 +1,56 @@
import { HTMLappendIt, svgNamespace } from "../types";
import { Tragable } from "./tragable";
export class SVGNode extends Tragable implements HTMLappendIt {
group;
circle;
circleText;
aboveText;
constructor(node) {
super();
// Create the group element
this.group = document.createElementNS(svgNamespace, 'g');
this.group.classList.add("PNode");
this.group.setAttribute('transform', `translate(${node.x}, ${node.y})`);
// Create the circle
this.circle = document.createElementNS(svgNamespace, 'circle');
this.circle.setAttribute('cx', '0');
this.circle.setAttribute('cy', '0');
this.circle.setAttribute('r', '25');
// Create the text inside the circle
this.circleText = document.createElementNS(svgNamespace, 'text');
this.circleText.classList.add("circleText");
this.circleText.setAttribute('x', '0');
this.circleText.setAttribute('y', '5');
this.circleText.textContent = '0/1';
// Create the text above the circle
this.aboveText = document.createElementNS(svgNamespace, 'text');
this.aboveText.classList.add("aboveText");
this.aboveText.setAttribute('x', '0');
this.aboveText.setAttribute('y', '-35');
this.aboveText.textContent = node.name;
// Append the circle and texts to the group
this.group.appendChild(this.circle);
this.group.appendChild(this.circleText);
this.group.appendChild(this.aboveText);
}
appendIt(svg) {
svg.appendChild(this.group);
this.initTrag(this.group);
}
translate(x, y) {
this.group.setAttribute('transform', `translate(${x}, ${y})`);
}
setName(name) {
this.aboveText.textContent = name;
}
setMarks(amount, max) {
this.circleText.textContent = `${amount}/${max}`;
}
}

View file

@ -0,0 +1,50 @@
import { HTMLappendIt, svgNamespace } from "../types";
import { Tragable } from "./tragable";
export class SVGTRansition extends Tragable implements HTMLappendIt {
group;
rect;
rectText;
constructor(trans) {
super();
// Create the group element
this.group = document.createElementNS(svgNamespace, 'g');
this.group.classList.add("PTransition");
this.group.setAttribute('transform', `translate(${trans.x}, ${trans.y})`);
// Create the circle
this.rect = document.createElementNS(svgNamespace, 'rect');
this.rect.setAttribute('x', '-12.5');
this.rect.setAttribute('y', '-25');
this.rect.setAttribute('height', '50');
this.rect.setAttribute('width', '25');
// Create the text inside the circle
this.rectText = document.createElementNS(svgNamespace, 'text');
this.rectText.classList.add("rectText");
this.rectText.setAttribute('x', '-5');
this.rectText.setAttribute('y', '-35');
this.rectText.textContent = trans.name;
// Append the circle and texts to the group
this.group.appendChild(this.rect);
this.group.appendChild(this.rectText);
}
appendIt(svg: SVGElement) {
svg.appendChild(this.group);
this.initTrag(this.group);
}
translate(x: number, y: number) {
this.group.setAttribute('transform', `translate(${x}, ${y})`);
}
setName(name: string) {
this.rectText.textContent = name;
}
setCanFire(can: boolean) {
if (can) this.group.classList.add("canFire");
else this.group.classList.remove("canFire");
}
}

38
js/graphics/tragable.ts Normal file
View file

@ -0,0 +1,38 @@
export class Tragable {
static getRootSVG(elem: SVGElement): SVGSVGElement {
while (!(elem instanceof SVGSVGElement)) {
if (!(elem instanceof SVGElement)) throw new Error("Not in an SVG");
elem = elem.parentElement as any;
}
return elem;
}
#moveCB: (event: MouseEvent) => any = () => { };
#clickCB: (event: MouseEvent) => any = () => { };
initTrag(element: SVGElement) {
let svg = Tragable.getRootSVG(element);
let selected = false;
element.addEventListener('mousedown', () => {
selected = true;
});
svg.addEventListener('mousemove', event => {
if (selected) this.#moveCB(event);
});
svg.addEventListener('mouseup', () => {
selected = false;
});
svg.addEventListener('mouseleave', event => {
selected = false;
});
svg.addEventListener('click', event => {
if (!selected) this.#clickCB(event);
});
}
onMove(cb) {
this.#moveCB = cb;
}
onClick(cb) {
this.#clickCB = cb;
}
}

47
js/index.ts Normal file
View file

@ -0,0 +1,47 @@
import { Edge } from "./PElems/Edge";
import { Transition } from "./PElems/Transition";
import { Node } from "./PElems/Node";
import { svgNamespace } from "./types";
export let svg = document.querySelector("svg") as SVGSVGElement;
export let svgNodes = document.createElementNS(svgNamespace, 'g') as SVGSVGElement;
export let svgArrows = document.createElementNS(svgNamespace, 'g') as SVGSVGElement;
svg.appendChild(svgArrows);
svg.appendChild(svgNodes);
let transitions: Transition[] = [];
let nodes: Node[] = [];
function loop() {
for (const trans of transitions) {
console.log(trans.name, trans.fire());
}
update();
}
function update() {
for (const nod of nodes) {
nod.updatePoints();
}
for (const trans of transitions) {
trans.canFire();
}
}
window.onresize = () => {
svg.setAttribute("viewBox", `0 0 ${window.innerWidth} ${window.innerHeight}`);
}
window.onresize(null as any);
let n1 = new Node("n1", 100, 100);
let n2 = new Node("n2", 100, 300);
let t1 = new Transition("t1", 100, 200);
t1.inEdges.push(new Edge(n1, t1, true))
t1.outEdges.push(new Edge(n2, t1, false));
nodes.push(n1, n2);
transitions.push(t1);

10
js/types.ts Normal file
View file

@ -0,0 +1,10 @@
export interface Positionable {
x: number;
y: number;
}
export interface HTMLappendIt {
appendIt(svg: SVGElement): void;
}
export const svgNamespace = 'http://www.w3.org/2000/svg';

160
main.js
View file

@ -1,160 +0,0 @@
let svg = document.querySelector("svg");
let nods = document.createElementNS(svgNamespace, 'g');
let arrows = document.createElementNS(svgNamespace, 'g');
svg.appendChild(arrows);
svg.appendChild(nods);
class Edge {
renderedElement;
end;
trans;
inEdge;
dimension = 1;
constructor(end, trans, inEdge = true) {
this.end = end;
this.trans = trans;
this.inEdge = inEdge;
this.renderedElement = inEdge ? new SVGArrow(end, trans) : new SVGArrow(trans, end);
this.renderedElement.appendIt(arrows);
end.updateList.push(this);
}
canSuck() {
return this.end.marks >= this.dimension;
}
suck() {
this.end.marks -= this.dimension;
this.end.updatePoints();
}
canPush() {
return this.end.capacity >= this.end.marks + this.dimension;
}
push() {
this.end.marks += this.dimension;
this.end.updatePoints();
}
updatePosition() {
this.renderedElement.updatePosition();
}
}
class Node {
renderedElement;
x = 0;
y = 0;
name;
capacity = 1;
marks = 0;
updateList = [];
constructor(name, x, y) {
this.name = name;
this.x = x;
this.y = y;
this.renderedElement = new SVGNode(this);
this.renderedElement.appendIt(nods);
}
updatePoints() {
this.renderedElement.setMarks(this.marks, this.capacity);
}
updatePosition(x, y) {
this.x = x;
this.y = y;
this.renderedElement.translate(x, y);
for (const elem of this.updateList) {
elem.updatePosition();
}
}
}
class Transition {
renderedElement;
name = "noname";
inEdges = [];
outEdges = [];
x;
y;
constructor(name, x, y) {
this.name = name;
this.x = x;
this.y = y;
this.renderedElement = new SVGTRansition(this);
this.renderedElement.appendIt(nods);
}
canFire() {
for (const inE of this.inEdges) {
if (!inE.canSuck()) {
this.renderedElement.setCanFire(false);
return false;
}
}
for (const outE of this.outEdges) {
if (!outE.canPush()) {
this.renderedElement.setCanFire(false);
return false;
}
}
this.renderedElement.setCanFire(true);
return true;
}
fire() {
if (!this.canFire()) return false;
for (const inE of this.inEdges) {
inE.suck();
}
for (const outE of this.outEdges) {
outE.push();
}
return true;
}
updatePosition(x, y) {
this.x = x;
this.y = y;
this.renderedElement.translate(x, y);
for (const inE of this.inEdges) {
inE.updatePosition();
}
for (const outE of this.outEdges) {
outE.updatePosition();
}
}
}
let transitions = [];
let nodes = [];
function loop() {
for (const trans of transitions) {
console.log(trans.name, trans.fire());
}
update();
}
function update() {
for (const nod of nodes) {
nod.updatePoints();
}
for (const trans of transitions) {
trans.canFire();
}
}
window.onresize = () => {
svg.setAttribute("viewBox", `0 0 ${window.innerWidth} ${window.innerHeight}`);
}
window.onresize();
let n1 = new Node("n1", 100, 100);
let n2 = new Node("n2", 100, 300);
let t1 = new Transition("t1", 100, 200);
t1.inEdges.push(new Edge(n1, t1, true))
t1.outEdges.push(new Edge(n2, t1, false));
nodes.push(n1, n2);
transitions.push(t1);

405
package-lock.json generated Normal file
View file

@ -0,0 +1,405 @@
{
"name": "pnet",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "pnet",
"version": "1.0.0",
"license": "ISC",
"devDependencies": {
"esbuild": "^0.18.6"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.6.tgz",
"integrity": "sha512-J3lwhDSXBBppSzm/LC1uZ8yKSIpExc+5T8MxrYD9KNVZG81FOAu2VF2gXi/6A/LwDDQQ+b6DpQbYlo3VwxFepQ==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.6.tgz",
"integrity": "sha512-pL0Ci8P9q1sWbtPx8CXbc8JvPvvYdJJQ+LO09PLFsbz3aYNdFBGWJjiHU+CaObO4Ames+GOFpXRAJZS2L3ZK/A==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.6.tgz",
"integrity": "sha512-hE2vZxOlJ05aY28lUpB0y0RokngtZtcUB+TVl9vnLEnY0z/8BicSvrkThg5/iI1rbf8TwXrbr2heEjl9fLf+EA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.6.tgz",
"integrity": "sha512-/tuyl4R+QhhoROQtuQj9E/yfJtZNdv2HKaHwYhhHGQDN1Teziem2Kh7BWQMumfiY7Lu9g5rO7scWdGE4OsQ6MQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.6.tgz",
"integrity": "sha512-L7IQga2pDT+14Ti8HZwsVfbCjuKP4U213T3tuPggOzyK/p4KaUJxQFXJgfUFHKzU0zOXx8QcYRYZf0hSQtppkw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.6.tgz",
"integrity": "sha512-bq10jFv42V20Kk77NvmO+WEZaLHBKuXcvEowixnBOMkaBgS7kQaqTc77ZJDbsUpXU3KKNLQFZctfaeINmeTsZA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.6.tgz",
"integrity": "sha512-HbDLlkDZqUMBQaiday0pJzB6/8Xx/10dI3xRebJBReOEeDSeS+7GzTtW9h8ZnfB7/wBCqvtAjGtWQLTNPbR2+g==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.6.tgz",
"integrity": "sha512-C+5kb6rgsGMmvIdUI7v1PPgC98A6BMv233e97aXZ5AE03iMdlILFD/20HlHrOi0x2CzbspXn9HOnlE4/Ijn5Kw==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.6.tgz",
"integrity": "sha512-NMY9yg/88MskEZH2s4i6biz/3av+M8xY5ua4HE7CCz5DBz542cr7REe317+v7oKjnYBCijHpkzo5vU85bkXQmQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.6.tgz",
"integrity": "sha512-AXazA0ljvQEp7cA9jscABNXsjodKbEcqPcAE3rDzKN82Vb3lYOq6INd+HOCA7hk8IegEyHW4T72Z7QGIhyCQEA==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.6.tgz",
"integrity": "sha512-JjBf7TwY7ldcPgHYt9UcrjZB03+WZqg/jSwMAfzOzM5ZG+tu5umUqzy5ugH/crGI4eoDIhSOTDp1NL3Uo/05Fw==",
"cpu": [
"loong64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.6.tgz",
"integrity": "sha512-kATNsslryVxcH1sO3KP2nnyUWtZZVkgyhAUnyTVVa0OQQ9pmDRjTpHaE+2EQHoCM5wt/uav2edrAUqbwn3tkKQ==",
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.6.tgz",
"integrity": "sha512-B+wTKz+8pi7mcWXFQV0LA79dJ+qhiut5uK9q0omoKnq8yRIwQJwfg3/vclXoqqcX89Ri5Y5538V0Se2v5qlcLA==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.6.tgz",
"integrity": "sha512-h44RBLVXFUSjvhOfseE+5UxQ/r9LVeqK2S8JziJKOm9W7SePYRPDyn7MhzhNCCFPkcjIy+soCxfhlJXHXXCR0A==",
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.6.tgz",
"integrity": "sha512-FlYpyr2Xc2AUePoAbc84NRV+mj7xpsISeQ36HGf9etrY5rTBEA+IU9HzWVmw5mDFtC62EQxzkLRj8h5Hq85yOQ==",
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.6.tgz",
"integrity": "sha512-Mc4EUSYwzLci77u0Kao6ajB2WbTe5fNc7+lHwS3a+vJISC/oprwURezUYu1SdWAYoczbsyOvKAJwuNftoAdjjg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.6.tgz",
"integrity": "sha512-3hgZlp7NqIM5lNG3fpdhBI5rUnPmdahraSmwAi+YX/bp7iZ7mpTv2NkypGs/XngdMtpzljICxnUG3uPfqLFd3w==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.6.tgz",
"integrity": "sha512-aEWTdZQHtSRROlDYn7ygB8yAqtnall/UnmoVIJVqccKitkAWVVSYocQUWrBOxLEFk8XdlRouVrLZe6WXszyviA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.6.tgz",
"integrity": "sha512-uxk/5yAGpjKZUHOECtI9W+9IcLjKj+2m0qf+RG7f7eRBHr8wP6wsr3XbNbgtOD1qSpPapd6R2ZfSeXTkCcAo5g==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.6.tgz",
"integrity": "sha512-oXlXGS9zvNCGoAT/tLHAsFKrIKye1JaIIP0anCdpaI+Dc10ftaNZcqfLzEwyhdzFAYInXYH4V7kEdH4hPyo9GA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.6.tgz",
"integrity": "sha512-qh7IcAHUvvmMBmoIG+V+BbE9ZWSR0ohF51e5g8JZvU08kZF58uDFL5tHs0eoYz31H6Finv17te3W3QB042GqVA==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.6.tgz",
"integrity": "sha512-9UDwkz7Wlm4N9jnv+4NL7F8vxLhSZfEkRArz2gD33HesAFfMLGIGNVXRoIHtWNw8feKsnGly9Hq1EUuRkWl0zA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/esbuild": {
"version": "0.18.6",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.6.tgz",
"integrity": "sha512-5QgxWaAhU/tPBpvkxUmnFv2YINHuZzjbk0LeUUnC2i3aJHjfi5yR49lgKgF7cb98bclOp/kans8M5TGbGFfJlQ==",
"dev": true,
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=12"
},
"optionalDependencies": {
"@esbuild/android-arm": "0.18.6",
"@esbuild/android-arm64": "0.18.6",
"@esbuild/android-x64": "0.18.6",
"@esbuild/darwin-arm64": "0.18.6",
"@esbuild/darwin-x64": "0.18.6",
"@esbuild/freebsd-arm64": "0.18.6",
"@esbuild/freebsd-x64": "0.18.6",
"@esbuild/linux-arm": "0.18.6",
"@esbuild/linux-arm64": "0.18.6",
"@esbuild/linux-ia32": "0.18.6",
"@esbuild/linux-loong64": "0.18.6",
"@esbuild/linux-mips64el": "0.18.6",
"@esbuild/linux-ppc64": "0.18.6",
"@esbuild/linux-riscv64": "0.18.6",
"@esbuild/linux-s390x": "0.18.6",
"@esbuild/linux-x64": "0.18.6",
"@esbuild/netbsd-x64": "0.18.6",
"@esbuild/openbsd-x64": "0.18.6",
"@esbuild/sunos-x64": "0.18.6",
"@esbuild/win32-arm64": "0.18.6",
"@esbuild/win32-ia32": "0.18.6",
"@esbuild/win32-x64": "0.18.6"
}
}
}
}

19
package.json Normal file
View file

@ -0,0 +1,19 @@
{
"name": "pnet",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"serve": "esbuild ./js/index.js --loader:.html=text --bundle --minify --outdir=html --servedir=html --sourcemap",
"build": "mkdir -p build && cp html/* build -r && esbuild ./js/index.js --loader:.html=text --bundle --minify --outdir=build"
},
"repository": {
"type": "git",
"url": "https://jusax.de/git/jusax23/PNet"
},
"author": "jusax23",
"license": "ISC",
"devDependencies": {
"esbuild": "^0.18.6"
}
}

20
tsconfig.json Normal file
View file

@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "node",
"declaration": true,
"outDir": "./dist",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
"files": [
"js/main.ts"
],
"exclude": [
"node_modules",
"dist"
]
}