typing update!!!
This commit is contained in:
parent
e1ce0e4ae2
commit
6e5baec8f8
12 changed files with 1725 additions and 454 deletions
60
css/base.css
60
css/base.css
|
@ -25,6 +25,7 @@ html[data-light] { --rosewater: #dc8a78; --flamingo: #dd7878; --pink: #ea76cb; -
|
||||||
text-decoration-color: var(--base);
|
text-decoration-color: var(--base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.red { color: var(--red); }
|
||||||
.green { color: var(--green); }
|
.green { color: var(--green); }
|
||||||
.blue { color: var(--blue); }
|
.blue { color: var(--blue); }
|
||||||
.pink { color: var(--pink); }
|
.pink { color: var(--pink); }
|
||||||
|
@ -38,14 +39,10 @@ a:focus {
|
||||||
outline: 1px solid var(--pink);
|
outline: 1px solid var(--pink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.red::selection, .red ::selection { background-color: var(--red); }
|
||||||
.green::selection, .green ::selection { background-color: var(--green); }
|
.green::selection, .green ::selection { background-color: var(--green); }
|
||||||
.blue::selection, .blue ::selection { background-color: var(--blue); }
|
.blue::selection, .blue ::selection { background-color: var(--blue); }
|
||||||
|
|
||||||
.cursor::selection {
|
|
||||||
color: var(--text);
|
|
||||||
background-color: var(--text);
|
|
||||||
}
|
|
||||||
|
|
||||||
a:link::selection,
|
a:link::selection,
|
||||||
a:visited::selection,
|
a:visited::selection,
|
||||||
.pink::selection,
|
.pink::selection,
|
||||||
|
@ -58,12 +55,15 @@ a:visited ::selection,
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: "Ubuntu Mono";
|
font-family: "Ubuntu Mono";
|
||||||
min-height: calc(100vh + 40px);
|
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body:has(footer) {
|
||||||
|
min-height: calc(100vh + 40px);
|
||||||
|
}
|
||||||
|
|
||||||
noscript {
|
noscript {
|
||||||
color: var(--red);
|
color: var(--red);
|
||||||
}
|
}
|
||||||
|
@ -89,8 +89,17 @@ header > nav {
|
||||||
}
|
}
|
||||||
|
|
||||||
.cursor {
|
.cursor {
|
||||||
color: var(--text);
|
color: var(--crust);
|
||||||
background-color: var(--text);
|
background-color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cursor::selection {
|
||||||
|
color: var(--text) !important;
|
||||||
|
background-color: transparent !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-container:focus .cursor,
|
||||||
|
.window-container:focus-within .cursor {
|
||||||
animation: cursor-blink 1s infinite;
|
animation: cursor-blink 1s infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,10 +108,25 @@ pre {
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes cursor-blink {
|
@keyframes cursor-blink {
|
||||||
0% { opacity: 100%; }
|
0% {
|
||||||
50% { opacity: 100%; }
|
background-color: var(--text);
|
||||||
50.001% { opacity: 0%; }
|
color: var(--crust);
|
||||||
100% { opacity: 0%; }
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
background-color: var(--text);
|
||||||
|
color: var(--crust);
|
||||||
|
}
|
||||||
|
|
||||||
|
50.001% {
|
||||||
|
background-color: transparent;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-color: transparent;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-title {
|
.header-title {
|
||||||
|
@ -140,6 +164,20 @@ pre {
|
||||||
transition: border-color 0.1s;
|
transition: border-color 0.1s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.window-input {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-type-area] {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
.window-outer {
|
.window-outer {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
BIN
img/favicon.png
Normal file
BIN
img/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 MiB |
223
index.html
223
index.html
|
@ -4,6 +4,7 @@
|
||||||
<head>
|
<head>
|
||||||
<title>trinkey's website!!!</title>
|
<title>trinkey's website!!!</title>
|
||||||
<link rel="stylesheet" href="css/base.css">
|
<link rel="stylesheet" href="css/base.css">
|
||||||
|
<link rel="icon" href="img/favicon.png">
|
||||||
|
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
<meta property="og:description" content="meoww :3">
|
<meta property="og:description" content="meoww :3">
|
||||||
<meta name="twitter:description" content="meoww :3">
|
<meta name="twitter:description" content="meoww :3">
|
||||||
|
|
||||||
|
<script src="js/shell.js"></script>
|
||||||
<script>
|
<script>
|
||||||
let _themeMM = matchMedia("(prefers-color-scheme: light)");
|
let _themeMM = matchMedia("(prefers-color-scheme: light)");
|
||||||
let light = _themeMM.matches;
|
let light = _themeMM.matches;
|
||||||
|
@ -72,200 +74,37 @@
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<div hidden id="window-templates">
|
<div hidden id="window-templates">
|
||||||
<div data-template-id="about">
|
<ol data-template-id="about">
|
||||||
<div data-template-field="title">~/about</div>
|
<li>cat about-me.txt</li>
|
||||||
<div data-template-field="content">
|
</ol>
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/about</b>$ cat about-me.txt</div>
|
<ol data-template-id="socials">
|
||||||
<div><b>hi there! i'm trinkey!</b></div>
|
<li>cat socials.txt</li>
|
||||||
<div>--------------------</div>
|
</ol>
|
||||||
<div>i'm a silly little kitty cat who lives in the usa.</div>
|
<ol data-template-id="people">
|
||||||
<div>i'm <span class="blue">t</span><span class="pink">r</span>a<span class="pink">n</span><span class="blue">s</span> (she/her, they/them and it/its are also fine) and a bit gay sometimes.</div>
|
<li>cd people</li>
|
||||||
<div>i'm not actively in a relationship, however i'm also not looking to get into one either.</div>
|
<li>cat 88x31.txt</li>
|
||||||
<div>--------------------</div>
|
<li>cat testimonials.txt</li>
|
||||||
<div>i like to code stuff (mostly websites)! some of my programs can be found on the <a href="javascript:windowPreset('projects')">projects page</a>. i know a few languages, those being python, javascript/typescript, html/css (if you count those), and a little bit of java.</div>
|
<li>cat webrings.txt</li>
|
||||||
<div>--------------------</div>
|
</ol>
|
||||||
<div>well, that's about it! i hope you like my website!</div>
|
<ol data-template-id="projects">
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/about</b>$ <i class="cursor">.</i></div>
|
<li>cat projects.txt</li>
|
||||||
</div>
|
</ol>
|
||||||
</div>
|
<ol data-template-id="directory">
|
||||||
<div data-template-id="socials">
|
<li>cat subdomains.txt</li>
|
||||||
<div data-template-field="title">~/socials</div>
|
</ol>
|
||||||
<div data-template-field="content">
|
<ol data-template-id="specs">
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/socials</b>$ cat socials.html</div>
|
<li>_internal_set_ps1 trinkey@desktop|ssh trinkey@desktop<br>Last login: Tue Sep 10 12:00:24 2024 from 192.168.1.254</li>
|
||||||
<div>- fedi - <b>@trinkey@trinkey.com</b> (or @trinkey@is.trinkey.com)</div>
|
<li>_internal_neofetch desktop</li>
|
||||||
<div>- forgejo - <a href="https://git.trinkey.com/trinkey/" target="_blank"><b>trinkey</b></a></div>
|
<li>_internal_set_ps1 trinkey@website|exit</li>
|
||||||
<div>- github - <a href="https://github.com/trinkey/" target="_blank"><b>trinkey</b></a></div>
|
<li>_internal_set_ps1 trinkey@laptop|ssh trinkey@laptop<br>Last login: Tue Sep 11 8:46:40 2001 from 192.168.1.254</li>
|
||||||
<div>- git.gay - <a href="https://git.gay/trinkey/" target="_blank"><b>trinkey</b></a> (inactive)</div>
|
<li>_internal_neofetch laptop</li>
|
||||||
<div>- smiggins - <a href="https://smiggins.trinkey.com/u/trinkey/" target="_blank"><b>trinkey</b></a></div>
|
<li>_internal_set_ps1 trinkey@website|exit</li>
|
||||||
<div>- signal - <b>@trinkey.01</b></div>
|
<li>_internal_set_ps1 trinkey@server|ssh trinkey@server<br>Last login: Tue Sep 11 9:03:02 2001 from 192.168.1.254</li>
|
||||||
<div>- email - <b>trinkey [at] proton [dot] me</b></div>
|
<li>_internal_neofetch server</li>
|
||||||
<div>- youtube - <a href="https://youtube.com/@trinkey" target="_blank"><b>@trinkey</b></a> (inactive)</div>
|
<li>_internal_set_ps1 trinkey@website|exit</li>
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/socials</b>$ <i class="cursor">.</i></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div data-template-id="people">
|
|
||||||
<div data-template-field="title">~/webrings</div>
|
|
||||||
<div data-template-field="content">
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/buttons</b>$ cat 88x31.html</div>
|
|
||||||
<div><b>my button:</b> (click to copy html)</div>
|
|
||||||
<div><img style="cursor: pointer;" src="img/88x31.png" alt="trinkey's 88x31. image of my cat on the right with the word trinkey taking up the rest of the button." title="trinkey's 88x31. image of my cat on the right with the word trinkey taking up the rest of the button." onclick="copyButton()"></div>
|
|
||||||
<div>--------------------</div>
|
|
||||||
<div><b>cool people:</b></div>
|
|
||||||
<div class="buttons-88x31">
|
|
||||||
<a href="https://notfire.cc" target="_blank"><img src="https://notfire.cc/design/images/buttons/notfire-cc-88x31-af.gif" alt="notfire.cc" title="notfire.cc"></a>
|
|
||||||
<a href="https://micro.niko.lgbt" target="_blank"><img src="https://micro.niko.lgbt/static/button_2.png" alt="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro"" title="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro""></a>
|
|
||||||
<a href="https://w.on-t.work" target="_blank"><img src="https://w.on-t.work/assets/88x31.png" alt="kopper's button" title="kopper's button"></a>
|
|
||||||
<a href="https://synth.download" target="_blank"><img src="https://synth.download/assets/buttons/sneexy.svg" alt="Sneexy" title="Sneexy"></a>
|
|
||||||
<a href="https://beepi.ng" target="_blank"><img src="https://beepi.ng/88x31.png" alt="unnick" title="unnick"></a>
|
|
||||||
</div>
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/buttons</b>$ cd ~/testimonials</div>
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/testimonials</b>$ cat testimonials.html</div>
|
|
||||||
<div>"warning: this user is trinkey"</div>
|
|
||||||
<div>- <a href="https://booping.synth.download/@breaadyboy" target="_blank">bread</a></div><br>
|
|
||||||
<div>"This user is only slightly crazy once was I. 10/10 would recommend"</div>
|
|
||||||
<div>- <a href="https://lea.pet/@subroutine" target="_blank">subroutine</a></div><br>
|
|
||||||
<div>"the f slur but repeated 36 times"</div>
|
|
||||||
<div>- <a href="https://oomfie.city/@cornfields74">corn fields seventy four</a></div>
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/testimonials</b>$ cd ~/webrings</div>
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/webrings</b>$ cat rings.html</div>
|
|
||||||
<div>
|
|
||||||
<a href="https://ctp-webr.ing/trinkey/previous">←</a>
|
|
||||||
<a href="https://ctp-webr.ing/">catppuccin webring</a>
|
|
||||||
<a href="https://ctp-webr.ing/trinkey/next">→</a>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a href="https://fediring.net/previous?host=trinkey.com">←</a>
|
|
||||||
<a href="https://fediring.net/">fediring</a>
|
|
||||||
<a href="https://fediring.net/next?host=trinkey.com">→</a>
|
|
||||||
</div>
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/webrings</b>$ <i class="cursor">.</i></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div data-template-id="projects">
|
|
||||||
<div data-template-field="title">~/projects</div>
|
|
||||||
<div data-template-field="content">
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/projects</b>$ cat projects.html</div>
|
|
||||||
<div><b>projects</b> - the things i made</div>
|
|
||||||
<div>- <a href="https://github.com/jerimiah-smiggins/smiggins/" target="_blank"><b>smiggins</b></a> (<a href="https://smiggins.trinkey.com/" target="_blank">website</a>) - a social media platform i made</div>
|
|
||||||
<div>- <a href="https://git.trinkey.com/trinkey/website/" target="_blank"><b>this website</b></a> - check out the code</div>
|
|
||||||
<div>- <a href="https://git.gay/trinkey/dotindex/" target="_blank"><b>dotindex</b></a> (<a href="https://pypi.org/project/DotIndex/" target="_blank">pypi</a>) - a python library that lets you access dicts using the dot notation (dict.key) instead of whatever python does (dict["key"])</div>
|
|
||||||
<div>- <a href="https://git.gay/trinkey/infopage/" target="_blank"><b>infopage</b></a> (<a href="https://infpg.pythonanywhere.com/" target="_blank">website</a>) - my very own pronouns.page clone</div>
|
|
||||||
<div>- <a href="https://git.trinkey.com/t" target="_blank"><b>tSuite</b></a> (<a href="https://auth.trinkey.com/" target="_blank">website</a>) - a collection of services that are all interconnected</div><br>
|
|
||||||
<div>i'll likely add more in the future, these are just the ones i'm most proud of at the moment.</div>
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/projects</b>$ <i class="cursor">.</i></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div data-template-id="directory">
|
|
||||||
<div data-template-field="title">~/dir</div>
|
|
||||||
<div data-template-field="content">
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/dir</b>$ cat subdomains.html</div>
|
|
||||||
<div>there's a lot that goes into this website. here are some links for your usage to help you navigate this hellhole</div><br>
|
|
||||||
<div><b><a href="https://trinkey.com/">trinkey.com</a>:</b></div>
|
|
||||||
<div>this is where you are right now</div><br>
|
|
||||||
<div>*<b><a href="https://akkofe.trinkey.com/">akkofe.trinkey.com</a>:</b></div>
|
|
||||||
<div>the frontend i use for <a href="https://fediverse.info/" target="_blank">fedi</a></div><br>
|
|
||||||
<div><b><a href="https://auth.trinkey.com/">auth.trinkey.com</a>:</b></div>
|
|
||||||
<div>authentication manager for tSuite</div><br>
|
|
||||||
<div><b><a href="https://blog.trinkey.com/">blog.trinkey.com</a>:</b></div>
|
|
||||||
<div>tBlog, from tSuite</div><br>
|
|
||||||
<div><b><a href="https://everyone.trinkey.com/">everyone.trinkey.com</a>:</b></div>
|
|
||||||
<div>frontend to a fedi bot that anyone can post to (@everyonebot@is.trinkey.com)</div><br>
|
|
||||||
<div>*<b><a href="https://git.trinkey.com/">git.trinkey.com</a>:</b></div>
|
|
||||||
<div>holds some of my git projects (older ones on <a href="https://github.com/trinkey/" target="_blank">github</a> or <a href="https://git.gay/trinkey/" target="_blank">git.gay</a>)</div><br>
|
|
||||||
<div>*<b><a href="https://is.trinkey.com/">is.trinkey.com</a>:</b></div>
|
|
||||||
<div>hosts <a href="https://iceshrimp.dev/iceshrimp/iceshrimp.net" target="_blank">iceshrimp.net</a>, which is the fedi backend i use</div><br>
|
|
||||||
<div><b><a href="https://message.trinkey.com/">message.trinkey.com</a>:</b></div>
|
|
||||||
<div>tMessage, from tSuite</div><br>
|
|
||||||
<div><b><a href="https://music.trinkey.com/">music.trinkey.com</a>:</b></div>
|
|
||||||
<div>has some music. i haven't actually updated the site in a while but i've been meaning to do rewrite it at some point. 100% legal i pinky promise</div><br>
|
|
||||||
<div><b><a href="https://smiggins.trinkey.com/">smiggins.trinkey.com</a>:</b></div>
|
|
||||||
<div>official jerimiah smiggins instance, that being my own social media platform</div><br>
|
|
||||||
<div>(asterisk (*) means i haven't written the code for it)</div><br>
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~/dir</b>$ <i class="cursor">.</i></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div data-template-id="specs">
|
|
||||||
<div data-template-field="title">~</div>
|
|
||||||
<div data-template-field="content">
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~</b>$ ssh trinkey@desktop</div>
|
|
||||||
<div>Last login: Tue Sep 11 8:46:40 2001 from 192.168.1.254</div>
|
|
||||||
<div><b class="green">trinkey@desktop</b>:<b class="blue">~</b>$ neofetch</div>
|
|
||||||
|
|
||||||
<pre> <b>...-:::::-...</b> <b class="green">trinkey</b>@<b class="green">desktop</b>
|
|
||||||
<b>.-MMMMMMMMMMMMMMM-.</b> ---------------
|
|
||||||
<b>.-MMMM<span class="green">`..-:::::::-..`</span>MMMM-.</b> <b class="green">OS</b>: Linux Mint 21.3 x86_64
|
|
||||||
<b>.:MMMM<span class="green">.:MMMMMMMMMMMMMMM:.</span>MMMM:.</b> <b class="green">Host</b>: MS-7E27 1.0
|
|
||||||
<b>-MMM<span class="green">-M---MMMMMMMMMMMMMMMMMMM.</span>MMM-</b> <b class="green">Resolution</b>: 1680x1050, 2560x1440
|
|
||||||
<b>`:MMM<span class="green">:MM` :MMMM:....::-...-MMMM:</span>MMM:`</b> <b class="green">DE</b>: Cinnamon 6.0.4
|
|
||||||
<b>:MMM<span class="green">:MMM` :MM:` `` `` `:MMM:</span>MMM:</b> <b class="green">WM</b>: Mutter (Muffin)
|
|
||||||
<b>.MMM<span class="green">.MMMM` :MM. -MM. .MM- `MMMM.</span>MMM.</b> <b class="green">CPU</b>: AMD Ryzen 9 7950X (32) @ 5.881GHz
|
|
||||||
<b>:MMM<span class="green">:MMMM` :MM. -MM- .MM: `MMMM-</span>MMM:</b> <b class="green">GPU</b>: AMD ATI 03:00.0 Device 747e
|
|
||||||
<b>:MMM<span class="green">:MMMM` :MM. -MM- .MM: `MMMM:</span>MMM:</b> <b class="green">GPU</b>: AMD ATI 11:00.0 Device 164e
|
|
||||||
<b>:MMM<span class="green">:MMMM` :MM. -MM- .MM: `MMMM-</span>MMM:</b> <b class="green">Memory</b>: 1MiB / 127901MiB
|
|
||||||
<b>.MMM<span class="green">.MMMM` :MM:--:MM:--:MM: `MMMM.</span>MMM.</b>
|
|
||||||
<b>:MMM<span class="green">:MMM- `-MMMMMMMMMMMM-` -MMM-</span>MMM:</b>
|
|
||||||
<b>:MMM<span class="green">:MMM:` `:MMM:</span>MMM:</b>
|
|
||||||
<b>.MMM<span class="green">.MMMM:--------------:MMMM.</span>MMM.</b>
|
|
||||||
<b>'-MMMM<span class="green">.-MMMMMMMMMMMMMMM-.</span>MMMM-'</b>
|
|
||||||
<b>'.-MMMM<span class="green">``--:::::--``</span>MMMM-.'</b>
|
|
||||||
<b>'-MMMMMMMMMMMMM-'</b>
|
|
||||||
<b>``-:::::-``</b></pre>
|
|
||||||
|
|
||||||
<div><b class="green">trinkey@desktop</b>:<b class="blue">~</b>$ exit</div>
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~</b>$ ssh trinkey@laptop</div>
|
|
||||||
<div>Last login: Tue Sep 11 8:46:40 2001 from 192.168.1.254</div>
|
|
||||||
<div><b class="green">trinkey@laptop</b>:<b class="blue">~</b>$ neofetch</div>
|
|
||||||
|
|
||||||
<pre> <b>...-:::::-...</b> <b class="green">trinkey</b>@<b class="green">laptop</b>
|
|
||||||
<b>.-MMMMMMMMMMMMMMM-.</b> ---------------
|
|
||||||
<b>.-MMMM<span class="green">`..-:::::::-..`</span>MMMM-.</b> <b class="green">OS</b>: Linux Mint 21.2 x86_64
|
|
||||||
<b>.:MMMM<span class="green">.:MMMMMMMMMMMMMMM:.</span>MMMM:.</b> <b class="green">Host</b>: Dell G15 5510
|
|
||||||
<b>-MMM<span class="green">-M---MMMMMMMMMMMMMMMMMMM.</span>MMM-</b> <b class="green">Resolution</b>: 2560x1440, 1920x1080, 1680x1050
|
|
||||||
<b>`:MMM<span class="green">:MM` :MMMM:....::-...-MMMM:</span>MMM:`</b> <b class="green">DE</b>: Cinnamon 5.8.4
|
|
||||||
<b>:MMM<span class="green">:MMM` :MM:` `` `` `:MMM:</span>MMM:</b> <b class="green">WM</b>: Mutter (Muffin)
|
|
||||||
<b>.MMM<span class="green">.MMMM` :MM. -MM. .MM- `MMMM.</span>MMM.</b> <b class="green">CPU</b>: Intel i5-10500H (12) @ 4.500GHz
|
|
||||||
<b>:MMM<span class="green">:MMMM` :MM. -MM- .MM: `MMMM-</span>MMM:</b> <b class="green">GPU</b>: NVIDIA GeForce RTX 3050 Ti Mobile
|
|
||||||
<b>:MMM<span class="green">:MMMM` :MM. -MM- .MM: `MMMM:</span>MMM:</b> <b class="green">GPU</b>: Intel CometLake-H GT2 [UHD Graphics]
|
|
||||||
<b>:MMM<span class="green">:MMMM` :MM. -MM- .MM: `MMMM-</span>MMM:</b> <b class="green">Memory</b>: 2001MiB / 15765MiB
|
|
||||||
<b>.MMM<span class="green">.MMMM` :MM:--:MM:--:MM: `MMMM.</span>MMM.</b>
|
|
||||||
<b>:MMM<span class="green">:MMM- `-MMMMMMMMMMMM-` -MMM-</span>MMM:</b>
|
|
||||||
<b>:MMM<span class="green">:MMM:` `:MMM:</span>MMM:</b>
|
|
||||||
<b>.MMM<span class="green">.MMMM:--------------:MMMM.</span>MMM.</b>
|
|
||||||
<b>'-MMMM<span class="green">.-MMMMMMMMMMMMMMM-.</span>MMMM-'</b>
|
|
||||||
<b>'.-MMMM<span class="green">``--:::::--``</span>MMMM-.'</b>
|
|
||||||
<b>'-MMMMMMMMMMMMM-'</b>
|
|
||||||
<b>``-:::::-``</b></pre>
|
|
||||||
|
|
||||||
<div><b class="green">trinkey@laptop</b>:<b class="blue">~</b>$ exit</div>
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~</b>$ ssh trinkey@server</div>
|
|
||||||
<div>Last login: Tue Sep 11 9:03:02 2001 from 192.168.1.254</div>
|
|
||||||
<div><b class="green">trinkey@server</b>:<b class="blue">~</b>$ neofetch</div>
|
|
||||||
<pre> <b>...-:::::-...</b> <b class="green">trinkey</b>@<b class="green">server</b>
|
|
||||||
<b>.-MMMMMMMMMMMMMMM-.</b> ---------------
|
|
||||||
<b>.-MMMM<span class="green">`..-:::::::-..`</span>MMMM-.</b> <b class="green">OS</b>: Linux Mint 21.2 x86_64
|
|
||||||
<b>.:MMMM<span class="green">.:MMMMMMMMMMMMMMM:.</span>MMMM:.</b> <b class="green">Host</b>: Macmini7,1 1.0
|
|
||||||
<b>-MMM<span class="green">-M---MMMMMMMMMMMMMMMMMMM.</span>MMM-</b> <b class="green">CPU</b>: Intel i5-4278U (4) @ 3.100GHz
|
|
||||||
<b>`:MMM<span class="green">:MM` :MMMM:....::-...-MMMM:</span>MMM:`</b> <b class="green">GPU</b>: Intel Haswell-ULT
|
|
||||||
<b>:MMM<span class="green">:MMM` :MM:` `` `` `:MMM:</span>MMM:</b> <b class="green">Memory</b>: 9011MiB / 15866MiB
|
|
||||||
<b>.MMM<span class="green">.MMMM` :MM. -MM. .MM- `MMMM.</span>MMM.</b>
|
|
||||||
<b>:MMM<span class="green">:MMMM` :MM. -MM- .MM: `MMMM-</span>MMM:</b>
|
|
||||||
<b>:MMM<span class="green">:MMMM` :MM. -MM- .MM: `MMMM:</span>MMM:</b>
|
|
||||||
<b>:MMM<span class="green">:MMMM` :MM. -MM- .MM: `MMMM-</span>MMM:</b>
|
|
||||||
<b>.MMM<span class="green">.MMMM` :MM:--:MM:--:MM: `MMMM.</span>MMM.</b>
|
|
||||||
<b>:MMM<span class="green">:MMM- `-MMMMMMMMMMMM-` -MMM-</span>MMM:</b>
|
|
||||||
<b>:MMM<span class="green">:MMM:` `:MMM:</span>MMM:</b>
|
|
||||||
<b>.MMM<span class="green">.MMMM:--------------:MMMM.</span>MMM.</b>
|
|
||||||
<b>'-MMMM<span class="green">.-MMMMMMMMMMMMMMM-.</span>MMMM-'</b>
|
|
||||||
<b>'.-MMMM<span class="green">``--:::::--``</span>MMMM-.'</b>
|
|
||||||
<b>'-MMMMMMMMMMMMM-'</b>
|
|
||||||
<b>``-:::::-``</b></pre>
|
|
||||||
|
|
||||||
<div><b class="green">trinkey@server</b>:<b class="blue">~</b>$ exit</div>
|
|
||||||
<div><b class="green">trinkey@website</b>:<b class="blue">~</b>$ <i class="cursor">.</i></div>
|
|
||||||
</div>
|
|
||||||
<div data-template-field="width" data-is-number>1000</div>
|
<div data-template-field="width" data-is-number>1000</div>
|
||||||
<div data-template-field="height" data-is-number>800</div>
|
<div data-template-field="height" data-is-number>800</div>
|
||||||
</div>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="js/index.js"></script>
|
<script src="js/index.js"></script>
|
||||||
|
|
|
@ -1,22 +1,19 @@
|
||||||
let points = [[0.3971449136734009, 0.2810116410255432, -0.3767290413379669], [0.23243144154548645, 0.3703259527683258, -0.3767290413379669], [0.30626851320266724, 0.23012861609458923, 0.08654531836509705], [0.15029972791671753, -0.29410237073898315, -0.3767290413379669], [0.3065343499183655, -0.2082172930240631, -0.3767290413379669], [0.3111562132835388, -0.06059299036860466, 0.13771235942840576], [0.16147799789905548, -0.09371967613697052, 0.23468825221061707], [0.36976975202560425, 0.12388059496879578, 0.08632178604602814], [0.31842663884162903, -0.019846681505441666, 0.3223131597042084], [0.20939035713672638, 0.15419937670230865, 0.2242213636636734], [0.17552560567855835, 0.012471526861190796, 0.27797016501426697], [0.16723567247390747, 0.1499461680650711, -0.3767290413379669], [0.4233801066875458, 0.1499461680650711, -0.3767290413379669], [0.3200271725654602, -0.22131121158599854, 0.026444125920534134], [0.15823997557163239, -0.25929194688796997, 0.0673588365316391], [0.44944703578948975, 0.1499461680650711, -0.06793694198131561], [0.2280614674091339, 0.36611324548721313, -0.2975170314311981], [0.38751867413520813, 0.2724340260028839, -0.293896347284317], [0.2147921323776245, 0.3551100790500641, -0.2049424648284912], [0.3594103455543518, 0.2775343060493469, -0.19233158230781555], [0.0, 0.42153987288475037, -0.2989161014556885], [0.0, 0.4475290775299072, -0.3767290413379669], [0.0, 0.10908085107803345, 0.23466001451015472], [0.0, -0.29616573452949524, 0.08896146714687347], [0.0, 0.1499461680650711, -0.3767290413379669], [0.0, -0.1545914262533188, 0.23468825221061707], [0.0, 0.012471422553062439, 0.28773677349090576], [0.0, -0.29410237073898315, -0.3767290413379669], [0.0, 0.3850858211517334, -0.2098153829574585], [0.15266574919223785, 0.33635783195495605, 0.08654531091451645], [0.0, 0.34858277440071106, 0.08654531836509705], [0.3163855969905853, -0.30245065689086914, -0.2832803726196289], [0.15313652157783508, -0.3652721643447876, -0.2640822231769562], [0.43641358613967896, 0.1499461680650711, -0.2795500159263611], [0.0, -0.3652721643447876, -0.2640821933746338], [0.3884555399417877, 0.012471545487642288, -0.3767290413379669], [0.34046298265457153, 0.012471519410610199, 0.11201705783605576], [0.1587677001953125, 0.01247154176235199, -0.3767290413379669], [0.384737104177475, 0.012471544556319714, -0.026815753430128098], [0.0, 0.012471549212932587, -0.3767290413379669], [0.39989548921585083, 0.012471545487642288, -0.30725497007369995], [-0.3971449136734009, 0.2810116410255432, -0.3767290413379669], [-0.23243144154548645, 0.3703259527683258, -0.3767290413379669], [-0.30626851320266724, 0.23012861609458923, 0.08654531836509705], [-0.15029972791671753, -0.29410237073898315, -0.3767290413379669], [-0.3065343499183655, -0.2082172930240631, -0.3767290413379669], [-0.3111562132835388, -0.06059299036860466, 0.13771235942840576], [-0.16147799789905548, -0.09371967613697052, 0.23468825221061707], [-0.36976975202560425, 0.12388059496879578, 0.08632178604602814], [-0.31842663884162903, -0.019846681505441666, 0.3223131597042084], [-0.20939035713672638, 0.15419937670230865, 0.2242213636636734], [-0.17552560567855835, 0.012471526861190796, 0.27797016501426697], [-0.16723567247390747, 0.1499461680650711, -0.3767290413379669], [-0.4233801066875458, 0.1499461680650711, -0.3767290413379669], [-0.3200271725654602, -0.22131121158599854, 0.026444125920534134], [-0.15823997557163239, -0.25929194688796997, 0.0673588365316391], [-0.44944703578948975, 0.1499461680650711, -0.06793694198131561], [-0.2280614674091339, 0.36611324548721313, -0.2975170314311981], [-0.38751867413520813, 0.2724340260028839, -0.293896347284317], [-0.2147921323776245, 0.3551100790500641, -0.2049424648284912], [-0.3594103455543518, 0.2775343060493469, -0.19233158230781555], [-0.15266574919223785, 0.33635783195495605, 0.08654531091451645], [-0.3163855969905853, -0.30245065689086914, -0.2832803726196289], [-0.15313652157783508, -0.3652721643447876, -0.2640822231769562], [-0.43641358613967896, 0.1499461680650711, -0.2795500159263611], [-0.3884555399417877, 0.012471545487642288, -0.3767290413379669], [-0.34046298265457153, 0.012471519410610199, 0.11201705783605576], [-0.1587677001953125, 0.01247154176235199, -0.3767290413379669], [-0.384737104177475, 0.012471544556319714, -0.026815753430128098], [-0.39989548921585083, 0.012471545487642288, -0.30725497007369995]];
|
let points = [[0.3971449136734009, 0.2810116410255432, -0.3767290413379669], [0.23243144154548645, 0.3703259527683258, -0.3767290413379669], [0.30626851320266724, 0.23012861609458923, 0.08654531836509705], [0.15029972791671753, -0.29410237073898315, -0.3767290413379669], [0.3065343499183655, -0.2082172930240631, -0.3767290413379669], [0.3111562132835388, -0.06059299036860466, 0.13771235942840576], [0.16147799789905548, -0.09371967613697052, 0.23468825221061707], [0.36976975202560425, 0.12388059496879578, 0.08632178604602814], [0.31842663884162903, -0.019846681505441666, 0.3223131597042084], [0.20939035713672638, 0.15419937670230865, 0.2242213636636734], [0.17552560567855835, 0.012471526861190796, 0.27797016501426697], [0.16723567247390747, 0.1499461680650711, -0.3767290413379669], [0.4233801066875458, 0.1499461680650711, -0.3767290413379669], [0.3200271725654602, -0.22131121158599854, 0.026444125920534134], [0.15823997557163239, -0.25929194688796997, 0.0673588365316391], [0.44944703578948975, 0.1499461680650711, -0.06793694198131561], [0.2280614674091339, 0.36611324548721313, -0.2975170314311981], [0.38751867413520813, 0.2724340260028839, -0.293896347284317], [0.2147921323776245, 0.3551100790500641, -0.2049424648284912], [0.3594103455543518, 0.2775343060493469, -0.19233158230781555], [0.0, 0.42153987288475037, -0.2989161014556885], [0.0, 0.4475290775299072, -0.3767290413379669], [0.0, 0.10908085107803345, 0.23466001451015472], [0.0, -0.29616573452949524, 0.08896146714687347], [0.0, 0.1499461680650711, -0.3767290413379669], [0.0, -0.1545914262533188, 0.23468825221061707], [0.0, 0.012471422553062439, 0.28773677349090576], [0.0, -0.29410237073898315, -0.3767290413379669], [0.0, 0.3850858211517334, -0.2098153829574585], [0.15266574919223785, 0.33635783195495605, 0.08654531091451645], [0.0, 0.34858277440071106, 0.08654531836509705], [0.3163855969905853, -0.30245065689086914, -0.2832803726196289], [0.15313652157783508, -0.3652721643447876, -0.2640822231769562], [0.43641358613967896, 0.1499461680650711, -0.2795500159263611], [0.0, -0.3652721643447876, -0.2640821933746338], [0.3884555399417877, 0.012471545487642288, -0.3767290413379669], [0.34046298265457153, 0.012471519410610199, 0.11201705783605576], [0.1587677001953125, 0.01247154176235199, -0.3767290413379669], [0.384737104177475, 0.012471544556319714, -0.026815753430128098], [0.0, 0.012471549212932587, -0.3767290413379669], [0.39989548921585083, 0.012471545487642288, -0.30725497007369995], [-0.3971449136734009, 0.2810116410255432, -0.3767290413379669], [-0.23243144154548645, 0.3703259527683258, -0.3767290413379669], [-0.30626851320266724, 0.23012861609458923, 0.08654531836509705], [-0.15029972791671753, -0.29410237073898315, -0.3767290413379669], [-0.3065343499183655, -0.2082172930240631, -0.3767290413379669], [-0.3111562132835388, -0.06059299036860466, 0.13771235942840576], [-0.16147799789905548, -0.09371967613697052, 0.23468825221061707], [-0.36976975202560425, 0.12388059496879578, 0.08632178604602814], [-0.31842663884162903, -0.019846681505441666, 0.3223131597042084], [-0.20939035713672638, 0.15419937670230865, 0.2242213636636734], [-0.17552560567855835, 0.012471526861190796, 0.27797016501426697], [-0.16723567247390747, 0.1499461680650711, -0.3767290413379669], [-0.4233801066875458, 0.1499461680650711, -0.3767290413379669], [-0.3200271725654602, -0.22131121158599854, 0.026444125920534134], [-0.15823997557163239, -0.25929194688796997, 0.0673588365316391], [-0.44944703578948975, 0.1499461680650711, -0.06793694198131561], [-0.2280614674091339, 0.36611324548721313, -0.2975170314311981], [-0.38751867413520813, 0.2724340260028839, -0.293896347284317], [-0.2147921323776245, 0.3551100790500641, -0.2049424648284912], [-0.3594103455543518, 0.2775343060493469, -0.19233158230781555], [-0.15266574919223785, 0.33635783195495605, 0.08654531091451645], [-0.3163855969905853, -0.30245065689086914, -0.2832803726196289], [-0.15313652157783508, -0.3652721643447876, -0.2640822231769562], [-0.43641358613967896, 0.1499461680650711, -0.2795500159263611], [-0.3884555399417877, 0.012471545487642288, -0.3767290413379669], [-0.34046298265457153, 0.012471519410610199, 0.11201705783605576], [-0.1587677001953125, 0.01247154176235199, -0.3767290413379669], [-0.384737104177475, 0.012471544556319714, -0.026815753430128098], [-0.39989548921585083, 0.012471545487642288, -0.30725497007369995]];
|
||||||
const connections = [[0, 1], [0, 12], [0, 17], [1, 11], [1, 16], [1, 21], [2, 7], [2, 9], [2, 19], [2, 29], [3, 4], [3, 27], [3, 32], [3, 37], [4, 31], [4, 35], [5, 6], [5, 8], [5, 13], [5, 36], [6, 8], [6, 10], [6, 14], [6, 25], [7, 8], [7, 9], [7, 15], [7, 36], [8, 9], [8, 10], [8, 36], [9, 10], [9, 22], [9, 29], [10, 26], [11, 12], [11, 24], [11, 37], [12, 33], [12, 35], [13, 14], [13, 31], [13, 38], [14, 23], [14, 32], [15, 19], [15, 33], [15, 38], [16, 17], [16, 18], [16, 20], [17, 19], [17, 33], [18, 19], [18, 28], [18, 29], [20, 21], [20, 28], [20, 57], [21, 24], [21, 42], [22, 26], [22, 30], [22, 50], [23, 25], [23, 34], [23, 55], [24, 39], [24, 52], [25, 26], [25, 47], [26, 51], [27, 34], [27, 39], [27, 44], [28, 30], [28, 59], [29, 30], [30, 61], [31, 32], [31, 40], [32, 34], [33, 40], [34, 63], [35, 37], [35, 40], [36, 38], [37, 39], [38, 40], [39, 67], [41, 42], [41, 53], [41, 58], [42, 52], [42, 57], [43, 48], [43, 50], [43, 60], [43, 61], [44, 45], [44, 63], [44, 67], [45, 62], [45, 65], [46, 47], [46, 49], [46, 54], [46, 66], [47, 49], [47, 51], [47, 55], [48, 49], [48, 50], [48, 56], [48, 66], [49, 50], [49, 51], [49, 66], [50, 51], [50, 61], [52, 53], [52, 67], [53, 64], [53, 65], [54, 55], [54, 62], [54, 68], [55, 63], [56, 60], [56, 64], [56, 68], [57, 58], [57, 59], [58, 60], [58, 64], [59, 60], [59, 61], [62, 63], [62, 69], [64, 69], [65, 67], [65, 69], [66, 68], [68, 69]];
|
const connections = [[0, 1], [0, 12], [0, 17], [1, 11], [1, 16], [1, 21], [2, 7], [2, 9], [2, 19], [2, 29], [3, 4], [3, 27], [3, 32], [3, 37], [4, 31], [4, 35], [5, 6], [5, 8], [5, 13], [5, 36], [6, 8], [6, 10], [6, 14], [6, 25], [7, 8], [7, 9], [7, 15], [7, 36], [8, 9], [8, 10], [8, 36], [9, 10], [9, 22], [9, 29], [10, 26], [11, 12], [11, 24], [11, 37], [12, 33], [12, 35], [13, 14], [13, 31], [13, 38], [14, 23], [14, 32], [15, 19], [15, 33], [15, 38], [16, 17], [16, 18], [16, 20], [17, 19], [17, 33], [18, 19], [18, 28], [18, 29], [20, 21], [20, 28], [20, 57], [21, 24], [21, 42], [22, 26], [22, 30], [22, 50], [23, 25], [23, 34], [23, 55], [24, 39], [24, 52], [25, 26], [25, 47], [26, 51], [27, 34], [27, 39], [27, 44], [28, 30], [28, 59], [29, 30], [30, 61], [31, 32], [31, 40], [32, 34], [33, 40], [34, 63], [35, 37], [35, 40], [36, 38], [37, 39], [38, 40], [39, 67], [41, 42], [41, 53], [41, 58], [42, 52], [42, 57], [43, 48], [43, 50], [43, 60], [43, 61], [44, 45], [44, 63], [44, 67], [45, 62], [45, 65], [46, 47], [46, 49], [46, 54], [46, 66], [47, 49], [47, 51], [47, 55], [48, 49], [48, 50], [48, 56], [48, 66], [49, 50], [49, 51], [49, 66], [50, 51], [50, 61], [52, 53], [52, 67], [53, 64], [53, 65], [54, 55], [54, 62], [54, 68], [55, 63], [56, 60], [56, 64], [56, 68], [57, 58], [57, 59], [58, 60], [58, 64], [59, 60], [59, 61], [62, 63], [62, 69], [64, 69], [65, 67], [65, 69], [66, 68], [68, 69]];
|
||||||
const blobcatColor = { light: "#df8e1d", dark: "#f9e2af" }
|
const blobcatColor = { light: "#df8e1d", dark: "#f9e2af" };
|
||||||
const focalLength = 1;
|
const focalLength = 1;
|
||||||
const radians = (2 * Math.PI / 360) * 3;
|
const radians = (2 * Math.PI / 360) * 3;
|
||||||
const rotationalMatrix = [
|
const rotationalMatrix = [
|
||||||
[Math.cos(radians), -Math.sin(radians), 0],
|
[Math.cos(radians), -Math.sin(radians), 0],
|
||||||
[Math.sin(radians), Math.cos(radians), 0],
|
[Math.sin(radians), Math.cos(radians), 0],
|
||||||
[0, 0, 1]
|
[0, 0, 1]
|
||||||
]
|
];
|
||||||
|
|
||||||
let blobcatElement = null;
|
let blobcatElement = null;
|
||||||
|
|
||||||
function dot(a, b) {
|
function dot(a, b) {
|
||||||
const rows = a.length;
|
const rows = a.length;
|
||||||
const colsA = a[0].length;
|
const colsA = a[0].length;
|
||||||
const colsB = b[0].length;
|
const colsB = b[0].length;
|
||||||
const result = Array.from({ length: rows }, () => Array(colsB).fill(0));
|
const result = Array.from({ length: rows }, () => Array(colsB).fill(0));
|
||||||
|
|
||||||
for (let i = 0; i < rows; i++) {
|
for (let i = 0; i < rows; i++) {
|
||||||
for (let j = 0; j < colsB; j++) {
|
for (let j = 0; j < colsB; j++) {
|
||||||
for (let k = 0; k < colsA; k++) {
|
for (let k = 0; k < colsA; k++) {
|
||||||
|
@ -24,24 +21,14 @@ function dot(a, b) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
function getLine(x1, y1, x2, y2, multiply, offsetX, offsetY, zIndex) {
|
||||||
function getLine(
|
|
||||||
x1, y1, x2, y2,
|
|
||||||
multiply,
|
|
||||||
offsetX,
|
|
||||||
offsetY,
|
|
||||||
zIndex
|
|
||||||
) {
|
|
||||||
let hr = document.createElement("hr");
|
let hr = document.createElement("hr");
|
||||||
|
|
||||||
x1 = x1 * multiply;
|
x1 = x1 * multiply;
|
||||||
y1 = y1 * multiply;
|
y1 = y1 * multiply;
|
||||||
x2 = x2 * multiply;
|
x2 = x2 * multiply;
|
||||||
y2 = y2 * multiply;
|
y2 = y2 * multiply;
|
||||||
|
|
||||||
hr.style.position = "absolute";
|
hr.style.position = "absolute";
|
||||||
hr.style.left = `${x1 + offsetX}px`;
|
hr.style.left = `${x1 + offsetX}px`;
|
||||||
hr.style.top = `${y1 + offsetY}px`;
|
hr.style.top = `${y1 + offsetY}px`;
|
||||||
|
@ -51,42 +38,34 @@ function getLine(
|
||||||
hr.style.transformOrigin = `0 0.5px`;
|
hr.style.transformOrigin = `0 0.5px`;
|
||||||
hr.style.backgroundColor = light ? blobcatColor.light : blobcatColor.dark;
|
hr.style.backgroundColor = light ? blobcatColor.light : blobcatColor.dark;
|
||||||
hr.style.border = "0";
|
hr.style.border = "0";
|
||||||
hr.style.zIndex = zIndex
|
hr.style.zIndex = String(zIndex);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function blobcatFrame() {
|
function blobcatFrame() {
|
||||||
if (!blobcatElement || !WINDOWS.blob) { return; }
|
if (!blobcatElement || !WINDOWS.blob) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let screenCoordinates = points.map((a) => ([
|
let screenCoordinates = points.map((a) => ([
|
||||||
(focalLength * a[0]) / (a[1] + focalLength),
|
(focalLength * a[0]) / (a[1] + focalLength),
|
||||||
-(focalLength * a[2]) / (a[1] + focalLength)
|
-(focalLength * a[2]) / (a[1] + focalLength)
|
||||||
]));
|
]));
|
||||||
|
let hrElements = connections.map((a) => (getLine(...screenCoordinates[a[0]], ...screenCoordinates[a[1]], 300, WINDOWS.blob.width / 2 + 11, WINDOWS.blob.height / 2 + 11, WINDOWS.blob.zIndex)));
|
||||||
let hrElements = connections.map((a) => (
|
|
||||||
getLine(...screenCoordinates[a[0]], ...screenCoordinates[a[1]], 300, WINDOWS.blob.width / 2 + 11, WINDOWS.blob.height / 2 + 11, WINDOWS.blob.zIndex)
|
|
||||||
));
|
|
||||||
|
|
||||||
blobcatElement.innerHTML = "";
|
blobcatElement.innerHTML = "";
|
||||||
blobcatElement.append(...hrElements);
|
blobcatElement.append(...hrElements);
|
||||||
points = dot(points, rotationalMatrix);
|
points = dot(points, rotationalMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBlob() {
|
function createBlob() {
|
||||||
createWindow({
|
createWindow({
|
||||||
id: "blob",
|
id: "blob",
|
||||||
title: "~/spinny-cat",
|
title: "~/spinny-cat",
|
||||||
content: "<div id='blobcat'></div>",
|
content: "<div id='blobcat'></div>",
|
||||||
onDestroy: destroyBlob,
|
onDestroy: destroyBlob,
|
||||||
height: 450
|
height: 450,
|
||||||
|
typeable: false
|
||||||
});
|
});
|
||||||
|
|
||||||
blobcatElement = document.getElementById("blobcat");
|
blobcatElement = document.getElementById("blobcat");
|
||||||
}
|
}
|
||||||
|
|
||||||
function destroyBlob() {
|
function destroyBlob() {
|
||||||
blobcatElement = null;
|
blobcatElement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
setInterval(blobcatFrame, 1000 / 30);
|
setInterval(blobcatFrame, 1000 / 30);
|
||||||
|
|
157
js/index.js
157
js/index.js
|
@ -1,54 +1,39 @@
|
||||||
/* config: {
|
|
||||||
title: string,
|
|
||||||
content: string,
|
|
||||||
id: string,
|
|
||||||
width?: number = 600,
|
|
||||||
height?: number = 400,
|
|
||||||
minWidth?: number = 200,
|
|
||||||
minHeight?: number = 200,
|
|
||||||
posX?: number = null, // automatically centers window based on w/h
|
|
||||||
posY?: number = null,
|
|
||||||
onDestroy?: () => void
|
|
||||||
} */
|
|
||||||
|
|
||||||
let WINDOWS = {};
|
let WINDOWS = {};
|
||||||
let MOUSE_MOVE_PROCESSING = {};
|
let MOUSE_MOVE_PROCESSING = {};
|
||||||
let globalIncrement = 1;
|
let globalIncrement = 1;
|
||||||
|
function escapeHTML(string) {
|
||||||
|
return string.replaceAll("&", "&").replaceAll("<", "<").replaceAll("\"", """);
|
||||||
|
}
|
||||||
|
function incrementZIndex(windowID, focus = false) {
|
||||||
|
WINDOWS[windowID].element.style.zIndex = String(globalIncrement);
|
||||||
|
WINDOWS[windowID].zIndex = globalIncrement;
|
||||||
|
globalIncrement++;
|
||||||
|
if (focus) {
|
||||||
|
WINDOWS[windowID].element.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
function createWindow(config) {
|
function createWindow(config) {
|
||||||
if (document.getElementById(config.id)) {
|
if (document.getElementById(config.id)) {
|
||||||
WINDOWS[config.id].element.style.zIndex = globalIncrement;
|
incrementZIndex(config.id);
|
||||||
WINDOWS[config.id].zIndex = globalIncrement;
|
|
||||||
globalIncrement++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 - border
|
|
||||||
// 10 - padding
|
|
||||||
// 35 - header
|
|
||||||
let _windowPaddingX = 1 * 2 + 10 * 2;
|
let _windowPaddingX = 1 * 2 + 10 * 2;
|
||||||
let _windowPaddingY = 1 * 2 + 10 * 2 + 35;
|
let _windowPaddingY = 1 * 2 + 10 * 2 + 35;
|
||||||
|
|
||||||
config.width = config.width || 600;
|
config.width = config.width || 600;
|
||||||
config.height = config.height || 400;
|
config.height = config.height || 400;
|
||||||
config.minWidth = config.minWidth || 200;
|
config.minWidth = config.minWidth || 200;
|
||||||
config.minHeight = config.minHeight || 200;
|
config.minHeight = config.minHeight || 200;
|
||||||
|
|
||||||
let realWidth = Math.max(config.minWidth, Math.min(config.width, innerWidth - _windowPaddingX - 20));
|
let realWidth = Math.max(config.minWidth, Math.min(config.width, innerWidth - _windowPaddingX - 20));
|
||||||
let realHeight = Math.max(config.minHeight, Math.min(config.height, innerHeight - _windowPaddingY - 20));
|
let realHeight = Math.max(config.minHeight, Math.min(config.height, innerHeight - _windowPaddingY - 20));
|
||||||
|
|
||||||
let posX = config.posX || Math.round((innerWidth / 2) - ((realWidth + _windowPaddingX) / 2));
|
let posX = config.posX || Math.round((innerWidth / 2) - ((realWidth + _windowPaddingX) / 2));
|
||||||
let posY = config.posY || Math.round((innerHeight / 2) - ((realHeight + _windowPaddingY) / 2));
|
let posY = config.posY || Math.round((innerHeight / 2) - ((realHeight + _windowPaddingY) / 2));
|
||||||
|
|
||||||
let wO = document.createElement("div");
|
let wO = document.createElement("div");
|
||||||
wO.classList.add("window-outer");
|
wO.classList.add("window-outer");
|
||||||
|
|
||||||
let w = document.createElement("div");
|
let w = document.createElement("div");
|
||||||
w.classList.add("window");
|
w.classList.add("window");
|
||||||
w.style.width = `${realWidth}px`;
|
w.style.width = `${realWidth}px`;
|
||||||
w.style.height = `${realHeight}px`;
|
w.style.height = `${realHeight}px`;
|
||||||
w.innerHTML = config.content;
|
w.innerHTML = config.content;
|
||||||
|
|
||||||
let wH = document.createElement("div");
|
let wH = document.createElement("div");
|
||||||
wH.classList.add("window-header");
|
wH.classList.add("window-header");
|
||||||
wH.innerHTML = `
|
wH.innerHTML = `
|
||||||
|
@ -60,50 +45,97 @@ function createWindow(config) {
|
||||||
<i data-no-move class="window-header-button fullscreen"></i>
|
<i data-no-move class="window-header-button fullscreen"></i>
|
||||||
<i data-no-move class="window-header-button close"></i>
|
<i data-no-move class="window-header-button close"></i>
|
||||||
`;
|
`;
|
||||||
|
let wC;
|
||||||
let wC = document.createElement("div");
|
let wI = null;
|
||||||
|
if (config.typeable !== false) {
|
||||||
|
function syncInputs() {
|
||||||
|
setTimeout(function () {
|
||||||
|
let text = wI.value;
|
||||||
|
let cursor = wI.selectionStart;
|
||||||
|
let el = wC.querySelector("[data-type-area]");
|
||||||
|
if (!el) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cursor == text.length) {
|
||||||
|
el.innerHTML = `${escapeHTML(text)}<i class="cursor"> </i>`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
el.innerHTML = `${escapeHTML(text.slice(0, cursor))}<span class="cursor">${escapeHTML(text[cursor])}</span>${escapeHTML(text.slice(cursor + 1))}`;
|
||||||
|
}
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
function setCursor() {
|
||||||
|
setTimeout(() => {
|
||||||
|
wI.setSelectionRange(wI.value.length, wI.value.length);
|
||||||
|
syncInputs();
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
wI = document.createElement("input");
|
||||||
|
wI.classList.add("window-input");
|
||||||
|
wI.id = `${config.id}__input`;
|
||||||
|
wI.oninput = (event) => {
|
||||||
|
syncInputs();
|
||||||
|
w.scrollTop = w.scrollHeight;
|
||||||
|
};
|
||||||
|
wI.onkeydown = (event) => {
|
||||||
|
if (event.key == "Enter") {
|
||||||
|
commandManager(config.id, wI.value.trim());
|
||||||
|
w.scrollTop = w.scrollHeight;
|
||||||
|
wI.value = "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
syncInputs();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
wI.onfocus = setCursor;
|
||||||
|
wI.onclick = setCursor;
|
||||||
|
wC = document.createElement("label");
|
||||||
|
wC.htmlFor = `${config.id}__input`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wC = document.createElement("div");
|
||||||
|
}
|
||||||
wC.classList.add("window-container");
|
wC.classList.add("window-container");
|
||||||
|
wC.tabIndex = 0;
|
||||||
wC.style.left = `${posX}px`;
|
wC.style.left = `${posX}px`;
|
||||||
wC.style.top = `${posY}px`;
|
wC.style.top = `${posY}px`;
|
||||||
wC.id = config.id;
|
wC.id = config.id;
|
||||||
wC.style.zIndex = globalIncrement;
|
wC.style.zIndex = String(globalIncrement);
|
||||||
wC.style.width = `${realWidth + _windowPaddingX - 2}px`;
|
wC.style.width = `${realWidth + _windowPaddingX - 2}px`;
|
||||||
|
wO.append(w);
|
||||||
wO.append(w)
|
|
||||||
wC.append(wH, wO);
|
wC.append(wH, wO);
|
||||||
|
|
||||||
document.body.append(wC);
|
document.body.append(wC);
|
||||||
|
if (config.typeable !== false) {
|
||||||
|
wC.append(wI);
|
||||||
|
wI.focus();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wC.focus();
|
||||||
|
}
|
||||||
WINDOWS[config.id] = {
|
WINDOWS[config.id] = {
|
||||||
element: wC,
|
element: wC,
|
||||||
height: realHeight,
|
height: realHeight,
|
||||||
width: realWidth,
|
width: realWidth,
|
||||||
posX: posX,
|
posX: posX,
|
||||||
posY: posY,
|
posY: posY,
|
||||||
mouseDown: false,
|
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
zIndex: globalIncrement,
|
zIndex: globalIncrement,
|
||||||
vars: {}
|
vars: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
function mouseMoveEvent(x, y) {
|
function mouseMoveEvent(x, y) {
|
||||||
WINDOWS[config.id].posX = Math.max(0, Math.min(innerWidth - WINDOWS[config.id].width - _windowPaddingX, x - WINDOWS[config.id].vars.mouseOffsetX));
|
WINDOWS[config.id].posX = Math.max(0, Math.min(innerWidth - WINDOWS[config.id].width - _windowPaddingX, x - WINDOWS[config.id].vars.mouseOffsetX));
|
||||||
WINDOWS[config.id].posY = Math.max(0, Math.min(innerHeight - WINDOWS[config.id].height - _windowPaddingY, y - WINDOWS[config.id].vars.mouseOffsetY));
|
WINDOWS[config.id].posY = Math.max(0, Math.min(innerHeight - WINDOWS[config.id].height - _windowPaddingY, y - WINDOWS[config.id].vars.mouseOffsetY));
|
||||||
wC.style.left = `${WINDOWS[config.id].posX}px`;
|
wC.style.left = `${WINDOWS[config.id].posX}px`;
|
||||||
wC.style.top = `${WINDOWS[config.id].posY}px`;
|
wC.style.top = `${WINDOWS[config.id].posY}px`;
|
||||||
}
|
}
|
||||||
|
wC.addEventListener("focus", function () { incrementZIndex(config.id); });
|
||||||
wC.addEventListener("mousedown", function() {
|
for (const link of wC.querySelectorAll("a")) {
|
||||||
wC.style.zIndex = globalIncrement;
|
link.addEventListener("focus", function () { incrementZIndex(config.id); });
|
||||||
WINDOWS[config.id].zIndex = globalIncrement;
|
}
|
||||||
globalIncrement++;
|
|
||||||
})
|
|
||||||
|
|
||||||
wH.addEventListener("mousedown", function (e) {
|
wH.addEventListener("mousedown", function (e) {
|
||||||
if (e.target.dataset.noMove !== undefined) {
|
if (e.target.dataset.noMove !== undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WINDOWS[config.id].mouseDown = true;
|
|
||||||
WINDOWS[config.id].vars.mouseOffsetX = e.clientX - WINDOWS[config.id].posX;
|
WINDOWS[config.id].vars.mouseOffsetX = e.clientX - WINDOWS[config.id].posX;
|
||||||
WINDOWS[config.id].vars.mouseOffsetY = e.clientY - WINDOWS[config.id].posY;
|
WINDOWS[config.id].vars.mouseOffsetY = e.clientY - WINDOWS[config.id].posY;
|
||||||
MOUSE_MOVE_PROCESSING[config.id] = {
|
MOUSE_MOVE_PROCESSING[config.id] = {
|
||||||
|
@ -111,17 +143,15 @@ function createWindow(config) {
|
||||||
mouseUp: true
|
mouseUp: true
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
wH.querySelector(".close").addEventListener("click", function () {
|
wH.querySelector(".close").addEventListener("click", function () {
|
||||||
delete WINDOWS[config.id];
|
delete WINDOWS[config.id];
|
||||||
|
delete windowInformation[config.id];
|
||||||
delete MOUSE_MOVE_PROCESSING[config.id];
|
delete MOUSE_MOVE_PROCESSING[config.id];
|
||||||
wC.remove();
|
wC.remove();
|
||||||
|
|
||||||
if (typeof config.onDestroy === "function") {
|
if (typeof config.onDestroy === "function") {
|
||||||
config.onDestroy();
|
config.onDestroy();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
wH.querySelector(".fullscreen").addEventListener("click", function () {
|
wH.querySelector(".fullscreen").addEventListener("click", function () {
|
||||||
if (WINDOWS[config.id].fullscreen) {
|
if (WINDOWS[config.id].fullscreen) {
|
||||||
WINDOWS[config.id].posX = WINDOWS[config.id].vars.oldPosX;
|
WINDOWS[config.id].posX = WINDOWS[config.id].vars.oldPosX;
|
||||||
|
@ -138,7 +168,8 @@ function createWindow(config) {
|
||||||
wC.style.width = `${WINDOWS[config.id].width + _windowPaddingX - 2}px`;
|
wC.style.width = `${WINDOWS[config.id].width + _windowPaddingX - 2}px`;
|
||||||
w.style.width = `${WINDOWS[config.id].width}px`;
|
w.style.width = `${WINDOWS[config.id].width}px`;
|
||||||
w.style.height = `${WINDOWS[config.id].height}px`;
|
w.style.height = `${WINDOWS[config.id].height}px`;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
WINDOWS[config.id].vars.oldPosX = WINDOWS[config.id].posX;
|
WINDOWS[config.id].vars.oldPosX = WINDOWS[config.id].posX;
|
||||||
WINDOWS[config.id].vars.oldPosY = WINDOWS[config.id].posY;
|
WINDOWS[config.id].vars.oldPosY = WINDOWS[config.id].posY;
|
||||||
WINDOWS[config.id].vars.oldWidth = WINDOWS[config.id].width;
|
WINDOWS[config.id].vars.oldWidth = WINDOWS[config.id].width;
|
||||||
|
@ -155,40 +186,44 @@ function createWindow(config) {
|
||||||
w.style.height = `${WINDOWS[config.id].height - _windowPaddingY}px`;
|
w.style.height = `${WINDOWS[config.id].height - _windowPaddingY}px`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
globalIncrement++;
|
globalIncrement++;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("mousemove", function (e) {
|
window.addEventListener("mousemove", function (e) {
|
||||||
for (const key of Object.keys(MOUSE_MOVE_PROCESSING)) {
|
for (const key of Object.keys(MOUSE_MOVE_PROCESSING)) {
|
||||||
MOUSE_MOVE_PROCESSING[key].callback(e.clientX, e.clientY);
|
MOUSE_MOVE_PROCESSING[key].callback(e.clientX, e.clientY);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener("mouseup", function () {
|
window.addEventListener("mouseup", function () {
|
||||||
for (const key of Object.keys(MOUSE_MOVE_PROCESSING)) {
|
for (const key of Object.keys(MOUSE_MOVE_PROCESSING)) {
|
||||||
if (MOUSE_MOVE_PROCESSING[key].mouseUp) {
|
if (MOUSE_MOVE_PROCESSING[key].mouseUp) {
|
||||||
delete MOUSE_MOVE_PROCESSING[key];
|
delete MOUSE_MOVE_PROCESSING[key];
|
||||||
};
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function windowPreset(template) {
|
function windowPreset(template) {
|
||||||
let el = document.querySelector(`#window-templates > [data-template-id="${template}"]`);
|
let el = document.querySelector(`#window-templates > [data-template-id="${template}"]`);
|
||||||
|
if (!el) {
|
||||||
if (!el) { return; }
|
return;
|
||||||
|
}
|
||||||
|
if (WINDOWS[template]) {
|
||||||
|
incrementZIndex(template, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
let config = {
|
let config = {
|
||||||
id: template
|
id: template,
|
||||||
|
title: "~ - tSh",
|
||||||
|
content: "<div><b class=\"green\">trinkey@website</b>:<b class=\"blue\">~</b>$ <span data-type-area><i class=\"cursor\"> </i></span></div>"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const field of el.querySelectorAll("[data-template-field]")) {
|
for (const field of el.querySelectorAll("[data-template-field]")) {
|
||||||
config[field.dataset.templateField] = field.dataset.isNumber === "" ? +field.innerText : field.innerHTML;
|
config[field.dataset.templateField] = field.dataset.isNumber === "" ? +field.innerText : field.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
createWindow(config);
|
createWindow(config);
|
||||||
|
for (const command of el.querySelectorAll("li")) {
|
||||||
|
WINDOWS[template].element.querySelector("[data-type-area]").innerHTML = command.innerHTML;
|
||||||
|
commandManager(template, command.innerHTML);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyButton() {
|
function copyButton() {
|
||||||
navigator.clipboard.writeText("<a href=\"https://trinkey.com/\" target=\"_blank\"><img src=\"https://trinkey.com/img/88x31.png\" alt=\"trinkey's 88x31. image of her cat on the right with the word trinkey taking up the rest of the button.\" title=\"trinkey's 88x31. image of her cat on the right with the word trinkey taking up the rest of the button.\"></a>");
|
navigator.clipboard.writeText("<a href=\"https://trinkey.com/\" target=\"_blank\"><img src=\"https://trinkey.com/img/88x31.png\" alt=\"trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button.\" title=\"trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button.\"></a>");
|
||||||
}
|
}
|
||||||
|
|
449
js/shell.js
Normal file
449
js/shell.js
Normal file
|
@ -0,0 +1,449 @@
|
||||||
|
function _internal_joinPaths(path1, path2) {
|
||||||
|
if (path2[0] == "/") {
|
||||||
|
return _internal_sanitizePath(path2);
|
||||||
|
}
|
||||||
|
else if (path2[0] == "~" && (path2.length == 1 || path2[1] == "/")) {
|
||||||
|
return _internal_sanitizePath(HOME_DIR + path2.slice(1));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return _internal_sanitizePath(path1 + "/" + path2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _internal_sanitizePath(path) {
|
||||||
|
while (path.includes("//")) {
|
||||||
|
path = path.replaceAll("//", "/");
|
||||||
|
}
|
||||||
|
while (path[path.length - 1] == "/") {
|
||||||
|
path = path.slice(0, path.length - 1);
|
||||||
|
}
|
||||||
|
let newPath = [];
|
||||||
|
for (const dir of path.split("/")) {
|
||||||
|
if (dir == ".") {
|
||||||
|
}
|
||||||
|
else if (dir == "..") {
|
||||||
|
if (newPath.length) {
|
||||||
|
newPath = newPath.slice(0, newPath.length - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dir) {
|
||||||
|
newPath.push(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "/" + newPath.join("/");
|
||||||
|
}
|
||||||
|
function _internal_getFile(path) {
|
||||||
|
function getFile_recursive(files, path) {
|
||||||
|
console.log(files, path);
|
||||||
|
let file = files[path[0]];
|
||||||
|
if (!file) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (path.length == 1) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
if (file.type == "file") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getFile_recursive(file.files, path.slice(1));
|
||||||
|
}
|
||||||
|
if (path == "/") {
|
||||||
|
return {
|
||||||
|
type: "directory",
|
||||||
|
name: "/",
|
||||||
|
files: FILESYSTEM
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let dirs = path.split("/");
|
||||||
|
if (dirs[0] == "") {
|
||||||
|
dirs = dirs.slice(1);
|
||||||
|
}
|
||||||
|
return getFile_recursive(FILESYSTEM, dirs);
|
||||||
|
}
|
||||||
|
function _internal_stringifyPath(path) {
|
||||||
|
if (path.startsWith(HOME_DIR)) {
|
||||||
|
return path.replace(HOME_DIR, "~");
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
function _internal_getPS1(winInfo) {
|
||||||
|
return `<b class="green">${winInfo.ps1Override || "trinkey@website"}</b>:<b class="blue">${_internal_stringifyPath(winInfo.PWD)}</b>$ `;
|
||||||
|
}
|
||||||
|
function _internal_getFlags(command) {
|
||||||
|
let flags = [];
|
||||||
|
let newCommand = [];
|
||||||
|
for (const thing of command.split(" ")) {
|
||||||
|
if (thing.startsWith("-")) {
|
||||||
|
flags.push(...thing.slice(1).split(""));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newCommand.push(thing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
flags: flags,
|
||||||
|
removed: newCommand.join(" ")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function _internal_fileSize(size) {
|
||||||
|
let suffix = "";
|
||||||
|
let amount = size;
|
||||||
|
const sizes = [
|
||||||
|
{ suffix: "K", amount: 1024, threshold: 10000 },
|
||||||
|
{ suffix: "M", amount: Math.pow(1024, 2), threshold: 1000000 }
|
||||||
|
];
|
||||||
|
for (const info of sizes) {
|
||||||
|
if (size > info.threshold) {
|
||||||
|
suffix = info.suffix;
|
||||||
|
amount = Math.round(size / info.amount * 10) / 10;
|
||||||
|
if (String(amount).length > 3) {
|
||||||
|
amount = Math.round(info.amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return `${amount}${suffix}`.padStart(4, " ");
|
||||||
|
}
|
||||||
|
function cat(path, windowID) {
|
||||||
|
if (!path) {
|
||||||
|
return "<div>cat: You must specify a file</div>";
|
||||||
|
}
|
||||||
|
path = _internal_joinPaths(windowInformation[windowID].PWD || HOME_DIR, path);
|
||||||
|
let file = _internal_getFile(path);
|
||||||
|
if (!file) {
|
||||||
|
return `<div>cat: ${escapeHTML(path)}: No such file or directory</div>`;
|
||||||
|
}
|
||||||
|
else if (file.type == "directory") {
|
||||||
|
return `<div>cat: ${escapeHTML(path)}: Is a directory</div>`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return file.content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function cd(path, windowID) {
|
||||||
|
if (!path) {
|
||||||
|
windowInformation[windowID].PWD = HOME_DIR;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
let newPWD = _internal_joinPaths(windowInformation[windowID].PWD, path);
|
||||||
|
let newFileObj = _internal_getFile(newPWD);
|
||||||
|
if (newFileObj === null) {
|
||||||
|
return `<div>cd: ${escapeHTML(path)}: No such file or directory</div>`;
|
||||||
|
}
|
||||||
|
else if (newFileObj.type == "file") {
|
||||||
|
return `<div>cd: ${escapeHTML(path)}: Not a directory</div>`;
|
||||||
|
}
|
||||||
|
windowInformation[windowID].PWD = newPWD;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
function clear(path, windowID) {
|
||||||
|
WINDOWS[windowID].element.querySelector(".window").innerHTML = "";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
function exit(path, windowID) {
|
||||||
|
setTimeout(() => {
|
||||||
|
WINDOWS[windowID].element.querySelector(".close").click();
|
||||||
|
}, 1);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
function help(path, windowID) {
|
||||||
|
return helpText;
|
||||||
|
}
|
||||||
|
function ls(path, windowID) {
|
||||||
|
let { flags, removed } = _internal_getFlags(path);
|
||||||
|
path = _internal_joinPaths(windowInformation[windowID].PWD || HOME_DIR, removed);
|
||||||
|
let file = _internal_getFile(path);
|
||||||
|
let files;
|
||||||
|
if (!file) {
|
||||||
|
return `<div>ls: ${escapeHTML(path)}: No such file or directory</div>`;
|
||||||
|
}
|
||||||
|
else if (file.type == "file") {
|
||||||
|
files = { [file.name]: file };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
files = file.files;
|
||||||
|
}
|
||||||
|
let directories = [];
|
||||||
|
let hidden = flags.includes("a") || flags.includes("A");
|
||||||
|
let long = flags.includes("l");
|
||||||
|
let out = flags.includes("a") ? (long ? "<div>drwxrwxr-x trinkey trinkey 4096 <span class=\"blue\">.</span></div><div>drwxr-xr-x trinkey trinkey 4096 <span class=\"blue\">..</span></div>" : "<span class=\"blue\">.</span> <span class=\"blue\">..</span> ") : "";
|
||||||
|
for (const file of Object.keys(files).sort((a, b) => (({ true: 1, false: -1 })[String(flags.includes("r") ? a < b : a > b)]))) {
|
||||||
|
if (file.startsWith(".") && !hidden) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let fObj = files[file];
|
||||||
|
if (long) {
|
||||||
|
if (fObj.type == "directory") {
|
||||||
|
directories.push(fObj);
|
||||||
|
out += `<div>drwxrwxr-x trinkey trinkey 4096 <span class=\"blue\">${escapeHTML(file)}</span></div>`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out += `<div>-rw-rw-r-- trinkey trinkey ${_internal_fileSize(fObj.content.length).replaceAll(" ", " ")} ${escapeHTML(file)}</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (fObj.type == "directory") {
|
||||||
|
directories.push(fObj);
|
||||||
|
out += `<span class=\"blue\">${escapeHTML(file)}</span> `;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out += `${escapeHTML(file)} `;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!long) {
|
||||||
|
out = out.slice(0, out.length - 7);
|
||||||
|
}
|
||||||
|
if (flags.includes("R")) {
|
||||||
|
for (const dir of directories) {
|
||||||
|
out += `<div><br>${escapeHTML(_internal_stringifyPath(_internal_joinPaths(path, dir.name)))}:</div>${ls(`${_internal_joinPaths(path, dir.name)} -${flags.join("")}`, windowID)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function _internal_set_ps1(args, windowID) {
|
||||||
|
windowInformation[windowID].ps1Override = args.split("|")[0];
|
||||||
|
WINDOWS[windowID].element.querySelector(".window [data-type-area]").innerHTML = args.split("|")[1];
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
function _internal_neofetch(args, windowID) {
|
||||||
|
WINDOWS[windowID].element.querySelector(".window [data-type-area]").innerHTML = "neofetch";
|
||||||
|
return _internal_neofetchOutputs[args];
|
||||||
|
}
|
||||||
|
const _internal_commands = {
|
||||||
|
cat: cat,
|
||||||
|
cd: cd,
|
||||||
|
clear: clear,
|
||||||
|
help: help,
|
||||||
|
ls: ls,
|
||||||
|
exit: exit,
|
||||||
|
_internal_set_ps1: _internal_set_ps1,
|
||||||
|
_internal_neofetch: _internal_neofetch
|
||||||
|
};
|
||||||
|
const _internal_defaultFiles = {
|
||||||
|
about: `<div><b>hi there! i'm trinkey!</b></div>
|
||||||
|
<div>--------------------</div>
|
||||||
|
<div>i'm a silly little kitty cat who lives in the usa.</div>
|
||||||
|
<div>i'm <span class="blue">t</span><span class="pink">r</span>a<span class="pink">n</span><span class="blue">s</span> (she/her, they/them and it/its are also fine).</div>
|
||||||
|
<div>i'm not actively in a relationship, however i'm also not looking to get into one either.</div>
|
||||||
|
<div>--------------------</div>
|
||||||
|
<div>i like to code stuff (mostly websites)! some of my programs can be found on the <a href="javascript:windowPreset('projects')">projects page</a>. i know a few languages, those being python, javascript/typescript, html/css (if you count those), and a little bit of java.</div>
|
||||||
|
<div>--------------------</div>
|
||||||
|
<div>well, that's about it! i hope you like my website!</div>`,
|
||||||
|
socials: `<div>- fedi - <b>@trinkey@trinkey.com</b> (or @trinkey@is.trinkey.com)</div>
|
||||||
|
<div>- forgejo - <a href="https://git.trinkey.com/trinkey/" target="_blank"><b>trinkey</b></a></div>
|
||||||
|
<div>- github - <a href="https://github.com/trinkey/" target="_blank"><b>trinkey</b></a></div>
|
||||||
|
<div>- git.gay - <a href="https://git.gay/trinkey/" target="_blank"><b>trinkey</b></a> (inactive)</div>
|
||||||
|
<div>- smiggins - <a href="https://smiggins.trinkey.com/u/trinkey/" target="_blank"><b>trinkey</b></a></div>
|
||||||
|
<div>- signal - <b>@trinkey.01</b></div>
|
||||||
|
<div>- email - <b>trinkey [at] proton [dot] me</b></div>
|
||||||
|
<div>- youtube - <a href="https://youtube.com/@trinkey" target="_blank"><b>@trinkey</b></a> (inactive)</div>`,
|
||||||
|
buttons: `<div><b>my button:</b> (click to copy html)</div>
|
||||||
|
<div><img style="cursor: pointer;" src="img/88x31.png" alt="trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button." title="trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button." onclick="copyButton()"></div>
|
||||||
|
<div>--------------------</div>
|
||||||
|
<div><b>cool people:</b></div>
|
||||||
|
<div class="buttons-88x31">
|
||||||
|
<a href="https://notfire.cc" target="_blank"><img src="https://notfire.cc/design/images/buttons/notfire-cc-88x31-af.gif" alt="notfire.cc" title="notfire.cc"></a>
|
||||||
|
<a href="https://micro.niko.lgbt" target="_blank"><img src="https://micro.niko.lgbt/static/button_2.png" alt="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro"" title="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro""></a>
|
||||||
|
<a href="https://w.on-t.work" target="_blank"><img src="https://w.on-t.work/assets/88x31.png" alt="kopper's button" title="kopper's button"></a>
|
||||||
|
<a href="https://synth.download" target="_blank"><img src="https://synth.download/assets/buttons/sneexy.svg" alt="Sneexy" title="Sneexy"></a>
|
||||||
|
<a href="https://beepi.ng" target="_blank"><img src="https://beepi.ng/88x31.png" alt="unnick" title="unnick"></a>
|
||||||
|
</div>`,
|
||||||
|
testimonials: `<div>"warning: this user is trinkey"</div>
|
||||||
|
<div>- <a href="https://booping.synth.download/@breaadyboy" target="_blank">bread</a></div><br>
|
||||||
|
<div>"This user is only slightly crazy once was I. 10/10 would recommend"</div>
|
||||||
|
<div>- <a href="https://lea.pet/@subroutine" target="_blank">subroutine</a></div><br>
|
||||||
|
<div>"the f slur but repeated 36 times"</div>
|
||||||
|
<div>- <a href="https://oomfie.city/@cornfields74">corn fields seventy four</a></div>`,
|
||||||
|
webrings: `<div>
|
||||||
|
<a href="https://ctp-webr.ing/trinkey/previous">←</a>
|
||||||
|
<a href="https://ctp-webr.ing/">catppuccin webring</a>
|
||||||
|
<a href="https://ctp-webr.ing/trinkey/next">→</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="https://fediring.net/previous?host=trinkey.com">←</a>
|
||||||
|
<a href="https://fediring.net/">fediring</a>
|
||||||
|
<a href="https://fediring.net/next?host=trinkey.com">→</a>
|
||||||
|
</div>`,
|
||||||
|
projects: `<div><b>projects</b> - the things i made</div>
|
||||||
|
<div>- <a href="https://github.com/jerimiah-smiggins/smiggins/" target="_blank"><b>smiggins</b></a> (<a href="https://smiggins.trinkey.com/" target="_blank">website</a>) - a social media platform i made</div>
|
||||||
|
<div>- <a href="https://git.trinkey.com/trinkey/website/" target="_blank"><b>this website</b></a> - check out the code</div>
|
||||||
|
<div>- <a href="https://git.gay/trinkey/dotindex/" target="_blank"><b>dotindex</b></a> (<a href="https://pypi.org/project/DotIndex/" target="_blank">pypi</a>) - a python library that lets you access dicts using the dot notation (dict.key) instead of whatever python does (dict["key"])</div>
|
||||||
|
<div>- <a href="https://git.gay/trinkey/infopage/" target="_blank"><b>infopage</b></a> (<a href="https://infpg.pythonanywhere.com/" target="_blank">website</a>) - my very own pronouns.page clone</div>
|
||||||
|
<div>- <a href="https://git.trinkey.com/t" target="_blank"><b>tSuite</b></a> (<a href="https://auth.trinkey.com/" target="_blank">website</a>) - a collection of services that are all interconnected</div><br>
|
||||||
|
<div>i'll likely add more in the future, these are just the ones i'm most proud of at the moment.</div>`,
|
||||||
|
directory: `<div>there's a lot that goes into this website. here are some links for your usage to help you navigate this hellhole</div><br>
|
||||||
|
<div><b><a href="https://trinkey.com/">trinkey.com</a>:</b></div>
|
||||||
|
<div>this is where you are right now</div><br>
|
||||||
|
<div>*<b><a href="https://akkofe.trinkey.com/">akkofe.trinkey.com</a>:</b></div>
|
||||||
|
<div>the frontend i use for <a href="https://fediverse.info/" target="_blank">fedi</a></div><br>
|
||||||
|
<div><b><a href="https://auth.trinkey.com/">auth.trinkey.com</a>:</b></div>
|
||||||
|
<div>authentication manager for tSuite</div><br>
|
||||||
|
<div><b><a href="https://blog.trinkey.com/">blog.trinkey.com</a>:</b></div>
|
||||||
|
<div>tBlog, from tSuite</div><br>
|
||||||
|
<div><b><a href="https://everyone.trinkey.com/">everyone.trinkey.com</a>:</b></div>
|
||||||
|
<div>frontend to a fedi bot that anyone can post to (@everyonebot@is.trinkey.com)</div><br>
|
||||||
|
<div>*<b><a href="https://git.trinkey.com/">git.trinkey.com</a>:</b></div>
|
||||||
|
<div>holds some of my git projects (older ones on <a href="https://github.com/trinkey/" target="_blank">github</a> or <a href="https://git.gay/trinkey/" target="_blank">git.gay</a>)</div><br>
|
||||||
|
<div>*<b><a href="https://is.trinkey.com/">is.trinkey.com</a>:</b></div>
|
||||||
|
<div>hosts <a href="https://iceshrimp.dev/iceshrimp/iceshrimp.net" target="_blank">iceshrimp.net</a>, which is the fedi backend i use</div><br>
|
||||||
|
<div><b><a href="https://message.trinkey.com/">message.trinkey.com</a>:</b></div>
|
||||||
|
<div>tMessage, from tSuite</div><br>
|
||||||
|
<div><b><a href="https://music.trinkey.com/">music.trinkey.com</a>:</b></div>
|
||||||
|
<div>has some music. i haven't actually updated the site in a while but i've been meaning to do rewrite it at some point. 100% legal i pinky promise</div><br>
|
||||||
|
<div><b><a href="https://smiggins.trinkey.com/">smiggins.trinkey.com</a>:</b></div>
|
||||||
|
<div>official jerimiah smiggins instance, that being my own social media platform</div><br>
|
||||||
|
<div>(asterisk (*) means i haven't written the code for it)</div><br>`
|
||||||
|
};
|
||||||
|
const _internal_neofetchOutputs = {
|
||||||
|
desktop: `<pre> <b>...-:::::-...</b> <b class="green">trinkey</b>@<b class="green">desktop</b>
|
||||||
|
<b>.-MMMMMMMMMMMMMMM-.</b> ---------------
|
||||||
|
<b>.-MMMM<span class="green">\`..-:::::::-..\`</span>MMMM-.</b> <b class="green">OS</b>: Linux Mint 21.3 x86_64
|
||||||
|
<b>.:MMMM<span class="green">.:MMMMMMMMMMMMMMM:.</span>MMMM:.</b> <b class="green">Host</b>: MS-7E27 1.0
|
||||||
|
<b>-MMM<span class="green">-M---MMMMMMMMMMMMMMMMMMM.</span>MMM-</b> <b class="green">Resolution</b>: 1680x1050, 2560x1440
|
||||||
|
<b>\`:MMM<span class="green">:MM\` :MMMM:....::-...-MMMM:</span>MMM:\`</b> <b class="green">DE</b>: Cinnamon 6.0.4
|
||||||
|
<b>:MMM<span class="green">:MMM\` :MM:\` \`\` \`\` \`:MMM:</span>MMM:</b> <b class="green">WM</b>: Mutter (Muffin)
|
||||||
|
<b>.MMM<span class="green">.MMMM\` :MM. -MM. .MM- \`MMMM.</span>MMM.</b> <b class="green">CPU</b>: AMD Ryzen 9 7950X (32) @ 5.881GHz
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM-</span>MMM:</b> <b class="green">GPU</b>: AMD ATI 03:00.0 Device 747e
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM:</span>MMM:</b> <b class="green">GPU</b>: AMD ATI 11:00.0 Device 164e
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM-</span>MMM:</b> <b class="green">Memory</b>: 1MiB / 127901MiB
|
||||||
|
<b>.MMM<span class="green">.MMMM\` :MM:--:MM:--:MM: \`MMMM.</span>MMM.</b>
|
||||||
|
<b>:MMM<span class="green">:MMM- \`-MMMMMMMMMMMM-\` -MMM-</span>MMM:</b>
|
||||||
|
<b>:MMM<span class="green">:MMM:\` \`:MMM:</span>MMM:</b>
|
||||||
|
<b>.MMM<span class="green">.MMMM:--------------:MMMM.</span>MMM.</b>
|
||||||
|
<b>'-MMMM<span class="green">.-MMMMMMMMMMMMMMM-.</span>MMMM-'</b>
|
||||||
|
<b>'.-MMMM<span class="green">\`\`--:::::--\`\`</span>MMMM-.'</b>
|
||||||
|
<b>'-MMMMMMMMMMMMM-'</b>
|
||||||
|
<b>\`\`-:::::-\`\`</b></pre>`,
|
||||||
|
laptop: `<pre> <b>...-:::::-...</b> <b class="green">trinkey</b>@<b class="green">laptop</b>
|
||||||
|
<b>.-MMMMMMMMMMMMMMM-.</b> ---------------
|
||||||
|
<b>.-MMMM<span class="green">\`..-:::::::-..\`</span>MMMM-.</b> <b class="green">OS</b>: Linux Mint 21.2 x86_64
|
||||||
|
<b>.:MMMM<span class="green">.:MMMMMMMMMMMMMMM:.</span>MMMM:.</b> <b class="green">Host</b>: Dell G15 5510
|
||||||
|
<b>-MMM<span class="green">-M---MMMMMMMMMMMMMMMMMMM.</span>MMM-</b> <b class="green">Resolution</b>: 2560x1440, 1920x1080, 1680x1050
|
||||||
|
<b>\`:MMM<span class="green">:MM\` :MMMM:....::-...-MMMM:</span>MMM:\`</b> <b class="green">DE</b>: Cinnamon 5.8.4
|
||||||
|
<b>:MMM<span class="green">:MMM\` :MM:\` \`\` \`\` \`:MMM:</span>MMM:</b> <b class="green">WM</b>: Mutter (Muffin)
|
||||||
|
<b>.MMM<span class="green">.MMMM\` :MM. -MM. .MM- \`MMMM.</span>MMM.</b> <b class="green">CPU</b>: Intel i5-10500H (12) @ 4.500GHz
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM-</span>MMM:</b> <b class="green">GPU</b>: NVIDIA GeForce RTX 3050 Ti Mobile
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM:</span>MMM:</b> <b class="green">GPU</b>: Intel CometLake-H GT2 [UHD Graphics]
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM-</span>MMM:</b> <b class="green">Memory</b>: 2001MiB / 15765MiB
|
||||||
|
<b>.MMM<span class="green">.MMMM\` :MM:--:MM:--:MM: \`MMMM.</span>MMM.</b>
|
||||||
|
<b>:MMM<span class="green">:MMM- \`-MMMMMMMMMMMM-\` -MMM-</span>MMM:</b>
|
||||||
|
<b>:MMM<span class="green">:MMM:\` \`:MMM:</span>MMM:</b>
|
||||||
|
<b>.MMM<span class="green">.MMMM:--------------:MMMM.</span>MMM.</b>
|
||||||
|
<b>'-MMMM<span class="green">.-MMMMMMMMMMMMMMM-.</span>MMMM-'</b>
|
||||||
|
<b>'.-MMMM<span class="green">\`\`--:::::--\`\`</span>MMMM-.'</b>
|
||||||
|
<b>'-MMMMMMMMMMMMM-'</b>
|
||||||
|
<b>\`\`-:::::-\`\`</b></pre>`,
|
||||||
|
server: `<pre> <b>...-:::::-...</b> <b class="green">trinkey</b>@<b class="green">server</b>
|
||||||
|
<b>.-MMMMMMMMMMMMMMM-.</b> ---------------
|
||||||
|
<b>.-MMMM<span class="green">\`..-:::::::-..\`</span>MMMM-.</b> <b class="green">OS</b>: Linux Mint 21.2 x86_64
|
||||||
|
<b>.:MMMM<span class="green">.:MMMMMMMMMMMMMMM:.</span>MMMM:.</b> <b class="green">Host</b>: Macmini7,1 1.0
|
||||||
|
<b>-MMM<span class="green">-M---MMMMMMMMMMMMMMMMMMM.</span>MMM-</b> <b class="green">CPU</b>: Intel i5-4278U (4) @ 3.100GHz
|
||||||
|
<b>\`:MMM<span class="green">:MM\` :MMMM:....::-...-MMMM:</span>MMM:\`</b> <b class="green">GPU</b>: Intel Haswell-ULT
|
||||||
|
<b>:MMM<span class="green">:MMM\` :MM:\` \`\` \`\` \`:MMM:</span>MMM:</b> <b class="green">Memory</b>: 9011MiB / 15866MiB
|
||||||
|
<b>.MMM<span class="green">.MMMM\` :MM. -MM. .MM- \`MMMM.</span>MMM.</b>
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM-</span>MMM:</b>
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM:</span>MMM:</b>
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM-</span>MMM:</b>
|
||||||
|
<b>.MMM<span class="green">.MMMM\` :MM:--:MM:--:MM: \`MMMM.</span>MMM.</b>
|
||||||
|
<b>:MMM<span class="green">:MMM- \`-MMMMMMMMMMMM-\` -MMM-</span>MMM:</b>
|
||||||
|
<b>:MMM<span class="green">:MMM:\` \`:MMM:</span>MMM:</b>
|
||||||
|
<b>.MMM<span class="green">.MMMM:--------------:MMMM.</span>MMM.</b>
|
||||||
|
<b>'-MMMM<span class="green">.-MMMMMMMMMMMMMMM-.</span>MMMM-'</b>
|
||||||
|
<b>'.-MMMM<span class="green">\`\`--:::::--\`\`</span>MMMM-.'</b>
|
||||||
|
<b>'-MMMMMMMMMMMMM-'</b>
|
||||||
|
<b>\`\`-:::::-\`\`</b></pre>`
|
||||||
|
};
|
||||||
|
const helpText = `<div> -=== <b class="pink">tSh help</b> ===-</div>
|
||||||
|
<div>--------------------</div>
|
||||||
|
<div>-= <b class="green">cat</b> =-</div>
|
||||||
|
<div>Displays the contents of a file.</div>
|
||||||
|
<div>-= <b class="green">cd</b> =-</div>
|
||||||
|
<div>Changes the working directory.</div>
|
||||||
|
<div>-= <b class="green">clear</b> =-</div>
|
||||||
|
<div>Clears the terminal output.</div>
|
||||||
|
<div>-= <b class="green">help</b> =-</div>
|
||||||
|
<div>Shows this help menu.</div>
|
||||||
|
<div>-= <b class="green">ls</b> =-</div>
|
||||||
|
<div>Lists all files in a directory.</div>
|
||||||
|
<div> -l - displays more information about each file</div>
|
||||||
|
<div> -a - displays all files</div>
|
||||||
|
<div> -A - displays all files except implied . and ..</div>
|
||||||
|
<div> -r - reverses the order of the files</div>
|
||||||
|
<div> -R - recurse through all subdirectories</div>
|
||||||
|
<div>-= <b class="green">exit</b> =-</div>
|
||||||
|
<div>Closes the terminal.</div>`;
|
||||||
|
const HOME_DIR = "/home/trinkey";
|
||||||
|
let FILESYSTEM = {
|
||||||
|
home: {
|
||||||
|
type: "directory",
|
||||||
|
name: "home",
|
||||||
|
files: {
|
||||||
|
trinkey: {
|
||||||
|
type: "directory",
|
||||||
|
name: "trinkey",
|
||||||
|
files: {
|
||||||
|
people: { type: "directory", name: "people", files: {
|
||||||
|
"88x31.txt": { type: "file", name: "88x31.txt", content: _internal_defaultFiles.buttons },
|
||||||
|
"testimonials.txt": { type: "file", name: "testimonials.txt", content: _internal_defaultFiles.testimonials },
|
||||||
|
"webrings.txt": { type: "file", name: "webrings.txt", content: _internal_defaultFiles.webrings }
|
||||||
|
} },
|
||||||
|
"about-me.txt": { type: "file", name: "about-me.txt", content: _internal_defaultFiles.about },
|
||||||
|
"socials.txt": { type: "file", name: "socials.txt", content: _internal_defaultFiles.socials },
|
||||||
|
"projects.txt": { type: "file", name: "projects.txt", content: _internal_defaultFiles.projects },
|
||||||
|
"subdomains.txt": { type: "file", name: "subdomains.txt", content: _internal_defaultFiles.directory }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bin: {
|
||||||
|
type: "directory",
|
||||||
|
name: "bin",
|
||||||
|
files: {
|
||||||
|
cat: { type: "file", name: "cat", content: "<div>function cat(file: string): string { ... }</div>" },
|
||||||
|
cd: { type: "file", name: "cd", content: "<div>function cd(directory: string): void { ... }</div>" },
|
||||||
|
clear: { type: "file", name: "clear", content: "<div>function clear(): void { ... }</div>" },
|
||||||
|
help: { type: "file", name: "help", content: "<div>function help(): string { ... }</div>" },
|
||||||
|
ls: { type: "file", name: "ls", content: "<div>function ls(directory: string): string { ... }</div>" },
|
||||||
|
neofetch: { type: "file", name: "neofetch", content: "<div>function neofetch(): string { ... }</div>" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
".secret-file": { type: "file", name: ".secret-file", content: "<div>meow :3</div>" }
|
||||||
|
};
|
||||||
|
let windowInformation = {};
|
||||||
|
function commandManager(windowID, command) {
|
||||||
|
if (!windowInformation[windowID]) {
|
||||||
|
windowInformation[windowID] = {
|
||||||
|
PWD: HOME_DIR
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let out;
|
||||||
|
if (_internal_commands[command.split(" ")[0]]) {
|
||||||
|
out = _internal_commands[command.split(" ")[0]](command.split(" ").slice(1).join(" ").trim(), windowID);
|
||||||
|
}
|
||||||
|
else if (command == "") {
|
||||||
|
out = "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out = `<div class="red">Unknown command '${escapeHTML(command.split(" ")[0])}'.</div><div>Type 'help' for a list of commands</div>`;
|
||||||
|
}
|
||||||
|
let el = document.createElement("div");
|
||||||
|
el.innerHTML = out;
|
||||||
|
WINDOWS[windowID].element.querySelector(".window").append(el);
|
||||||
|
let dTE = WINDOWS[windowID].element.querySelector("[data-type-area]");
|
||||||
|
if (dTE) {
|
||||||
|
dTE.removeAttribute("data-type-area");
|
||||||
|
if (dTE.querySelector("i.cursor")) {
|
||||||
|
dTE.querySelector("i.cursor").remove();
|
||||||
|
}
|
||||||
|
else if (dTE.querySelector(".cursor")) {
|
||||||
|
dTE.querySelector(".cursor").classList.remove("cursor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WINDOWS[windowID].element.querySelector(".window-header-title").innerText = `${_internal_stringifyPath(windowInformation[windowID].PWD)} - tSh`;
|
||||||
|
let ps1 = document.createElement("div");
|
||||||
|
ps1.innerHTML = _internal_getPS1(windowInformation[windowID]);
|
||||||
|
let typeArea = document.createElement("span");
|
||||||
|
typeArea.dataset.typeArea = "";
|
||||||
|
typeArea.innerHTML = "<i class=\"cursor\"> </i>";
|
||||||
|
ps1.append(typeArea);
|
||||||
|
WINDOWS[windowID].element.querySelector(".window").append(ps1);
|
||||||
|
}
|
|
@ -56,7 +56,7 @@
|
||||||
|
|
||||||
<h2>people</h2>
|
<h2>people</h2>
|
||||||
<h3>my button:</h3>
|
<h3>my button:</h3>
|
||||||
<div><img style="cursor: pointer;" src="img/88x31.png" alt="trinkey's 88x31. image of my cat on the right with the word trinkey taking up the rest of the button." title="trinkey's 88x31. image of my cat on the right with the word trinkey taking up the rest of the button."></div>
|
<div><img style="cursor: pointer;" src="img/88x31.png" alt="trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button." title="trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button."></div>
|
||||||
<div>html:</div>
|
<div>html:</div>
|
||||||
<code style="overflow-x: scroll; display: inline-block; background-color: var(--mantle); padding: 5px 8px; border-radius: 5px;"><a href="https://trinkey.com/" target="_blank"><img src="https://trinkey.com/img/88x31.png" alt="trinkey's 88x31. image of her cat on the right with the word trinkey name taking up the rest of the button." title="trinkey's 88x31. image of her cat on the right with the word trinkey name taking up the rest of the button."></a></code>
|
<code style="overflow-x: scroll; display: inline-block; background-color: var(--mantle); padding: 5px 8px; border-radius: 5px;"><a href="https://trinkey.com/" target="_blank"><img src="https://trinkey.com/img/88x31.png" alt="trinkey's 88x31. image of her cat on the right with the word trinkey name taking up the rest of the button." title="trinkey's 88x31. image of her cat on the right with the word trinkey name taking up the rest of the button."></a></code>
|
||||||
<div>--------------------</div>
|
<div>--------------------</div>
|
||||||
|
|
93
ts/blobcat.ts
Normal file
93
ts/blobcat.ts
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
let points: [number, number, number][] = [[0.3971449136734009, 0.2810116410255432, -0.3767290413379669], [0.23243144154548645, 0.3703259527683258, -0.3767290413379669], [0.30626851320266724, 0.23012861609458923, 0.08654531836509705], [0.15029972791671753, -0.29410237073898315, -0.3767290413379669], [0.3065343499183655, -0.2082172930240631, -0.3767290413379669], [0.3111562132835388, -0.06059299036860466, 0.13771235942840576], [0.16147799789905548, -0.09371967613697052, 0.23468825221061707], [0.36976975202560425, 0.12388059496879578, 0.08632178604602814], [0.31842663884162903, -0.019846681505441666, 0.3223131597042084], [0.20939035713672638, 0.15419937670230865, 0.2242213636636734], [0.17552560567855835, 0.012471526861190796, 0.27797016501426697], [0.16723567247390747, 0.1499461680650711, -0.3767290413379669], [0.4233801066875458, 0.1499461680650711, -0.3767290413379669], [0.3200271725654602, -0.22131121158599854, 0.026444125920534134], [0.15823997557163239, -0.25929194688796997, 0.0673588365316391], [0.44944703578948975, 0.1499461680650711, -0.06793694198131561], [0.2280614674091339, 0.36611324548721313, -0.2975170314311981], [0.38751867413520813, 0.2724340260028839, -0.293896347284317], [0.2147921323776245, 0.3551100790500641, -0.2049424648284912], [0.3594103455543518, 0.2775343060493469, -0.19233158230781555], [0.0, 0.42153987288475037, -0.2989161014556885], [0.0, 0.4475290775299072, -0.3767290413379669], [0.0, 0.10908085107803345, 0.23466001451015472], [0.0, -0.29616573452949524, 0.08896146714687347], [0.0, 0.1499461680650711, -0.3767290413379669], [0.0, -0.1545914262533188, 0.23468825221061707], [0.0, 0.012471422553062439, 0.28773677349090576], [0.0, -0.29410237073898315, -0.3767290413379669], [0.0, 0.3850858211517334, -0.2098153829574585], [0.15266574919223785, 0.33635783195495605, 0.08654531091451645], [0.0, 0.34858277440071106, 0.08654531836509705], [0.3163855969905853, -0.30245065689086914, -0.2832803726196289], [0.15313652157783508, -0.3652721643447876, -0.2640822231769562], [0.43641358613967896, 0.1499461680650711, -0.2795500159263611], [0.0, -0.3652721643447876, -0.2640821933746338], [0.3884555399417877, 0.012471545487642288, -0.3767290413379669], [0.34046298265457153, 0.012471519410610199, 0.11201705783605576], [0.1587677001953125, 0.01247154176235199, -0.3767290413379669], [0.384737104177475, 0.012471544556319714, -0.026815753430128098], [0.0, 0.012471549212932587, -0.3767290413379669], [0.39989548921585083, 0.012471545487642288, -0.30725497007369995], [-0.3971449136734009, 0.2810116410255432, -0.3767290413379669], [-0.23243144154548645, 0.3703259527683258, -0.3767290413379669], [-0.30626851320266724, 0.23012861609458923, 0.08654531836509705], [-0.15029972791671753, -0.29410237073898315, -0.3767290413379669], [-0.3065343499183655, -0.2082172930240631, -0.3767290413379669], [-0.3111562132835388, -0.06059299036860466, 0.13771235942840576], [-0.16147799789905548, -0.09371967613697052, 0.23468825221061707], [-0.36976975202560425, 0.12388059496879578, 0.08632178604602814], [-0.31842663884162903, -0.019846681505441666, 0.3223131597042084], [-0.20939035713672638, 0.15419937670230865, 0.2242213636636734], [-0.17552560567855835, 0.012471526861190796, 0.27797016501426697], [-0.16723567247390747, 0.1499461680650711, -0.3767290413379669], [-0.4233801066875458, 0.1499461680650711, -0.3767290413379669], [-0.3200271725654602, -0.22131121158599854, 0.026444125920534134], [-0.15823997557163239, -0.25929194688796997, 0.0673588365316391], [-0.44944703578948975, 0.1499461680650711, -0.06793694198131561], [-0.2280614674091339, 0.36611324548721313, -0.2975170314311981], [-0.38751867413520813, 0.2724340260028839, -0.293896347284317], [-0.2147921323776245, 0.3551100790500641, -0.2049424648284912], [-0.3594103455543518, 0.2775343060493469, -0.19233158230781555], [-0.15266574919223785, 0.33635783195495605, 0.08654531091451645], [-0.3163855969905853, -0.30245065689086914, -0.2832803726196289], [-0.15313652157783508, -0.3652721643447876, -0.2640822231769562], [-0.43641358613967896, 0.1499461680650711, -0.2795500159263611], [-0.3884555399417877, 0.012471545487642288, -0.3767290413379669], [-0.34046298265457153, 0.012471519410610199, 0.11201705783605576], [-0.1587677001953125, 0.01247154176235199, -0.3767290413379669], [-0.384737104177475, 0.012471544556319714, -0.026815753430128098], [-0.39989548921585083, 0.012471545487642288, -0.30725497007369995]];
|
||||||
|
const connections: [number, number][] = [[0, 1], [0, 12], [0, 17], [1, 11], [1, 16], [1, 21], [2, 7], [2, 9], [2, 19], [2, 29], [3, 4], [3, 27], [3, 32], [3, 37], [4, 31], [4, 35], [5, 6], [5, 8], [5, 13], [5, 36], [6, 8], [6, 10], [6, 14], [6, 25], [7, 8], [7, 9], [7, 15], [7, 36], [8, 9], [8, 10], [8, 36], [9, 10], [9, 22], [9, 29], [10, 26], [11, 12], [11, 24], [11, 37], [12, 33], [12, 35], [13, 14], [13, 31], [13, 38], [14, 23], [14, 32], [15, 19], [15, 33], [15, 38], [16, 17], [16, 18], [16, 20], [17, 19], [17, 33], [18, 19], [18, 28], [18, 29], [20, 21], [20, 28], [20, 57], [21, 24], [21, 42], [22, 26], [22, 30], [22, 50], [23, 25], [23, 34], [23, 55], [24, 39], [24, 52], [25, 26], [25, 47], [26, 51], [27, 34], [27, 39], [27, 44], [28, 30], [28, 59], [29, 30], [30, 61], [31, 32], [31, 40], [32, 34], [33, 40], [34, 63], [35, 37], [35, 40], [36, 38], [37, 39], [38, 40], [39, 67], [41, 42], [41, 53], [41, 58], [42, 52], [42, 57], [43, 48], [43, 50], [43, 60], [43, 61], [44, 45], [44, 63], [44, 67], [45, 62], [45, 65], [46, 47], [46, 49], [46, 54], [46, 66], [47, 49], [47, 51], [47, 55], [48, 49], [48, 50], [48, 56], [48, 66], [49, 50], [49, 51], [49, 66], [50, 51], [50, 61], [52, 53], [52, 67], [53, 64], [53, 65], [54, 55], [54, 62], [54, 68], [55, 63], [56, 60], [56, 64], [56, 68], [57, 58], [57, 59], [58, 60], [58, 64], [59, 60], [59, 61], [62, 63], [62, 69], [64, 69], [65, 67], [65, 69], [66, 68], [68, 69]];
|
||||||
|
const blobcatColor: { light: string, dark: string } = { light: "#df8e1d", dark: "#f9e2af" }
|
||||||
|
const focalLength: number = 1;
|
||||||
|
const radians: number = (2 * Math.PI / 360) * 3;
|
||||||
|
const rotationalMatrix: [number, number, number][] = [
|
||||||
|
[Math.cos(radians), -Math.sin(radians), 0],
|
||||||
|
[Math.sin(radians), Math.cos(radians), 0],
|
||||||
|
[0, 0, 1]
|
||||||
|
]
|
||||||
|
|
||||||
|
let blobcatElement: HTMLDivElement | null = null;
|
||||||
|
|
||||||
|
function dot(a: number[][], b: number[][]): number[][] {
|
||||||
|
const rows: number = a.length;
|
||||||
|
const colsA: number = a[0].length;
|
||||||
|
const colsB: number = b[0].length;
|
||||||
|
const result: number[][] = Array.from({ length: rows }, (): number[] => Array(colsB).fill(0));
|
||||||
|
|
||||||
|
for (let i: number = 0; i < rows; i++) {
|
||||||
|
for (let j: number = 0; j < colsB; j++) {
|
||||||
|
for (let k: number = 0; k < colsA; k++) {
|
||||||
|
result[i][j] += a[i][k] * b[k][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLine(
|
||||||
|
x1: number, y1: number, x2: number, y2: number,
|
||||||
|
multiply: number,
|
||||||
|
offsetX: number,
|
||||||
|
offsetY: number,
|
||||||
|
zIndex: number
|
||||||
|
): HTMLHRElement {
|
||||||
|
let hr: HTMLHRElement = document.createElement("hr");
|
||||||
|
|
||||||
|
x1 = x1 * multiply;
|
||||||
|
y1 = y1 * multiply;
|
||||||
|
x2 = x2 * multiply;
|
||||||
|
y2 = y2 * multiply;
|
||||||
|
|
||||||
|
hr.style.position = "absolute";
|
||||||
|
hr.style.left = `${x1 + offsetX}px`;
|
||||||
|
hr.style.top = `${y1 + offsetY}px`;
|
||||||
|
hr.style.height = `1px`;
|
||||||
|
hr.style.width = `${Math.sqrt(((x2-x1) * (x2-x1)) + ((y2-y1) * (y2-y1)))}px`;
|
||||||
|
hr.style.rotate = `${Math.atan2(y2 - y1, x2 - x1)}rad`;
|
||||||
|
hr.style.transformOrigin = `0 0.5px`;
|
||||||
|
hr.style.backgroundColor = light ? blobcatColor.light : blobcatColor.dark;
|
||||||
|
hr.style.border = "0";
|
||||||
|
hr.style.zIndex = String(zIndex)
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function blobcatFrame(): void {
|
||||||
|
if (!blobcatElement || !WINDOWS.blob) { return; }
|
||||||
|
|
||||||
|
let screenCoordinates: [number, number][] = points.map((a: [number, number, number]): [number, number] => ([
|
||||||
|
(focalLength * a[0]) / (a[1] + focalLength),
|
||||||
|
-(focalLength * a[2]) / (a[1] + focalLength)
|
||||||
|
]));
|
||||||
|
|
||||||
|
let hrElements: HTMLHRElement[] = connections.map((a: [number, number]): HTMLHRElement => (
|
||||||
|
getLine(...screenCoordinates[a[0]], ...screenCoordinates[a[1]], 300, WINDOWS.blob.width / 2 + 11, WINDOWS.blob.height / 2 + 11, WINDOWS.blob.zIndex)
|
||||||
|
));
|
||||||
|
|
||||||
|
blobcatElement.innerHTML = "";
|
||||||
|
blobcatElement.append(...hrElements);
|
||||||
|
points = dot(points, rotationalMatrix) as [number, number, number][];
|
||||||
|
}
|
||||||
|
|
||||||
|
function createBlob(): void {
|
||||||
|
createWindow({
|
||||||
|
id: "blob",
|
||||||
|
title: "~/spinny-cat",
|
||||||
|
content: "<div id='blobcat'></div>",
|
||||||
|
onDestroy: destroyBlob,
|
||||||
|
height: 450,
|
||||||
|
typeable: false
|
||||||
|
});
|
||||||
|
|
||||||
|
blobcatElement = document.getElementById("blobcat") as HTMLDivElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroyBlob(): void {
|
||||||
|
blobcatElement = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(blobcatFrame, 1000 / 30);
|
49
ts/globals.d.ts
vendored
Normal file
49
ts/globals.d.ts
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
declare let light: boolean;
|
||||||
|
|
||||||
|
type StringDict = { [key: string]: string }
|
||||||
|
|
||||||
|
type _winInitConf = {
|
||||||
|
title: string,
|
||||||
|
content: string,
|
||||||
|
id: string,
|
||||||
|
width?: number, // = 600
|
||||||
|
height?: number, // = 400
|
||||||
|
minWidth?: number, // = 200
|
||||||
|
minHeight?: number, // = 200
|
||||||
|
typeable?: boolean, // true
|
||||||
|
posX?: number, // = automatically centered
|
||||||
|
posY?: number, // = automatically centered
|
||||||
|
onDestroy?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
type _winConf = {
|
||||||
|
element: HTMLElement,
|
||||||
|
height: number,
|
||||||
|
width: number,
|
||||||
|
posX: number,
|
||||||
|
posY: number,
|
||||||
|
fullscreen: boolean,
|
||||||
|
zIndex: number,
|
||||||
|
vars: {
|
||||||
|
[key: string]: any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type _files = {
|
||||||
|
[key: string]: _file
|
||||||
|
}
|
||||||
|
|
||||||
|
type _file = {
|
||||||
|
type: "directory",
|
||||||
|
name: string,
|
||||||
|
files: _files
|
||||||
|
} | {
|
||||||
|
type: "file",
|
||||||
|
name: string,
|
||||||
|
content: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type _tShWinInfo = {
|
||||||
|
PWD: string,
|
||||||
|
ps1Override?: string
|
||||||
|
}
|
272
ts/index.ts
Normal file
272
ts/index.ts
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
let WINDOWS: { [key: string]: _winConf } = {};
|
||||||
|
let MOUSE_MOVE_PROCESSING: {
|
||||||
|
[key: string]: {
|
||||||
|
callback: (x: number, y: number) => void,
|
||||||
|
mouseUp: boolean
|
||||||
|
}
|
||||||
|
} = {};
|
||||||
|
|
||||||
|
let globalIncrement: number = 1;
|
||||||
|
|
||||||
|
function escapeHTML(string: string): string {
|
||||||
|
return string.replaceAll("&", "&").replaceAll("<", "<").replaceAll("\"", """);
|
||||||
|
}
|
||||||
|
|
||||||
|
function incrementZIndex(windowID: string, focus: boolean=false): void {
|
||||||
|
WINDOWS[windowID].element.style.zIndex = String(globalIncrement);
|
||||||
|
WINDOWS[windowID].zIndex = globalIncrement;
|
||||||
|
globalIncrement++;
|
||||||
|
|
||||||
|
if (focus) {
|
||||||
|
WINDOWS[windowID].element.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createWindow(config: _winInitConf): void {
|
||||||
|
if (document.getElementById(config.id)) {
|
||||||
|
incrementZIndex(config.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1 - border
|
||||||
|
// 10 - padding
|
||||||
|
// 35 - header
|
||||||
|
let _windowPaddingX: number = 1*2 + 10*2;
|
||||||
|
let _windowPaddingY: number = 1*2 + 10*2 + 35;
|
||||||
|
|
||||||
|
config.width = config.width || 600;
|
||||||
|
config.height = config.height || 400;
|
||||||
|
config.minWidth = config.minWidth || 200;
|
||||||
|
config.minHeight = config.minHeight || 200;
|
||||||
|
|
||||||
|
let realWidth: number = Math.max(config.minWidth, Math.min(config.width, innerWidth - _windowPaddingX - 20));
|
||||||
|
let realHeight: number = Math.max(config.minHeight, Math.min(config.height, innerHeight - _windowPaddingY - 20));
|
||||||
|
|
||||||
|
let posX: number = config.posX || Math.round((innerWidth / 2) - ((realWidth + _windowPaddingX) / 2));
|
||||||
|
let posY: number = config.posY || Math.round((innerHeight / 2) - ((realHeight + _windowPaddingY) / 2));
|
||||||
|
|
||||||
|
let wO: HTMLDivElement = document.createElement("div");
|
||||||
|
wO.classList.add("window-outer");
|
||||||
|
|
||||||
|
let w: HTMLDivElement = document.createElement("div");
|
||||||
|
w.classList.add("window");
|
||||||
|
w.style.width = `${realWidth}px`;
|
||||||
|
w.style.height = `${realHeight}px`;
|
||||||
|
w.innerHTML = config.content;
|
||||||
|
|
||||||
|
let wH: HTMLDivElement = document.createElement("div");
|
||||||
|
wH.classList.add("window-header");
|
||||||
|
wH.innerHTML = `
|
||||||
|
<i class="window-header-button blank"></i>
|
||||||
|
<i class="window-header-button blank"></i>
|
||||||
|
<i class="window-header-button blank"></i>
|
||||||
|
<strong class="window-header-title">${config.title}</strong>
|
||||||
|
<i data-no-move class="window-header-button minimize"></i>
|
||||||
|
<i data-no-move class="window-header-button fullscreen"></i>
|
||||||
|
<i data-no-move class="window-header-button close"></i>
|
||||||
|
`;
|
||||||
|
|
||||||
|
let wC: HTMLDivElement | HTMLLabelElement;
|
||||||
|
let wI: HTMLInputElement = null;
|
||||||
|
if (config.typeable !== false) {
|
||||||
|
function syncInputs(): void {
|
||||||
|
setTimeout(function(): void {
|
||||||
|
let text: string = wI.value;
|
||||||
|
let cursor: number = wI.selectionStart;
|
||||||
|
let el: HTMLElement = wC.querySelector("[data-type-area]");
|
||||||
|
|
||||||
|
if (!el) { return; }
|
||||||
|
|
||||||
|
if (cursor == text.length) {
|
||||||
|
el.innerHTML = `${escapeHTML(text)}<i class="cursor"> </i>`;
|
||||||
|
} else {
|
||||||
|
el.innerHTML = `${escapeHTML(text.slice(0, cursor))}<span class="cursor">${escapeHTML(text[cursor])}</span>${escapeHTML(text.slice(cursor + 1))}`;
|
||||||
|
}
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCursor(): void {
|
||||||
|
setTimeout((): void => {
|
||||||
|
wI.setSelectionRange(wI.value.length, wI.value.length);
|
||||||
|
syncInputs();
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
wI = document.createElement("input");
|
||||||
|
wI.classList.add("window-input");
|
||||||
|
wI.id = `${config.id}__input`;
|
||||||
|
|
||||||
|
wI.oninput = (event: KeyboardEvent): void => {
|
||||||
|
syncInputs();
|
||||||
|
w.scrollTop = w.scrollHeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
wI.onkeydown = (event: KeyboardEvent): void => {
|
||||||
|
if (event.key == "Enter") {
|
||||||
|
commandManager(config.id, wI.value.trim());
|
||||||
|
w.scrollTop = w.scrollHeight;
|
||||||
|
wI.value = "";
|
||||||
|
} else {
|
||||||
|
syncInputs();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
wI.onfocus = setCursor;
|
||||||
|
wI.onclick = setCursor;
|
||||||
|
|
||||||
|
wC = document.createElement("label");
|
||||||
|
wC.htmlFor = `${config.id}__input`;
|
||||||
|
} else {
|
||||||
|
wC = document.createElement("div");
|
||||||
|
}
|
||||||
|
|
||||||
|
wC.classList.add("window-container");
|
||||||
|
wC.tabIndex = 0;
|
||||||
|
wC.style.left = `${posX}px`;
|
||||||
|
wC.style.top = `${posY}px`;
|
||||||
|
wC.id = config.id;
|
||||||
|
wC.style.zIndex = String(globalIncrement);
|
||||||
|
wC.style.width = `${realWidth + _windowPaddingX - 2}px`;
|
||||||
|
|
||||||
|
wO.append(w);
|
||||||
|
wC.append(wH, wO);
|
||||||
|
document.body.append(wC);
|
||||||
|
|
||||||
|
if (config.typeable !== false) {
|
||||||
|
wC.append(wI);
|
||||||
|
wI.focus();
|
||||||
|
} else {
|
||||||
|
wC.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
WINDOWS[config.id] = {
|
||||||
|
element: wC,
|
||||||
|
height: realHeight,
|
||||||
|
width: realWidth,
|
||||||
|
posX: posX,
|
||||||
|
posY: posY,
|
||||||
|
fullscreen: false,
|
||||||
|
zIndex: globalIncrement,
|
||||||
|
vars: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
function mouseMoveEvent(x: number, y: number): void {
|
||||||
|
WINDOWS[config.id].posX = Math.max(0, Math.min(innerWidth - WINDOWS[config.id].width - _windowPaddingX, x - WINDOWS[config.id].vars.mouseOffsetX));
|
||||||
|
WINDOWS[config.id].posY = Math.max(0, Math.min(innerHeight - WINDOWS[config.id].height - _windowPaddingY, y - WINDOWS[config.id].vars.mouseOffsetY));
|
||||||
|
wC.style.left = `${WINDOWS[config.id].posX}px`;
|
||||||
|
wC.style.top = `${WINDOWS[config.id].posY}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wC.addEventListener("mousedown", function(): void { incrementZIndex(config.id); });
|
||||||
|
wC.addEventListener("focus", function(): void { incrementZIndex(config.id); });
|
||||||
|
|
||||||
|
for (const link of wC.querySelectorAll("a")) {
|
||||||
|
link.addEventListener("focus", function(): void { incrementZIndex(config.id); });
|
||||||
|
}
|
||||||
|
|
||||||
|
wH.addEventListener("mousedown", function(e: MouseEvent): void {
|
||||||
|
if ((e.target as HTMLElement).dataset.noMove !== undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WINDOWS[config.id].vars.mouseOffsetX = e.clientX - WINDOWS[config.id].posX;
|
||||||
|
WINDOWS[config.id].vars.mouseOffsetY = e.clientY - WINDOWS[config.id].posY;
|
||||||
|
MOUSE_MOVE_PROCESSING[config.id] = {
|
||||||
|
callback: mouseMoveEvent,
|
||||||
|
mouseUp: true
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
wH.querySelector(".close").addEventListener("click", function(): void {
|
||||||
|
delete WINDOWS[config.id];
|
||||||
|
delete windowInformation[config.id];
|
||||||
|
delete MOUSE_MOVE_PROCESSING[config.id];
|
||||||
|
wC.remove();
|
||||||
|
|
||||||
|
if (typeof config.onDestroy === "function") {
|
||||||
|
config.onDestroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
wH.querySelector(".fullscreen").addEventListener("click", function(): void {
|
||||||
|
if (WINDOWS[config.id].fullscreen) {
|
||||||
|
WINDOWS[config.id].posX = WINDOWS[config.id].vars.oldPosX;
|
||||||
|
WINDOWS[config.id].posY = WINDOWS[config.id].vars.oldPosY;
|
||||||
|
WINDOWS[config.id].width = WINDOWS[config.id].vars.oldWidth;
|
||||||
|
WINDOWS[config.id].height = WINDOWS[config.id].vars.oldHeight;
|
||||||
|
WINDOWS[config.id].fullscreen = false;
|
||||||
|
delete WINDOWS[config.id].vars.oldPosX;
|
||||||
|
delete WINDOWS[config.id].vars.oldPosY;
|
||||||
|
delete WINDOWS[config.id].vars.oldWidth;
|
||||||
|
delete WINDOWS[config.id].vars.oldHeight;
|
||||||
|
wC.style.left = `${WINDOWS[config.id].posX}px`;
|
||||||
|
wC.style.top = `${WINDOWS[config.id].posY}px`;
|
||||||
|
wC.style.width = `${WINDOWS[config.id].width + _windowPaddingX - 2}px`;
|
||||||
|
w.style.width = `${WINDOWS[config.id].width}px`;
|
||||||
|
w.style.height = `${WINDOWS[config.id].height}px`;
|
||||||
|
} else {
|
||||||
|
WINDOWS[config.id].vars.oldPosX = WINDOWS[config.id].posX;
|
||||||
|
WINDOWS[config.id].vars.oldPosY = WINDOWS[config.id].posY;
|
||||||
|
WINDOWS[config.id].vars.oldWidth = WINDOWS[config.id].width;
|
||||||
|
WINDOWS[config.id].vars.oldHeight = WINDOWS[config.id].height;
|
||||||
|
WINDOWS[config.id].fullscreen = true;
|
||||||
|
WINDOWS[config.id].posX = 0;
|
||||||
|
WINDOWS[config.id].posY = 0;
|
||||||
|
WINDOWS[config.id].width = innerWidth;
|
||||||
|
WINDOWS[config.id].height = innerHeight;
|
||||||
|
wC.style.left = "0px";
|
||||||
|
wC.style.top = "0px";
|
||||||
|
wC.style.width = `${WINDOWS[config.id].width}px`;
|
||||||
|
w.style.width = `${WINDOWS[config.id].width - _windowPaddingX}px`;
|
||||||
|
w.style.height = `${WINDOWS[config.id].height - _windowPaddingY}px`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
globalIncrement++;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("mousemove", function(e: MouseEvent): void {
|
||||||
|
for (const key of Object.keys(MOUSE_MOVE_PROCESSING)) {
|
||||||
|
MOUSE_MOVE_PROCESSING[key].callback(e.clientX, e.clientY);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("mouseup", function(): void {
|
||||||
|
for (const key of Object.keys(MOUSE_MOVE_PROCESSING)) {
|
||||||
|
if (MOUSE_MOVE_PROCESSING[key].mouseUp) {
|
||||||
|
delete MOUSE_MOVE_PROCESSING[key];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function windowPreset(template: string): void {
|
||||||
|
let el: HTMLElement = document.querySelector(`#window-templates > [data-template-id="${template}"]`);
|
||||||
|
|
||||||
|
if (!el) { return; }
|
||||||
|
|
||||||
|
if (WINDOWS[template]) {
|
||||||
|
incrementZIndex(template, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let config: _winInitConf = {
|
||||||
|
id: template,
|
||||||
|
title: "~ - tSh",
|
||||||
|
content: "<div><b class=\"green\">trinkey@website</b>:<b class=\"blue\">~</b>$ <span data-type-area><i class=\"cursor\"> </i></span></div>"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const field of el.querySelectorAll("[data-template-field]")) {
|
||||||
|
config[(field as HTMLElement).dataset.templateField] = (field as HTMLElement).dataset.isNumber === "" ? +(field as HTMLElement).innerText : (field as HTMLElement).innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
createWindow(config);
|
||||||
|
|
||||||
|
for (const command of el.querySelectorAll("li")) {
|
||||||
|
WINDOWS[template].element.querySelector("[data-type-area]").innerHTML = command.innerHTML;
|
||||||
|
commandManager(template, command.innerHTML);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyButton(): void {
|
||||||
|
navigator.clipboard.writeText("<a href=\"https://trinkey.com/\" target=\"_blank\"><img src=\"https://trinkey.com/img/88x31.png\" alt=\"trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button.\" title=\"trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button.\"></a>");
|
||||||
|
}
|
504
ts/shell.ts
Normal file
504
ts/shell.ts
Normal file
|
@ -0,0 +1,504 @@
|
||||||
|
// -= Helper Functions =- //
|
||||||
|
function _internal_joinPaths(path1: string, path2: string): string {
|
||||||
|
if (path2[0] == "/") {
|
||||||
|
return _internal_sanitizePath(path2);
|
||||||
|
} else if (path2[0] == "~" && (path2.length == 1 || path2[1] == "/")) {
|
||||||
|
return _internal_sanitizePath(HOME_DIR + path2.slice(1));
|
||||||
|
} else {
|
||||||
|
return _internal_sanitizePath(path1 + "/" + path2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _internal_sanitizePath(path: string): string {
|
||||||
|
while (path.includes("//")) {
|
||||||
|
path = path.replaceAll("//", "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (path[path.length - 1] == "/") {
|
||||||
|
path = path.slice(0, path.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let newPath: string[] = []
|
||||||
|
for (const dir of path.split("/")) {
|
||||||
|
if (dir == ".") {
|
||||||
|
//
|
||||||
|
} else if (dir == "..") {
|
||||||
|
if (newPath.length) {
|
||||||
|
newPath = newPath.slice(0, newPath.length - 1);
|
||||||
|
}
|
||||||
|
} else if (dir) {
|
||||||
|
newPath.push(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "/" + newPath.join("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
function _internal_getFile(path: string): _file | null {
|
||||||
|
function getFile_recursive(files: _files, path: string[]): _file | null {
|
||||||
|
console.log(files, path)
|
||||||
|
let file: _file = files[path[0]];
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.length == 1) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.type == "file") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getFile_recursive(file.files, path.slice(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path == "/") {
|
||||||
|
return {
|
||||||
|
type: "directory",
|
||||||
|
name: "/",
|
||||||
|
files: FILESYSTEM
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let dirs: string[] = path.split("/");
|
||||||
|
|
||||||
|
if (dirs[0] == "") {
|
||||||
|
dirs = dirs.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getFile_recursive(FILESYSTEM, dirs);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _internal_stringifyPath(path: string): string {
|
||||||
|
if (path.startsWith(HOME_DIR)) {
|
||||||
|
return path.replace(HOME_DIR, "~");
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _internal_getPS1(winInfo: _tShWinInfo): string {
|
||||||
|
return `<b class="green">${winInfo.ps1Override || "trinkey@website"}</b>:<b class="blue">${_internal_stringifyPath(winInfo.PWD)}</b>$ `
|
||||||
|
}
|
||||||
|
|
||||||
|
function _internal_getFlags(command: string): {
|
||||||
|
flags: string[]
|
||||||
|
removed: string
|
||||||
|
} {
|
||||||
|
let flags: string[] = [];
|
||||||
|
let newCommand: string[] = [];
|
||||||
|
|
||||||
|
for (const thing of command.split(" ")) {
|
||||||
|
if (thing.startsWith("-")) {
|
||||||
|
flags.push(...thing.slice(1).split(""))
|
||||||
|
} else {
|
||||||
|
newCommand.push(thing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
flags: flags,
|
||||||
|
removed: newCommand.join(" ")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function _internal_fileSize(size: number): string {
|
||||||
|
let suffix: string = ""
|
||||||
|
let amount: number = size;
|
||||||
|
|
||||||
|
const sizes: { suffix: string, amount: number, threshold: number }[] = [
|
||||||
|
{ suffix: "K", amount: 1024 , threshold: 10_000 },
|
||||||
|
{ suffix: "M", amount: 1024 ** 2, threshold: 1_000_000 }
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const info of sizes) {
|
||||||
|
if (size > info.threshold) {
|
||||||
|
suffix = info.suffix;
|
||||||
|
amount = Math.round(size / info.amount * 10) / 10;
|
||||||
|
|
||||||
|
if (String(amount).length > 3) {
|
||||||
|
amount = Math.round(info.amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${amount}${suffix}`.padStart(4, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -= Commands =- //
|
||||||
|
function cat(path: string, windowID: string): string {
|
||||||
|
if (!path) {
|
||||||
|
return "<div>cat: You must specify a file</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
path = _internal_joinPaths(windowInformation[windowID].PWD || HOME_DIR, path);
|
||||||
|
let file: _file = _internal_getFile(path);
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
return `<div>cat: ${escapeHTML(path)}: No such file or directory</div>`;
|
||||||
|
} else if (file.type == "directory") {
|
||||||
|
return `<div>cat: ${escapeHTML(path)}: Is a directory</div>`;
|
||||||
|
} else {
|
||||||
|
return file.content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cd(path: string, windowID: string): string {
|
||||||
|
if (!path) {
|
||||||
|
windowInformation[windowID].PWD = HOME_DIR;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
let newPWD: string = _internal_joinPaths(windowInformation[windowID].PWD, path);
|
||||||
|
let newFileObj: _file | null = _internal_getFile(newPWD);
|
||||||
|
|
||||||
|
if (newFileObj === null) {
|
||||||
|
return `<div>cd: ${escapeHTML(path)}: No such file or directory</div>`;
|
||||||
|
} else if (newFileObj.type == "file") {
|
||||||
|
return `<div>cd: ${escapeHTML(path)}: Not a directory</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
windowInformation[windowID].PWD = newPWD;
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear(path: string, windowID: string): string {
|
||||||
|
WINDOWS[windowID].element.querySelector(".window").innerHTML = "";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function exit(path: string, windowID: string): string {
|
||||||
|
setTimeout((): void => {
|
||||||
|
(WINDOWS[windowID].element.querySelector(".close") as HTMLElement).click();
|
||||||
|
}, 1);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function help(path: string, windowID: string): string {
|
||||||
|
return helpText;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ls(path: string, windowID: string): string {
|
||||||
|
let { flags, removed } = _internal_getFlags(path);
|
||||||
|
|
||||||
|
path = _internal_joinPaths(windowInformation[windowID].PWD || HOME_DIR, removed);
|
||||||
|
|
||||||
|
let file: _file = _internal_getFile(path);
|
||||||
|
let files: _files;
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
return `<div>ls: ${escapeHTML(path)}: No such file or directory</div>`;
|
||||||
|
} else if (file.type == "file") {
|
||||||
|
files = { [file.name]: file };
|
||||||
|
} else {
|
||||||
|
files = file.files;
|
||||||
|
}
|
||||||
|
|
||||||
|
let directories: _file[] = [];
|
||||||
|
let hidden: boolean = flags.includes("a") || flags.includes("A");
|
||||||
|
let long: boolean = flags.includes("l");
|
||||||
|
let out: string = flags.includes("a") ? (long ? "<div>drwxrwxr-x trinkey trinkey 4096 <span class=\"blue\">.</span></div><div>drwxr-xr-x trinkey trinkey 4096 <span class=\"blue\">..</span></div>" : "<span class=\"blue\">.</span> <span class=\"blue\">..</span> ") : "";
|
||||||
|
|
||||||
|
for (const file of Object.keys(files).sort((a: string, b: string): number => (
|
||||||
|
({ true: 1, false: -1 })[String(flags.includes("r") ? a < b : a > b)]
|
||||||
|
))) {
|
||||||
|
if (file.startsWith(".") && !hidden) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let fObj: _file = files[file];
|
||||||
|
if (long) {
|
||||||
|
if (fObj.type == "directory") {
|
||||||
|
directories.push(fObj);
|
||||||
|
out += `<div>drwxrwxr-x trinkey trinkey 4096 <span class=\"blue\">${escapeHTML(file)}</span></div>`;
|
||||||
|
} else {
|
||||||
|
out += `<div>-rw-rw-r-- trinkey trinkey ${_internal_fileSize(fObj.content.length).replaceAll(" ", " ")} ${escapeHTML(file)}</div>`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (fObj.type == "directory") {
|
||||||
|
directories.push(fObj);
|
||||||
|
out += `<span class=\"blue\">${escapeHTML(file)}</span> `;
|
||||||
|
} else {
|
||||||
|
out += `${escapeHTML(file)} `;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!long) {
|
||||||
|
out = out.slice(0, out.length - 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags.includes("R")) {
|
||||||
|
for (const dir of directories) {
|
||||||
|
out += `<div><br>${escapeHTML(_internal_stringifyPath(_internal_joinPaths(path, dir.name)))}:</div>${ls(`${_internal_joinPaths(path, dir.name)} -${flags.join("")}`, windowID)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _internal_set_ps1(args: string, windowID: string): string {
|
||||||
|
windowInformation[windowID].ps1Override = args.split("|")[0];
|
||||||
|
WINDOWS[windowID].element.querySelector(".window [data-type-area]").innerHTML = args.split("|")[1];
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function _internal_neofetch(args: string, windowID: string): string {
|
||||||
|
WINDOWS[windowID].element.querySelector(".window [data-type-area]").innerHTML = "neofetch";
|
||||||
|
return _internal_neofetchOutputs[args];
|
||||||
|
}
|
||||||
|
|
||||||
|
const _internal_commands: { [key: string]: (args: string, windowID: string) => string } = {
|
||||||
|
cat: cat,
|
||||||
|
cd: cd,
|
||||||
|
clear: clear,
|
||||||
|
help: help, // NEEDS UPDATING
|
||||||
|
ls: ls,
|
||||||
|
exit: exit,
|
||||||
|
_internal_set_ps1: _internal_set_ps1,
|
||||||
|
_internal_neofetch: _internal_neofetch
|
||||||
|
};
|
||||||
|
|
||||||
|
// -= Variables + Other =- //
|
||||||
|
const _internal_defaultFiles: StringDict = {
|
||||||
|
about: `<div><b>hi there! i'm trinkey!</b></div>
|
||||||
|
<div>--------------------</div>
|
||||||
|
<div>i'm a silly little kitty cat who lives in the usa.</div>
|
||||||
|
<div>i'm <span class="blue">t</span><span class="pink">r</span>a<span class="pink">n</span><span class="blue">s</span> (she/her, they/them and it/its are also fine).</div>
|
||||||
|
<div>i'm not actively in a relationship, however i'm also not looking to get into one either.</div>
|
||||||
|
<div>--------------------</div>
|
||||||
|
<div>i like to code stuff (mostly websites)! some of my programs can be found on the <a href="javascript:windowPreset('projects')">projects page</a>. i know a few languages, those being python, javascript/typescript, html/css (if you count those), and a little bit of java.</div>
|
||||||
|
<div>--------------------</div>
|
||||||
|
<div>well, that's about it! i hope you like my website!</div>`,
|
||||||
|
socials: `<div>- fedi - <b>@trinkey@trinkey.com</b> (or @trinkey@is.trinkey.com)</div>
|
||||||
|
<div>- forgejo - <a href="https://git.trinkey.com/trinkey/" target="_blank"><b>trinkey</b></a></div>
|
||||||
|
<div>- github - <a href="https://github.com/trinkey/" target="_blank"><b>trinkey</b></a></div>
|
||||||
|
<div>- git.gay - <a href="https://git.gay/trinkey/" target="_blank"><b>trinkey</b></a> (inactive)</div>
|
||||||
|
<div>- smiggins - <a href="https://smiggins.trinkey.com/u/trinkey/" target="_blank"><b>trinkey</b></a></div>
|
||||||
|
<div>- signal - <b>@trinkey.01</b></div>
|
||||||
|
<div>- email - <b>trinkey [at] proton [dot] me</b></div>
|
||||||
|
<div>- youtube - <a href="https://youtube.com/@trinkey" target="_blank"><b>@trinkey</b></a> (inactive)</div>`,
|
||||||
|
buttons: `<div><b>my button:</b> (click to copy html)</div>
|
||||||
|
<div><img style="cursor: pointer;" src="img/88x31.png" alt="trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button." title="trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button." onclick="copyButton()"></div>
|
||||||
|
<div>--------------------</div>
|
||||||
|
<div><b>cool people:</b></div>
|
||||||
|
<div class="buttons-88x31">
|
||||||
|
<a href="https://notfire.cc" target="_blank"><img src="https://notfire.cc/design/images/buttons/notfire-cc-88x31-af.gif" alt="notfire.cc" title="notfire.cc"></a>
|
||||||
|
<a href="https://micro.niko.lgbt" target="_blank"><img src="https://micro.niko.lgbt/static/button_2.png" alt="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro"" title="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro""></a>
|
||||||
|
<a href="https://w.on-t.work" target="_blank"><img src="https://w.on-t.work/assets/88x31.png" alt="kopper's button" title="kopper's button"></a>
|
||||||
|
<a href="https://synth.download" target="_blank"><img src="https://synth.download/assets/buttons/sneexy.svg" alt="Sneexy" title="Sneexy"></a>
|
||||||
|
<a href="https://beepi.ng" target="_blank"><img src="https://beepi.ng/88x31.png" alt="unnick" title="unnick"></a>
|
||||||
|
</div>`,
|
||||||
|
testimonials: `<div>"warning: this user is trinkey"</div>
|
||||||
|
<div>- <a href="https://booping.synth.download/@breaadyboy" target="_blank">bread</a></div><br>
|
||||||
|
<div>"This user is only slightly crazy once was I. 10/10 would recommend"</div>
|
||||||
|
<div>- <a href="https://lea.pet/@subroutine" target="_blank">subroutine</a></div><br>
|
||||||
|
<div>"the f slur but repeated 36 times"</div>
|
||||||
|
<div>- <a href="https://oomfie.city/@cornfields74">corn fields seventy four</a></div>`,
|
||||||
|
webrings: `<div>
|
||||||
|
<a href="https://ctp-webr.ing/trinkey/previous">←</a>
|
||||||
|
<a href="https://ctp-webr.ing/">catppuccin webring</a>
|
||||||
|
<a href="https://ctp-webr.ing/trinkey/next">→</a>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="https://fediring.net/previous?host=trinkey.com">←</a>
|
||||||
|
<a href="https://fediring.net/">fediring</a>
|
||||||
|
<a href="https://fediring.net/next?host=trinkey.com">→</a>
|
||||||
|
</div>`,
|
||||||
|
projects: `<div><b>projects</b> - the things i made</div>
|
||||||
|
<div>- <a href="https://github.com/jerimiah-smiggins/smiggins/" target="_blank"><b>smiggins</b></a> (<a href="https://smiggins.trinkey.com/" target="_blank">website</a>) - a social media platform i made</div>
|
||||||
|
<div>- <a href="https://git.trinkey.com/trinkey/website/" target="_blank"><b>this website</b></a> - check out the code</div>
|
||||||
|
<div>- <a href="https://git.gay/trinkey/dotindex/" target="_blank"><b>dotindex</b></a> (<a href="https://pypi.org/project/DotIndex/" target="_blank">pypi</a>) - a python library that lets you access dicts using the dot notation (dict.key) instead of whatever python does (dict["key"])</div>
|
||||||
|
<div>- <a href="https://git.gay/trinkey/infopage/" target="_blank"><b>infopage</b></a> (<a href="https://infpg.pythonanywhere.com/" target="_blank">website</a>) - my very own pronouns.page clone</div>
|
||||||
|
<div>- <a href="https://git.trinkey.com/t" target="_blank"><b>tSuite</b></a> (<a href="https://auth.trinkey.com/" target="_blank">website</a>) - a collection of services that are all interconnected</div><br>
|
||||||
|
<div>i'll likely add more in the future, these are just the ones i'm most proud of at the moment.</div>`,
|
||||||
|
directory: `<div>there's a lot that goes into this website. here are some links for your usage to help you navigate this hellhole</div><br>
|
||||||
|
<div><b><a href="https://trinkey.com/">trinkey.com</a>:</b></div>
|
||||||
|
<div>this is where you are right now</div><br>
|
||||||
|
<div>*<b><a href="https://akkofe.trinkey.com/">akkofe.trinkey.com</a>:</b></div>
|
||||||
|
<div>the frontend i use for <a href="https://fediverse.info/" target="_blank">fedi</a></div><br>
|
||||||
|
<div><b><a href="https://auth.trinkey.com/">auth.trinkey.com</a>:</b></div>
|
||||||
|
<div>authentication manager for tSuite</div><br>
|
||||||
|
<div><b><a href="https://blog.trinkey.com/">blog.trinkey.com</a>:</b></div>
|
||||||
|
<div>tBlog, from tSuite</div><br>
|
||||||
|
<div><b><a href="https://everyone.trinkey.com/">everyone.trinkey.com</a>:</b></div>
|
||||||
|
<div>frontend to a fedi bot that anyone can post to (@everyonebot@is.trinkey.com)</div><br>
|
||||||
|
<div>*<b><a href="https://git.trinkey.com/">git.trinkey.com</a>:</b></div>
|
||||||
|
<div>holds some of my git projects (older ones on <a href="https://github.com/trinkey/" target="_blank">github</a> or <a href="https://git.gay/trinkey/" target="_blank">git.gay</a>)</div><br>
|
||||||
|
<div>*<b><a href="https://is.trinkey.com/">is.trinkey.com</a>:</b></div>
|
||||||
|
<div>hosts <a href="https://iceshrimp.dev/iceshrimp/iceshrimp.net" target="_blank">iceshrimp.net</a>, which is the fedi backend i use</div><br>
|
||||||
|
<div><b><a href="https://message.trinkey.com/">message.trinkey.com</a>:</b></div>
|
||||||
|
<div>tMessage, from tSuite</div><br>
|
||||||
|
<div><b><a href="https://music.trinkey.com/">music.trinkey.com</a>:</b></div>
|
||||||
|
<div>has some music. i haven't actually updated the site in a while but i've been meaning to do rewrite it at some point. 100% legal i pinky promise</div><br>
|
||||||
|
<div><b><a href="https://smiggins.trinkey.com/">smiggins.trinkey.com</a>:</b></div>
|
||||||
|
<div>official jerimiah smiggins instance, that being my own social media platform</div><br>
|
||||||
|
<div>(asterisk (*) means i haven't written the code for it)</div><br>`
|
||||||
|
};
|
||||||
|
|
||||||
|
const _internal_neofetchOutputs: StringDict = {
|
||||||
|
desktop: `<pre> <b>...-:::::-...</b> <b class="green">trinkey</b>@<b class="green">desktop</b>
|
||||||
|
<b>.-MMMMMMMMMMMMMMM-.</b> ---------------
|
||||||
|
<b>.-MMMM<span class="green">\`..-:::::::-..\`</span>MMMM-.</b> <b class="green">OS</b>: Linux Mint 21.3 x86_64
|
||||||
|
<b>.:MMMM<span class="green">.:MMMMMMMMMMMMMMM:.</span>MMMM:.</b> <b class="green">Host</b>: MS-7E27 1.0
|
||||||
|
<b>-MMM<span class="green">-M---MMMMMMMMMMMMMMMMMMM.</span>MMM-</b> <b class="green">Resolution</b>: 1680x1050, 2560x1440
|
||||||
|
<b>\`:MMM<span class="green">:MM\` :MMMM:....::-...-MMMM:</span>MMM:\`</b> <b class="green">DE</b>: Cinnamon 6.0.4
|
||||||
|
<b>:MMM<span class="green">:MMM\` :MM:\` \`\` \`\` \`:MMM:</span>MMM:</b> <b class="green">WM</b>: Mutter (Muffin)
|
||||||
|
<b>.MMM<span class="green">.MMMM\` :MM. -MM. .MM- \`MMMM.</span>MMM.</b> <b class="green">CPU</b>: AMD Ryzen 9 7950X (32) @ 5.881GHz
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM-</span>MMM:</b> <b class="green">GPU</b>: AMD ATI 03:00.0 Device 747e
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM:</span>MMM:</b> <b class="green">GPU</b>: AMD ATI 11:00.0 Device 164e
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM-</span>MMM:</b> <b class="green">Memory</b>: 1MiB / 127901MiB
|
||||||
|
<b>.MMM<span class="green">.MMMM\` :MM:--:MM:--:MM: \`MMMM.</span>MMM.</b>
|
||||||
|
<b>:MMM<span class="green">:MMM- \`-MMMMMMMMMMMM-\` -MMM-</span>MMM:</b>
|
||||||
|
<b>:MMM<span class="green">:MMM:\` \`:MMM:</span>MMM:</b>
|
||||||
|
<b>.MMM<span class="green">.MMMM:--------------:MMMM.</span>MMM.</b>
|
||||||
|
<b>'-MMMM<span class="green">.-MMMMMMMMMMMMMMM-.</span>MMMM-'</b>
|
||||||
|
<b>'.-MMMM<span class="green">\`\`--:::::--\`\`</span>MMMM-.'</b>
|
||||||
|
<b>'-MMMMMMMMMMMMM-'</b>
|
||||||
|
<b>\`\`-:::::-\`\`</b></pre>`,
|
||||||
|
laptop: `<pre> <b>...-:::::-...</b> <b class="green">trinkey</b>@<b class="green">laptop</b>
|
||||||
|
<b>.-MMMMMMMMMMMMMMM-.</b> ---------------
|
||||||
|
<b>.-MMMM<span class="green">\`..-:::::::-..\`</span>MMMM-.</b> <b class="green">OS</b>: Linux Mint 21.2 x86_64
|
||||||
|
<b>.:MMMM<span class="green">.:MMMMMMMMMMMMMMM:.</span>MMMM:.</b> <b class="green">Host</b>: Dell G15 5510
|
||||||
|
<b>-MMM<span class="green">-M---MMMMMMMMMMMMMMMMMMM.</span>MMM-</b> <b class="green">Resolution</b>: 2560x1440, 1920x1080, 1680x1050
|
||||||
|
<b>\`:MMM<span class="green">:MM\` :MMMM:....::-...-MMMM:</span>MMM:\`</b> <b class="green">DE</b>: Cinnamon 5.8.4
|
||||||
|
<b>:MMM<span class="green">:MMM\` :MM:\` \`\` \`\` \`:MMM:</span>MMM:</b> <b class="green">WM</b>: Mutter (Muffin)
|
||||||
|
<b>.MMM<span class="green">.MMMM\` :MM. -MM. .MM- \`MMMM.</span>MMM.</b> <b class="green">CPU</b>: Intel i5-10500H (12) @ 4.500GHz
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM-</span>MMM:</b> <b class="green">GPU</b>: NVIDIA GeForce RTX 3050 Ti Mobile
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM:</span>MMM:</b> <b class="green">GPU</b>: Intel CometLake-H GT2 [UHD Graphics]
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM-</span>MMM:</b> <b class="green">Memory</b>: 2001MiB / 15765MiB
|
||||||
|
<b>.MMM<span class="green">.MMMM\` :MM:--:MM:--:MM: \`MMMM.</span>MMM.</b>
|
||||||
|
<b>:MMM<span class="green">:MMM- \`-MMMMMMMMMMMM-\` -MMM-</span>MMM:</b>
|
||||||
|
<b>:MMM<span class="green">:MMM:\` \`:MMM:</span>MMM:</b>
|
||||||
|
<b>.MMM<span class="green">.MMMM:--------------:MMMM.</span>MMM.</b>
|
||||||
|
<b>'-MMMM<span class="green">.-MMMMMMMMMMMMMMM-.</span>MMMM-'</b>
|
||||||
|
<b>'.-MMMM<span class="green">\`\`--:::::--\`\`</span>MMMM-.'</b>
|
||||||
|
<b>'-MMMMMMMMMMMMM-'</b>
|
||||||
|
<b>\`\`-:::::-\`\`</b></pre>`,
|
||||||
|
server: `<pre> <b>...-:::::-...</b> <b class="green">trinkey</b>@<b class="green">server</b>
|
||||||
|
<b>.-MMMMMMMMMMMMMMM-.</b> ---------------
|
||||||
|
<b>.-MMMM<span class="green">\`..-:::::::-..\`</span>MMMM-.</b> <b class="green">OS</b>: Linux Mint 21.2 x86_64
|
||||||
|
<b>.:MMMM<span class="green">.:MMMMMMMMMMMMMMM:.</span>MMMM:.</b> <b class="green">Host</b>: Macmini7,1 1.0
|
||||||
|
<b>-MMM<span class="green">-M---MMMMMMMMMMMMMMMMMMM.</span>MMM-</b> <b class="green">CPU</b>: Intel i5-4278U (4) @ 3.100GHz
|
||||||
|
<b>\`:MMM<span class="green">:MM\` :MMMM:....::-...-MMMM:</span>MMM:\`</b> <b class="green">GPU</b>: Intel Haswell-ULT
|
||||||
|
<b>:MMM<span class="green">:MMM\` :MM:\` \`\` \`\` \`:MMM:</span>MMM:</b> <b class="green">Memory</b>: 9011MiB / 15866MiB
|
||||||
|
<b>.MMM<span class="green">.MMMM\` :MM. -MM. .MM- \`MMMM.</span>MMM.</b>
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM-</span>MMM:</b>
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM:</span>MMM:</b>
|
||||||
|
<b>:MMM<span class="green">:MMMM\` :MM. -MM- .MM: \`MMMM-</span>MMM:</b>
|
||||||
|
<b>.MMM<span class="green">.MMMM\` :MM:--:MM:--:MM: \`MMMM.</span>MMM.</b>
|
||||||
|
<b>:MMM<span class="green">:MMM- \`-MMMMMMMMMMMM-\` -MMM-</span>MMM:</b>
|
||||||
|
<b>:MMM<span class="green">:MMM:\` \`:MMM:</span>MMM:</b>
|
||||||
|
<b>.MMM<span class="green">.MMMM:--------------:MMMM.</span>MMM.</b>
|
||||||
|
<b>'-MMMM<span class="green">.-MMMMMMMMMMMMMMM-.</span>MMMM-'</b>
|
||||||
|
<b>'.-MMMM<span class="green">\`\`--:::::--\`\`</span>MMMM-.'</b>
|
||||||
|
<b>'-MMMMMMMMMMMMM-'</b>
|
||||||
|
<b>\`\`-:::::-\`\`</b></pre>`
|
||||||
|
};
|
||||||
|
|
||||||
|
const helpText: string = `<div> -=== <b class="pink">tSh help</b> ===-</div>
|
||||||
|
<div>--------------------</div>
|
||||||
|
<div>-= <b class="green">cat</b> =-</div>
|
||||||
|
<div>Displays the contents of a file.</div>
|
||||||
|
<div>-= <b class="green">cd</b> =-</div>
|
||||||
|
<div>Changes the working directory.</div>
|
||||||
|
<div>-= <b class="green">clear</b> =-</div>
|
||||||
|
<div>Clears the terminal output.</div>
|
||||||
|
<div>-= <b class="green">help</b> =-</div>
|
||||||
|
<div>Shows this help menu.</div>
|
||||||
|
<div>-= <b class="green">ls</b> =-</div>
|
||||||
|
<div>Lists all files in a directory.</div>
|
||||||
|
<div> -l - displays more information about each file</div>
|
||||||
|
<div> -a - displays all files</div>
|
||||||
|
<div> -A - displays all files except implied . and ..</div>
|
||||||
|
<div> -r - reverses the order of the files</div>
|
||||||
|
<div> -R - recurse through all subdirectories</div>
|
||||||
|
<div>-= <b class="green">exit</b> =-</div>
|
||||||
|
<div>Closes the terminal.</div>`;
|
||||||
|
|
||||||
|
const HOME_DIR: string = "/home/trinkey";
|
||||||
|
|
||||||
|
let FILESYSTEM: _files = {
|
||||||
|
home: {
|
||||||
|
type: "directory",
|
||||||
|
name: "home",
|
||||||
|
files: {
|
||||||
|
trinkey: {
|
||||||
|
type: "directory",
|
||||||
|
name: "trinkey",
|
||||||
|
files: {
|
||||||
|
people: { type: "directory", name: "people", files: {
|
||||||
|
"88x31.txt": { type: "file", name: "88x31.txt", content: _internal_defaultFiles.buttons },
|
||||||
|
"testimonials.txt": { type: "file", name: "testimonials.txt", content: _internal_defaultFiles.testimonials },
|
||||||
|
"webrings.txt": { type: "file", name: "webrings.txt", content: _internal_defaultFiles.webrings }
|
||||||
|
}},
|
||||||
|
"about-me.txt": { type: "file", name: "about-me.txt", content: _internal_defaultFiles.about },
|
||||||
|
"socials.txt": { type: "file", name: "socials.txt", content: _internal_defaultFiles.socials },
|
||||||
|
"projects.txt": { type: "file", name: "projects.txt", content: _internal_defaultFiles.projects },
|
||||||
|
"subdomains.txt": { type: "file", name: "subdomains.txt", content: _internal_defaultFiles.directory }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bin: {
|
||||||
|
type: "directory",
|
||||||
|
name: "bin",
|
||||||
|
files: {
|
||||||
|
cat: { type: "file", name: "cat", content: "<div>function cat(file: string): string { ... }</div>" },
|
||||||
|
cd: { type: "file", name: "cd", content: "<div>function cd(directory: string): void { ... }</div>" },
|
||||||
|
clear: { type: "file", name: "clear", content: "<div>function clear(): void { ... }</div>" },
|
||||||
|
help: { type: "file", name: "help", content: "<div>function help(): string { ... }</div>" },
|
||||||
|
ls: { type: "file", name: "ls", content: "<div>function ls(directory: string): string { ... }</div>" },
|
||||||
|
neofetch: { type: "file", name: "neofetch", content: "<div>function neofetch(): string { ... }</div>" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
".secret-file": { type: "file", name: ".secret-file", content: "<div>meow :3</div>" }
|
||||||
|
};
|
||||||
|
|
||||||
|
let windowInformation: { [key: string]: _tShWinInfo } = {};
|
||||||
|
|
||||||
|
function commandManager(windowID: string, command: string): void {
|
||||||
|
if (!windowInformation[windowID]) {
|
||||||
|
windowInformation[windowID] = {
|
||||||
|
PWD: HOME_DIR
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let out: string;
|
||||||
|
if (_internal_commands[command.split(" ")[0]]) {
|
||||||
|
out = _internal_commands[command.split(" ")[0]](command.split(" ").slice(1).join(" ").trim(), windowID);
|
||||||
|
} else if (command == "") {
|
||||||
|
out = ""
|
||||||
|
} else {
|
||||||
|
out = `<div class="red">Unknown command '${escapeHTML(command.split(" ")[0])}'.</div><div>Type 'help' for a list of commands</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let el: HTMLDivElement = document.createElement("div");
|
||||||
|
el.innerHTML = out;
|
||||||
|
WINDOWS[windowID].element.querySelector(".window").append(el);
|
||||||
|
|
||||||
|
let dTE: HTMLElement = WINDOWS[windowID].element.querySelector("[data-type-area]");
|
||||||
|
if (dTE) {
|
||||||
|
dTE.removeAttribute("data-type-area");
|
||||||
|
if (dTE.querySelector("i.cursor")) {
|
||||||
|
dTE.querySelector("i.cursor").remove();
|
||||||
|
} else if (dTE.querySelector(".cursor")) {
|
||||||
|
dTE.querySelector(".cursor").classList.remove("cursor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(WINDOWS[windowID].element.querySelector(".window-header-title") as HTMLElement).innerText = `${_internal_stringifyPath(windowInformation[windowID].PWD)} - tSh`;
|
||||||
|
|
||||||
|
let ps1: HTMLDivElement = document.createElement("div");
|
||||||
|
ps1.innerHTML = _internal_getPS1(windowInformation[windowID]);
|
||||||
|
|
||||||
|
let typeArea: HTMLSpanElement = document.createElement("span");
|
||||||
|
typeArea.dataset.typeArea = "";
|
||||||
|
typeArea.innerHTML = "<i class=\"cursor\"> </i>";
|
||||||
|
|
||||||
|
ps1.append(typeArea)
|
||||||
|
WINDOWS[windowID].element.querySelector(".window").append(ps1);
|
||||||
|
}
|
13
tsconfig.json
Normal file
13
tsconfig.json
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": [ "dom", "es2021", "dom.iterable" ],
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"outDir": "./js/",
|
||||||
|
"removeComments": true,
|
||||||
|
"target": "es6"
|
||||||
|
},
|
||||||
|
|
||||||
|
"include": [
|
||||||
|
"./ts/*.ts"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in a new issue