From c1c6e145a03f26ba8ff73320556adb742e9764d1 Mon Sep 17 00:00:00 2001
From: sfja <sfja2004@gmail.com>
Date: Tue, 6 May 2025 13:11:24 +0200
Subject: [PATCH] add deno web project

---
 .gitignore         |   2 +
 bundle.ts          |  51 ++++++++++++++++++
 deno.jsonc         |  13 +++++
 deno.lock          | 128 +++++++++++++++++++++++++++++++++++++++++++++
 src/main.ts        |   9 ++++
 static/favicon.ico | Bin 0 -> 16958 bytes
 static/index.html  |  13 +++++
 static/style.css   |  11 ++++
 8 files changed, 227 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 bundle.ts
 create mode 100644 deno.jsonc
 create mode 100644 deno.lock
 create mode 100644 src/main.ts
 create mode 100644 static/favicon.ico
 create mode 100644 static/index.html
 create mode 100644 static/style.css

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..dc84959
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+build/
+
diff --git a/bundle.ts b/bundle.ts
new file mode 100644
index 0000000..2cc8a6a
--- /dev/null
+++ b/bundle.ts
@@ -0,0 +1,51 @@
+import * as esbuild from "npm:esbuild@0.20.2";
+import { denoPlugins } from "jsr:@luca/esbuild-deno-loader@^0.11.0";
+
+async function buildCode() {
+    await esbuild.build({
+        plugins: [...denoPlugins()],
+        entryPoints: ["./src/main.ts"],
+        outfile: "./build/bundle.js",
+        bundle: true,
+        format: "esm",
+    });
+
+    esbuild.stop();
+}
+
+async function copyStatic(path: string[] = []) {
+    const dir = path.join("/");
+    await Deno.mkdir("build/" + dir).catch((_) => _);
+    for await (const file of Deno.readDir(`static/${dir}`)) {
+        if (file.isDirectory) {
+            await copyStatic([...path, file.name]);
+            continue;
+        }
+        await Deno.copyFile(
+            `static/${dir}/${file.name}`,
+            `build/${dir}/${file.name}`,
+        );
+    }
+}
+
+type BundleOptions = {
+    quiet?: boolean;
+};
+
+export async function bundle(options?: BundleOptions) {
+    if (!options?.quiet) {
+        console.log("info: copying static files");
+    }
+    await copyStatic();
+    if (!options?.quiet) {
+        console.log("info: building code");
+    }
+    await buildCode();
+    if (!options?.quiet) {
+        console.log("success: output in 'build/'");
+    }
+}
+
+if (import.meta.main) {
+    await bundle();
+}
diff --git a/deno.jsonc b/deno.jsonc
new file mode 100644
index 0000000..db44517
--- /dev/null
+++ b/deno.jsonc
@@ -0,0 +1,13 @@
+{
+    "tasks": {
+        "bundle": "deno run --allow-read --allow-write --allow-env --allow-run bundle.ts",
+        "dev": "deno run --allow-net --allow-read --allow-write --allow-env --allow-run dev.ts"
+    },
+    "compilerOptions": {
+        "lib": ["dom", "dom.iterable", "dom.asynciterable", "deno.ns"]
+    },
+    "fmt": {
+        "indentWidth": 4
+    }
+}
+
diff --git a/deno.lock b/deno.lock
new file mode 100644
index 0000000..571acf6
--- /dev/null
+++ b/deno.lock
@@ -0,0 +1,128 @@
+{
+  "version": "4",
+  "specifiers": {
+    "jsr:@luca/esbuild-deno-loader@0.11": "0.11.1",
+    "jsr:@std/bytes@^1.0.2": "1.0.4",
+    "jsr:@std/encoding@^1.0.5": "1.0.5",
+    "jsr:@std/path@^1.0.6": "1.0.8",
+    "npm:esbuild@0.20.2": "0.20.2"
+  },
+  "jsr": {
+    "@luca/esbuild-deno-loader@0.11.1": {
+      "integrity": "dc020d16d75b591f679f6b9288b10f38bdb4f24345edb2f5732affa1d9885267",
+      "dependencies": [
+        "jsr:@std/bytes",
+        "jsr:@std/encoding",
+        "jsr:@std/path"
+      ]
+    },
+    "@std/bytes@1.0.4": {
+      "integrity": "11a0debe522707c95c7b7ef89b478c13fb1583a7cfb9a85674cd2cc2e3a28abc"
+    },
+    "@std/encoding@1.0.5": {
+      "integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04"
+    },
+    "@std/path@1.0.8": {
+      "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be"
+    }
+  },
+  "npm": {
+    "@esbuild/aix-ppc64@0.20.2": {
+      "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g=="
+    },
+    "@esbuild/android-arm64@0.20.2": {
+      "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg=="
+    },
+    "@esbuild/android-arm@0.20.2": {
+      "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w=="
+    },
+    "@esbuild/android-x64@0.20.2": {
+      "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg=="
+    },
+    "@esbuild/darwin-arm64@0.20.2": {
+      "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA=="
+    },
+    "@esbuild/darwin-x64@0.20.2": {
+      "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA=="
+    },
+    "@esbuild/freebsd-arm64@0.20.2": {
+      "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw=="
+    },
+    "@esbuild/freebsd-x64@0.20.2": {
+      "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw=="
+    },
+    "@esbuild/linux-arm64@0.20.2": {
+      "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A=="
+    },
+    "@esbuild/linux-arm@0.20.2": {
+      "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg=="
+    },
+    "@esbuild/linux-ia32@0.20.2": {
+      "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig=="
+    },
+    "@esbuild/linux-loong64@0.20.2": {
+      "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ=="
+    },
+    "@esbuild/linux-mips64el@0.20.2": {
+      "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA=="
+    },
+    "@esbuild/linux-ppc64@0.20.2": {
+      "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg=="
+    },
+    "@esbuild/linux-riscv64@0.20.2": {
+      "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg=="
+    },
+    "@esbuild/linux-s390x@0.20.2": {
+      "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ=="
+    },
+    "@esbuild/linux-x64@0.20.2": {
+      "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw=="
+    },
+    "@esbuild/netbsd-x64@0.20.2": {
+      "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ=="
+    },
+    "@esbuild/openbsd-x64@0.20.2": {
+      "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ=="
+    },
+    "@esbuild/sunos-x64@0.20.2": {
+      "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w=="
+    },
+    "@esbuild/win32-arm64@0.20.2": {
+      "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ=="
+    },
+    "@esbuild/win32-ia32@0.20.2": {
+      "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ=="
+    },
+    "@esbuild/win32-x64@0.20.2": {
+      "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ=="
+    },
+    "esbuild@0.20.2": {
+      "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
+      "dependencies": [
+        "@esbuild/aix-ppc64",
+        "@esbuild/android-arm",
+        "@esbuild/android-arm64",
+        "@esbuild/android-x64",
+        "@esbuild/darwin-arm64",
+        "@esbuild/darwin-x64",
+        "@esbuild/freebsd-arm64",
+        "@esbuild/freebsd-x64",
+        "@esbuild/linux-arm",
+        "@esbuild/linux-arm64",
+        "@esbuild/linux-ia32",
+        "@esbuild/linux-loong64",
+        "@esbuild/linux-mips64el",
+        "@esbuild/linux-ppc64",
+        "@esbuild/linux-riscv64",
+        "@esbuild/linux-s390x",
+        "@esbuild/linux-x64",
+        "@esbuild/netbsd-x64",
+        "@esbuild/openbsd-x64",
+        "@esbuild/sunos-x64",
+        "@esbuild/win32-arm64",
+        "@esbuild/win32-ia32",
+        "@esbuild/win32-x64"
+      ]
+    }
+  }
+}
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..afb0a6d
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,9 @@
+const c = document.querySelector<HTMLCanvasElement>("canvas#editor")!;
+const g = c.getContext("2d")!;
+
+c.width = document.body.clientWidth;
+c.height = document.body.clientHeight;
+c.style.position = "absolute";
+
+g.fillStyle = "#aa2233";
+g.fillRect(0, 0, c.width, c.height);
diff --git a/static/favicon.ico b/static/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..4a61c86e18bc601596b2098ac908231c5ca39df7
GIT binary patch
literal 16958
zcmeHNJx>EM3{59k5F0CuUD()*koX%&to#Ys_$3I59VRwLMg}T%sQNjx(E%Eq!U+?S
zb8@++M|p>?$=QzW_v}lLwo0|=@9<F3>z-;KDYc`NYST#~bwQ_*;{XF-01SWuFaQR?
zKrRMGqmkyP6qjsYxqZLi-;~xgS<kVUxs)sLqyD^S(ErW7|9idO2G#0jI2`tUC$FWM
z`|Jui*}Pk828GTsK1`?618GlLhMsacwetM2&*#)pE|1H===0g_cDHik3yDP>ocZ#t
zTTc00h2)gmrf!@*e}wCaW1CDS$FxuH<vw{1X70<kZaKwz=CKL4`M4?j!E*q9)IV1P
zqW^LK^Sx)C_dkx)H*X4lSAMB`g3G5ZlknU2q1RIGA$}wul0GB`@RvXTgmCDxsiQWM
zk1Be~HR}1#g)KxT<!1Yk?Ca8};`ikdizn9J7dKW8{AvB~<2$yVvG%^Wv2xTO_2<18
z`~L6iH}2ESeRhRB*1lMmI#S$!^ZsXZ?7EJvzsrY9Ce_Kc#+FGwB)#p=bq)OM`~2&w
zw=I+EFZEbey`6{ax~lK8brdIR|10yAqO<X)_=;Hz{HQ<gy{6p%F+H4Oi~dLd|L6Xv
z@7nJ;{-(@R?&+Adgm=Fwm{}gTF&I*9DegUsy|UlFeC04t#ZzVdcsxE?H3yW#b(P$6
zt+Dx$;*$L<UqjCp`2DLyT7&hxmS!%ciu$AfdC&ay`(NsJ=)nLO00UqE41j_B4CwS@
z`{jJ$q<mcbhf0QT24hF-nHhH-BkATw9yl6bbEUQFT(n%{%*Yr1E(dYr=Q^L?B5r7&
Uzw9jh1uq3pT9@<rt=B2X2Z<(FkpKVy

literal 0
HcmV?d00001

diff --git a/static/index.html b/static/index.html
new file mode 100644
index 0000000..d51da97
--- /dev/null
+++ b/static/index.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en-US">
+    <head>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <link rel="stylesheet" href="style.css">
+        <script src="bundle.js" defer></script>
+        <title>LogiCirc</title>
+    </head>
+    <body>
+        <canvas id="editor"></canvas>
+    </body>
+</html>
diff --git a/static/style.css b/static/style.css
new file mode 100644
index 0000000..013f9dd
--- /dev/null
+++ b/static/style.css
@@ -0,0 +1,11 @@
+:root {
+    color-scheme: light dark;
+}
+
+body {
+    margin: 0;
+    height: 100vh;
+}
+
+
+