From 6c393addc3913bdd62e8319c256b34badd081e06 Mon Sep 17 00:00:00 2001 From: Parker Date: Mon, 23 Dec 2024 23:52:16 -0600 Subject: [PATCH] Redo site --- .gitignore | 3 - README.md | 2 +- app/static/css/about.css | 109 -------------- app/static/css/contact.css | 186 ------------------------ app/static/css/index.css | 155 -------------------- app/static/github.png | Bin 2747 -> 0 bytes app/static/gnupg.png | Bin 2892 -> 0 bytes app/static/js/altcha.js | 8 -- app/static/linkedin.png | Bin 2006 -> 0 bytes app/static/mail.png | Bin 1781 -> 0 bytes app/static/xmpp.png | Bin 3532 -> 0 bytes app/templates/about.html | 37 ----- app/templates/contact.html | 104 -------------- app/templates/index.html | 48 ------- app/templates/pgp.html | 71 --------- app/views.py | 115 --------------- css/index.css | 215 ++++++++++++++++++++++++++++ {app/static/css => css}/pgp.css | 0 index.html | 114 +++++++++++++++ js/toggle.js | 30 ++++ app/static/parker.asc => parker.asc | 0 pkrm.service | 14 -- pkrm.sh | 2 - app/static/robots.txt => robots.txt | 0 run.py | 4 - 25 files changed, 360 insertions(+), 857 deletions(-) delete mode 100644 .gitignore delete mode 100644 app/static/css/about.css delete mode 100644 app/static/css/contact.css delete mode 100644 app/static/css/index.css delete mode 100644 app/static/github.png delete mode 100644 app/static/gnupg.png delete mode 100644 app/static/js/altcha.js delete mode 100644 app/static/linkedin.png delete mode 100644 app/static/mail.png delete mode 100644 app/static/xmpp.png delete mode 100644 app/templates/about.html delete mode 100644 app/templates/contact.html delete mode 100644 app/templates/index.html delete mode 100644 app/templates/pgp.html delete mode 100644 app/views.py create mode 100644 css/index.css rename {app/static/css => css}/pgp.css (100%) create mode 100644 index.html create mode 100644 js/toggle.js rename app/static/parker.asc => parker.asc (100%) delete mode 100644 pkrm.service delete mode 100755 pkrm.sh rename app/static/robots.txt => robots.txt (100%) delete mode 100644 run.py diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 5fd41de..0000000 --- a/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -.env -__pycache__ \ No newline at end of file diff --git a/README.md b/README.md index 5799d7b..487c548 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # [PKRM.DEV](https://pkrm.dev) -This is the repo for my personal website ([pkrm.dev](https://pkrm.dev)). +This is the repo for my personal website ([pkrm.dev](https://pkrm.dev)). Heavily inspired by the "Hello Friend NG" HUGO Theme, found [here](https://github.com/rhazdon/hugo-theme-hello-friend-ng). diff --git a/app/static/css/about.css b/app/static/css/about.css deleted file mode 100644 index 100e909..0000000 --- a/app/static/css/about.css +++ /dev/null @@ -1,109 +0,0 @@ -/* Import Montserrat font */ -@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@200;300;400;500;600;700&display=swap'); - -body { - margin: 0; - padding: 0; - font-family: 'Montserrat', sans-serif; - background-color: #242528; - color: #9F9FAA; -} - - -/* Navbar styles */ -nav { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1rem 2rem; - background-color: #212223; - color: #9F9FAA; -} - -nav a { - text-decoration: none; - color: #9F9FAA; - font-size: 1.5rem; - margin: 0 1rem; -} - -nav a:hover { - color: #fff; -} - -.navbar-left { - display: flex; - justify-content: flex-start; - align-items: center; - margin-left: 15%; -} - -.navbar-right { - display: flex; - justify-content: flex-end; - align-items: center; - margin-right: 15%; -} - -/* Navbar media query for mobile */ -@media only screen and (max-width: 600px) { - nav a { - margin: 0; - font-size: 1rem; - } - - .navbar-left { - margin: 0 1rem; - } - - .navbar-right { - margin: 0 1rem; - } - - .navbar-right a { - margin-left: 1rem; - } -} - -/* Container styles */ -.container { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - font-size: 1.75rem; - text-align: center; - width: 600px; -} - -/* Continer media query for mobile */ -@media only screen and (max-width: 600px) { - .container { - font-size: 1.25rem; - width: 300px; - } - - .container p { - margin: 1rem 0 2rem 0; - } -} - - -/* Footer styles */ -footer { - position: absolute; - bottom: 0; - left: 50%; - transform: translateX(-50%); - font-size: 1rem; - text-align: center; - margin-bottom: 2rem; - width: 90vw; -} - -/* Footer media query for mobile */ -@media only screen and (max-width: 600px) { - footer { - bottom: -2rem; - } -} \ No newline at end of file diff --git a/app/static/css/contact.css b/app/static/css/contact.css deleted file mode 100644 index ab8e95b..0000000 --- a/app/static/css/contact.css +++ /dev/null @@ -1,186 +0,0 @@ -/* Import Montserrat font */ -@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@200;300;400;500;600;700&display=swap'); - -* { - font-family: 'Montserrat', sans-serif; -} - -body { - margin: 0; - padding: 0; - background-color: #242528; - color: #9F9FAA; -} - - -/* Navbar styles */ -nav { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1rem 2rem; - background-color: #212223; - color: #9F9FAA; -} - -nav a { - text-decoration: none; - color: #9F9FAA; - font-size: 1.5rem; - margin: 0 1rem; -} - -nav a:hover { - color: #fff; -} - -.navbar-left { - display: flex; - justify-content: flex-start; - align-items: center; - margin-left: 15%; -} - -.navbar-right { - display: flex; - justify-content: flex-end; - align-items: center; - margin-right: 15%; -} - -/* Navbar media query for mobile */ -@media only screen and (max-width: 600px) { - nav a { - margin: 0; - font-size: 1rem; - } - - .navbar-left { - margin: 0 1rem; - } - - .navbar-right { - margin: 0 1rem; - } - - .navbar-right a { - margin-left: 1rem; - } -} - - -/* Container styles */ -.container { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - font-size: 1.75rem; - text-align: center; - border: 1px solid #9F9FAA; - border-radius: 5px; - padding: 2rem; - height: 450px; - width: 550px; -} - -.container h1 { - margin: 0 0 1rem 0; -} - -/* Continer media query for mobile */ -@media only screen and (max-width: 600px) { - .container { - font-size: 1.25rem; - width: 250px; - } - - .container h1 { - margin: 0 0 2rem 0; - } -} - -/* Form styles */ -form { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} - -input { - margin: 0.75rem 0; - padding: 0.5rem 1rem; - border: 1px solid #9F9FAA; - border-radius: 5px; - background-color: #242528; - color: #9F9FAA; - font-size: 1.25rem; - width: 500px; -} - -input[type="submit"] { - width: calc(500px + 2rem); - cursor: pointer; -} - -textarea { - margin: 0.75rem 0; - padding: 0.5rem 1rem; - border: 1px solid #9F9FAA; - border-radius: 5px; - background-color: #242528; - color: #9F9FAA; - font-size: 1.25rem; - height: 100px; - width: 500px; - resize: none; -} - -/* Form media query for mobile */ -@media only screen and (max-width: 600px) { - input { - width: 250px; - } - - input[type="submit"] { - width: calc(250px + 2rem); - } - - textarea { - width: 250px; - } -} - -/* Success/Error messages */ -.success-message { - color: #71A172; - font-size: 1.25rem; - margin-top: 0.5rem; -} - -.error-message { - color: #B16161; - font-size: 1.25rem; - margin-top: 0.5rem; -} - - -/* Footer styles */ -footer { - position: absolute; - bottom: 0; - left: 50%; - transform: translateX(-50%); - font-size: 1rem; - text-align: center; - margin-bottom: 2rem; - width: 90vw; -} - -/* Footer media query for mobile */ -@media only screen and (max-width: 600px) { - footer { - bottom: -2rem; - } -} \ No newline at end of file diff --git a/app/static/css/index.css b/app/static/css/index.css deleted file mode 100644 index 3e6d017..0000000 --- a/app/static/css/index.css +++ /dev/null @@ -1,155 +0,0 @@ -/* Import Montserrat font */ -@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@200;300;400;500;600;700&display=swap'); - -body { - margin: 0; - padding: 0; - font-family: 'Montserrat', sans-serif; - background-color: #242528; - color: #9F9FAA; -} - - -/* Navbar styles */ -nav { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1rem 2rem; - background-color: #212223; - color: #9F9FAA; -} - -nav a { - text-decoration: none; - color: #9F9FAA; - font-size: 1.5rem; - margin: 0 1rem; -} - -nav a:hover { - color: #fff; -} - -.navbar-left { - display: flex; - justify-content: flex-start; - align-items: center; - margin-left: 15%; -} - -.navbar-right { - display: flex; - justify-content: flex-end; - align-items: center; - margin-right: 15%; -} - -/* Navbar media query for mobile */ -@media only screen and (max-width: 600px) { - nav a { - margin: 0; - font-size: 1rem; - } - - .navbar-left { - margin: 0 1rem; - } - - .navbar-right { - margin: 0 1rem; - } - - .navbar-right a { - margin-left: 1rem; - } -} - - -/* Container styles */ -.container { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - height: 80vh; - margin: 0; - text-align: center; - font-size: 1.75rem; -} - -.text { - width: 500px; -} - -.text h1 { - margin-bottom: 0; -} - -.text p { - margin: 2rem 0 3rem 0; -} - -/* Icon styles */ - -.icons { - width: 100%; -} - -.icon { - margin: 0 1rem; - height: 50px; - width: 50px; - color: #9F9FAA; -} - -/* Icons media query for mobile */ -@media only screen and (max-width: 600px) { - .icon { - margin: 0 0.5rem; - } -} - -.icon:hover { - cursor: pointer; - opacity: 0.6; - transition: opacity 0.25s ease-in-out; - -} - -/* Continer media query for mobile */ -@media only screen and (max-width: 600px) { - .text { - font-size: 1.5rem; - width: 300px; - } - - .text p { - margin: 1rem 0 2rem 0; - } - - .icon { - height: 40px; - width: 40px; - } -} - - -/* Footer styles */ -footer { - position: absolute; - bottom: 0; - left: 50%; - transform: translateX(-50%); - font-size: 1rem; - text-align: center; - margin-bottom: 2rem; - width: 90vw; -} - -/* Footer media query for mobile */ -@media only screen and (max-width: 600px) { - footer { - bottom: -2rem; - } -} \ No newline at end of file diff --git a/app/static/github.png b/app/static/github.png deleted file mode 100644 index 3cdff932248a2d0729a25fbc3b0723d6209fc8ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2747 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 BO@aUb diff --git a/app/static/gnupg.png b/app/static/gnupg.png deleted file mode 100644 index 7efc4154b90b8823a3bdb13187f20c7aa7a87f55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2892 zcmV-S3$yfzP)DB$RNe7I#$Jn&Q-^{{Hc(~@hd+w(EGjHB|_nmj{ z`M>jT=l}m(hZtJ7?$)>=adaGj;{lulU>Sh90Ga^Q184v+0$>n8KY$^A{viMZ;2^K1 zre(|CTl25wtlZV0763m5@FCCflbp}r=Syi7fXe_JEn<Frv)}N~c7!xYv z7xSw!xE;WqWPU4v9sv6RJV(*Dq^kHg09z;t(*c|X;2l&M1>)nzgcShGMS|hH)?CVK zB4a{B=2eHE1aPe`7Qi<}g4;!c#{hKko^9OqnE*}%FcH82fM)?bArfo?a2bNqfYN6vF6$w^yK7D_RlGAQX*pbKDGXr2uxSobib^T@lpVJ*z{Wd0?ONIxXzw{HR zeyYSt1Ox;KWb&vnVVT!E0bC8>s{kGWpenG!m~d6r^=Ea1hCAN};O79oA`+6L7%Um?-Ws}1jrh(rCTxjY zgh=ol)o`OVirkz;lr#`(bbP&v;qAPxetic&pCb}%aTwR&WdVTq19&}vSJVJr-QwE; z{MwlCW|80@F(5oc7p(Ko0dT!uPQp-93HS-$)py?@5_D0|RT}Dy31>x^S8;zAfNul1 zoC_^cT;B@dbp%C?nldsT!1;7{*BBGd_gK?r0HG5ojZeZ*5*yG+J=NX61HdN;L`5Vx zOy;dovS)(#&|06)P*)fDr)ox#qW>L7mzA+AMS>@5t)h?Gv5{I z4Gdx$=n23;$S$bFSpHLF{$3S*k>KH49zi5HC=y%(;3d3tq4Ho%cwEfd{tn=N0EcMh<0-~z|X zj5U5I4_tk`)arY$Bmgw={V-Jlw7z<}d%_N)=Ts+Z6`RP@K{vh!O4QO$#*d|NKc|otSwaA-G0aY zHu_HN1Hg4;{w|KU<*jO@2a-Pn_$@&g@Z1qse62W_2)1U1o~iano)l*|2c`oa_ZuZ2 z02cE73Xa#4;O-jZ6`Wg{scCQk7;EQTU`i2PFF7Fe0@yi5o^c#gVdpdDHibX!_26ri zd;oYEjvaiwPIWAC?T!H{6B!duq)l4H0_w|oU;-1Y-ZsYv06mb@YrU?3{Ju9ax!T4J zS}Hk)_p}g=TN+7)5uM6=Dd-1shi*LU<=UIpOY|91db z?yk_Kw$hb0(_J-@X%*!Y$owg6l9oCGnG5nOy*n3@OXNOMl#vTY*K~SU6oUPzFO-Lk^9&Jtx_j@k~WA0``9|u zh8W5X0Os`PFp0Tb*oY1YfN}NdlBA5H~UMb&mIs7j>OFS z0?G`4F`d|Ku6sIwD1QdqjHH;{n?OlkMq;>%e1MoN}4`axdWN+8yY1Y6UrKQ#bc z%-J+Dip>-NKHsD;>rM>FWN-YV;*b?G#N)?D@0pHV1j|*~Jr} zR)zQRp7R+OoI$ml4P^cD#c?G}F-Cq>a)}EAIX58dX z>J_$$1m0<{T2wdyG;}tZ(MIb%k@`M`y~5M@+v3RIH4Ak&yT!E)=IOi`w^S$qbaAm+ z8Hc*qOx4Mk#sS(c)9rMV+qoN<9n$Diwn2do*dXjk~Vr|3}#?oS6!*-HQb6j-R*B3RW2GxUY(n4r_4M zwvW-Dw#{9m9qM^8uax&wWA!|^oWvNujSN1JoXR#3s@*e}JN%g?gCqxR(}Q#lDAKsfAEh0M?UnOT#Q;?&KqI`xw3sIL5BzWP{86 zt=l>N?xJPy^?7h2D`f#-C7JJI`TPMs(Y2k-?`L{ys7kHQ8o43oH99WO2P5MsEdXwi zGr(wV3w3p`(?Jd=Ng6G!S;j}4Mo3*xDdXd?N1V>}SP4oCfIY^xGeBADWNcqdw7Dn% zl=K*@CpZmBHBX>rC{0@_AZ~|--Gyp?-#$gEhR*FRN=r7ms?6&es}q2K13cQD0JTkg qBLDyZ4rN$LW=%~1DgXcg2mk;800000(o>TF0000t in e?je(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,x=(e,t,n)=>(Ge(e,"symbol"!=typeof t?t+"":t,n),n);function Z(){}function de(e){return e()}function ie(){return Object.create(null)}function H(e){e.forEach(de)}function ge(e){return"function"==typeof e}function Ae(e,t){return e!=e?t==t:e!==t||e&&"object"==typeof e||"function"==typeof e}function Se(e){return 0===Object.keys(e).length}function m(e,t){e.appendChild(t)}function Ve(e,t,n){const r=Me(e);if(!r.getElementById(t)){const e=v("style");e.id=t,e.textContent=n,Ue(r,e)}}function Me(e){if(!e)return document;const t=e.getRootNode?e.getRootNode():e.ownerDocument;return t&&t.host?t:e.ownerDocument}function Ue(e,t){return m(e.head||e,t),t.sheet}function q(e,t,n){e.insertBefore(t,n||null)}function I(e){e.parentNode&&e.parentNode.removeChild(e)}function v(e){return document.createElement(e)}function G(e){return document.createElementNS("http://www.w3.org/2000/svg",e)}function Fe(e){return document.createTextNode(e)}function M(){return Fe(" ")}function D(e,t,n,r){return e.addEventListener(t,n,r),()=>e.removeEventListener(t,n,r)}function c(e,t,n){null==n?e.removeAttribute(t):e.getAttribute(t)!==n&&e.setAttribute(t,n)}function Ye(e){return Array.from(e.childNodes)}function le(e,t,n){e.classList.toggle(t,!!n)}function Ze(e,t,{bubbles:n=!1,cancelable:r=!1}={}){return new CustomEvent(e,{detail:t,bubbles:n,cancelable:r})}function Oe(e){const t={};return e.childNodes.forEach((e=>{t[e.slot||"default"]=!0})),t}let B;function O(e){B=e}function ee(){if(!B)throw new Error("Function called outside component initialization");return B}function Be(e){ee().$$.on_mount.push(e)}function He(e){ee().$$.on_destroy.push(e)}function We(){const e=ee();return(t,n,{cancelable:r=!1}={})=>{const o=e.$$.callbacks[t];if(o){const c=Ze(t,n,{cancelable:r});return o.slice().forEach((t=>{t.call(e,c)})),!c.defaultPrevented}return!0}}const F=[],z=[];let Y=[];const oe=[],me=Promise.resolve();let J=!1;function we(){J||(J=!0,me.then(C))}function Pe(){return we(),me}function Q(e){Y.push(e)}const K=new Set;let U=0;function C(){if(0!==U)return;const e=B;do{try{for(;U-1===e.indexOf(r)?t.push(r):n.push(r))),n.forEach((e=>e())),Y=t}const De=new Set;function Ke(e,t){e&&e.i&&(De.delete(e),e.i(t))}function ze(e,t,n){const{fragment:r,after_update:o}=e.$$;r&&r.m(t,n),Q((()=>{const t=e.$$.on_mount.map(de).filter(ge);e.$$.on_destroy?e.$$.on_destroy.push(...t):H(t),e.$$.on_mount=[]})),o.forEach(Q)}function Je(e,t){const n=e.$$;null!==n.fragment&&(Xe(n.after_update),H(n.on_destroy),n.fragment&&n.fragment.d(t),n.on_destroy=n.fragment=null,n.ctx=[])}function Qe(e,t){-1===e.$$.dirty[0]&&(F.push(e),we(),e.$$.dirty.fill(0)),e.$$.dirty[t/31|0]|=1<{const c=r.length?r[0]:n;return a.ctx&&o(a.ctx[t],a.ctx[t]=c)&&(!a.skip_bound&&a.bound[t]&&a.bound[t](c),u&&Qe(e,t)),n})):[],a.update(),u=!0,H(a.before_update),a.fragment=!!r&&r(a.ctx),t.target){if(t.hydrate){const e=Ye(t.target);a.fragment&&a.fragment.l(e),e.forEach(I)}else a.fragment&&a.fragment.c();t.intro&&Ke(e.$$.fragment),ze(e,t.target,t.anchor),C()}O(s)}let be;function P(e,t,n,r){var o;const c=null==(o=n[e])?void 0:o.type;if(t="Boolean"===c&&"boolean"!=typeof t?null!=t:t,!r||!n[e])return t;if("toAttribute"===r)switch(c){case"Object":case"Array":return null==t?null:JSON.stringify(t);case"Boolean":return t?"":null;case"Number":return t??null;default:return t}else switch(c){case"Object":case"Array":return t&&JSON.parse(t);case"Boolean":default:return t;case"Number":return null!=t?+t:t}}function tt(e,t,n,r,o,c){let i=class extends be{constructor(){super(e,n,o),this.$$p_d=t}static get observedAttributes(){return Object.keys(t).map((e=>(t[e].attribute||e).toLowerCase()))}};return Object.keys(t).forEach((e=>{Object.defineProperty(i.prototype,e,{get(){return this.$$c&&e in this.$$c?this.$$c[e]:this.$$d[e]},set(n){var r;n=P(e,n,t),this.$$d[e]=n,null==(r=this.$$c)||r.$set({[e]:n})}})})),r.forEach((e=>{Object.defineProperty(i.prototype,e,{get(){var t;return null==(t=this.$$c)?void 0:t[e]}})})),c&&(i=c(i)),e.element=i,i}"function"==typeof HTMLElement&&(be=class extends HTMLElement{constructor(e,t,n){super(),x(this,"$$ctor"),x(this,"$$s"),x(this,"$$c"),x(this,"$$cn",!1),x(this,"$$d",{}),x(this,"$$r",!1),x(this,"$$p_d",{}),x(this,"$$l",{}),x(this,"$$l_u",new Map),this.$$ctor=e,this.$$s=t,n&&this.attachShadow({mode:"open"})}addEventListener(e,t,n){if(this.$$l[e]=this.$$l[e]||[],this.$$l[e].push(t),this.$$c){const n=this.$$c.$on(e,t);this.$$l_u.set(t,n)}super.addEventListener(e,t,n)}removeEventListener(e,t,n){if(super.removeEventListener(e,t,n),this.$$c){const e=this.$$l_u.get(t);e&&(e(),this.$$l_u.delete(t))}}async connectedCallback(){if(this.$$cn=!0,!this.$$c){let e=function(e){return()=>{let t;return{c:function(){t=v("slot"),"default"!==e&&c(t,"name",e)},m:function(e,n){q(e,t,n)},d:function(e){e&&I(t)}}}};if(await Promise.resolve(),!this.$$cn)return;const t={},n=Oe(this);for(const r of this.$$s)r in n&&(t[r]=[e(r)]);for(const e of this.attributes){const t=this.$$g_p(e.name);t in this.$$d||(this.$$d[t]=P(t,e.value,this.$$p_d,"toProp"))}this.$$c=new this.$$ctor({target:this.shadowRoot||this,props:{...this.$$d,$$slots:t,$$scope:{ctx:[]}}});const r=()=>{this.$$r=!0;for(const e in this.$$p_d)if(this.$$d[e]=this.$$c.$$.ctx[this.$$c.$$.props[e]],this.$$p_d[e].reflect){const t=P(e,this.$$d[e],this.$$p_d,"toAttribute");null==t?this.removeAttribute(this.$$p_d[e].attribute||e):this.setAttribute(this.$$p_d[e].attribute||e,t)}this.$$r=!1};this.$$c.$$.after_update.push(r),r();for(const e in this.$$l)for(const t of this.$$l[e]){const n=this.$$c.$on(e,t);this.$$l_u.set(t,n)}this.$$l={}}}attributeChangedCallback(e,t,n){var r;this.$$r||(e=this.$$g_p(e),this.$$d[e]=P(e,n,this.$$p_d,"toProp"),null==(r=this.$$c)||r.$set({[e]:this.$$d[e]}))}disconnectedCallback(){this.$$cn=!1,Promise.resolve().then((()=>{this.$$cn||(this.$$c.$destroy(),this.$$c=void 0)}))}$$g_p(e){return Object.keys(this.$$p_d).find((t=>this.$$p_d[t].attribute===e||!this.$$p_d[t].attribute&&t.toLowerCase()===e))||e}});class nt{constructor(){x(this,"$$"),x(this,"$$set")}$destroy(){Je(this,1),this.$destroy=Z}$on(e,t){if(!ge(t))return Z;const n=this.$$.callbacks[e]||(this.$$.callbacks[e]=[]);return n.push(t),()=>{const e=n.indexOf(t);-1!==e&&n.splice(e,1)}}$set(e){this.$$set&&!Se(e)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}}const rt="4";typeof window<"u"&&(window.__svelte||(window.__svelte={v:new Set})).v.add(rt);const _e="KGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2NvbnN0IHI9bmV3IFRleHRFbmNvZGVyO2Z1bmN0aW9uIGMoZSl7cmV0dXJuWy4uLm5ldyBVaW50OEFycmF5KGUpXS5tYXAobj0+bi50b1N0cmluZygxNikucGFkU3RhcnQoMiwiMCIpKS5qb2luKCIiKX1hc3luYyBmdW5jdGlvbiBsKGUsbixhKXtyZXR1cm4gYyhhd2FpdCBjcnlwdG8uc3VidGxlLmRpZ2VzdChhLnRvVXBwZXJDYXNlKCksci5lbmNvZGUoZStuKSkpfWFzeW5jIGZ1bmN0aW9uIGkoZSxuLGE9IlNIQS0yNTYiLG89MWU3KXtjb25zdCBzPURhdGUubm93KCk7Zm9yKGxldCB0PTA7dDw9bzt0KyspaWYoYXdhaXQgbChuLHQsYSk9PT1lKXJldHVybntudW1iZXI6dCx0b29rOkRhdGUubm93KCktc307cmV0dXJuIG51bGx9b25tZXNzYWdlPWFzeW5jIGU9Pntjb25zdHthbGc6bixjaGFsbGVuZ2U6YSxtYXg6byxzYWx0OnN9PWUuZGF0YXx8e307aWYoYSYmcyl7Y29uc3QgdD1hd2FpdCBpKGEscyxuLG8pO3NlbGYucG9zdE1lc3NhZ2UodCYmey4uLnQsd29ya2VyOiEwfSl9ZWxzZSBzZWxmLnBvc3RNZXNzYWdlKG51bGwpfX0pKCk7Cg==",se=typeof window<"u"&&window.Blob&&new Blob([atob(_e)],{type:"text/javascript;charset=utf-8"});function it(){let e;try{if(e=se&&(window.URL||window.webkitURL).createObjectURL(se),!e)throw"";return new Worker(e)}catch{return new Worker("data:application/javascript;base64,"+_e)}finally{e&&(window.URL||window.webkitURL).revokeObjectURL(e)}}const lt=1e7,ot=new TextEncoder;function st(e){return[...new Uint8Array(e)].map((e=>e.toString(16).padStart(2,"0"))).join("")}async function ct(e=1e5,t="SHA-256"){const n=Date.now().toString(16),r=Math.round(Math.random()*e);return{algorithm:t,challenge:await $e(n,r,t),salt:n,signature:""}}async function $e(e,t,n){return st(await crypto.subtle.digest(n.toUpperCase(),ot.encode(e+t)))}async function at(e,t,n="SHA-256",r=lt){const o=Date.now();for(let c=0;c<=r;c++)if(await $e(t,c,n)===e)return{number:c,took:Date.now()-o};return null}var p=(e=>(e.ERROR="error",e.VERIFIED="verified",e.VERIFYING="verifying",e.UNVERIFIED="unverified",e))(p||{});function ft(e){Ve(e,"svelte-fqcw55",".altcha.svelte-fqcw55.svelte-fqcw55{background:var(--altcha-color-base, transparent);border:1px solid var(--altcha-color-border, #a0a0a0);border-radius:3px;color:var(--altcha-color-text, currentColor);display:flex;flex-direction:column;max-width:260px;overflow:hidden;position:relative;text-align:left}.altcha.svelte-fqcw55.svelte-fqcw55:focus-within{border-color:var(--altcha-color-border-focus, currentColor)}.altcha-main.svelte-fqcw55.svelte-fqcw55{align-items:center;display:flex;gap:0.4rem;padding:0.7rem}.altcha-label.svelte-fqcw55.svelte-fqcw55{flex-grow:1}.altcha-label.svelte-fqcw55 label.svelte-fqcw55{cursor:pointer}.altcha-logo.svelte-fqcw55.svelte-fqcw55{color:currentColor;opacity:0.3}.altcha-logo.svelte-fqcw55.svelte-fqcw55:hover{opacity:1}.altcha-error.svelte-fqcw55.svelte-fqcw55{color:var(--altcha-color-error-text, #f23939);display:flex;font-size:0.85rem;gap:0.3rem;padding:0 0.7rem 0.7rem}.altcha-footer.svelte-fqcw55.svelte-fqcw55{align-items:center;background-color:var(--altcha-color-footer-bg, transparent);display:flex;font-size:0.75rem;opacity:0.4;padding:0.2rem 0.7rem;text-align:right}.altcha-footer.svelte-fqcw55.svelte-fqcw55:hover{opacity:1}.altcha-footer.svelte-fqcw55>.svelte-fqcw55:first-child{flex-grow:1}.altcha-footer.svelte-fqcw55 a{color:currentColor}.altcha-checkbox.svelte-fqcw55.svelte-fqcw55{display:flex;align-items:center;height:24px;width:24px}.altcha-checkbox.svelte-fqcw55 input.svelte-fqcw55{width:18px;height:18px;margin:0}.altcha-hidden.svelte-fqcw55.svelte-fqcw55{display:none}.altcha-spinner.svelte-fqcw55.svelte-fqcw55{animation:svelte-fqcw55-altcha-spinner 0.75s infinite linear;transform-origin:center}@keyframes svelte-fqcw55-altcha-spinner{100%{transform:rotate(360deg)}}")}function ce(e){let t,n,r;return{c(){t=G("svg"),n=G("path"),r=G("path"),c(n,"d","M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"),c(n,"fill","currentColor"),c(n,"opacity",".25"),c(r,"d","M12,4a8,8,0,0,1,7.89,6.7A1.53,1.53,0,0,0,21.38,12h0a1.5,1.5,0,0,0,1.48-1.75,11,11,0,0,0-21.72,0A1.5,1.5,0,0,0,2.62,12h0a1.53,1.53,0,0,0,1.49-1.3A8,8,0,0,1,12,4Z"),c(r,"fill","currentColor"),c(r,"class","altcha-spinner svelte-fqcw55"),c(t,"width","24"),c(t,"height","24"),c(t,"viewBox","0 0 24 24"),c(t,"xmlns","http://www.w3.org/2000/svg")},m(e,o){q(e,t,o),m(t,n),m(t,r)},d(e){e&&I(t)}}}function ut(e){let t,n,r=e[9].label+"";return{c(){t=v("label"),c(t,"for",n=e[3]+"_checkbox"),c(t,"class","svelte-fqcw55")},m(e,n){q(e,t,n),t.innerHTML=r},p(e,o){512&o[0]&&r!==(r=e[9].label+"")&&(t.innerHTML=r),8&o[0]&&n!==(n=e[3]+"_checkbox")&&c(t,"for",n)},d(e){e&&I(t)}}}function ht(e){let t,n=e[9].verifying+"";return{c(){t=v("span")},m(e,r){q(e,t,r),t.innerHTML=n},p(e,r){512&r[0]&&n!==(n=e[9].verifying+"")&&(t.innerHTML=n)},d(e){e&&I(t)}}}function dt(e){let t,n,r,o=e[9].verified+"";return{c(){t=v("span"),n=M(),r=v("input"),c(r,"type","hidden"),c(r,"name",e[3]),r.value=e[4]},m(e,c){q(e,t,c),t.innerHTML=o,q(e,n,c),q(e,r,c)},p(e,n){512&n[0]&&o!==(o=e[9].verified+"")&&(t.innerHTML=o),8&n[0]&&c(r,"name",e[3]),16&n[0]&&(r.value=e[4])},d(e){e&&(I(t),I(n),I(r))}}}function ae(e){let t,n,r,o,i,l;return{c(){t=v("div"),n=v("a"),r=G("svg"),o=G("path"),i=G("path"),l=G("path"),c(o,"d","M2.33955 16.4279C5.88954 20.6586 12.1971 21.2105 16.4279 17.6604C18.4699 15.947 19.6548 13.5911 19.9352 11.1365L17.9886 10.4279C17.8738 12.5624 16.909 14.6459 15.1423 16.1284C11.7577 18.9684 6.71167 18.5269 3.87164 15.1423C1.03163 11.7577 1.4731 6.71166 4.8577 3.87164C8.24231 1.03162 13.2883 1.4731 16.1284 4.8577C16.9767 5.86872 17.5322 7.02798 17.804 8.2324L19.9522 9.01429C19.7622 7.07737 19.0059 5.17558 17.6604 3.57212C14.1104 -0.658624 7.80283 -1.21043 3.57212 2.33956C-0.658625 5.88958 -1.21046 12.1971 2.33955 16.4279Z"),c(o,"fill","currentColor"),c(i,"d","M3.57212 2.33956C1.65755 3.94607 0.496389 6.11731 0.12782 8.40523L2.04639 9.13961C2.26047 7.15832 3.21057 5.25375 4.8577 3.87164C8.24231 1.03162 13.2883 1.4731 16.1284 4.8577L13.8302 6.78606L19.9633 9.13364C19.7929 7.15555 19.0335 5.20847 17.6604 3.57212C14.1104 -0.658624 7.80283 -1.21043 3.57212 2.33956Z"),c(i,"fill","currentColor"),c(l,"d","M7 10H5C5 12.7614 7.23858 15 10 15C12.7614 15 15 12.7614 15 10H13C13 11.6569 11.6569 13 10 13C8.3431 13 7 11.6569 7 10Z"),c(l,"fill","currentColor"),c(r,"width","22"),c(r,"height","22"),c(r,"viewBox","0 0 20 20"),c(r,"fill","none"),c(r,"xmlns","http://www.w3.org/2000/svg"),c(n,"href",ve),c(n,"target","_blank"),c(n,"class","altcha-logo svelte-fqcw55")},m(e,c){q(e,t,c),m(t,n),m(n,r),m(r,o),m(r,i),m(r,l)},p:Z,d(e){e&&I(t)}}}function fe(e){let t,n,r,o,i,l=e[9].error+"";return{c(){t=v("div"),n=G("svg"),r=G("path"),o=M(),i=v("div"),c(r,"stroke-linecap","round"),c(r,"stroke-linejoin","round"),c(r,"d","M6 18L18 6M6 6l12 12"),c(n,"width","14"),c(n,"height","14"),c(n,"xmlns","http://www.w3.org/2000/svg"),c(n,"fill","none"),c(n,"viewBox","0 0 24 24"),c(n,"stroke-width","1.5"),c(n,"stroke","currentColor"),c(i,"title",e[8]),c(t,"class","altcha-error svelte-fqcw55")},m(e,c){q(e,t,c),m(t,n),m(n,r),m(t,o),m(t,i),i.innerHTML=l},p(e,t){512&t[0]&&l!==(l=e[9].error+"")&&(i.innerHTML=l),256&t[0]&&c(i,"title",e[8])},d(e){e&&I(t)}}}function ue(e){let t,n,r=e[9].footer+"";return{c(){t=v("div"),n=v("div"),c(n,"class","svelte-fqcw55"),c(t,"class","altcha-footer svelte-fqcw55")},m(e,o){q(e,t,o),m(t,n),n.innerHTML=r},p(e,t){512&t[0]&&r!==(r=e[9].footer+"")&&(n.innerHTML=r)},d(e){e&&I(t)}}}function gt(e){let t,n,r,o,i,l,s,a,u,h,d,f,$,g,w=e[5]===p.VERIFYING&&ce();function b(e,t){return e[5]===p.VERIFIED?dt:e[5]===p.VERIFYING?ht:ut}let y=b(e),x=y(e),C=!0!==e[2]&&ae(),E=e[8]&&fe(e),k=e[9].footer&&!0!==e[1]&&ue(e);return{c(){t=v("div"),n=v("div"),w&&w.c(),r=M(),o=v("div"),i=v("input"),a=M(),u=v("div"),x.c(),h=M(),C&&C.c(),d=M(),E&&E.c(),f=M(),k&&k.c(),c(i,"type","checkbox"),c(i,"id",l=e[3]+"_checkbox"),i.required=s="onsubmit"!==e[0],c(i,"class","svelte-fqcw55"),c(o,"class","altcha-checkbox svelte-fqcw55"),le(o,"altcha-hidden",e[5]===p.VERIFYING),c(u,"class","altcha-label svelte-fqcw55"),c(n,"class","altcha-main svelte-fqcw55"),c(t,"class","altcha svelte-fqcw55"),c(t,"data-state",e[5])},m(c,l){q(c,t,l),m(t,n),w&&w.m(n,null),m(n,r),m(n,o),m(o,i),i.checked=e[6],m(n,a),m(n,u),x.m(u,null),m(n,h),C&&C.m(n,null),m(t,d),E&&E.m(t,null),m(t,f),k&&k.m(t,null),e[23](t),$||(g=[D(i,"change",e[22]),D(i,"change",e[10]),D(i,"invalid",e[11])],$=!0)},p(e,a){e[5]===p.VERIFYING?w||(w=ce(),w.c(),w.m(n,r)):w&&(w.d(1),w=null),8&a[0]&&l!==(l=e[3]+"_checkbox")&&c(i,"id",l),1&a[0]&&s!==(s="onsubmit"!==e[0])&&(i.required=s),64&a[0]&&(i.checked=e[6]),32&a[0]&&le(o,"altcha-hidden",e[5]===p.VERIFYING),y===(y=b(e))&&x?x.p(e,a):(x.d(1),x=y(e),x&&(x.c(),x.m(u,null))),!0!==e[2]?C?C.p(e,a):(C=ae(),C.c(),C.m(n,null)):C&&(C.d(1),C=null),e[8]?E?E.p(e,a):(E=fe(e),E.c(),E.m(t,f)):E&&(E.d(1),E=null),e[9].footer&&!0!==e[1]?k?k.p(e,a):(k=ue(e),k.c(),k.m(t,null)):k&&(k.d(1),k=null),32&a[0]&&c(t,"data-state",e[5])},i:Z,o:Z,d(n){n&&I(t),w&&w.d(),x.d(),C&&C.d(),E&&E.d(),k&&k.d(),e[23](null),$=!1,H(g)}}}const ve="https://altcha.org/";function he(e){return JSON.parse(e)}function mt(e,t,n){let r,o,c,{auto:i}=t,{challengeurl:l}=t,{challengejson:s}=t,{debug:a=!1}=t,{hidefooter:u=!1}=t,{hidelogo:h=!1}=t,{name:d="altcha"}=t,{maxnumber:f}=t,{mockerror:$=!1}=t,{strings:m}=t,{test:g=!1}=t;const v=We(),w=["SHA-256","SHA-384","SHA-512"];let b,y=!1,x=null,C=null,E=null,k=p.UNVERIFIED;function I(...e){(a||e.some((e=>e instanceof Error)))&&console[e[0]instanceof Error?"error":"log"]("ALTCHA",...e)}function q(e){x&&"onsubmit"===i&&k===p.UNVERIFIED&&(e.preventDefault(),e.stopPropagation(),N().then((()=>{null==x||x.requestSubmit()})))}function _(){L()}async function G(e){let t=null;if("Worker"in window){try{t=await async function(e,t,n){const r=new it;return new Promise((o=>{r.addEventListener("message",(e=>{o(e.data)})),r.postMessage({alg:n,challenge:e,max:f,salt:t})}))}(e.challenge,e.salt,e.algorithm)}catch(e){I(e)}if(void 0!==(null==t?void 0:t.number))return{data:e,solution:t}}return{data:e,solution:await at(e.challenge,e.salt,e.algorithm,f)}}function L(e=p.UNVERIFIED){n(6,y=!1),n(8,C=null),n(4,E=null),n(5,k=e)}async function N(){return L(p.VERIFYING),async function(){if($)throw I("mocking error"),new Error("Mocked error.");if(r)return I("using provided json data"),r;if(g)return I("generating test challenge"),ct();{if(!l)throw new Error("Attribute challengeurl not set.");I("fetching challenge from",l);const e=await fetch(l);if(200!==e.status)throw new Error(`Server responded with ${e.status}.`);return e.json()}}().then((e=>(function(e){if(!e.algorithm)throw new Error("Invalid challenge. Property algorithm is missing.");if(void 0===e.signature)throw new Error("Invalid challenge. Property signature is missing.");if(!w.includes(e.algorithm.toUpperCase()))throw new Error(`Unknown algorithm value. Allowed values: ${w.join(", ")}`);if(!e.challenge||e.challenge.length<40)throw new Error("Challenge is too short. Min. 40 chars.");if(!e.salt||e.salt.length<10)throw new Error("Salt is too short. Min. 10 chars.")}(e),I("challenge",e),G(e)))).then((({data:e,solution:t})=>{if(I("solution",t),void 0===(null==t?void 0:t.number))throw new Error("Unexpected result returned.");I("verified"),n(5,k=p.VERIFIED),n(6,y=!0),n(4,E=function(e,t){return btoa(JSON.stringify({algorithm:e.algorithm,challenge:e.challenge,number:t.number,salt:e.salt,signature:e.signature,test:!!g||void 0,took:t.took}))}(e,t)),I("payload",E),Pe().then((()=>{v("verified",{payload:E})}))})).catch((e=>{I(e),n(5,k=p.ERROR),n(6,y=!1),n(8,C=e)}))}return He((()=>{x&&(x.removeEventListener("submit",q),x.removeEventListener("reset",_),x=null)})),Be((()=>{I("mounted","0.1.6"),g&&I("using test mode"),void 0!==i&&I("auto",i),x=b.closest("form"),x&&(x.addEventListener("submit",q),x.addEventListener("reset",_)),"onload"===i&&N()})),e.$$set=e=>{"auto"in e&&n(0,i=e.auto),"challengeurl"in e&&n(12,l=e.challengeurl),"challengejson"in e&&n(13,s=e.challengejson),"debug"in e&&n(14,a=e.debug),"hidefooter"in e&&n(1,u=e.hidefooter),"hidelogo"in e&&n(2,h=e.hidelogo),"name"in e&&n(3,d=e.name),"maxnumber"in e&&n(15,f=e.maxnumber),"mockerror"in e&&n(16,$=e.mockerror),"strings"in e&&n(17,m=e.strings),"test"in e&&n(18,g=e.test)},e.$$.update=()=>{8192&e.$$.dirty[0]&&(r=s?he(s):void 0),131072&e.$$.dirty[0]&&n(21,o=m?he(m):{}),2097152&e.$$.dirty[0]&&n(9,c={error:"Verification failed. Try again later.",footer:`Protected by ALTCHA`,label:"I'm not a robot",verified:"Verified",verifying:"Verifying...",waitAlert:"Verifying... please wait.",...o}),48&e.$$.dirty[0]&&v("statechange",{payload:E,state:k})},[i,u,h,d,E,k,y,b,C,c,function(){[p.UNVERIFIED,p.ERROR].includes(k)?N():n(6,y=!0)},function(){k===p.VERIFYING&&alert(c.waitAlert)},l,s,a,f,$,m,g,L,N,o,function(){y=this.checked,n(6,y)},function(e){z[e?"unshift":"push"]((()=>{b=e,n(7,b)}))}]}class wt extends nt{constructor(e){super(),et(this,e,mt,gt,Ae,{auto:0,challengeurl:12,challengejson:13,debug:14,hidefooter:1,hidelogo:2,name:3,maxnumber:15,mockerror:16,strings:17,test:18,reset:19,verify:20},ft,[-1,-1])}get auto(){return this.$$.ctx[0]}set auto(e){this.$$set({auto:e}),C()}get challengeurl(){return this.$$.ctx[12]}set challengeurl(e){this.$$set({challengeurl:e}),C()}get challengejson(){return this.$$.ctx[13]}set challengejson(e){this.$$set({challengejson:e}),C()}get debug(){return this.$$.ctx[14]}set debug(e){this.$$set({debug:e}),C()}get hidefooter(){return this.$$.ctx[1]}set hidefooter(e){this.$$set({hidefooter:e}),C()}get hidelogo(){return this.$$.ctx[2]}set hidelogo(e){this.$$set({hidelogo:e}),C()}get name(){return this.$$.ctx[3]}set name(e){this.$$set({name:e}),C()}get maxnumber(){return this.$$.ctx[15]}set maxnumber(e){this.$$set({maxnumber:e}),C()}get mockerror(){return this.$$.ctx[16]}set mockerror(e){this.$$set({mockerror:e}),C()}get strings(){return this.$$.ctx[17]}set strings(e){this.$$set({strings:e}),C()}get test(){return this.$$.ctx[18]}set test(e){this.$$set({test:e}),C()}get reset(){return this.$$.ctx[19]}get verify(){return this.$$.ctx[20]}}customElements.define("altcha-widget",tt(wt,{auto:{},challengeurl:{},challengejson:{},debug:{type:"Boolean"},hidefooter:{type:"Boolean"},hidelogo:{type:"Boolean"},name:{},maxnumber:{},mockerror:{type:"Boolean"},strings:{},test:{type:"Boolean"}},[],["reset","verify"],!1));export{wt as Altcha}; -//# sourceMappingURL=/sm/3946beb23f2e7b329f9d4f976183586f81ab9506ca82e19e9433e759dcf4e908.map \ No newline at end of file diff --git a/app/static/linkedin.png b/app/static/linkedin.png deleted file mode 100644 index f52d8a4501c7b6a131fcf38126704f18fd3efe29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2006 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 - - - - - - - - - - - - - - - About Me | pkrm.dev - - - - -
-

About Me

-

I am a freshman in Computer Science who enjoys programming and learning more about different technologies. I manage a Debian based home server where I self-host tools like: DNSCrypt, AdGuard, WireGuard, Syncthing, XMPP, and many more media/system management utilities.

Find my work by viewing my open-sourced repositories on GitHub.

-
- -
PGP Fingerprint: FD5C 7FFF 860B 6E97 7049 E27E 505E D36F C12B 5D5E
- - \ No newline at end of file diff --git a/app/templates/contact.html b/app/templates/contact.html deleted file mode 100644 index 9da956d..0000000 --- a/app/templates/contact.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Contact | pkrm.dev - - - - -
-

Contact Me

- -
- - - - - - -
- - {% if success %} -

Thank you for contacting me. I'll get back soon.

- {% endif %} - {% if error %} -

An error occured, please try again later.

- {% endif %} -
- -
PGP Fingerprint: FD5C 7FFF 860B 6E97 7049 E27E 505E D36F C12B 5D5E
- - - - \ No newline at end of file diff --git a/app/templates/index.html b/app/templates/index.html deleted file mode 100644 index f97509f..0000000 --- a/app/templates/index.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - Home | pkrm.dev - - - - -
-
-

Hello, I'm Parker

-

A student with a strong passion for technology and privacy.

-
- -
- Mail Logo - GitHub Logo - LinkedIn Logo - XMPP Logo - GnuPG Logo -
-
- -
PGP Fingerprint: FD5C 7FFF 860B 6E97 7049 E27E 505E D36F C12B 5D5E
- - \ No newline at end of file diff --git a/app/templates/pgp.html b/app/templates/pgp.html deleted file mode 100644 index f63c19c..0000000 --- a/app/templates/pgp.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - PGP Key | pkrm.dev - - - - -
-

Copy my key below, or click here to download it.

-

- -----BEGIN PGP PUBLIC KEY BLOCK----- -

- mDMEZyMGlhYJKwYBBAHaRw8BAQdAoO/hA2S3fx16L55Bx+2bRN+zZe+8+wyME8vQ - 7KANwn+0G1BhcmtlciBNIDxjb250YWN0QHBrcm0uZGV2PoiTBBMWCgA7AhsDBQsJ - CAcCAiICBhUKCQgLAgQWAgMBAh4HAheAFiEE/Vx//4YLbpdwSeJ+UF7Tb8ErXV4F - AmcjB84ACgkQUF7Tb8ErXV5MGQD/Uxy3OwbaGmSDYcJks3fT2xrcwrTLHpYHDU/e - MgIrFnUBALJ9X18ugx6s3CPtNgnyvm6cLU/ttzeRoRWdG8PuODYFiJMEExYKADsW - IQT9XH//hgtul3BJ4n5QXtNvwStdXgUCZyMGlgIbAwULCQgHAgIiAgYVCgkICwIE - FgIDAQIeBwIXgAAKCRBQXtNvwStdXjeOAP9qQ4qg2k0WamMec/SdOchux/p8wzTo - F0Z9yXwIXsjmeAD/RxeHB8x9ZCfe1t1eNk+oVcPBmw/fLPr8OALpjJkG9Aq4OARn - IwaWEgorBgEEAZdVAQUBAQdAyDo44/FnbZMNqQUxYHgaQY1qImz9YsLSD/fmHzrA - ymIDAQgHiHgEGBYKACAWIQT9XH//hgtul3BJ4n5QXtNvwStdXgUCZyMGlgIbDAAK - CRBQXtNvwStdXiqSAP4/QwITUsUE6OLRKUQZ5JN4WQhjWto18vIZI/NlNVvibAEA - knJ7V0TYPjX8LhOCno47dDkwSWAHT/S9oMbRg9rCigk= - =oX5k -
- -----END PGP PUBLIC KEY BLOCK----- -

-
- -
PGP Fingerprint: FD5C 7FFF 860B 6E97 7049 E27E 505E D36F C12B 5D5E
- - - - \ No newline at end of file diff --git a/app/views.py b/app/views.py deleted file mode 100644 index 415fac7..0000000 --- a/app/views.py +++ /dev/null @@ -1,115 +0,0 @@ -import flask -import os -import discord -import dotenv -import hashlib -import secrets -import hmac -import json -import base64 -import random - -app = flask.Flask(__name__) -dotenv.load_dotenv() -webhook_url = os.getenv("WEBHOOK_URL") -hmac_key = random.randbytes(500) - - -@app.route("/", methods=["GET"]) -def index(): - return flask.render_template("index.html") - - -@app.route("/about", methods=["GET"]) -def about(): - return flask.render_template("about.html") - - -@app.route("/contact", methods=["GET", "POST"]) -def contact(): - if flask.request.method == "GET": - return flask.render_template("contact.html") - - if flask.request.method == "POST": - try: - # Decode payload - data = json.loads( - base64.b64decode(flask.request.form["altcha"]).decode() - ) - - # Validate algorithm - if data["algorithm"] != "SHA-256": - return flask.render_template("contact.html", error=True) - # Validate challenge - expected_challenge = hashlib.sha256( - (data["salt"] + str(data["number"])).encode() - ).hexdigest() - if data["challenge"] != expected_challenge: - return flask.render_template("contact.html", error=True) - # Validate signature - signature = hmac.new( - hmac_key, data["challenge"].encode(), hashlib.sha256 - ).hexdigest() - if data["signature"] != signature: - return flask.render_template("contact.html", error=True) - - # All checks passed, send off form data - - name = flask.request.form["name"] - email = flask.request.form["email"] - message = flask.request.form["message"] - # Send the contact form to Discord via a webhook - webhook = discord.SyncWebhook.from_url(webhook_url) - - embed = discord.Embed( - title="New Message", - description=( - f"**Name:** ` {name} `\n**Email:** `" - f" {email} `\n**Message:** ` {message} `" - ), - color=0x85C0F7, - ) - webhook.send(embed=embed) - - return flask.render_template("contact.html", success=True) - # If any error happens for any reason, return the contact page with error - except: - return flask.render_template("contact.html", error=True) - - -@app.route("/altcha-challenge", methods=["GET"]) -def altcha_challenge(): - salt = secrets.token_urlsafe(25) - secret_number = random.randint(10000, 50000) - - challenge_data = f"{salt}{secret_number}".encode() - challenge = hashlib.sha256(challenge_data).hexdigest() - - signature = hmac.new( - hmac_key, challenge.encode(), hashlib.sha256 - ).hexdigest() - - response = { - "algorithm": "SHA-256", - "challenge": challenge, - "salt": salt, - "signature": signature, - } - - return flask.jsonify(response) - - -@app.route("/pgp", methods=["GET"]) -def pgp(): - return flask.render_template("pgp.html") - - -@app.route("/robots.txt", methods=["GET"]) -def robots(): - return flask.send_file("static/robots.txt") - - -@app.route("/parker.asc", methods=["GET"]) -def parker(): - # Send the file to download - return flask.send_file("static/parker.asc", as_attachment=True) diff --git a/css/index.css b/css/index.css new file mode 100644 index 0000000..4b58b69 --- /dev/null +++ b/css/index.css @@ -0,0 +1,215 @@ +html { + font-family: "Open Sans", Arial; + color: #454545; + scroll-behavior: smooth; +} + +html.dark * { + background-color: #242528; + color: #9F9FAA; +} + +html.dark svg, +html.dark #about a { + color: #9F9FAA; + fill: #9F9FAA; +} + +html.increased-contrast * { + background-color: #FFF; + color: #050505; +} + +html.increased-contrast svg, +html.increased-contrast #about a { + fill: #050505; + color: #050505; +} + +body { + margin: 0; + padding: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + min-height: 200vh; +} + +nav { + font-weight: 600; + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); + font-size: 1rem; + text-align: center; + margin-top: 2rem; + width: 90vw; +} + +nav a { + margin: 0 1rem; + text-decoration: none; + color: #454545; +} + +nav a:hover { + text-decoration: underline; + cursor: pointer; + opacity: 0.6; + transition: opacity 0.25s ease-in-out; +} + +#toggle { + /* Move to the top right of the screen */ + position: absolute; + top: 0; + right: 0; + margin: 1rem; + font-size: 1.5rem; + color: #454545; +} + +#moon, #sun { + position: absolute; + transition: opacity 0.1s ease; +} + +#moon { + opacity: 0; +} + +#sun { + opacity: 1; +} + +/* Toggle media query for mobile */ +@media only screen and (max-width: 600px) { + #toggle { + display: none; + } +} + + +/* Container styles */ +header { + position: absolute; + top: 45%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; +} + +header h1 { + font-size: 45px; + width: 500px; +} + +header h2 { + font-size: 25px; + width: 500px; +} + +/* Header media query for mobile */ +@media only screen and (max-width: 600px) { + header h1 { + font-size: 1.5rem; + width: 300px; + } + + header h2 { + margin: 1rem 0 2rem 0; + width: 300px; + } +} + +header a { + text-decoration: none; +} + +svg { + margin: 0 1rem; + height: 50px; + width: 50px; +} + +/* Icons media query for mobile */ +@media only screen and (max-width: 600px) { + svg { + height: 40px; + width: 40px; + margin: 0 0.5rem; + } +} + +svg:hover { + cursor: pointer; + opacity: 0.6; + transition: opacity 0.25s ease-in-out; +} + +#down-arrow { + position: absolute; + bottom: 2%; + left: 50%; + transform: translateX(-50%); + color: #454545; + font-size: 2rem; +} + +#about { + margin-top: 100vh; + width: 1000px; +} + +#about h1 { + font-size: 25px; +} + +#about h2 { + font-size: 20px; +} + +#about p{ + font-size: 18px; +} + +#about ul li { + font-size: 18px; + margin-top: 7px; +} + +/* About media query for mobile */ +@media only screen and (max-width: 600px) { + #about { + width: 90%; + } + + #about h1 { + font-size: 1.5rem; + } + + #about h2 { + font-size: 1.25rem; + } + + #about p, #about ul li { + font-size: 1rem; + } + + #about ul li { + margin-top: 10px; + } +} + +#about a { + text-decoration: underline; + color: #454545; +} + +#about a:hover { + cursor: pointer; + opacity: 0.6; + transition: opacity 0.25s ease-in-out; +} \ No newline at end of file diff --git a/app/static/css/pgp.css b/css/pgp.css similarity index 100% rename from app/static/css/pgp.css rename to css/pgp.css diff --git a/index.html b/index.html new file mode 100644 index 0000000..1e3a93a --- /dev/null +++ b/index.html @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + Parker M. + + + +
+

Hello, I'm Parker

+

A student with a strong passion for technology and privacy.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+

About Me

+

I am a freshman in Computer Science at the University of Texas at Austin - also in FRI Quantum Computing. I manage a Debian based home server where I self-host everything I can. In addition to this, I actively work on personal projects, most of which are open-sourced.

+

View my projects on GitHub, or, if you prefer something lighter and not behind Cloudflare, check them out on my Cgit instance.

+
+

Things I run on my server

+
    +
  • WireGuard: Easy access to my home network when I'm away
  • +
  • Syncthing: Sync important files/databases across all of my machines
  • +
  • DNSCrypt: My own encrypted DNS resolver
  • +
  • AdGuard: DNS sinkhole to block ads + DNS hostnames
  • +
  • XMPP: I host my own personal XMPP server for people to contact me ( always use encryption )
  • +
  • Immich: Cloud photo storage with tons of features - alternative to Google Photos
  • +
  • Lavalink: Audio node for my Discord music bot
  • +
  • Guava: My open source and easily self-hostable Discord music bot
  • +
  • LinkLogger: My open source link shortener and IP logger
  • +
  • ... and a lot of media management services/tools
  • +
+
+

Personal Projects

+ +

Top 3

+
    +
  • Guava: Dead simple Discord music bot. Allows playing music from Spotify, Apple Music, SoundCloud, YouTube, Deezer, Bandcamp, and Twitch. Currently in >225 unique servers!
  • +
  • LinkLogger: Link shortener and IP logger. Features a full Web UI in React with a public API built on FastAPI.
  • +
  • EduStore (Inactive + Closed Source): Inventory management for school districts. Developed during my internship at and for Mansfield ISD. Won 1st place in the Congressional App Challenge for Texas' 6th District.
  • +
+ +

Others

+
    +
  • CordArr: Request new content for Radarr/Sonarr libraries and create temporary Jellyfin accounts through Discord commands.
  • +
  • PeakPass (Inactive): Web-based password manager that checks user hashes against previosuly breached passwords. Features strong encryption algorithms, password hashing + salting, and a custom implementation of breach detection ( rather than using an API like HIBP )
  • +
+
+ + \ No newline at end of file diff --git a/js/toggle.js b/js/toggle.js new file mode 100644 index 0000000..2399f7a --- /dev/null +++ b/js/toggle.js @@ -0,0 +1,30 @@ +const moon = document.getElementById('moon'); +const sun = document.getElementById('sun'); + +moon.addEventListener('click', () => { + document.documentElement.classList.remove('dark'); + + // Fade out moon and fade in sun + moon.style.opacity = '0'; + sun.style.opacity = '1'; + + // After the transition ends, hide the moon and show the sun (for accessibility) + setTimeout(() => { + moon.style.display = 'none'; + sun.style.display = 'block'; + }, 100); // Match the duration of the transition (100ms) +}); + +sun.addEventListener('click', () => { + document.documentElement.classList.add('dark'); + + // Fade out sun and fade in moon + sun.style.opacity = '0'; + moon.style.opacity = '1'; + + // After the transition ends, hide the sun and show the moon (for accessibility) + setTimeout(() => { + sun.style.display = 'none'; + moon.style.display = 'block'; + }, 100); // Match the duration of the transition (100ms) +}); diff --git a/app/static/parker.asc b/parker.asc similarity index 100% rename from app/static/parker.asc rename to parker.asc diff --git a/pkrm.service b/pkrm.service deleted file mode 100644 index 55ddc64..0000000 --- a/pkrm.service +++ /dev/null @@ -1,14 +0,0 @@ -# Systemd service file, feel free to edit to your needs, this isnt needed though - -[Unit] -Description=Keep PKRM.DEV Up and Running -After=network.target - -[Service] -Type=simple -WorkingDirectory=/home/parker/services/pkrm -ExecStart=/usr/bin/bash /home/parker/services/pkrm/pkrm.sh -Restart=always - -[Install] -WantedBy=multi-user.target \ No newline at end of file diff --git a/pkrm.sh b/pkrm.sh deleted file mode 100755 index f01bbf2..0000000 --- a/pkrm.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -gunicorn -b 0.0.0.0:4343 run:app \ No newline at end of file diff --git a/app/static/robots.txt b/robots.txt similarity index 100% rename from app/static/robots.txt rename to robots.txt diff --git a/run.py b/run.py deleted file mode 100644 index ea15d11..0000000 --- a/run.py +++ /dev/null @@ -1,4 +0,0 @@ -from app.views import app - -if __name__ == "__main__": - app.run(port="4343")