Initial commit. Basic functional page.
This commit is contained in:
commit
d514bd2a72
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1 @@
|
|||
!function(){function t(){var t=0,e=0;this.output="",this.readByte=function(r){return"string"==typeof r&&(r=r.charCodeAt(0)),0>t?e|=r>>-t:e=r<<t&248,t>3?(t-=8,1):(4>t&&(this.output+=i[e>>3],t+=5),0)},this.finish=function(r){var n=this.output+(0>t?i[e>>3]:"")+(r?"$":"");return this.output="",n}}function e(){var t=0,e=0;this.output="",this.readChar=function(r){"string"!=typeof r&&"number"==typeof r&&(r=String.fromCharCode(r)),r=r.toLowerCase();var n=s()[r];"undefined"!=typeof n&&(n<<=3,e|=n>>>t,t+=5,t>=8&&(this.output+=String.fromCharCode(e),t-=8,e=t>0?n<<5-t&255:0))},this.finish=function(e){var r=this.output+(0>t?i[bits>>3]:"")+(e?"$":"");return this.output="",r}}function r(e){var r=new t,n=r.update(e,!0);return n}function n(t){var r=new e,n=r.update(t,!0);return n}function u(t,e){"undefined"==typeof f&&(f=require("crypto"));var n=f.createHash("sha1");if(n.digest=function(t){return function(){return r(t.call(this,"binary"))}}(n.digest),e){if("string"==typeof t||Buffer.isBuffer(t))try{return e(null,u(t))}catch(i){return e(i,null)}return t.on("data",function(t){n.update(t)}),void t.on("end",function(){e(null,n.digest())})}return t?n.update(t).digest():n}var i="0123456789abcdefghjkmnpqrtuvwxyz",o={o:0,i:1,l:1,s:5},s=function(){for(var t={},e=0;e<i.length;e++)t[i[e]]=e;for(var r in o)o.hasOwnProperty(r)&&(t[r]=t[""+o[r]]);return s=function(){return t},t};t.prototype.update=function(t,e){for(var r=0;r<t.length;)r+=this.readByte(t[r]);var n=this.output;return this.output="",e&&(n+=this.finish()),n},e.prototype.update=function(t,e){for(var r=0;r<t.length;r++)this.readChar(t[r]);var n=this.output;return this.output="",e&&(n+=this.finish()),n};var f,a;u.file=function(t,e){return"-"==t?(process.stdin.resume(),u(process.stdin,e)):("undefined"==typeof a&&(a=require("fs")),a.stat(t,function(r,n){return r?e(r,null):n.isDirectory()?e({dir:!0,message:"Is a directory"}):u(require("fs").createReadStream(t),e)}))};var d={Decoder:e,Encoder:t,encode:r,decode:n,sha1:u};"undefined"!=typeof window&&(window.base32=d),"undefined"!=typeof module&&module.exports&&(module.exports=d)}();
|
Binary file not shown.
After Width: | Height: | Size: 957 B |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="16" height="16"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<path d="M11 4h3.627c-0.078-0.126-0.172-0.266-0.286-0.421-0.347-0.473-0.831-1.027-1.362-1.558s-1.085-1.015-1.558-1.362c-0.155-0.114-0.295-0.208-0.421-0.286v3.627z"></path>
|
||||
<path d="M7 7h2v2h-2v-2z"></path>
|
||||
<path d="M10.5 5c-0.276 0-0.5-0.224-0.5-0.5v-4.5h-7.75c-0.689 0-1.25 0.561-1.25 1.25v13.5c0 0.689 0.561 1.25 1.25 1.25h11.5c0.689 0 1.25-0.561 1.25-1.25v-9.75h-4.5zM11 13.5c0 0.275-0.225 0.5-0.5 0.5h-5c-0.275 0-0.5-0.225-0.5-0.5v-4c0-0.275 0.225-0.5 0.5-0.5h0.5v-2.5c0-0.276 0.224-0.5 0.5-0.5h3c0.276 0 0.5 0.224 0.5 0.5v2.5h0.5c0.275 0 0.5 0.225 0.5 0.5v4z"></path>
|
||||
</svg><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
|
||||
@media (prefers-color-scheme: dark) { :root { filter: invert(100%); } }
|
||||
</style></svg>
|
After Width: | Height: | Size: 992 B |
|
@ -0,0 +1,269 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Based</title>
|
||||
|
||||
|
||||
<link rel="icon" type="image/png" href="//favicon-96x96.png" sizes="96x96" />
|
||||
<link rel="icon" type="image/svg+xml" href="./favicon.svg" />
|
||||
<link rel="shortcut icon" href="./favicon.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="./apple-touch-icon.png" />
|
||||
<link rel="manifest" href="./site.webmanifest" />
|
||||
|
||||
<meta name="apple-mobile-web-app-title" content="Based" />
|
||||
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=.75,maximum-scale=.75,user-scalable=no,interactive-widget=resizes-content">
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--primary: #0ad;
|
||||
--shadow: rgba(0, 0, 0, .25);
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%:
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.25rem;
|
||||
font-family: sans-serif;
|
||||
background: #fafafa;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: .25rem;
|
||||
background: #111;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.title {
|
||||
padding: .5rem 1rem;
|
||||
margin: 0;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
.feedback {
|
||||
width: 100%;
|
||||
height: 1.5rem;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
opacity: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.feedback.hidden {
|
||||
opacity: 0;
|
||||
transition: opacity 1s ease-out;
|
||||
}
|
||||
|
||||
.section {
|
||||
width: 100%;
|
||||
max-width: 1500px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
padding: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.section-heading {
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
|
||||
.row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.input {
|
||||
font-size: 1.25rem;
|
||||
flex-grow: 1;
|
||||
box-sizing: border-box;
|
||||
padding: .5rem .75rem;
|
||||
border: solid 1px var(--shadow);
|
||||
border-radius: .25rem;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.input:focus {
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 3px var(--shadow);
|
||||
}
|
||||
|
||||
.arrow-down {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media(max-width: 1000px) {
|
||||
body {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.row {
|
||||
flex-direction: column;
|
||||
gap: .5rem;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 100%;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.arrow-right{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.arrow-down {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="./base32.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="header">
|
||||
<h1 class="title">Based</h1>
|
||||
</header>
|
||||
|
||||
<span
|
||||
id="feedback"
|
||||
class="feedback feedback-copy hidden"
|
||||
>Copied '<span id="feedbackValue" class="feedback-value"></span>' to clipboard!</span>
|
||||
|
||||
<section class="section">
|
||||
<h2 class="section-heading">Encode</h2>
|
||||
|
||||
<div class="row">
|
||||
<input
|
||||
id="nameInput"
|
||||
placeholder="Name"
|
||||
class="input"
|
||||
>
|
||||
|
||||
<span class="arrow arrow-right">➡</span>
|
||||
<span class="arrow arrow-down"> ⬇</span>
|
||||
|
||||
<input
|
||||
id="codeOutput"
|
||||
placeholder="Code"
|
||||
class="input"
|
||||
readonly
|
||||
>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2 class="section-heading">Decode</h2>
|
||||
|
||||
<div class="row">
|
||||
<input
|
||||
id="codeInput"
|
||||
placeholder="Code"
|
||||
class="input"
|
||||
>
|
||||
|
||||
<span class="arrow arrow-right">➡</span>
|
||||
<span class="arrow arrow-down"> ⬇</span>
|
||||
|
||||
<input
|
||||
id="nameOutput"
|
||||
placeholder="Name"
|
||||
class="input"
|
||||
readonly
|
||||
>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
const nameInput = document.querySelector('#nameInput');
|
||||
const codeOutput = document.querySelector('#codeOutput');
|
||||
const codeInput = document.querySelector('#codeInput');
|
||||
const nameOutput = document.querySelector('#nameOutput');
|
||||
|
||||
const feedback = document.querySelector('#feedback');
|
||||
const feedbackValue = document.querySelector('#feedbackValue');
|
||||
|
||||
function normalize(text) {
|
||||
return text
|
||||
.normalize("NFD")
|
||||
.toLowerCase()
|
||||
.replace(/\p{Diacritic}/gu, "")
|
||||
.replace(/[^a-z0-9]/g, ' ')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
}
|
||||
|
||||
function getCode() {
|
||||
const normalized = normalize(nameInput.value);
|
||||
const encoded = base32.encode(normalized).toUpperCase();
|
||||
|
||||
codeOutput.value = encoded;
|
||||
}
|
||||
|
||||
function getName() {
|
||||
const decoded = base32.decode(codeInput.value);
|
||||
const capitalized = decoded.split(' ').map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`).join(' ');
|
||||
|
||||
nameOutput.value = capitalized;
|
||||
}
|
||||
|
||||
nameInput.addEventListener('input', () => getCode());
|
||||
codeInput.addEventListener('input', () => getName());
|
||||
|
||||
function selectCopy(event) {
|
||||
const text = event.target.value;
|
||||
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.target.select();
|
||||
navigator.clipboard.writeText(text);
|
||||
|
||||
feedbackValue.textContent = text;
|
||||
feedback.classList.remove('hidden');
|
||||
|
||||
setTimeout(() => {
|
||||
feedback.classList.add('hidden');
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
codeOutput.addEventListener('focus', selectCopy);
|
||||
nameOutput.addEventListener('focus', selectCopy);
|
||||
|
||||
nameInput.addEventListener('focus', (event) => event.target.select());
|
||||
codeInput.addEventListener('focus', (event) => event.target.select());
|
||||
|
||||
const query = new URL(window.location);
|
||||
|
||||
const urlName = query.searchParams.get('name');
|
||||
const urlCode = query.searchParams.get('code');
|
||||
|
||||
if (urlName) {
|
||||
nameInput.value = urlName;
|
||||
getCode();
|
||||
}
|
||||
|
||||
if (urlCode) {
|
||||
codeInput.value = urlCode;
|
||||
getName();
|
||||
}
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "Based",
|
||||
"short_name": "Based",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/web-app-manifest-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/web-app-manifest-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Loading…
Reference in New Issue