What if you could live for a 1000 years?

This commit is contained in:
flash 2024-05-30 19:47:26 +00:00
parent 1820c7b9ed
commit 48a4809f1f
109 changed files with 2254 additions and 1814 deletions

2
.gitignore vendored
View file

@ -14,3 +14,5 @@
/public/error-404.html
/public/error-500.html
/public/error-503.html
/public/fonts
/assets/makai.css/fonts.css

View file

@ -3,7 +3,6 @@
padding: 0;
box-sizing: border-box;
position: relative;
outline-style: none;
}
html, body {

View file

@ -1,100 +0,0 @@
.ascii-wrap {
margin-bottom: calc(100vh - 70px);
}
.ascii-chars {
text-align: center;
max-width: 1200px;
margin: 0 auto;
}
.ascii-char {
display: inline-flex;
flex-direction: column;
border: 2px solid #4a3650;
border-radius: 5px;
overflow: hidden;
width: 200px;
text-align: left;
margin: 2px;
background-color: #333;
cursor: pointer !important;
transition: background-color .1s;
}
.ascii-char:hover,
.ascii-char:focus {
background-color: #444;
}
.ascii-char:active {
background-color: #222;
}
.ascii-char-print {
white-space: pre;
font-family: var(--font-monospace, monospace);
font-size: 2.5em;
text-align: center;
padding: 10px;
pointer-events: none;
}
.ascii-char-desc {
text-align: center;
font-size: 1.2em;
padding: 0 5px 5px;
pointer-events: none;
}
.ascii-char-misc {
display: flex;
justify-content: space-evenly;
border-top: 1px solid #4a3650;
}
.ascii-char-misc-item {
flex: 1 1 auto;
padding: 2px 5px;
transition: background-color .1s;
background-color: #444;
}
.ascii-char-misc-item:not(:last-child) {
border-right: 1px solid #4a3650;
}
.ascii-char-misc-item:hover,
.ascii-char-misc-item:focus {
background-color: #666;
}
.ascii-char-misc-item:active {
background-color: #555;
}
.ascii-char-misc-item-head {
font-variant: small-caps;
}
.ascii-char-misc-item-value {
font-family: var(--font-monospace, monospace);
text-align: right;
}
.ascii-search {
padding-top: 10px;
position: sticky;
top: 0;
z-index: 1000;
background-image: linear-gradient(180deg, #4a3650 51px, transparent);
}
.ascii-search-box {
border: 1px solid #000;
border-radius: 5px;
overflow: hidden;
max-width: 1200px;
margin: 0 auto;
}
.ascii-search-box input {
border-width: 0;
background-color: #111;
color: #fff;
width: 100%;
height: 100%;
font-size: 2em;
padding: 5px;
}
.ascii-search-hint {
font-size: .9em;
padding: 0 5px;
transition: opacity .2s;
max-width: 1200px;
margin: 0 auto;
}

View file

@ -0,0 +1,26 @@
.badges {
margin-top: var(--global-spacing);
background: var(--container-colour);
border: 1px solid var(--container-border);
display: grid;
grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
gap: var(--global-spacing-0-5x);
padding: var(--global-spacing);
}
.badges-item {
display: flex;
justify-content: center;
align-items: center;
color: inherit;
text-decoration: none;
}
.badges-item img {
display: block;
image-rendering: crisp-edges;
width: 88px;
height: 31px;
flex-shrink: 0;
flex-grow: 0;
}

View file

@ -1,115 +0,0 @@
.clock {
width: 200px;
height: 200px;
border-radius: 100%;
border: 4px solid #c0c0c0;
overflow: hidden;
box-sizing: content-box;
filter: drop-shadow(0 1px 5px #000);
}
.clock-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #fffd;
filter: blur(20px);
}
.clock-center {
position: absolute;
top: 96px;
left: 96px;
width: 8px;
height: 8px;
background-color: #000;
border-radius: 100%;
z-index: 1000;
}
.clock-hand {
--hand-rotation: 0deg;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: rotate(var(--hand-rotation));
z-index: 900;
}
.clock-hand-display {
position: absolute;
width: 2px;
left: 99px;
height: 99px;
background-color: #000;
}
.clock-hand-hours {
z-index: 910;
}
.clock-hand-minutes {
z-index: 920;
}
.clock-hand-seconds {
z-index: 930;
}
.clock-hand-hours .clock-hand-display {
height: 70px;
margin-top: 30px;
filter: drop-shadow(0 1px 2px #000);
}
.clock-hand-minutes .clock-hand-display {
height: 80px;
margin-top: 20px;
filter: drop-shadow(0 1px 3px #000);
}
.clock-hand-seconds .clock-hand-display {
height: 100px;
margin-top: 15px;
opacity: .6;
background-color: #f00;
filter: drop-shadow(0 1px 4px #000);
}
.clock-number {
position: absolute;
top: 0;
left: 0;
z-index: 500;
width: 100px;
height: 100px;
}
.clock-number-display {
position: absolute;
width: 2px;
height: 10px;
background-color: #000;
}
.clock-number-9 .clock-number-display,
.clock-number-3 .clock-number-display {
width: 10px;
height: 2px;
}
.clock-number-6 .clock-number-display {
bottom: 0;
}
.clock-number-12 .clock-number-display {
right: 0;
height: 15px;
}
.clock-number-3 .clock-number-display {
right: 0;
bottom: 0;
}
.clock-number-12 {
left: 1px;
}
.clock-number-9 {
top: 99px;
}
.clock-number-6 {
top: 100px;
left: 99px;
}
.clock-number-3 {
top: 1px;
left: 100px;
}

View file

@ -0,0 +1,48 @@
.columns {
margin: 0 auto;
padding: 0 var(--global-spacing);
display: flex;
max-width: calc(var(--site-max-width) + var(--global-spacing-2x));
width: 100%;
gap: var(--global-spacing);
}
.columns-side {
flex-grow: 0;
flex-shrink: 0;
max-width: 260px;
width: 100%;
}
.columns-left {
order: 1;
}
.columns-right {
order: 3;
}
.columns-centre {
flex-grow: 1;
flex-shrink: 1;
order: 2;
}
@media (max-width: 1039px) {
.columns {
flex-direction: column;
gap: var(--global-spacing-2x);
}
.columns-left {
order: 2;
}
.columns-centre {
order: 1;
}
.columns-side {
max-width: 100%;
}
}

View file

@ -1,60 +0,0 @@
.index-featured {
display: grid;
grid-template-columns: 1fr 1fr;
flex: 1 1 auto;
overflow: hidden;
margin: 5px auto;
padding: 0 10px;
margin-bottom: 0;
column-gap: 10px;
row-gap: 10px;
width: 100%;
max-width: 1000px;
}
@media(max-width: 900px) { .index-featured { grid-template-columns: 1fr; overflow: visible; } }
.index-feature {
overflow: auto;
scrollbar-width: thin;
}
.index-feature-header {
border-bottom: 1px solid #333;
display: flex;
align-items: center;
}
.index-feature-header-link {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.index-feature-header-title {
font-family: var(--font-header, sans-serif);
font-size: 2em;
line-height: 1.5em;
pointer-events: none;
flex: 1 1 auto;
}
.index-feature-header-more {
pointer-events: none;
flex: 0 0 auto;
margin: 0 5px;
padding: 2px 8px;
border-radius: 2em;
font-size: .9em;
line-height: 1.5em;
background-color: #1a1a1a;
transition: background-color .2s;
}
.index-feature-header-more::after {
content: " »";
}
.index-feature-header:focus-within .index-feature-header-more,
.index-feature-header:hover .index-feature-header-more,
.index-feature-header-more:focus {
background-color: #2a2a2a;
}
.index-feature-header:active .index-feature-header-more,
.index-feature-header-more:active {
background-color: #222;
}

View file

@ -0,0 +1,11 @@
.footer {
font-size: .9em;
line-height: 1.5em;
text-align: center;
margin: 5px auto;
max-width: var(--site-max-width);
}
.footer-spacing {
height: var(--global-spacing);
}

View file

@ -0,0 +1,149 @@
.header {
width: 100%;
overflow: hidden;
transition: height .5s;
display: flex;
flex-direction: column;
color: var(--header-text-colour);
}
.header-background {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
overflow: hidden;
}
.header-background img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
transform: scale(1.3);
filter: brightness(0.6) blur(12px);
}
.header-forehead {
height: 150px;
flex-shrink: 0;
flex-grow: 0;
}
.header-foreground {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
background-color: #0005;
flex-shrink: 0;
flex-grow: 0;
text-shadow: 0 0 1px #000;
}
.header-main {
width: 100%;
max-width: var(--site-max-width, 100%);
display: flex;
justify-content: space-between;
align-items: center;
}
.header-logo {
font-family: var(--font-header);
color: transparent;
text-decoration: none;
display: flex;
flex-grow: 0;
flex-shrink: 0;
font-size: 2em;
line-height: 1.5em;
flex-shrink: 0;
flex-grow: 0;
margin: var(--global-spacing-0-5x);
}
.header-flash {
color: var(--logo-part1-colour);
white-space: pre;
}
.header-wave {
color: var(--logo-part2-colour);
white-space: pre;
}
.header-nav {
display: flex;
flex-wrap: wrap;
flex-shrink: 1;
flex-grow: 0;
justify-content: flex-end;
gap: var(--global-spacing);
max-width: 700px;
padding: var(--global-spacing-0-5x);
}
.header-nav a {
display: block;
color: inherit;
text-decoration: none;
font-size: 1.2em;
line-height: 1.4em;
padding: var(--global-spacing-2x);
transition: background-color .1s;
}
.header-nav a:hover,
.header-nav a:focus {
background-color: #fff1;
}
.header-nav a:active {
background-color: #0005;
}
.header-sub {
width: 100%;
background-color: #0005;
display: flex;
justify-content: center;
}
.header-breadcrumbs {
width: 100%;
max-width: var(--site-max-width, 100%);
display: flex;
align-items: center;
font-size: .9em;
line-height: 1.5em;
}
.header-breadcrumbs-sep {
padding: 0 var(--global-spacing);
}
.header-breadcrumbs-link {
display: block;
color: inherit;
text-decoration: none;
padding: 0 var(--global-spacing);
transition: background-color .1s;
}
.header-breadcrumbs-link:hover,
.header-breadcrumbs-link:focus {
background-color: #fff1;
}
.header-breadcrumbs-link:active {
background-color: #0005;
}
@media (max-width: 900px) {
.header-forehead {
display: none;
}
.header-main {
flex-direction: column;
}
.header-nav {
justify-content: center;
max-width: initial;
}
}

View file

@ -1,100 +0,0 @@
.php {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 177;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
pointer-events: none;
}
.php-search {
max-width: 600px;
width: 100%;
pointer-events: initial;
}
.php-search-input {
border: 1px solid #999;
background-color: #fff;
opacity: .5;
box-shadow: 0 2px .5em #000a, inset 0 1px 2px #000a;
transition: opacity .5s, box-shadow .5s;
}
.php-search-input:hover,
.php-search-input:focus,
.php-search-input:focus-within {
opacity: 1;
box-shadow: 0 2px 1em #000, inset 0 1px 2px #000a;
}
.php-search-input input {
border-width: 0;
background-color: transparent;
color: #000;
font-family: var(--font-regular, sans-serif);
font-size: 24px;
line-height: 35px;
width: 100%;
height: 100%;
padding: 2px 5px;
}
.php-time {
display: flex;
justify-content: center;
align-items: center;
margin: 20px auto;
width: 100%;
}
.php-time-analog {
flex: 0 0 auto;
}
.php-time-alter {
flex: 0 0 auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 300px;
font-family: var(--font-header, sans-serif);
filter: drop-shadow(0 1px 5px #000);
color: transparent;
}
.php-time-digital {
font-size: 7em;
line-height: 1.5em;
display: flex;
flex: 0 0 auto;
max-width: 300px;
width: 100%;
align-items: center;
justify-content: center;
}
.php-time-date {
font-size: 2em;
}
.php-time-digital-separator {
margin-top: -4px;
}
.php-time-digital-separator-hidden {
visibility: hidden;
}
.php-time-digital-hours,
.php-time-digital-separator,
.php-date-label {
background-image: linear-gradient(180deg, #eee 0%, #ddd 50%, #ccc 50%, #aaa 100%);
background-clip: text;
-webkit-background-clip: text;
}
.php-time-digital-minutes,
.php-date-week,
.php-date-day,
.php-date-month,
.php-date-year {
background-image: linear-gradient(0deg, #281430 0%, #392540 50%, #4a3650 50%, #6c5871 100%);
background-clip: text;
-webkit-background-clip: text;
}

View file

@ -1,47 +1,54 @@
.index {
display: flex;
flex-direction: column;
height: 100%;
max-height: 100vh;
overflow: hidden;
margin-top: var(--global-spacing);
background-color: var(--container-colour);
border: 1px solid var(--container-border);
}
@media(max-width: 900px) { .index {
max-height: initial;
overflow: auto;
} }
.index-menu {
width: 100%;
display: flex;
justify-content: center;
background-image: linear-gradient(0deg, #111 0%, #222 50%, #333 50%, #555 100%);
flex: 0 0 auto;
box-shadow: 0 0 1em rgba(0, 0, 0, .8);
.index h1 {
font-size: 2em;
--header-colour: var(--accent-colour1);
}
.index-menu a {
display: block;
color: #fff;
text-decoration: none;
.index h2 {
font-size: 1.5em;
line-height: 1.2em;
padding: 5px 10px;
transition: background-color .1s;
--header-colour: var(--accent-colour2);
margin-top: 1em;
}
.index-menu a:hover,
.index-menu a:focus {
background-color: rgba(255, 255, 255, .1);
.index h1,
.index h2 {
line-height: 1.4em;
}
.index-menu a:active {
background-color: rgba(127, 127, 127, .1);
.index h1 span,
.index h2 span {
display: inline-block;
background-color: var(--header-colour);
padding: 0 .5rem 0 1rem;
}
@media (max-width: 600px) {
.index-menu {
flex-wrap: wrap;
}
.index-menu a {
min-width: 200px;
margin: 2px;
padding: 10px;
text-align: center;
}
.index p {
margin: .5rem 1rem;
}
.index p code {
font-family: var(--font-monospace);
font-size: .8em;
}
.index p a {
color: inherit;
text-decoration: underline;
text-decoration-style: dashed;
text-decoration-color: var(--accent-colour3);
}
.index p a:visited {
text-decoration-color: var(--accent-colour2);
}
.index p a:hover,
.index p a:focus {
text-decoration-style: solid;
}
.index p a:active {
text-decoration-style: dotted;
}

View file

@ -3,7 +3,6 @@
padding: 0;
box-sizing: border-box;
position: relative;
outline-style: none;
}
html, body {
@ -12,12 +11,67 @@ html, body {
}
:root {
--font-size: 12px;
--line-height: 20px;
--font-size: 16px;
--line-height: 25px;
--font-regular: 'Zen Maru Gothic', Verdana, Geneva, 'Dejavu Sans', sans-serif;
--font-cursive: 'Hachi Maru Pop', cursive;
--font-monospace: 'Victor Mono', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
--font-header: 'Electrolize', Verdana, 'Dejavu Sans', sans-serif;
--site-max-width: 1600px;
--global-spacing: 4px;
--global-spacing-0-5x: calc(var(--global-spacing) * 0.5);
--global-spacing-1-5x: calc(var(--global-spacing) * 1.5);
--global-spacing-2x: calc(var(--global-spacing) * 2);
--traffic-border: #ebdfe0;
--traffic-red: #ec5c62;
--traffic-red-dark: #e55960;
--traffic-red-darker: #c34c52;
--traffic-yellow: #efeca4;
--traffic-yellow-dark: #e7e5a0;
--traffic-yellow-darker: #c5c388;
--traffic-green: #5decd4;
--traffic-green-dark: #59e5cd;
--traffic-green-darker: #4cc3af;
--logo-part1-colour: #fff;
--logo-part2-colour: #f79293;
--header-text-colour: #fff;
/* keep everything that should be dark theme'd below this line */
--background-colour: #9f8ff2;
--container-colour: #fff;
--container-border: #000;
--text-colour: #000;
--text-colour-inverted: #fff;
--accent-colour1: #ffdd60;
--accent-colour2: #f79293;
--accent-colour2-dark: #ef8d8f;
--accent-colour2-darker: #cd797a;
--accent-colour3: #929cf7;
--accent-colour3-dark: #8d97ef;
--accent-colour3-darker: #7981cd;
}
@media (prefers-color-scheme: dark) {
:root {
--background-colour: #000;
--container-colour: #12111d;
--container-border: #ff60d1;
--text-colour: #fff;
--text-colour-inverted: #000;
--accent-colour1: #ff60d1;
--accent-colour2: #ff4493;
--accent-colour2-dark: #f6438e;
--accent-colour2-darker: #d4397a;
--accent-colour3: #457eff;
--accent-colour3-dark: #4379f6;
--accent-colour3-darker: #3968d4;
}
}
.hidden {
@ -25,220 +79,34 @@ html, body {
visibility: hidden !important;
}
.invisible {
opacity: 0;
}
html {
scrollbar-color: #4a3650 #111;
}
pre, code {
font-family: var(--font-monospace, monospace);
}
/* an attempt to replicate scrollbar-color for chromosome */
::-webkit-scrollbar {
width: 6px;
background-color: #111;
}
::-webkit-scrollbar-thumb {
background-color: #4a3650;
}
::-webkit-scrollbar-thumb:hover {
background-color: #5b4761;
}
::-webkit-scrollbar-thumb:active {
background-color: #6c5872;
scrollbar-color: var(--accent-colour1) var(--background-colour);
scrollbar-width: thin;
}
body {
background-color: #111;
color: #fff;
background-color: var(--background-colour);
color: var(--text-colour);
font-size: var(--font-size, 12px);
line-height: var(--line-height, 20px);
font-family: var(--font-regular, sans-serif);
display: flex;
flex-direction: column;
font-family: var(--font-regular);
}
@include sprite.css;
@include header.css;
@include footer.css;
.header, .footer { flex: 0 0 auto; }
.container { flex: 1 1 auto; }
.header {
width: 100%;
height: 200px;
overflow: hidden;
transition: height .5s;
}
.header-minimal .header {
height: auto;
}
@media (max-width: 700px) {
.header { height: auto; }
}
.index .header {
height: 50vh;
}
.fullscreen-header .header {
height: 100%;
}
.header-background {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
overflow: hidden;
}
.header-background img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
filter: blur(20px) brightness(80%);
transform: scale(1.2);
opacity: 1;
transition: opacity .5s;
}
.header-foreground {
width: 100%;
height: 100%;
display: flex;
max-width: 1200px;
margin: 0 auto;
justify-content: space-between;
align-items: flex-end;
padding: 10px;
}
.header-minimal .header-foreground {
align-items: center;
}
@media (max-width: 700px) {
.header-foreground {
justify-content: center;
align-items: center;
flex-direction: column;
}
}
.index .header-foreground {
align-items: center;
justify-content: flex-end;
flex-direction: column;
}
.header-logo {
font-family: var(--font-header, sans-serif);
font-size: 3em;
line-height: 1.2em;
filter: drop-shadow(0 1px 5px #000);
color: transparent;
text-decoration: none;
display: flex;
flex: 0 0 auto;
}
.index .header-logo {
font-size: 5em;
}
.header-flash {
background-image: linear-gradient(180deg, #eee 0%, #ddd 50%, #ccc 50%, #aaa 100%);
background-clip: text;
-webkit-background-clip: text;
white-space: pre;
}
.header-wave {
background-image: linear-gradient(0deg, #281430 0%, #392540 50%, #4a3650 50%, #6c5871 100%);
-webkit-background-clip: text;
white-space: pre;
}
.header-right {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.header-menu {
display: flex;
justify-content: center;
flex: 0 0 auto;
margin-top: 10px;
}
.header-minimal .header-menu {
margin-top: 0;
}
.index .header-menu,
.fullscreen-header .header-menu,
.now-playing .header-menu {
display: none;
}
.header-menu a {
display: block;
color: #fff;
text-decoration: none;
font-size: 1.5em;
line-height: 1.2em;
margin: 0 2px;
padding: 5px 10px;
border-radius: 5px;
text-shadow: 0 1px 5px #000;
transition: background-color .1s;
}
.header-menu a:hover,
.header-menu a:focus {
background-color: rgba(255, 255, 255, .1);
}
.header-menu a:active {
background-color: rgba(127, 127, 127, .1);
}
@media (max-width: 800px) {
.header-menu {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.header-menu a {
text-align: center;
min-width: 150px;
margin: 2px;
padding: 10px 0;
}
.header-menu :first-child {
display: none;
}
}
@media (max-width: 480px) {
.header-menu { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 320px) {
.header-menu { grid-template-columns: 1fr; }
}
.footer {}
.index .footer,
.fullscreen-header .footer,
.now-playing .footer {
display: none;
}
.footer-text {
opacity: .2;
font-size: .9em;
text-align: center;
max-width: 1200px;
margin: 5px auto;
}
@include index.css;
@include noscript.css;
@include columns.css;
@include sidelist.css;
@include np.css;
@include featured.css;
@include sidecontact.css;
@include badges.css;
@include section.css;
@include socials.css;
@include project.css;
@include home.css;
@include clock.css;
@include tools/iframe.css;
@include tools/ascii.css;
@include tools/whois.css;
@include ascii.css;
@include whois.css;
@include index.css;

View file

@ -0,0 +1,39 @@
.noscript {
max-width: var(--site-max-width);
margin: var(--global-spacing) auto 0;
background: var(--traffic-red);
border: 1px solid var(--container-border);
padding: var(--global-spacing);
display: flex;
justify-content: center;
align-items: center;
gap: var(--global-spacing);
}
.noscript-icon {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
background: var(--traffic-red-darker);
font-family: var(--font-cursive);
font-size: 1.2em;
line-height: 1.5em;
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.noscript-icon-inner {
width: 30px;
height: 30px;
line-height: 32px;
margin-top: 3px;
text-align: center;
background: #fff;
color: #000;
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.noscript-text {
font-size: 1.2em;
line-height: 1.5em;
}

View file

@ -1,56 +1,58 @@
.header-now-playing {
max-height: 60px;
min-width: 300px;
max-width: 500px;
height: 100%;
background-image: linear-gradient(0deg, #111c 0%, #222c 50%, #333c 50%, #555c 100%);
box-shadow: 0 2px 1em #000;
border-radius: 5px;
.np {
background: var(--accent-colour1);
border: 1px solid var(--container-border);
margin-top: var(--global-spacing);
overflow: hidden;
align-items: center;
bottom: 0;
padding: 5px;
display: grid;
grid-template-columns: 25px 50px 1fr;
column-gap: 5px;
transition: bottom .5s, width .2s, max-height .5s, padding .2s;
}
.header-now-playing-hidden {
bottom: -80px;
max-height: 0;
padding: 0;
.np-header {
font-size: .8em;
line-height: 1.5em;
padding: 0 2px;
}
.header-now-playing-icon img {
vertical-align: middle;
.np-header-icon {
font-family: var(--font-cursive);
padding: 2px;
}
.header-now-playing-cover {
.np-header-text {
font-family: var(--font-header);
}
.np-cover {
float: right;
display: inline-block;
margin: 1px;
width: 50px;
height: 50px;
flex-grow: 0;
flex-shrink: 0;
border: 1px solid var(--container-colour);
background: var(--container-colour);
}
.header-now-playing-cover img {
.np-cover img {
width: 100%;
height: 100%;
vertical-align: middle;
object-fit: cover;
}
.header-now-playing-details {
overflow: hidden;
white-space: nowrap;
.np-details {
margin: 0 4px 2px;
}
.header-now-playing-details a {
color: #fff;
.np-details a {
color: inherit;
text-decoration: none;
transition: width .2s;
}
.header-now-playing-details a:hover,
.header-now-playing-details a:focus {
.np-details a:hover,
.np-details a:focus {
text-decoration: underline;
}
.header-now-playing-title {
.np-title {
font-size: 1.2em;
line-height: 1.5em;
}
.header-now-playing-title,
.header-now-playing-artist {
overflow: hidden;
text-overflow: ellipsis;
.np-artist {
font-size: .9em;
line-height: 1.5em;
}

View file

@ -1,126 +1,47 @@
.project {
padding: 0 10px;
/*background-color: var(--project-colour);
background-image: linear-gradient(#111e, #111e);
overflow: hidden;*/
}
.project-content {
max-width: 1100px;
width: 100%;
margin: 1em auto;
overflow: hidden;
background-color: var(--project-colour);
background-image: linear-gradient(180deg, #555c 0, #333c 38px, #222c 38px, #111c 100%);
box-shadow: 0 2px 1em #000;
border-radius: 5px;
}
.project-languages {
font-size: 0;
line-height: 0;
display: inline-block;
font-family: var(--font-regular, sans-serif);
margin-left: 4px;
}
.project-language {
font-size: 11px;
line-height: 18px;
display: inline-block;
border-left: 4px solid var(--language-colour);
background-color: var(--language-colour);
background-image: linear-gradient(90deg, #1118, #111a);
border-radius: 4px;
overflow: hidden;
padding: 0 4px;
margin: 0 4px;
box-shadow: 0 0 1px var(--language-colour);
}
.project-details {
margin: 10px;
margin-bottom: 0;
}
.project-details h2 {
font-family: var(--font-header, sans-serif);
font-size: 2em;
line-height: 1em;
font-weight: 400;
margin-bottom: 5px;
}
.project-details p {
font-size: .9em;
line-height: 1.8em;
}
.project-details .project-details-summary {
font-size: 1.2em;
line-height: 1.5em;
}
.project-links {
display: flex;
margin: 0 3px;
}
.project-link {
margin: 4px 1px;
color: #fff;
text-decoration: none;
min-width: 100px;
padding: 2px 8px;
border-radius: 4px;
transition: background-color .2s;
}
.project-link:hover,
.project-link:active {
background-color: #fff2;
}
.project-link:focus {
background-color: #fff1;
border: 1px solid var(--container-border);
background-color: var(--container-colour);
margin-top: var(--global-spacing);
}
.index-project {
margin: 5px;
background-image: linear-gradient(180deg, #555c 0, #333c 32px, #222c 32px, #111c 100%);
box-shadow: 0 2px 5px #000;
border-radius: 5px;
overflow: hidden;
}
.index-project-anchor {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.index-project-content {
margin: 5px 8px;
margin-bottom: 0;
pointer-events: none;
}
.index-project-name {
font-family: var(--font-header, sans-serif);
flex: 1 1 auto;
.project h2 {
font-size: 1.5em;
line-height: 1.5em;
line-height: 1.4em;
font-weight: 700;
font-family: var(--font-header);
background-color: var(--project-colour);
padding: var(--global-spacing-0-5x) var(--global-spacing);
}
.index-project-summary {
margin-top: 2px;
.project p {
margin: var(--global-spacing-0-5x) var(--global-spacing);
}
.index-project-links {
.project-tags {
display: flex;
pointer-events: none;
margin: 0 3px;
flex-wrap: wrap;
gap: var(--global-spacing-2x);
margin: var(--global-spacing);
}
.index-project-link {
pointer-events: initial;
margin: 4px 1px;
color: #fff;
text-decoration: none;
min-width: 100px;
padding: 2px 8px;
border-radius: 4px;
transition: background-color .2s;
.project-tag {
color: var(--text-colour);
border-left: var(--global-spacing) solid var(--tag-colour, var(--accent-colour2));
padding: 0 var(--global-spacing);
}
.index-project-link:hover,
.index-project-link:focus {
background-color: #fff2;
.project-tag-link {
text-decoration: underline;
text-decoration-style: dashed;
text-decoration-color: var(--tag-colour, var(--accent-colour3));
}
.index-project-link:active {
background-color: #fff1;
.project-tag-link:visited {
text-decoration-color: var(--accent-colour2);
}
.project-tag-link:hover,
.project-tag-link:focus {
text-decoration-style: solid;
}
.project-tag-link:active {
text-decoration-style: dotted;
}

View file

@ -1,27 +0,0 @@
.section {
padding: 0 15px;
}
.section:not(:first-child) {
margin-top: 30px;
}
.section-content {
max-width: 1100px;
margin: 10px auto;
padding: 10px 20px;
filter: drop-shadow(0 1px 5px #000);
}
.section-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(0deg, #111 0%, #222 50%, #333 50%, #555 100%);
transform: skew(-15deg);
}
.section-content h1 {
font-family: var(--font-header, sans-serif);
font-size: 2em;
line-height: 1em;
font-weight: 400;
}

View file

@ -0,0 +1,3 @@
.sidecontact-site {
font-weight: 700;
}

View file

@ -0,0 +1,93 @@
.sidelist {
background-color: var(--container-colour);
border: 1px solid var(--container-border);
margin-top: var(--global-spacing);
}
.sidelist-title {
background-color: var(--accent-colour1);
font-family: var(--font-header);
font-weight: 700;
font-size: 1.2em;
line-height: 1.5em;
padding: var(--global-spacing-0-5x) var(--global-spacing-1-5x) 0;
}
.sidelist-body {
display: flex;
flex-direction: column;
padding: var(--global-spacing-0-5x);
}
.sidelist-body > p {
font-size: 0.9em;
line-height: 1.5em;
margin: 0 0.1em 0.1em 0.1em;
}
.sidelist-body > p a {
color: inherit;
text-decoration: underline;
text-decoration-style: dashed;
text-decoration-color: var(--accent-colour3);
}
.sidelist-body > p a:visited {
text-decoration-color: var(--accent-colour2);
}
.sidelist-body > p a:hover,
.sidelist-body > p a:focus {
text-decoration-style: solid;
}
.sidelist-body > p a:active {
text-decoration-style: dotted;
}
.sidelist-item {
display: flex;
font-size: .9em;
padding: 0 var(--global-spacing-1-5x);
border-bottom: 1px dashed var(--text-colour);
gap: var(--global-spacing);
align-items: baseline;
}
.sidelist-item-link {
color: inherit;
text-decoration: inherit;
}
.sidelist-item-link:hover,
.sidelist-item-link:focus {
border-bottom-style: solid;
}
.sidelist-item-link:active {
border-bottom-style: dotted;
}
.sidelist-item-icon {
top: 1px;
display: inline-block;
font-weight: 700;
font-size: var(--font-size);
width: var(--font-size);
line-height: var(--font-size);
text-align: center;
font-family: var(--font-cursive);
}
.sidelist-item-icon img {
vertical-align: bottom;
}
.sidelist-item-label {
display: inline-block;
}
.sidelist-empty {
margin: var(--global-spacing-2x) auto;
}
.sidelist-empty-icon {
display: inline-block;
font-family: var(--font-cursive);
}
.sidelist-empty-label {
display: inline-block;
}

View file

@ -1,61 +0,0 @@
.index-contact {
padding: 5px 15px;
overflow: auto;
}
.socials {
max-width: 1100px;
width: 100%;
margin: 10px auto;
padding: 0 15px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
justify-content: space-evenly;
column-gap: 10px;
}
@media(max-width: 980px) { .socials { grid-template-columns: 1fr 1fr; } }
@media(max-width: 640px) { .socials { grid-template-columns: 1fr; } }
.social {
width: 100%;
margin: 5px 0;
filter: drop-shadow(0 1px 5px #000);
cursor: pointer;
display: flex;
align-items: center;
padding: 5px;
}
.index-contact .social {
margin: 10px 0;
}
.social-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(0deg, #1118 0%, #2228 50%, #3338 50%, #5558 100%);
transform: skew(-15deg);
background-color: var(--social-colour);
}
.social:active .social-background {
background-image: linear-gradient(0deg, #1118 0%, #2228 50%, #3338 50%, #3338 100%);
}
.social-icon {
width: 25px;
height: 25px;
margin: 3px 4px 2px 8px;
pointer-events: none;
}
.social-content {
margin: 2px 5px;
pointer-events: none;
}
.social-name {
font-size: .9em;
line-height: 1.5em;
}
.social-handle {
font-size: 1.5em;
line-height: 1.3em;
font-family: var(--font-header, sans-serif);
}

View file

@ -1,27 +0,0 @@
.fmi {
background-image: url('/images/sprite.png');
width: 25px;
height: 25px;
background-size: 450px 25px;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) {
.fmi { background-image: url('/images/sprite@2x.png'); background-size: 450px 25px; }
}
.fmi.fmi-bluesky { background-position: 450px 0px; }
.fmi.fmi-email { background-position: 425px 0px; }
.fmi.fmi-flashii { background-position: 400px 0px; }
.fmi.fmi-github { background-position: 375px 0px; }
.fmi.fmi-lastfm { background-position: 350px 0px; }
.fmi.fmi-line { background-position: 325px 0px; }
.fmi.fmi-music { background-position: 300px 0px; }
.fmi.fmi-n3ds { background-position: 275px 0px; }
.fmi.fmi-osu { background-position: 250px 0px; }
.fmi.fmi-patreon { background-position: 225px 0px; }
.fmi.fmi-paypal { background-position: 200px 0px; }
.fmi.fmi-steam { background-position: 175px 0px; }
.fmi.fmi-switch { background-position: 150px 0px; }
.fmi.fmi-tetrio { background-position: 125px 0px; }
.fmi.fmi-twitch { background-position: 100px 0px; }
.fmi.fmi-twitter { background-position: 75px 0px; }
.fmi.fmi-wiiu { background-position: 50px 0px; }
.fmi.fmi-youtube { background-position: 25px 0px; }

View file

@ -0,0 +1,112 @@
.ascii-chars {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: var(--global-spacing);
}
.ascii-char-control {
--ascii-accent: var(--accent-colour2);
--ascii-accent-dark: var(--accent-colour2-dark);
--ascii-accent-darker: var(--accent-colour2-darker);
}
.ascii-char-printable {
--ascii-accent: var(--accent-colour3);
--ascii-accent-dark: var(--accent-colour3-dark);
--ascii-accent-darker: var(--accent-colour3-darker);
}
.ascii-char {
display: flex;
flex-direction: column;
border: 1px solid var(--container-border);
overflow: hidden;
background-color: var(--container-colour);
cursor: pointer !important;
transition: background-color .1s;
}
.ascii-char-main {
flex-grow: 1;
flex-shrink: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.ascii-char-print {
white-space: pre;
font-family: var(--font-cursive);
font-size: 2.5em;
line-height: 1.5em;
text-align: center;
padding: var(--global-spacing-2x);
pointer-events: none;
}
.ascii-char-desc {
text-align: center;
font-size: 1.2em;
line-height: 1.5em;
padding: 0 var(--global-spacing) var(--global-spacing);
pointer-events: none;
}
.ascii-char-misc {
display: flex;
justify-content: space-evenly;
border-top: 1px solid var(--ascii-accent);
}
.ascii-char-misc-item {
flex-grow: 1;
flex-shrink: 1;
padding: var(--global-spacing) var(--global-spacing-2x);
background-color: var(--ascii-accent);
transition: background-color .1s;
}
.ascii-char-misc-item:hover,
.ascii-char-misc-item:focus {
background-color: var(--ascii-accent-dark);
}
.ascii-char-misc-item:active {
background-color: var(--ascii-accent-darker);
}
.ascii-char-misc-item-head {
font-size: .9em;
line-height: 1.5em;
}
.ascii-char-misc-item-value {
font-family: var(--font-monospace);
text-align: right;
}
.ascii-search {
background-color: var(--background-colour);
padding: var(--global-spacing) 0;
position: sticky;
top: 0;
z-index: 1000;
}
.ascii-search-box {
display: flex;
border: 1px solid var(--container-border);
overflow: hidden;
}
.ascii-search-box input {
display: block;
flex-grow: 1;
flex-shrink: 1;
padding: var(--global-spacing-2x);
border: 0;
border-radius: 0;
background-color: var(--container-colour);
color: var(--text-colour);
font-size: var(--font-size);
line-height: var(--line-height);
font-family: var(--font-regular);
}
.ascii-hint {
font-size: .9em;
margin-top: calc(var(--global-spacing) * -1);
transition: opacity .2s;
}
.ascii-hint code {
font-size: .8em;
font-family: var(--font-monospace);
}

View file

@ -0,0 +1,11 @@
.tools-frame {
margin-top: var(--global-spacing);
border: 1px solid var(--container-border);
background: var(--container-colour);
width: 100%;
height: 100%;
}
.tools-frame-ipaddr {
min-height: 400px;
}

View file

@ -0,0 +1,98 @@
.whois-locked .columns-left,
.whois-locked .columns-centre {
opacity: .5;
pointer-events: none;
}
.whois-lookup-form {
display: flex;
margin-top: var(--global-spacing);
overflow: hidden;
transition: opacity .2s;
background-color: var(--container-colour);
border: 1px solid var(--container-border);
}
.whois-lookup-form-input {
display: block;
flex-grow: 1;
flex-shrink: 1;
padding: var(--global-spacing-2x);
border: 0;
border-radius: 0;
background-color: var(--container-colour);
color: var(--text-colour);
font-size: var(--font-size);
line-height: var(--line-height);
font-family: var(--font-monospace);
}
.whois-lookup-form-submit {
flex-grow: 0;
flex-shrink: 0;
font-family: inherit;
background-color: var(--accent-colour2);
color: var(--text-colour);
border: 0;
border-radius: 0;
padding: var(--global-spacing) var(--global-spacing-2x);
cursor: pointer;
transition: background-color .2s;
}
.whois-lookup-form-submit:focus,
.whois-lookup-form-submit:hover {
background-color: var(--accent-colour2-dark);
}
.whois-lookup-form-submit:active {
background-color: var(--accent-colour2-darker);
}
.whois-result-container {
margin-top: var(--global-spacing);
background-color: var(--container-colour);
border: 1px solid var(--container-border);
}
.whois-result {
padding: var(--global-spacing) var(--global-spacing-2x);
white-space: pre-wrap;
font-family: var(--font-monospace);
font-size: 14px;
transition: opacity .2s;
overflow: auto;
}
.whois-result-tabs {
display: flex;
overflow-x: auto;
scrollbar-width: thin;
background-color: var(--accent-colour2);
}
.whois-result-tab {
color: inherit;
padding: var(--global-spacing) var(--global-spacing-2x);
font-size: 14px;
cursor: pointer;
display: block;
text-decoration: none;
transition: background-color .1s;
}
.whois-result-tab:hover,
.whois-result-tab:focus {
background-color: var(--accent-colour2-dark);
}
.whois-result-tab:active {
background-color: var(--accent-colour2-darker);
}
.whois-result-tab-active {
background-color: var(--container-colour) !important;
}
.whois-result-tab-header {
font-size: 1.3em;
line-height: 1.2em;
}
.whois-result-tab-server {
font-size: .9em;
line-height: 1.2em;
opacity: .6;
white-space: pre-wrap;
font-family: var(--font-monospace);
}

View file

@ -1,102 +0,0 @@
.whois-container {
max-width: 1200px;
margin: 0 auto;
}
.whois-lookup-form {
display: flex;
border-radius: 5px;
margin: 10px;
overflow: hidden;
box-shadow: 0 1px 5px #222;
transition: opacity .2s;
}
.whois-locked .whois-lookup-form {
opacity: .5;
}
.whois-lookup-form-input {
display: block;
flex: 1 1 auto;
padding: 10px;
background-color: #212121;
background-image: linear-gradient(0deg, #262626, #202020);
border-width: 0;
color: #fff;
font-family: var(--font-regular, sans-serif);
}
.whois-lookup-form-submit {
flex: 0 0 auto;
background-color: #333333;
background-image: linear-gradient(0deg, transparent, #404040);
color: #fff;
border-width: 0;
padding: 10px;
cursor: pointer;
border-radius: 0;
transition: background-color .2s;
}
.whois-lookup-form-submit:focus,
.whois-lookup-form-submit:hover {
background-color: #3F3F3F;
}
.whois-lookup-form-submit:active {
background-color: #393939;
}
.whois-result {
margin: 10px;
padding: 6px 10px;
white-space: pre-wrap;
font-family: var(--font-monospace, monospace);
font-size: 14px;
transition: opacity .2s;
background-color: #202020;
border-radius: 5px;
box-shadow: 0 1px 5px #222;
overflow: auto;
}
.whois-locked .whois-result {
opacity: .5;
}
.whois-result-tabs {
display: flex;
margin: 0 5px;
overflow-x: auto;
scrollbar-width: thin;
}
.whois-locked .whois-result-tabs {
opacity: .5;
}
.whois-result-tab {
margin: 0 5px;
padding: 6px 10px;
font-size: 14px;
transition: opacity .2s;
background-color: #202020;
border-radius: 5px;
box-shadow: 0 1px 5px #222;
opacity: .5;
cursor: pointer;
display: block;
color: #fff;
text-decoration: none;
}
.whois-result-tab:hover,
.whois-result-tab:focus {
opacity: .7;
}
.whois-result-tab-active {
opacity: 1 !important;
}
.whois-result-tab-header {
font-size: 1.3em;
line-height: 1.2em;
}
.whois-result-tab-server {
font-size: .9em;
line-height: 1.2em;
color: #888;
white-space: pre-wrap;
font-family: var(--font-monospace, monospace);
}

View file

@ -1,59 +0,0 @@
#include utility.js
const MakaiDevHome = () => {
const digitalClock = $q('.php-time-digital');
const analogClock = $q('.php-time-analog');
const dateZone = $q('.php-time-date');
const digHours = digitalClock.querySelector('.php-time-digital-hours');
const digSeparator = digitalClock.querySelector('.php-time-digital-separator');
const digMinutes = digitalClock.querySelector('.php-time-digital-minutes');
const angHours = analogClock.querySelector('.clock-hand-hours');
const angMinutes = analogClock.querySelector('.clock-hand-minutes');
const angSeconds = analogClock.querySelector('.clock-hand-seconds');
const dateWeek = dateZone.querySelector('.php-date-week');
const dateDay = dateZone.querySelector('.php-date-day');
const dateMonth = dateZone.querySelector('.php-date-month');
const dateYear = dateZone.querySelector('.php-date-year');
homeInterval = setInterval(() => {
if(!document.body.contains(digitalClock)) {
clearInterval(homeInterval);
homeInterval = undefined;
return;
}
const time = new Date;
let dHour = time.getHours();
let dMin = time.getMinutes();
if(dHour < 10)
dHour = '0' + dHour;
if(dMin < 10)
dMin = '0' + dMin;
dateWeek.textContent = (() => {
const wd = new Date(time.getTime());
wd.setHours(0, 0, 0, 0);
wd.setDate(wd.getDate() + 3 - (wd.getDay() + 6) % 7);
const week1 = new Date(wd.getFullYear(), 0, 4);
return 1 + Math.round(((wd.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7);
})();
dateDay.textContent = time.getDate();
dateMonth.textContent = time.getMonth() + 1;
dateYear.textContent = time.getFullYear();
digHours.textContent = dHour;
digMinutes.textContent = dMin;
digSeparator.classList[time.getSeconds() % 2 ? 'add' : 'remove']('php-time-digital-separator-hidden');
const rSec = time.getSeconds() / 60;
const rMin = (time.getMinutes() + Math.min(.99, rSec)) / 60;
const rHour = (time.getHours() + Math.min(.99, rMin)) / 12;
angHours.style.setProperty('--hand-rotation', (rHour * 360).toString() + 'deg');
angMinutes.style.setProperty('--hand-rotation', (rMin * 360).toString() + 'deg');
angSeconds.style.setProperty('--hand-rotation', (rSec * 360).toString() + 'deg');
}, 200);
};

View file

@ -1,139 +0,0 @@
#include utility.js
#include xhr.js
const MakaiDevIndex = npInterval => {
let headerBackground;
let originalHeaderBackground;
const defaultCoverImage = 'https://lastfm.freetls.fastly.net/i/u/174s/2a96cbd8b46e442fc41c2b86b821562f.png';
let indexIsPlaying = false;
let indexPlayingDefaultCover = false;
let indexPlayingContainer;
let indexPlayingCover;
let indexPlayingTitle;
let indexPlayingArtist;
let indexLastNp;
let indexPlayingInterval;
let homeInterval;
if(!sessionStorage.getItem('header-bgs') || sessionStorage.getItem('header-bgs-loaded') < Date.now() - 86400000)
$x.get('/header-bgs.json').then(output => {
if(output.status !== 200)
return;
sessionStorage.setItem('header-bgs', output.body());
sessionStorage.setItem('header-bgs-loaded', Date.now());
});
const getNowListening = callback => {
if(!callback)
return;
$x.get('https://now.flash.moe/get.php?u=flashwave_').then(output => {
if(output.status !== 200)
return;
let info = output.json();
if(info.length < 1)
return;
info = info[0];
callback({
name: info.name,
now_playing: !!info.nowplaying,
url: info.url,
cover: info.images?.large ?? '',
artist: {
name: info.artist?.name ?? '',
url: info.url.split('/_/')[0]
},
});
});
};
const updateIndexNowListening = () => {
getNowListening(info => {
if(!indexLastNp || indexLastNp.url != info.url || indexLastNp.now_playing != info.now_playing) {
if(indexLastNp)
originalHeaderBackground = getRandomHeaderBackground();
indexLastNp = info;
} else return;
indexIsPlaying = info.now_playing;
indexPlayingDefaultCover = !info.cover || info.cover === defaultCoverImage;
indexPlayingContainer.classList[info.now_playing ? 'remove' : 'add']('header-now-playing-hidden');
indexPlayingCover.alt = indexPlayingCover.src = (info.cover !== defaultCoverImage ? info.cover : '//now.flash.moe/resources/no-cover.png');
indexPlayingTitle.textContent = indexPlayingTitle.title = info.name;
indexPlayingTitle.href = info.url;
indexPlayingArtist.textContent = indexPlayingArtist.title = (info.artist || {}).name || '';
indexPlayingArtist.href = (info.artist || {}).url || '';
switchHeaderBackground(
info.now_playing && !indexPlayingDefaultCover
? indexPlayingCover.src
: originalHeaderBackground
);
});
};
const getRandomHeaderBackground = () => {
var set = JSON.parse(sessionStorage.getItem('header-bgs'));
if(!set)
return '/images/404.jpg';
return set[parseInt(Math.random() * set.length) - 1];
};
const setRandomHeaderBackground = () => {
switchHeaderBackground(getRandomHeaderBackground());
};
const getCurrentHeaderBackground = function() {
return headerBackground.querySelector('img').src;
};
let headerBackgroundIsChanging = false;
const switchHeaderBackground = function(url) {
if(headerBackgroundIsChanging || getCurrentHeaderBackground() === url)
return;
headerBackgroundIsChanging = true;
var newImg = document.createElement('img'),
oldImg = headerBackground.querySelector('img');
newImg.alt = newImg.src = url;
newImg.style.opacity = '0';
oldImg.style.zIndex = '-1';
newImg.style.zIndex = '0';
headerBackground.appendChild(newImg);
newImg.onload = () => {
setTimeout(() => {
newImg.style.opacity = null;
setTimeout(() => {
newImg.style.zIndex = null;
headerBackground.removeChild(oldImg);
headerBackgroundIsChanging = false;
}, 500);
}, 50);
};
newImg.onerror = () => {
headerBackgroundIsChanging = false;
switchHeaderBackground(originalHeaderBackground);
};
};
headerBackground = $q('.header-background');
originalHeaderBackground = headerBackground.querySelector('img').src;
if(!indexPlayingContainer) {
indexPlayingContainer = document.querySelector('.header-now-playing');
indexPlayingCover = indexPlayingContainer.querySelector('.header-now-playing-cover img');
indexPlayingCover.onerror = () => { indexPlayingCover.src = '//now.flash.moe/resources/no-cover.png'; }
indexPlayingTitle = indexPlayingContainer.querySelector('.header-now-playing-title a');
indexPlayingArtist = indexPlayingContainer.querySelector('.header-now-playing-artist a');
}
if(indexPlayingInterval) {
clearInterval(indexPlayingInterval);
indexPlayingInterval = undefined;
}
updateIndexNowListening();
indexPlayingInterval = setInterval(updateIndexNowListening, (npInterval || 30) * 1000);
};

View file

@ -0,0 +1,101 @@
#include elem.js
#include xhr.js
const MakaiSiteHeaderImages = function() {
const url = '/header-bgs.json';
let headers;
const all = async () => {
if(!Array.isArray(headers))
headers = (await $x.get('/header-bgs.json')).json();
return headers;
};
return {
all: all,
random: async () => {
const images = await all();
if(images.length < 1)
return '/flonnerator.png';
return images[Math.floor(Math.random() * images.length)];
},
};
};
const MakaiSiteHeader = function(element) {
if(!(element instanceof Element))
throw 'element must be an instance of Element';
const images = new MakaiSiteHeaderImages;
const bgElem = element.querySelector('.js-header-background');
const getBgImgElem = () => bgElem.querySelector('img');
const setBackgroundImage = (url, duration) => {
return new Promise((resolve, reject) => {
if(typeof duration !== 'number')
duration = 500;
while(bgElem.childElementCount > 1)
bgElem.removeChild(bgElem.lastChild);
const prevImage = getBgImgElem();
if(prevImage.src === url) {
resolve();
return;
}
let startTimeStamp;
const updateTransition = timeStamp => {
if(startTimeStamp === undefined)
startTimeStamp = timeStamp;
const elapsed = timeStamp - startTimeStamp;
const t = Math.min(1, Math.max(0, elapsed / duration));
prevImage.style.opacity = 1 - t;
if(t < 1)
requestAnimationFrame(updateTransition);
else {
$r(prevImage);
resolve();
}
};
prevImage.style.zIndex = '2';
const nextImage = $e({
tag: 'img',
attrs: {
alt: url,
src: url,
onerror: () => {
prevImage.style.opacity = null;
prevImage.style.zIndex = null;
bgElem.removeChild(nextImage);
reject();
},
onload: () => {
requestAnimationFrame(updateTransition);
},
},
style: { zIndex: '1' },
});
bgElem.appendChild(nextImage);
});
};
return {
get images() { return images; },
get backgroundElement() { return bgElem; },
get backgroundImage() { return getBgImgElem().src; },
setBackgroundImage: setBackgroundImage,
randomBackgroundImage: async () => {
await setBackgroundImage(await images.random());
},
};
};

View file

@ -0,0 +1,173 @@
const MakaiSideListEmptyElement = function(element) {
if(!(element instanceof Element))
element = <div class="sidelist-empty">
<div class="sidelist-empty-icon"></div>
<div class="sidelist-empty-label">Nothing yet!</div>
</div>;
const iconElem = element.querySelector('.sidelist-empty-icon');
const labelElem = element.querySelector('.sidelist-empty-label');
return {
get element() { return element; },
get icon() { return iconElem.textContent; },
set icon(value) {
iconElem.textContent = value;
},
get label() { return labelElem.textContent; },
set label(value) {
labelElem.textContent = value;
},
};
};
const MakaiSideListItemElement = function(element, icon, link, click) {
const linkClass = 'sidelist-item-link';
if(!(element instanceof Element)) {
element = <a class="sidelist-item">
<div class="sidelist-item-icon">{icon ?? (Math.random() < 0.5 ? '☆' : '★')}</div>
<div class="sidelist-item-label">{element ?? ''}</div>
</a>;
if(typeof link === 'string') {
element.classList.add(linkClass);
element.href = link;
}
if(typeof click === 'function')
element.onclick = click;
}
const isLink = () => element.classList.contains(linkClass);
const iconElem = element.querySelector('.sidelist-item-icon');
const labelElem = element.querySelector('.sidelist-item-label');
return {
get element() { return element; },
get isLink() { return isLink(); },
get link() { return element.href ?? ''; },
set link(value) {
if(value === undefined)
value = null;
element.href = value;
element.classList.toggle(linkClass, typeof value === 'string' && value !== '');
},
get icon() { return iconElem.textContent; },
set icon(value) {
iconElem.textContent = value;
},
get label() { return labelElem.textContent; },
set label(value) {
labelElem.textContent = value;
},
};
};
const MakaiSideListElement = function(element) {
if(!(element instanceof Element))
element = <div class="sidelist">
<div class="sidelist-title">{element ?? ''}</div>
<div class="sidelist-body"/>
</div>;
const titleElem = element.querySelector('.sidelist-title');
const bodyElem = element.querySelector('.sidelist-body');
const emptyElem = new MakaiSideListEmptyElement(bodyElem.querySelector('.sidelist-empty'));
const getBodyChildren = () => {
const elems = [];
for(const elem of bodyElem.children) {
let item = elem;
if(item.classList.contains('sidelist-empty'))
item = new MakaiSideListEmptyElement(item);
else if(item.classList.contains('sidelist-item'))
item = new MakaiSideListItemElement(item);
elems.push(item);
}
return elems;
};
const insertEmptyElement = () => {
if(!bodyElem.contains(emptyElem.element) && bodyElem.childElementCount < 1)
bodyElem.appendChild(emptyElem.element);
};
const clearEmptyElement = () => {
if(bodyElem.contains(emptyElem.element))
bodyElem.removeChild(emptyElem.element);
};
const clearBody = insertEmpty => {
$rc(bodyElem);
insertEmptyElement();
};
const addItemCommon = (item, ...args) => {
if(typeof item === 'string')
item = new MakaiSideListItemElement(item, ...args);
else if(typeof item !== 'object' || item === null)
throw 'item must be a non-null object';
const elem = 'element' in item ? item.element : item;
if(bodyElem.contains(elem))
return;
clearEmptyElement();
return {
item: item,
elem: elem,
};
};
const appendItem = (...args) => {
const common = addItemCommon(...args);
if(common === undefined)
return;
bodyElem.appendChild(common.elem);
return common.item;
};
const prependItem = (...args) => {
const common = addItemCommon(...args);
if(common === undefined)
return;
bodyElem.insertBefore(common.elem, bodyElem.firstChild);
return common.item;
};
const removeItem = item => {
const elem = 'element' in item ? item.element : item;
if(bodyElem.contains(elem))
bodyElem.removeChild(elem);
insertEmptyElement();
return item;
};
if(bodyElem.childElementCount < 1)
insertEmptyElement();
return {
get element() { return element; },
get titleElem() { return titleElem; },
get bodyElem() { return bodyElem; },
get emptyElem() { return emptyElem; },
get children() { return getBodyChildren(); },
get title() { return titleElem.textContent; },
set title(value) {
titleElem.textContent = value;
},
appendItem: appendItem,
prependItem: prependItem,
removeItem: removeItem,
};
};

View file

@ -1,20 +1,24 @@
#include elem.js
#include ascii.js
#include dev-index.js
#include dev-home.js
#include whois.js
#include elems/head.js
#include np/init.js
#include tools/ascii.js
#include tools/whois.js
const makai = (() => {
const header = new MakaiSiteHeader($q('.js-header'));
(() => {
const runIfPathStartsWith = (prefix, func, ...args) => {
if(location.pathname === prefix || location.pathname.startsWith(`${prefix}/`))
func(...args);
};
runIfPathStartsWith('/ascii', MakaiASCII);
runIfPathStartsWith('/whois', MakaiWHOIS);
runIfPathStartsWith('/home', MakaiDevHome);
runIfPathStartsWith('/tools/ascii', MakaiASCII);
runIfPathStartsWith('/tools/whois', MakaiWHOIS);
runIfPathStartsWith('/home', MakaiDevIndex, 10);
runIfPathStartsWith('/now-listening', MakaiDevIndex, 10);
if(location.pathname === '/') MakaiDevIndex();
const nowPlaying = MakaiNowPlayingInit(header);
return {
get header() { return header; },
get nowPlaying() { return nowPlaying; },
};
})();

View file

@ -0,0 +1,45 @@
#include xhr.js
const MakaiNowPlaying = function(userName) {
const noCoverUrl = 'https://lastfm.freetls.fastly.net/i/u/174s/2a96cbd8b46e442fc41c2b86b821562f.png';
const fetchTarget = `https://now.flash.moe/get.php?u=${userName}`;
let lastResult;
const format = info => {
const coverUrl = info.images?.large ?? '';
const result = {
first: lastResult === undefined,
changed: false,
name: info.name,
now_playing: !!info.nowplaying,
url: info.url,
cover: coverUrl === noCoverUrl ? '' : coverUrl,
artist: {
name: info.artist?.name ?? '',
url: info.url.split('/_/')[0]
},
};
if(lastResult === undefined || result.url !== lastResult.url || result.now_playing !== lastResult.now_playing)
result.changed = true;
lastResult = result;
return result;
};
return {
fetch: async () => {
const result = await $x.get(fetchTarget);
if(result.status !== 200)
throw `http ${result.status}`;
let info = result.json();
if(info.length < 1)
throw 'no data';
return format(info[0]);
},
};
};

View file

@ -0,0 +1,64 @@
const MakaiNowPlayingElement = function() {
const noCoverUrl = '//now.flash.moe/resources/no-cover.png';
const hiddenClass = 'hidden';
let coverElem, titleElem, artistElem;
const element = <div class={`np ${hiddenClass}`}>
<div class="np-header">
<span class="np-header-icon"></span>
<span class="np-header-text">Now listening to...</span>
</div>
<div class="np-cover">
{coverElem = <img src={noCoverUrl} alt={noCoverUrl} onerror={() => {
coverElem.alt = noCoverUrl;
coverElem.src = noCoverUrl;
}}/>}
</div>
<div class="np-details">
<div class="np-artist">{artistElem = <a href="#" target="_blank" rel="noopener"></a>}</div>
<div class="np-title">{titleElem = <a href="#" target="_blank" rel="noopener"></a>}</div>
</div>
</div>;
return {
get element() { return element; },
get hidden() { element.classList.has(hiddenClass); },
set hidden(value) {
element.classList.toggle(hiddenClass, value);
},
get isDefaultCover() {
return coverElem.src === noCoverUrl
|| coverElem.src === (location.protocol + noCoverUrl);
},
get coverUrl() { return coverElem.src; },
set coverUrl(value) {
if(value === undefined || value === null || value === '')
value = noCoverUrl;
coverElem.alt = value;
coverElem.src = value;
},
get titleText() { return titleElem.textContent; },
set titleText(value) {
titleElem.title = value;
titleElem.textContent = value;
},
get titleUrl() { return titleElem.href; },
set titleUrl(value) {
titleElem.href = value;
},
get artistText() { return artistElem.textContent; },
set artistText(value) {
artistElem.title = value;
artistElem.textContent = value;
},
get artistUrl() { return artistElem.href; },
set artistUrl(value) {
artistElem.href = value;
},
};
};

View file

@ -0,0 +1,68 @@
#include utility.js
#include np/client.js
#include np/element.jsx
const MakaiNowPlayingInit = siteHeader => {
const target = $q('.js-np-target');
if(!(target instanceof Element))
return;
const userName = target.dataset.username;
if(typeof userName !== 'string')
return;
const client = new MakaiNowPlaying(userName);
const element = new MakaiNowPlayingElement;
$rp(target, element.element);
const update = () => {
client.fetch().then(result => {
if(!result.changed)
return;
element.hidden = !result.now_playing;
element.coverUrl = result.cover;
element.titleText = result.name;
element.titleUrl = result.url;
element.artistText = result.artist.name;
element.artistUrl = result.artist.url;
if(result.now_playing && !element.isDefaultCover)
siteHeader.setBackgroundImage(element.coverUrl);
else if(!result.first)
siteHeader.images.random().then(image => {
siteHeader.setBackgroundImage(image);
});
});
};
let interval;
let currentRate;
const stop = () => {
if(interval !== undefined)
clearInterval(interval);
interval = undefined;
};
const start = rate => {
if(typeof rate !== 'number')
rate = 30000;
if(interval !== undefined || currentRate !== rate)
stop();
update();
setInterval(update, rate);
};
start();
return {
get client() { return client; },
get element() { return element; },
start: start,
stop: stop,
};
};

View file

@ -1,8 +1,8 @@
#include utility.js
const MakaiASCII = () => {
const chars = $c('ascii-char');
const search = $i('search');
const chars = $qa('.js-ascii-char');
const search = $q('.js-ascii-search');
const charsFilter = (filter) => {
if(!filter) {
@ -27,22 +27,13 @@ const MakaiASCII = () => {
}
};
window.addEventListener('scroll', () => {
const atTop = window.scrollY === 0;
const hidden = $c('js-hidden-on-scroll');
for(const elem of hidden)
elem.classList.toggle('hidden', !atTop);
const invisible = $c('js-invisible-on-scroll');
for(const elem of invisible)
elem.classList.toggle('invisible', !atTop);
});
search.addEventListener('keyup', () => {
location.hash = search.value.trim();
});
window.addEventListener('hashchange', () => {
charsFilter(decodeURIComponent((location.hash || '#').substring(1)));
const filter = decodeURIComponent((location.hash || '#').substring(1));
search.value = filter;
charsFilter(filter);
});
if(location.hash.length > 0) {
search.value = location.hash.substring(1).trim();

View file

@ -1,12 +1,20 @@
#include utility.js
#include xhr.js
#include elems/sidelist.jsx
const MakaiWHOIS = () => {
let locked = false;
const input = $i('lookup-input');
const submit = $i('lookup-submit');
const result = $i('lookup-result');
const tabs = $i('lookup-tabs');
const input = $q('.js-whois-input');
const submit = $q('.js-whois-submit');
const result = $q('.js-whois-body');
const tabs = $q('.js-whois-tabs');
const historic = [];
const history = (() => {
const element = $q('.js-whois-sidelist');
if(element instanceof Element)
return new MakaiSideListElement(element);
})();
const lock = () => {
if(locked)
@ -32,7 +40,7 @@ const MakaiWHOIS = () => {
if(!lock())
return;
$x.post('/whois/lookup', {}, { _csrfp: $csrfp.get(), target: target }).then(output => {
$x.post('/tools/whois/lookup', {}, { _csrfp: $csrfp.get(), target: target }).then(output => {
let headers = output.headers();
if(headers.has('x-csrfp'))
$csrfp.set(headers.get('x-csrfp'));
@ -43,12 +51,18 @@ const MakaiWHOIS = () => {
let count = 0;
tabs.innerHTML = '';
if(resp.result && resp.result.responses)
$rc(tabs);
if(resp.result && Array.isArray(resp.result.responses) && resp.result.responses.length > 0) {
if(!historic.includes(resp.result.target)) {
historic.push(resp.result.target);
history.prependItem(resp.result.target, '←', `#${resp.result.target}`);
}
for(const response of resp.result.responses) {
const tab = document.createElement('a');
const tabHeader = document.createElement('div');
const tabServer = document.createElement('div');
const tab = $e({tag: 'a'});
const tabHeader = $e();
const tabServer = $e();
tab.href = 'javascript:;';
tab.className = 'whois-result-tab';
@ -73,6 +87,7 @@ const MakaiWHOIS = () => {
++count;
}
}
if(tabs.firstChild)
tabs.firstChild.click();

View file

@ -21,6 +21,11 @@ const $rc = function(element) {
element.removeChild(element.lastChild);
};
const $rp = function(target, replace) {
$ib(target, replace);
$r(target);
};
const $ar = function(array, index) {
array.splice(index, 1);
};

285
package-lock.json generated
View file

@ -5,7 +5,7 @@
"packages": {
"": {
"dependencies": {
"@swc/core": "^1.4.17",
"@swc/core": "^1.5.24",
"autoprefixer": "^10.4.19",
"cssnano": "^6.1.2",
"html-minifier-terser": "^7.2.0",
@ -16,6 +16,7 @@
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"license": "MIT",
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
@ -29,6 +30,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"license": "MIT",
"engines": {
"node": ">=6.0.0"
}
@ -37,6 +39,7 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"license": "MIT",
"engines": {
"node": ">=6.0.0"
}
@ -45,6 +48,7 @@
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
@ -53,25 +57,28 @@
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@swc/core": {
"version": "1.4.17",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.17.tgz",
"integrity": "sha512-tq+mdWvodMBNBBZbwFIMTVGYHe9N7zvEaycVVjfvAx20k1XozHbHhRv+9pEVFJjwRxLdXmtvFZd3QZHRAOpoNQ==",
"version": "1.5.24",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.24.tgz",
"integrity": "sha512-Eph9zvO4xvqWZGVzTdtdEJ0Vqf0VIML/o/e4Qd2RLOqtfgnlRi7avmMu5C0oqciJ0tk+hqdUKVUZ4JPoPaiGvQ==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@swc/counter": "^0.1.2",
"@swc/types": "^0.1.5"
"@swc/counter": "^0.1.3",
"@swc/types": "^0.1.7"
},
"engines": {
"node": ">=10"
@ -81,19 +88,19 @@
"url": "https://opencollective.com/swc"
},
"optionalDependencies": {
"@swc/core-darwin-arm64": "1.4.17",
"@swc/core-darwin-x64": "1.4.17",
"@swc/core-linux-arm-gnueabihf": "1.4.17",
"@swc/core-linux-arm64-gnu": "1.4.17",
"@swc/core-linux-arm64-musl": "1.4.17",
"@swc/core-linux-x64-gnu": "1.4.17",
"@swc/core-linux-x64-musl": "1.4.17",
"@swc/core-win32-arm64-msvc": "1.4.17",
"@swc/core-win32-ia32-msvc": "1.4.17",
"@swc/core-win32-x64-msvc": "1.4.17"
"@swc/core-darwin-arm64": "1.5.24",
"@swc/core-darwin-x64": "1.5.24",
"@swc/core-linux-arm-gnueabihf": "1.5.24",
"@swc/core-linux-arm64-gnu": "1.5.24",
"@swc/core-linux-arm64-musl": "1.5.24",
"@swc/core-linux-x64-gnu": "1.5.24",
"@swc/core-linux-x64-musl": "1.5.24",
"@swc/core-win32-arm64-msvc": "1.5.24",
"@swc/core-win32-ia32-msvc": "1.5.24",
"@swc/core-win32-x64-msvc": "1.5.24"
},
"peerDependencies": {
"@swc/helpers": "^0.5.0"
"@swc/helpers": "*"
},
"peerDependenciesMeta": {
"@swc/helpers": {
@ -102,12 +109,13 @@
}
},
"node_modules/@swc/core-darwin-arm64": {
"version": "1.4.17",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.17.tgz",
"integrity": "sha512-HVl+W4LezoqHBAYg2JCqR+s9ife9yPfgWSj37iIawLWzOmuuJ7jVdIB7Ee2B75bEisSEKyxRlTl6Y1Oq3owBgw==",
"version": "1.5.24",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.24.tgz",
"integrity": "sha512-M7oLOcC0sw+UTyAuL/9uyB9GeO4ZpaBbH76JSH6g1m0/yg7LYJZGRmplhDmwVSDAR5Fq4Sjoi1CksmmGkgihGA==",
"cpu": [
"arm64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"darwin"
@ -117,12 +125,13 @@
}
},
"node_modules/@swc/core-darwin-x64": {
"version": "1.4.17",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.17.tgz",
"integrity": "sha512-WYRO9Fdzq4S/he8zjW5I95G1zcvyd9yyD3Tgi4/ic84P5XDlSMpBDpBLbr/dCPjmSg7aUXxNQqKqGkl6dQxYlA==",
"version": "1.5.24",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.24.tgz",
"integrity": "sha512-MfcFjGGYognpSBSos2pYUNYJSmqEhuw5ceGr6qAdME7ddbjGXliza4W6FggsM+JnWwpqa31+e7/R+GetW4WkaQ==",
"cpu": [
"x64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"darwin"
@ -132,12 +141,13 @@
}
},
"node_modules/@swc/core-linux-arm-gnueabihf": {
"version": "1.4.17",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.17.tgz",
"integrity": "sha512-cgbvpWOvtMH0XFjvwppUCR+Y+nf6QPaGu6AQ5hqCP+5Lv2zO5PG0RfasC4zBIjF53xgwEaaWmGP5/361P30X8Q==",
"version": "1.5.24",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.24.tgz",
"integrity": "sha512-amI2pwtcWV3E/m/nf+AQtn1LWDzKLZyjCmWd3ms7QjEueWYrY8cU1Y4Wp7wNNsxIoPOi8zek1Uj2wwFD/pttNQ==",
"cpu": [
"arm"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
@ -147,12 +157,13 @@
}
},
"node_modules/@swc/core-linux-arm64-gnu": {
"version": "1.4.17",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.17.tgz",
"integrity": "sha512-l7zHgaIY24cF9dyQ/FOWbmZDsEj2a9gRFbmgx2u19e3FzOPuOnaopFj0fRYXXKCmtdx+anD750iBIYnTR+pq/Q==",
"version": "1.5.24",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.24.tgz",
"integrity": "sha512-sTSvmqMmgT1ynH/nP75Pc51s+iT4crZagHBiDOf5cq+kudUYjda9lWMs7xkXB/TUKFHPCRK0HGunl8bkwiIbuw==",
"cpu": [
"arm64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
@ -162,12 +173,13 @@
}
},
"node_modules/@swc/core-linux-arm64-musl": {
"version": "1.4.17",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.17.tgz",
"integrity": "sha512-qhH4gr9gAlVk8MBtzXbzTP3BJyqbAfUOATGkyUtohh85fPXQYuzVlbExix3FZXTwFHNidGHY8C+ocscI7uDaYw==",
"version": "1.5.24",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.24.tgz",
"integrity": "sha512-vd2/hfOBGbrX21FxsFdXCUaffjkHvlZkeE2UMRajdXifwv79jqOHIJg3jXG1F3ZrhCghCzirFts4tAZgcG8XWg==",
"cpu": [
"arm64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
@ -177,12 +189,13 @@
}
},
"node_modules/@swc/core-linux-x64-gnu": {
"version": "1.4.17",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.17.tgz",
"integrity": "sha512-vRDFATL1oN5oZMImkwbgSHEkp8xG1ofEASBypze01W1Tqto8t+yo6gsp69wzCZBlxldsvPpvFZW55Jq0Rn+UnA==",
"version": "1.5.24",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.24.tgz",
"integrity": "sha512-Zrdzi7NqzQxm2BvAG5KyOSBEggQ7ayrxh599AqqevJmsUXJ8o2nMiWQOBvgCGp7ye+Biz3pvZn1EnRzAp+TpUg==",
"cpu": [
"x64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
@ -192,12 +205,13 @@
}
},
"node_modules/@swc/core-linux-x64-musl": {
"version": "1.4.17",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.17.tgz",
"integrity": "sha512-zQNPXAXn3nmPqv54JVEN8k2JMEcMTQ6veVuU0p5O+A7KscJq+AGle/7ZQXzpXSfUCXlLMX4wvd+rwfGhh3J4cw==",
"version": "1.5.24",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.24.tgz",
"integrity": "sha512-1F8z9NRi52jdZQCGc5sflwYSctL6omxiVmIFVp8TC9nngjQKc00TtX/JC2Eo2HwvgupkFVl5YQJidAck9YtmJw==",
"cpu": [
"x64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
@ -207,12 +221,13 @@
}
},
"node_modules/@swc/core-win32-arm64-msvc": {
"version": "1.4.17",
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.17.tgz",
"integrity": "sha512-z86n7EhOwyzxwm+DLE5NoLkxCTme2lq7QZlDjbQyfCxOt6isWz8rkW5QowTX8w9Rdmk34ncrjSLvnHOeLY17+w==",
"version": "1.5.24",
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.24.tgz",
"integrity": "sha512-cKpP7KvS6Xr0jFSTBXY53HZX/YfomK5EMQYpCVDOvfsZeYHN20sQSKXfpVLvA/q2igVt1zzy1XJcOhpJcgiKLg==",
"cpu": [
"arm64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"win32"
@ -222,12 +237,13 @@
}
},
"node_modules/@swc/core-win32-ia32-msvc": {
"version": "1.4.17",
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.17.tgz",
"integrity": "sha512-JBwuSTJIgiJJX6wtr4wmXbfvOswHFj223AumUrK544QV69k60FJ9q2adPW9Csk+a8wm1hLxq4HKa2K334UHJ/g==",
"version": "1.5.24",
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.24.tgz",
"integrity": "sha512-IoPWfi0iwqjZuf7gE223+B97/ZwkKbu7qL5KzGP7g3hJrGSKAvv7eC5Y9r2iKKtLKyv5R/T6Ho0kFR/usi7rHw==",
"cpu": [
"ia32"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"win32"
@ -237,12 +253,13 @@
}
},
"node_modules/@swc/core-win32-x64-msvc": {
"version": "1.4.17",
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.17.tgz",
"integrity": "sha512-jFkOnGQamtVDBm3MF5Kq1lgW8vx4Rm1UvJWRUfg+0gx7Uc3Jp3QMFeMNw/rDNQYRDYPG3yunCC+2463ycd5+dg==",
"version": "1.5.24",
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.24.tgz",
"integrity": "sha512-zHgF2k1uVJL8KIW+PnVz1To4a3Cz9THbh2z2lbehaF/gKHugH4c3djBozU4das1v35KOqf5jWIEviBLql2wDLQ==",
"cpu": [
"x64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"win32"
@ -254,12 +271,14 @@
"node_modules/@swc/counter": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
"integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="
"integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
"license": "Apache-2.0"
},
"node_modules/@swc/types": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.6.tgz",
"integrity": "sha512-/JLo/l2JsT/LRd80C3HfbmVpxOAJ11FO2RCEslFrgzLltoP9j8XIbsyDcfCt2WWyX+CM96rBoNM+IToAkFOugg==",
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.7.tgz",
"integrity": "sha512-scHWahbHF0eyj3JsxG9CFJgFdFNaVQCNAimBlT6PzS3n/HptxqREjsm4OH6AN3lYcffZYSPxXW8ua2BEHp0lJQ==",
"license": "Apache-2.0",
"dependencies": {
"@swc/counter": "^0.1.3"
}
@ -268,6 +287,7 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
"license": "ISC",
"engines": {
"node": ">=10.13.0"
}
@ -276,6 +296,7 @@
"version": "8.11.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
"integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@ -301,6 +322,7 @@
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"browserslist": "^4.23.0",
"caniuse-lite": "^1.0.30001599",
@ -322,7 +344,8 @@
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
"license": "ISC"
},
"node_modules/browserslist": {
"version": "4.23.0",
@ -342,6 +365,7 @@
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"caniuse-lite": "^1.0.30001587",
"electron-to-chromium": "^1.4.668",
@ -358,12 +382,14 @@
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"license": "MIT"
},
"node_modules/camel-case": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
"integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
"license": "MIT",
"dependencies": {
"pascal-case": "^3.1.2",
"tslib": "^2.0.3"
@ -373,6 +399,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
"integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
"license": "MIT",
"dependencies": {
"browserslist": "^4.0.0",
"caniuse-lite": "^1.0.0",
@ -381,9 +408,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001612",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz",
"integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==",
"version": "1.0.30001625",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001625.tgz",
"integrity": "sha512-4KE9N2gcRH+HQhpeiRZXd+1niLB/XNLAhSy4z7fI8EzcbcPoAqjNInxVHTiTwWfTIV4w096XG8OtCOCQQKPv3w==",
"funding": [
{
"type": "opencollective",
@ -397,12 +424,14 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
]
],
"license": "CC-BY-4.0"
},
"node_modules/clean-css": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
"integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
"license": "MIT",
"dependencies": {
"source-map": "~0.6.0"
},
@ -413,12 +442,14 @@
"node_modules/colord": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
"integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw=="
"integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
"license": "MIT"
},
"node_modules/commander": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"license": "MIT",
"engines": {
"node": ">=14"
}
@ -427,6 +458,7 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz",
"integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==",
"license": "ISC",
"engines": {
"node": "^14 || ^16 || >=18"
},
@ -438,6 +470,7 @@
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
"license": "BSD-2-Clause",
"dependencies": {
"boolbase": "^1.0.0",
"css-what": "^6.1.0",
@ -453,6 +486,7 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
"integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
"license": "MIT",
"dependencies": {
"mdn-data": "2.0.30",
"source-map-js": "^1.0.1"
@ -465,6 +499,7 @@
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">= 6"
},
@ -476,6 +511,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"license": "MIT",
"bin": {
"cssesc": "bin/cssesc"
},
@ -487,6 +523,7 @@
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz",
"integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==",
"license": "MIT",
"dependencies": {
"cssnano-preset-default": "^6.1.2",
"lilconfig": "^3.1.1"
@ -506,6 +543,7 @@
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz",
"integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==",
"license": "MIT",
"dependencies": {
"browserslist": "^4.23.0",
"css-declaration-sorter": "^7.2.0",
@ -549,6 +587,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz",
"integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==",
"license": "MIT",
"engines": {
"node": "^14 || ^16 || >=18.0"
},
@ -560,6 +599,7 @@
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
"integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
"license": "MIT",
"dependencies": {
"css-tree": "~2.2.0"
},
@ -572,6 +612,7 @@
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
"integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
"license": "MIT",
"dependencies": {
"mdn-data": "2.0.28",
"source-map-js": "^1.0.1"
@ -584,12 +625,14 @@
"node_modules/csso/node_modules/mdn-data": {
"version": "2.0.28",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
"integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="
"integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
"license": "CC0-1.0"
},
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"license": "MIT",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
@ -608,12 +651,14 @@
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
]
],
"license": "BSD-2-Clause"
},
"node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"license": "BSD-2-Clause",
"dependencies": {
"domelementtype": "^2.3.0"
},
@ -628,6 +673,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"license": "BSD-2-Clause",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
@ -641,20 +687,23 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
"integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/electron-to-chromium": {
"version": "1.4.747",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.747.tgz",
"integrity": "sha512-+FnSWZIAvFHbsNVmUxhEqWiaOiPMcfum1GQzlWCg/wLigVtshOsjXHyEFfmt6cFK6+HkS3QOJBv6/3OPumbBfw=="
"version": "1.4.787",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.787.tgz",
"integrity": "sha512-d0EFmtLPjctczO3LogReyM2pbBiiZbnsKnGF+cdZhsYzHm/A0GV7W94kqzLD8SN4O3f3iHlgLUChqghgyznvCQ==",
"license": "ISC"
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
@ -666,6 +715,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
@ -674,6 +724,7 @@
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
"integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
"license": "MIT",
"engines": {
"node": "*"
},
@ -686,6 +737,7 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz",
"integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==",
"license": "MIT",
"dependencies": {
"camel-case": "^4.1.2",
"clean-css": "~5.3.2",
@ -706,6 +758,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz",
"integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==",
"license": "MIT",
"engines": {
"node": ">=14"
},
@ -716,17 +769,20 @@
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
"integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="
"integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
"license": "MIT"
},
"node_modules/lodash.uniq": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
"integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="
"integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
"license": "MIT"
},
"node_modules/lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"license": "MIT",
"dependencies": {
"tslib": "^2.0.3"
}
@ -734,7 +790,8 @@
"node_modules/mdn-data": {
"version": "2.0.30",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
"license": "CC0-1.0"
},
"node_modules/nanoid": {
"version": "3.3.7",
@ -746,6 +803,7 @@
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@ -757,6 +815,7 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"license": "MIT",
"dependencies": {
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
@ -765,12 +824,14 @@
"node_modules/node-releases": {
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
"license": "MIT"
},
"node_modules/normalize-range": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
"integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@ -779,6 +840,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"license": "BSD-2-Clause",
"dependencies": {
"boolbase": "^1.0.0"
},
@ -790,6 +852,7 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
"integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
"license": "MIT",
"dependencies": {
"dot-case": "^3.0.4",
"tslib": "^2.0.3"
@ -799,15 +862,17 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
"integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
"license": "ISC"
},
"node_modules/postcss": {
"version": "8.4.38",
@ -827,6 +892,7 @@
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.0",
@ -840,6 +906,7 @@
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz",
"integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==",
"license": "MIT",
"dependencies": {
"postcss-selector-parser": "^6.0.11",
"postcss-value-parser": "^4.2.0"
@ -855,6 +922,7 @@
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz",
"integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==",
"license": "MIT",
"dependencies": {
"browserslist": "^4.23.0",
"caniuse-api": "^3.0.0",
@ -872,6 +940,7 @@
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz",
"integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==",
"license": "MIT",
"dependencies": {
"browserslist": "^4.23.0",
"postcss-value-parser": "^4.2.0"
@ -887,6 +956,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz",
"integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==",
"license": "MIT",
"engines": {
"node": "^14 || ^16 || >=18.0"
},
@ -898,6 +968,7 @@
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz",
"integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==",
"license": "MIT",
"engines": {
"node": "^14 || ^16 || >=18.0"
},
@ -909,6 +980,7 @@
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz",
"integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==",
"license": "MIT",
"engines": {
"node": "^14 || ^16 || >=18.0"
},
@ -920,6 +992,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz",
"integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==",
"license": "MIT",
"engines": {
"node": "^14 || ^16 || >=18.0"
},
@ -931,6 +1004,7 @@
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz",
"integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==",
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.2.0",
"stylehacks": "^6.1.1"
@ -946,6 +1020,7 @@
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz",
"integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==",
"license": "MIT",
"dependencies": {
"browserslist": "^4.23.0",
"caniuse-api": "^3.0.0",
@ -963,6 +1038,7 @@
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz",
"integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==",
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
@ -977,6 +1053,7 @@
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz",
"integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==",
"license": "MIT",
"dependencies": {
"colord": "^2.9.3",
"cssnano-utils": "^4.0.2",
@ -993,6 +1070,7 @@
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz",
"integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==",
"license": "MIT",
"dependencies": {
"browserslist": "^4.23.0",
"cssnano-utils": "^4.0.2",
@ -1009,6 +1087,7 @@
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz",
"integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==",
"license": "MIT",
"dependencies": {
"postcss-selector-parser": "^6.0.16"
},
@ -1023,6 +1102,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz",
"integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==",
"license": "MIT",
"engines": {
"node": "^14 || ^16 || >=18.0"
},
@ -1034,6 +1114,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz",
"integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==",
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
@ -1048,6 +1129,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz",
"integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==",
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
@ -1062,6 +1144,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz",
"integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==",
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
@ -1076,6 +1159,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz",
"integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==",
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
@ -1090,6 +1174,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz",
"integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==",
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
@ -1104,6 +1189,7 @@
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz",
"integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==",
"license": "MIT",
"dependencies": {
"browserslist": "^4.23.0",
"postcss-value-parser": "^4.2.0"
@ -1119,6 +1205,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz",
"integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==",
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
@ -1133,6 +1220,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz",
"integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==",
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
@ -1147,6 +1235,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz",
"integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==",
"license": "MIT",
"dependencies": {
"cssnano-utils": "^4.0.2",
"postcss-value-parser": "^4.2.0"
@ -1162,6 +1251,7 @@
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz",
"integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==",
"license": "MIT",
"dependencies": {
"browserslist": "^4.23.0",
"caniuse-api": "^3.0.0"
@ -1177,6 +1267,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz",
"integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==",
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.2.0"
},
@ -1188,9 +1279,10 @@
}
},
"node_modules/postcss-selector-parser": {
"version": "6.0.16",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
"integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz",
"integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==",
"license": "MIT",
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@ -1203,6 +1295,7 @@
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz",
"integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==",
"license": "MIT",
"dependencies": {
"postcss-value-parser": "^4.2.0",
"svgo": "^3.2.0"
@ -1218,6 +1311,7 @@
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz",
"integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==",
"license": "MIT",
"dependencies": {
"postcss-selector-parser": "^6.0.16"
},
@ -1231,12 +1325,14 @@
"node_modules/postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"license": "MIT"
},
"node_modules/relateurl": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
"integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
@ -1245,6 +1341,7 @@
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
@ -1253,6 +1350,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
@ -1261,6 +1359,7 @@
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@ -1270,6 +1369,7 @@
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz",
"integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==",
"license": "MIT",
"dependencies": {
"browserslist": "^4.23.0",
"postcss-selector-parser": "^6.0.16"
@ -1282,9 +1382,10 @@
}
},
"node_modules/svgo": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz",
"integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==",
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz",
"integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==",
"license": "MIT",
"dependencies": {
"@trysound/sax": "0.2.0",
"commander": "^7.2.0",
@ -1309,14 +1410,16 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
"license": "MIT",
"engines": {
"node": ">= 10"
}
},
"node_modules/terser": {
"version": "5.30.4",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.30.4.tgz",
"integrity": "sha512-xRdd0v64a8mFK9bnsKVdoNP9GQIKUAaJPTaqEQDL4w/J8WaW4sWXXoMZ+6SimPkfT5bElreXf8m9HnmPc3E1BQ==",
"version": "5.31.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz",
"integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==",
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
@ -1333,17 +1436,19 @@
"node_modules/terser/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"license": "MIT"
},
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
"license": "0BSD"
},
"node_modules/update-browserslist-db": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz",
"integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==",
"funding": [
{
"type": "opencollective",
@ -1358,9 +1463,10 @@
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"escalade": "^3.1.1",
"picocolors": "^1.0.0"
"escalade": "^3.1.2",
"picocolors": "^1.0.1"
},
"bin": {
"update-browserslist-db": "cli.js"
@ -1372,7 +1478,8 @@
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"license": "MIT"
}
}
}

View file

@ -1,6 +1,6 @@
{
"dependencies": {
"@swc/core": "^1.4.17",
"@swc/core": "^1.5.24",
"autoprefixer": "^10.4.19",
"cssnano": "^6.1.2",
"html-minifier-terser": "^7.2.0",

BIN
private/88x31.psd Normal file

Binary file not shown.

View file

@ -0,0 +1,70 @@
<?php
define('CSS2_SOURCE', 'https://fonts.googleapis.com/css2?family=Electrolize&family=Hachi+Maru+Pop&family=Victor+Mono:ital,wght@0,100..700;1,100..700&family=Zen+Maru+Gothic:wght@400;700&display=swap');
define('CSS2_TARGET', __DIR__ . '/../../assets/makai.css/fonts.css');
define('WOFF2_TARGET_FS', __DIR__ . '/../../public/fonts');
define('WOFF2_TARGET_PUB', '/fonts/%s');
$css2 = file_get_contents(CSS2_SOURCE);
$lines = explode("\n", $css2);
$info = null;
$files = [];
foreach($lines as $line) {
$line = trim($line);
if($line === '')
continue;
if($line === '}') {
if(!str_starts_with($info->url, 'https://fonts.gstatic.com/'))
continue;
$woff2name = sprintf('%s-%03d-%s-%s.woff2', $info->name, $info->weight, $info->style, $info->hash);
$woff2path = sprintf('%s/%s', WOFF2_TARGET_FS, $woff2name);
if(!is_dir(WOFF2_TARGET_FS))
mkdir(WOFF2_TARGET_FS);
if(!is_file($woff2path))
file_put_contents($woff2path, file_get_contents($info->url));
$files[$info->url] = sprintf(WOFF2_TARGET_PUB, $woff2name);
continue;
}
if(str_starts_with($line, '@font-face')) {
$info = new stdClass;
$info->family = null;
$info->style = null;
$info->weight = null;
$info->hash = null;
$info->url = null;
continue;
}
if(str_starts_with($line, 'font-family:')) {
$info->family = trim(substr($line, 13), "'; ");
$info->name = strtolower(strtr($info->family, [' ' => '-']));
continue;
}
if(str_starts_with($line, 'font-style:')) {
$info->style = trim(substr($line, 12), '; ');
continue;
}
if(str_starts_with($line, 'font-weight:')) {
$info->weight = (int)trim(substr($line, 13), ' ');
continue;
}
if(str_starts_with($line, 'unicode-range:')) {
$info->hash = hash('xxh3', trim(substr($line, 15), '; '));
continue;
}
if(str_starts_with($line, 'src: url(') && str_ends_with($line, ") format('woff2');")) {
$info->url = trim(substr($line, 9, -18), '; ');
continue;
}
}
file_put_contents(CSS2_TARGET, strtr($css2, $files));

BIN
public/badges/2hu.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

BIN
public/badges/akane.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
public/badges/aroltd.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
public/badges/ddg.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
public/badges/debian.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

BIN
public/badges/denpa.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9 KiB

BIN
public/badges/firefox3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
public/badges/flash-moe.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
public/badges/flashii.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
public/badges/flashpl.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 924 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

BIN
public/badges/gebruiker.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

BIN
public/badges/ipv6.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
public/badges/konata.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
public/badges/kurarin3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
public/badges/kuromi.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
public/badges/len2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
public/badges/mikokuro.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
public/badges/modarch.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
public/badges/mozilla2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

BIN
public/badges/mpv.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
public/badges/needa_mac.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
public/badges/nook-zone.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
public/badges/osk.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
public/badges/ostan.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
public/badges/saikuru.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
public/badges/sublime.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

BIN
public/badges/szylol.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

BIN
public/badges/un4seen.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
public/badges/valid-bad.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
public/badges/warpnow.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
public/badges/windowsme.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
public/badges/xp.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -46,6 +46,18 @@ class ContactInfo {
return $this->icon;
}
public function iconIsDomain(): bool {
return str_starts_with($this->icon, 'url:');
}
public function iconIsImage(): bool {
return mb_strlen($this->icon) > 1;
}
public function getIconDomain(): string {
return substr($this->icon, 4);
}
public function getColour(): Colour {
return ColourRGB::fromRawRGB($this->colour);
}

View file

@ -14,13 +14,13 @@ class Contacts {
}
public function getContacts(
bool $homePageOnly = false,
bool $featuredOnly = false,
?int $take = null
): array {
$hasTake = $take !== null;
$query = 'SELECT cont_name, cont_homepage, cont_order, cont_title, cont_icon, cont_colour, cont_display, cont_link FROM fm_contacts';
if($homePageOnly)
if($featuredOnly)
$query .= ' WHERE cont_homepage <> 0';
$query .= ' ORDER BY cont_order';
if($hasTake)

View file

@ -18,8 +18,6 @@ class DeveloperRoutes extends RouteHandler {
$projectInfos = $this->projects->getProjects(
featuredOnly: true,
deleted: false,
take: 3,
random: true,
);
$projects = [];
@ -29,58 +27,36 @@ class DeveloperRoutes extends RouteHandler {
'colour' => $projectInfo->hasColour() ? $projectInfo->getColour() : $this->projects->getProjectColour($projectInfo),
];
$contacts = $this->contacts->getContacts(
homePageOnly: true,
take: 3,
);
return $this->templating->render('dev/index', [
'projects' => $projects,
'contacts' => $contacts,
]);
}
#[HttpGet('/home')]
public function getPersonalHome(): string {
return $this->templating->render('dev/home');
}
#[HttpGet('/contact')]
public function getContact(): string {
return $this->templating->render('dev/contact', [
'contacts' => $this->contacts->getContacts(),
'side_projects' => $projects,
'side_contacts' => $this->contacts->getContacts(),
]);
}
#[HttpGet('/projects')]
public function getProjects(): string {
$projectInfos = $this->projects->getProjects(deleted: false);
$items = [];
$projects = [];
foreach($projectInfos as $projectInfo)
$items[] = [
$projects[] = [
'info' => $projectInfo,
'langs' => $this->projects->getLanguages(projectInfo: $projectInfo),
'colour' => $projectInfo->hasColour() ? $projectInfo->getColour() : $this->projects->getProjectColour($projectInfo),
];
$sections = [
'projects' => [
'title' => 'Projects',
'desc' => '',
'items' => $items,
],
];
return $this->templating->render('dev/projects', [
'sections' => $sections,
'projects' => $projects,
'side_contacts' => $this->contacts->getContacts(featuredOnly: true),
]);
}
#[HttpGet('/now-listening')]
public function getNowListening($response, $request): string {
return $this->templating->render('dev/np', [
'header_offset' => (int)$request->getParam('offset', FILTER_SANITIZE_NUMBER_INT),
]);
#[HttpGet('/tools')]
public function temporaryRedirect($response): void {
$response->redirect('/');
}
#[HttpGet('/contact')]
public function permanentRedirect($response): void {
$response->redirect('/', true);
}
}

View file

@ -93,10 +93,10 @@ final class MakaiContext {
$routingCtx->register(new DeveloperRoutes($this->templating, $this->contacts, $this->projects));
$routingCtx->register(new AssetsRoutes($this->siteInfo));
$routingCtx->register(new Whois\WhoisRoutes($this->templating, $this->csrfp));
$routingCtx->register(new SSHKeys\SSHKeysRoutes($this->sshKeys));
$routingCtx->register(new Tools\AsciiRoutes($this->templating));
$routingCtx->register(new Tools\RandomStringRoutes);
$routingCtx->register(new Tools\Ascii\AsciiRoutes($this->templating));
$routingCtx->register(new Tools\Whois\WhoisRoutes($this->templating, $this->csrfp));
return $routingCtx;
}

View file

@ -8,7 +8,7 @@ class RoutingErrorHandler extends HtmlErrorHandler {
public function handle(HttpResponseBuilder $response, HttpRequest $request, int $code, string $message): void {
if($code === 401 || $code === 403 || $code === 404 || $code === 500 || $code === 503) {
$response->setTypeHTML();
$response->accelRedirect(sprintf('/error-%s.html', $code));
$response->setContent(file_get_contents(sprintf('%s/error-%s.html', MKI_DIR_PUBLIC, $code)));
return;
}

View file

@ -4,9 +4,17 @@ namespace Makai;
class SiteInfo {
public function getHeaderNavigation(): array {
return [
['title' => 'Home', 'link' => '/'],
['title' => 'Projects', 'link' => '/projects'],
['title' => 'Contact', 'link' => '/contact'],
['title' => 'Home', 'url' => '/'],
['title' => 'Projects', 'url' => '/projects'],
];
}
public function getToolsMenu(): array {
return [
['icon' => '♪', 'title' => 'Now Listening', 'url' => '//now.flash.moe'],
['icon' => 'A', 'title' => 'ASCII Table', 'url' => '/tools/ascii'],
['icon' => '?', 'title' => 'WHOIS', 'url' => '/tools/whois'],
['icon' => '◎', 'title' => 'IP Addresses', 'url' => '//ip.flash.moe'],
];
}
@ -40,10 +48,4 @@ class SiteInfo {
'/images/mkt-063.jpg',
];
}
public function getFooterQuotes(): array {
return [
'if it ain\'t broke, i\'ll break it',
];
}
}

View file

@ -0,0 +1,232 @@
<?php
namespace Makai\Tools\Ascii;
use InvalidArgumentException;
use JsonSerializable;
class AsciiCharacter implements JsonSerializable {
public function __construct(
private int $char
) {
if($char < 0 || $char > 0xFF)
throw new InvalidArgumentException('$char must be a single byte');
}
public function getDecimal(): string {
return (string)$this->char;
}
public function getOctal(): string {
return decoct($this->char);
}
public function getHex(): string {
return dechex($this->char);
}
public function isPrintable(): bool {
return $this->char > 31
&& $this->char < 127;
}
public function hasHtml(): bool {
return $this->char === 34
|| $this->char === 38
|| $this->char === 60
|| $this->char === 62;
}
public function getHtml(): string {
return match($this->char) {
34 => 'quot',
38 => 'amp',
60 => 'lt',
62 => 'gt',
default => '',
};
}
public function getString(): string {
return match($this->char) {
0 => 'NUL', 1 => 'SOH', 2 => 'STX', 3 => 'ETX', 4 => 'EOT',
5 => 'ENQ', 6 => 'ACK', 7 => 'BEL', 8 => 'BS', 9 => 'HT',
10 => 'LF', 11 => 'VT', 12 => 'FF', 13 => 'CR', 14 => 'SO',
15 => 'SI', 16 => 'DLE', 17 => 'DC1', 18 => 'DC2', 19 => 'DC3',
20 => 'DC4', 21 => 'NAK', 22 => 'SYN', 23 => 'ETB', 24 => 'CAN',
25 => 'EM', 26 => 'SUB', 27 => 'ESC', 28 => 'FS', 29 => 'GS',
30 => 'RS', 31 => 'US', 127 => 'DEL',
default => chr($this->char),
};
}
public function getName(): string {
return match($this->char) {
0 => 'Null character',
1 => 'Start of heading',
2 => 'Start of text',
3 => 'End of text',
4 => 'End of transmission',
5 => 'Enquiry',
6 => 'Acknowledgement',
7 => 'Bell',
8 => 'Backspace',
9 => 'Horizontal tab',
10 => 'Line feed',
11 => 'Vertical tab',
12 => 'Form feed',
13 => 'Carriage return',
14 => 'Shift out/X-On',
15 => 'Shift in/X-Off',
16 => 'Delta line escape',
17 => 'Device control 1 (often XON)',
18 => 'Device control 2',
19 => 'Device control 3 (often XOFF)',
20 => 'Device control 4',
21 => 'Negative acknowledgement',
22 => 'Synchronous idle',
23 => 'End of transmit block',
24 => 'Cancel',
25 => 'End of medium',
26 => 'Substitute',
27 => 'Escape',
28 => 'File separator',
29 => 'Group separator',
30 => 'Record separator',
31 => 'Unit separator',
32 => 'Space',
33 => 'Exclamation mark',
34 => 'Double quotes',
35 => 'Hash',
36 => 'Dollar',
37 => 'Percent',
38 => 'Ampersand',
39 => 'Single quote',
40 => 'Open parenthesis',
41 => 'Close parenthesis',
42 => 'Asterisk',
43 => 'Plus',
44 => 'Comma',
45 => 'Hyphen',
46 => 'Period',
47 => 'Slash',
48 => 'Zero',
49 => 'One',
50 => 'Two',
51 => 'Three',
52 => 'Four',
53 => 'Five',
54 => 'Six',
55 => 'Seven',
56 => 'Eight',
57 => 'Nine',
58 => 'Colon',
59 => 'Semicolon',
60 => 'Less than',
61 => 'Equals',
62 => 'Greater than',
63 => 'Question mark',
64 => 'At symbol',
65 => 'Uppercase A',
66 => 'Uppercase B',
67 => 'Uppercase C',
68 => 'Uppercase D',
69 => 'Uppercase E',
70 => 'Uppercase F',
71 => 'Uppercase G',
72 => 'Uppercase H',
73 => 'Uppercase I',
74 => 'Uppercase J',
75 => 'Uppercase K',
76 => 'Uppercase L',
77 => 'Uppercase M',
78 => 'Uppercase N',
79 => 'Uppercase O',
80 => 'Uppercase P',
81 => 'Uppercase Q',
82 => 'Uppercase R',
83 => 'Uppercase S',
84 => 'Uppercase T',
85 => 'Uppercase U',
86 => 'Uppercase V',
87 => 'Uppercase W',
88 => 'Uppercase X',
89 => 'Uppercase Y',
90 => 'Uppercase Z',
91 => 'Opening bracket',
92 => 'Backslash',
93 => 'Closing bracket',
94 => 'Caret',
95 => 'Underscore',
96 => 'Accent grave',
97 => 'Lowercase a',
98 => 'Lowercase b',
99 => 'Lowercase c',
100 => 'Lowercase d',
101 => 'Lowercase e',
102 => 'Lowercase f',
103 => 'Lowercase g',
104 => 'Lowercase h',
105 => 'Lowercase i',
106 => 'Lowercase j',
107 => 'Lowercase k',
108 => 'Lowercase l',
109 => 'Lowercase m',
110 => 'Lowercase n',
111 => 'Lowercase o',
112 => 'Lowercase p',
113 => 'Lowercase q',
114 => 'Lowercase r',
115 => 'Lowercase s',
116 => 'Lowercase t',
117 => 'Lowercase u',
118 => 'Lowercase v',
119 => 'Lowercase w',
120 => 'Lowercase x',
121 => 'Lowercase y',
122 => 'Lowercase z',
123 => 'Opening curly brace',
124 => 'Vertical bar',
125 => 'Closing curly brace',
126 => 'Tilde',
127 => 'Delete',
default => '?',
};
}
public function __toString(): string {
return $this->getString();
}
public function jsonSerialize(): mixed {
$info = [
'dec' => $this->getDecimal(),
'oct' => $this->getOctal(),
'hex' => $this->getHex(),
'string' => $this->getString(),
'name' => $this->getName(),
];
if($this->hasHtml())
$info['html'] = $this->getHtml();
return $info;
}
public static function all(): array {
$chars = [];
for($i = 0; $i < 128; ++$i)
$chars[] = new AsciiCharacter($i);
return $chars;
}
}

View file

@ -1,5 +1,5 @@
<?php
namespace Makai\Tools;
namespace Makai\Tools\Ascii;
use Index\Http\Routing\{HttpGet,RouteHandler};
use Sasae\SasaeEnvironment;
@ -9,17 +9,16 @@ class AsciiRoutes extends RouteHandler {
private SasaeEnvironment $templating
) {}
#[HttpGet('/ascii')]
#[HttpGet('/tools/ascii')]
public function getAsciiTable($response, $request): string {
$this->templating->addFilter('chr', 'chr');
$this->templating->addFilter('decoct', 'decoct');
$this->templating->addFilter('dechex', 'dechex');
return $this->templating->render('ascii/index');
return $this->templating->render('tools/ascii/index', [
'chars' => AsciiCharacter::all(),
]);
}
#[HttpGet('/ascii')]
#[HttpGet('/ascii.php')]
public function getAsciiPHP($response, $request): void {
$response->redirect('/ascii', true);
$response->redirect('/tools/ascii', true);
}
}

View file

@ -5,7 +5,7 @@ use Index\XString;
use Index\Http\Routing\{HttpGet,RouteHandler};
class RandomStringRoutes extends RouteHandler {
#[HttpGet('/rngstr')]
#[HttpGet('/tools/random')]
public function getRandomString($response, $request): string {
$response->setTypePlain();
@ -23,8 +23,9 @@ class RandomStringRoutes extends RouteHandler {
}
#[HttpGet('/key.php')]
public function getKeyPHP($response, $request): void {
$url = '/rngstr';
#[HttpGet('/rngstr')]
public function getRedirect($response, $request): void {
$url = '/tools/random';
$length = (int)$request->getParam('length', FILTER_SANITIZE_NUMBER_INT);
if($length > 0 && $length <= 1024)

View file

@ -1,5 +1,8 @@
<?php
namespace Makai\Whois;
namespace Makai\Tools\Whois;
use Exception;
use ErrorException;
class WhoisClient {
public const ROOT = 'whois.iana.org';
@ -17,12 +20,15 @@ class WhoisClient {
$sock = @fsockopen($this->server, self::PORT, $errno, $errstr, $timeout);
if(!$sock) throw new \RuntimeException('WhoisClient: ' . $errstr);
$lines = [];
try {
fwrite($sock, $target . "\r\n");
$lines = [];
while($line = fgets($sock))
$lines[] = trim($line);
} catch(ErrorException $ex) {
$lines[] = $ex->getMessage();
} finally {
fclose($sock);
}
@ -47,7 +53,7 @@ class WhoisClient {
$client = new WhoisClient($server);
}
} catch(\RuntimeException $ex) {
} catch(\Exception $ex) {
if(empty($responses))
throw $ex;
}

View file

@ -1,5 +1,5 @@
<?php
namespace Makai\Whois;
namespace Makai\Tools\Whois;
class WhoisResponse implements \JsonSerializable {
private const WHOIS_SERVER_PREFIXES = ['refer', 'whois', 'registrar whois server'];

View file

@ -1,5 +1,5 @@
<?php
namespace Makai\Whois;
namespace Makai\Tools\Whois;
class WhoisResult implements \JsonSerializable {
public function __construct(

View file

@ -1,5 +1,5 @@
<?php
namespace Makai\Whois;
namespace Makai\Tools\Whois;
use Exception;
use Memcached;
@ -14,12 +14,17 @@ class WhoisRoutes extends RouteHandler {
private CSRFPContainer $csrfp,
) {}
#[HttpGet('/whois')]
#[HttpGet('/tools/whois')]
public function getIndex(): string {
return $this->templating->render('whois/index');
return $this->templating->render('tools/whois/index');
}
#[HttpPost('/whois/lookup')]
#[HttpGet('/whois')]
public function getWhoisPHP($response, $request): void {
$response->redirect('/tools/whois', true);
}
#[HttpPost('/tools/whois/lookup')]
public function postLookup($response, $request): array {
if(!$request->isFormContent())
return 400;
@ -52,7 +57,7 @@ class WhoisRoutes extends RouteHandler {
if($result === null) {
$client = new WhoisClient;
$result = $client->lookup($target);
$cache->set($prefix . $hash, serialize($result), 1800);
$cache->set($prefix . $hash, serialize($result), 3600);
$source = 'fresh';
} else {
$result = unserialize($result);

View file

@ -1,182 +0,0 @@
{% extends 'ascii/master.twig' %}
{% set header_title = 'ascii table' %}
{% set header_minimal = true %}
{% set table = [
['Null character', 'NUL'],
['Start of heading', 'SOH'],
['Start of text', 'STX'],
['End of text', 'ETX'],
['End of transmission', 'EOT'],
['Enquiry', 'ENQ'],
['Acknowledgement', 'ACK'],
['Bell', 'BEL'],
['Backspace', 'BS' ],
['Horizontal tab', 'HT' ],
['Line feed', 'LF' ],
['Vertical tab', 'VT' ],
['Form feed', 'FF' ],
['Carriage return', 'CR' ],
['Shift out/X-On', 'SO' ],
['Shift in/X-Off', 'SI' ],
['Delta line escape', 'DLE'],
['Device control 1 (often XON)', 'DC1'],
['Device control 2', 'DC2'],
['Device control 3 (often XOFF)', 'DC3'],
['Device control 4', 'DC4'],
['Negative acknowledgement', 'NAK'],
['Synchronous idle', 'SYN'],
['End of transmit block', 'ETB'],
['Cancel', 'CAN'],
['End of medium', 'EM' ],
['Substitute', 'SUB'],
['Escape', 'ESC'],
['File separator', 'FS' ],
['Group separator', 'GS' ],
['Record separator', 'RS' ],
['Unit separator', 'US' ],
['Space'],
['Excalamation mark'],
['Double quotes', 'quot'],
['Hash'],
['Dollar'],
['Percent'],
['Ampersand', 'amp'],
['Single quote'],
['Open parenthesis'],
['Close parenthesis'],
['Asterisk'],
['Plus'],
['Comma'],
['Hyphen'],
['Period'],
['Slash'],
['Zero'],
['One'],
['Two'],
['Three'],
['Four'],
['Five'],
['Six'],
['Seven'],
['Eight'],
['Nine'],
['Colon'],
['Semicolon'],
['Less than', 'lt'],
['Equals'],
['Greater than', 'gt'],
['Question mark'],
['At symbol'],
['Uppercase A'],
['Uppercase B'],
['Uppercase C'],
['Uppercase D'],
['Uppercase E'],
['Uppercase F'],
['Uppercase G'],
['Uppercase H'],
['Uppercase I'],
['Uppercase J'],
['Uppercase K'],
['Uppercase L'],
['Uppercase M'],
['Uppercase N'],
['Uppercase O'],
['Uppercase P'],
['Uppercase Q'],
['Uppercase R'],
['Uppercase S'],
['Uppercase T'],
['Uppercase U'],
['Uppercase V'],
['Uppercase W'],
['Uppercase X'],
['Uppercase Y'],
['Uppercase Z'],
['Opening bracket'],
['Backslash'],
['Closing bracket'],
['Caret'],
['Underscore'],
['Accent grave'],
['Lowercase a'],
['Lowercase b'],
['Lowercase c'],
['Lowercase d'],
['Lowercase e'],
['Lowercase f'],
['Lowercase g'],
['Lowercase h'],
['Lowercase i'],
['Lowercase j'],
['Lowercase k'],
['Lowercase l'],
['Lowercase m'],
['Lowercase n'],
['Lowercase o'],
['Lowercase p'],
['Lowercase q'],
['Lowercase r'],
['Lowercase s'],
['Lowercase t'],
['Lowercase u'],
['Lowercase v'],
['Lowercase w'],
['Lowercase x'],
['Lowercase y'],
['Lowercase z'],
['Opening curly brace'],
['Vertical bar'],
['Closing curly brace'],
['Tilde'],
['Delete', 'DEL'],
] %}
{% block container %}
<div class="ascii-wrap">
<div class="ascii-search">
<div class="ascii-search-box">
<input type="search" id="search" placeholder="Filter..." autocomplete="off">
</div>
<div class="ascii-search-hint js-invisible-on-scroll">
Type <em><code>printable</code></em> for all printable characters, or <em><code>control</code></em> for all control characters.
</div>
</div>
<div class="ascii-chars">
{% for code, info in table %}
{% set is_printable = code > 31 and code < 127 %}
{% set has_html = is_printable and info[1] is defined %}
{% set print = is_printable ? code|chr : info[1] %}
<div class="ascii-char" data-key-code="{{ code }}" data-key-desc="{{ info[0] }}" data-key-print="{{ print }}" data-copy="{{ print }}" {% if has_html %}data-key-html="{{ info[1] }}"{% endif %}>
<div class="ascii-char-print">{{ print }}</div>
<div class="ascii-char-desc">{{ info[0] }}</div>
<div class="ascii-char-misc">
<div class="ascii-char-misc-item" data-copy="{{ code }}">
<div class="ascii-char-misc-item-head">Decimal</div>
<div class="ascii-char-misc-item-value">{{ code }}</div>
</div>
<div class="ascii-char-misc-item" data-copy="{{ code|decoct }}">
<div class="ascii-char-misc-item-head">Octal</div>
<div class="ascii-char-misc-item-value">{{ code|decoct }}</div>
</div>
<div class="ascii-char-misc-item" data-copy="{{ code|dechex }}">
<div class="ascii-char-misc-item-head">Hex</div>
<div class="ascii-char-misc-item-value">{{ code|dechex }}</div>
</div>
{% if has_html %}
<div class="ascii-char-misc-item" data-copy="&amp;{{ info[1] }};">
<div class="ascii-char-misc-item-head">HTML</div>
<div class="ascii-char-misc-item-value">&amp;{{ info[1] }};</div>
</div>
{% endif %}
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}

View file

@ -1 +0,0 @@
{% extends 'master.twig' %}

View file

@ -1,27 +0,0 @@
{% extends 'dev/master.twig' %}
{% set header_title = 'contact' %}
{% block container %}
<div class="section">
<div class="section-content">
<div class="section-background"></div>
<h1>Contact</h1>
</div>
</div>
<div class="socials">
{% for contact in contacts %}
<div class="social social-{{ contact.name }}" style="--social-colour: {{ contact.colour }}">
{% if contact.hasLink %}
<a href="{{ contact.link }}" class="social-background" target="_blank" rel="noopener"></a>
{% endif %}
<div class="social-icon {{ contact.icon }}"></div>
<div class="social-content">
<div class="social-name">{{ contact.title }}</div>
<div class="social-handle">{{ contact.display }}</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}

View file

@ -1,42 +0,0 @@
{% extends 'dev/master.twig' %}
{% set header_title = 'homepage' %}
{% set header_full = true %}
{% block container %}
<div class="php">
<div class="php-time">
<div class="php-time-analog">
<div class="clock">
<div class="clock-background"></div>
<div class="clock-center"></div>
<div class="clock-hand clock-hand-hours"><div class="clock-hand-display"></div></div>
<div class="clock-hand clock-hand-minutes"><div class="clock-hand-display"></div></div>
<div class="clock-hand clock-hand-seconds"><div class="clock-hand-display"></div></div>
<div class="clock-number clock-number-3"><div class="clock-number-display"></div></div>
<div class="clock-number clock-number-6"><div class="clock-number-display"></div></div>
<div class="clock-number clock-number-9"><div class="clock-number-display"></div></div>
<div class="clock-number clock-number-12"><div class="clock-number-display"></div></div>
</div>
</div>
<div class="php-time-alter">
<div class="php-time-digital">
<div class="php-time-digital-hours">--</div>
<div class="php-time-digital-separator">:</div>
<div class="php-time-digital-minutes">--</div>
</div>
<div class="php-time-date">
<span class="php-date-label">Week</span>
<span class="php-date-week">--</span>
<span class="php-date-label">&nbsp;&mdash;&nbsp;</span>
<span class="php-date-year">----</span><span class="php-date-label">-</span><span class="php-date-month">---</span><span class="php-date-label">-</span><span class="php-date-day">--</span>
</div>
</div>
</div>
<form class="php-search" method="get" action="https://duckduckgo.com/">
<div class="php-search-input">
<input type="search" name="q" placeholder="Search using DuckDuckGo...">
</div>
</form>
</div>
{% endblock %}

View file

@ -1,69 +1,98 @@
{% extends 'dev/master.twig' %}
{% set header_is_index = true %}
{% set master_breadcrumbs = [{ url: '/', text: 'home' }] %}
{% block container %}
<div class="index-menu">
{% for link in globals.siteInfo.headerNavigation|slice(1) %}
<a href="{{ link.link }}">{{ link.title }}</a>
{% endfor %}
</div>
{% set index_badges = [
{ img: '/badges/flash-moe.gif', url: '//flash.moe', title: "This badge isn't very good, but you can use it to link to me if you're like!" },
{ img: '/badges/nook-zone.gif', url: '//nook.zone' },
{ img: '/badges/osk.gif', url: '//osk.sh' },
{ img: '/badges/szylol.gif', url: '//szy.lol' },
{ img: '/badges/gebruiker.gif', url: '//cockdickball.in' },
{ img: '/badges/aroltd.gif', url: 'http://dev.aroltd.com' },
{ img: '/badges/saikuru.gif', url: '//saikuru.net' },
<div class="index-featured">
<div class="index-feature">
<div class="index-feature-header">
<a href="/projects" class="index-feature-header-link"></a>
<div class="index-feature-header-title">Projects</div>
<div class="index-feature-header-more">More</div>
</div>
{% for project in projects %}
<div class="index-project" style="background-color: {{ project.colour }};">
<a href="/projects#{{ project.info.cleanName }}" class="index-project-anchor"></a>
<div class="index-project-content">
<div class="index-project-name">{{ project.info.name }}</div>
{% if project.info.hasSummary %}
<div class="index-project-summary">{{ project.info.summary }}</div>
{% endif %}
</div>
{ img: '/badges/flashii.gif', url: '//flashii.net' },
<div class="index-project-links">
{% if project.info.hasHomePageUrl %}
<a class="index-project-link index-project-link-homepage" href="{{ project.info.homePageUrl }}" rel="noopener" target="_blank">Homepage</a>
{% endif %}
{ img: '/badges/debian.gif', url: '//www.debian.org', title: "Actually, it's currently still Ubuntu, but details..." },
{ img: '/badges/php4_88x31.gif', url: '//www.php.net' },
{ img: '/badges/sublime.gif', url: '//www.sublimetext.com' },
{ img: '/badges/valid-html5.gif' },
{ img: '/badges/valid-css-blue.gif' },
{ img: '/badges/ipv6.gif', url: '//ip.flash.moe' },
{% if project.info.hasSourceUrl %}
<a class="index-project-link index-project-link-repository" href="{{ project.info.sourceUrl }}" rel="noopener" target="_blank">Source</a>
{% endif %}
{ img: '/badges/xp.gif', url: '//www.youtube.com/watch?v=9gQb0qdc1OQ' },
{ img: '/badges/tetoteteto.gif', url: '//www.nicovideo.jp/watch/sm6157102' },
{ img: '/badges/akane.gif', url: '//www.nicovideo.jp/watch/sm32492001' },
{ img: '/badges/kurarin3.gif', url: '//www.nicovideo.jp/watch/sm39257413' },
{ img: '/badges/kuromi.gif', url: '//www.youtube.com/watch?v=fnOsmf-JUPc' },
{ img: '/badges/2hu.gif', url: '//www.nicovideo.jp/watch/sm9688678' },
{ img: '/badges/firefox3.gif', url: '//firefox.com' },
{ img: '/badges/anythingbut.gif', url: '//www.apple.com/safari' },
{ img: '/badges/mozilla2.gif', url: '//developer.mozilla.org' },
{ img: '/badges/seedyourtorrents.gif', url: '//abyss.flash.moe/SWF/ruffle.php?play=pirate.swf' },
{ img: '/badges/mikokuro.gif', url: '//www.nicovideo.jp/watch/sm8104274' },
{ img: '/badges/mpv.gif', url: '//mpv.io' },
{ img: '/badges/un4seen.gif', url: '//www.un4seen.com' },
{ img: '/badges/foobar2000.gif', url: '//www.foobar2000.org' },
{ img: '/badges/ddg.gif', url: '//duckduckgo.com' },
{ img: '/badges/konata.gif', url: '//www.nicovideo.jp/watch/sm3912151' },
{ img: '/badges/len2.gif', url: '//www.nicovideo.jp/watch/sm18972745' },
{ img: '/badges/flashpl.gif', url: '//abyss.flash.moe/Software/Flash%20Player%2032' },
{ img: '/badges/ostan.gif', url: '//www.nicovideo.jp/watch/sm61070' },
{ img: '/badges/warpnow.gif', url: '//static.flash.moe/sounds/os2shutdown.opus' },
{ img: '/badges/modarch.gif', url: '//modarchive.org' },
{ img: '/badges/windowsme.gif', url: '//abyss.flash.moe/SWF/ruffle.php?play=troubled_windows.swf' },
{ img: '/badges/denpa.gif', url: '//www.youtube.com/watch?v=fMHj3U3-RA4' },
{ img: '/badges/needa_mac.gif', url: '//www.youtube.com/watch?v=i1IqqlW1U4k' },
] %}
{% if project.info.hasDiscussionUrl %}
<a class="index-project-link index-project-link-forum" href="{{ project.info.discussionUrl }}" rel="noopener" target="_blank">Discussion</a>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% block column_centre %}
<article class="index">
<h1><span>Welcome (back) to flash.moe!</span></h1>
<p>
If you've been here before you'll probably notice that things are looking quite different!
We're not quite to where I want to be yet, however.
I'd like to reintroduce the blog as the main feature of the website.
This series of blerbs will likely be converted into a blog post once we're there.
Something I've wanted to do for a long time actually, but I found it difficult to fit it within the previous design.
</p>
<h2><span>Why a redesign?</span></h2>
<p>
Well, because I felt like it.
Okay, there are actually deeper reasons for it unrelated to age.
Though, previous one is already like 5 years old, can you believe it?
While the previous design had that Vista-like Aero eye candy going on, I found it extremely difficult to add new things to the site that didn't feel out of place somehow.
Between dodgy document structure to achieve the positioning I wanted, terrible Javascripting practices and strange browser behaviour, I was pretty much guaranteed to burn out whenever I tried to do anything.
Design is not exactly my forte, so keeping it simple seems like the best way to go forward for the good for this website.
</p>
<h2><span>What is this colour scheme?</span></h2>
<p>
flash.moe has always been dark grey with slight accents and I began finding that extremely boring.
So I welcome you to this new experiment!
This redo has both a light mode and a dark mode, the light variant having my personal preference, but it's ok to be wrong and prefer dark.
Both themes are heavily, let's say, Inspired by <a href="//youtu.be/3em-J9yYPAo" rel="noopener" target="_blank">いよわ's 1000<ruby>年<rt>ねん</ruby><ruby>生<rt>い</ruby>きている</a>.
I did really feel like how the Windows team must've felt while nuking all the <code>filter</code>s, <code>linear-gradient</code>s and <code>text-/box-shadow</code>s from the design at first...
As the general rhetoric with the flatter design languages is that the content will have carry, and I think I'll follow that here as well.
It is definitely experimental but I'm happy with how things have turned out so far, and I hope you'll enjoy it as well!
</p>
<h2><span>What's next?</span></h2>
<p>
It will probably be another while before I bother to actually implement the blogging software, so this will be it for now.
You can actually navigate to the WHOIS and ASCII tools and I'll see about reimplementing some of the other tools that are scattered around the abyss and various other places on here.
They will also be reachable via the same menu.
There's still a bunch that needs overhauling and restructuring, but I'll cross those bridges when I get to them.
</p>
<p>
Thank you for visiting and I hope you enjoy your stay!
If you have any feedback, be sure to let me know.
</p>
</article>
<div class="index-feature">
<div class="index-feature-header">
<a href="/contact" class="index-feature-header-link"></a>
<div class="index-feature-header-title">Contact</div>
<div class="index-feature-header-more">More</div>
</div>
<div class="index-contact">
{% for contact in contacts %}
<div class="social social-{{ contact.name }}" style="--social-colour: {{ contact.colour }}">
{% if contact.hasLink %}
<a href="{{ contact.link }}" class="social-background" target="_blank" rel="noopener"></a>
{% endif %}
<div class="social-icon {{ contact.icon }}"></div>
<div class="social-content">
<div class="social-name">{{ contact.title }}</div>
<div class="social-handle">{{ contact.display }}</div>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="badges">
{% for badge in index_badges %}
<a class="badges-item"{% if badge.url is defined %} rel="noopener" target="_blank" href="{{ badge.url }}"{% endif %}{% if badge.title is defined %} title="{{ badge.title }}"{% endif %}>
<img src="{{ badge.img }}" alt="">
</a>
{% endfor %}
</div>
{% endblock %}

View file

@ -1 +1,57 @@
{% extends 'master.twig' %}
{% block column_right %}
{% if side_contacts is defined %}
<div class="sidelist">
<div class="sidelist-title">Elsewhere</div>
<div class="sidelist-body">
{% for contact in side_contacts %}
<a class="{{ html_classes('sidelist-item', 'sidecontact', { 'sidelist-item-link': contact.hasLink }) }}" {% if contact.hasLink %} href="{{ contact.link }}" target="_blank" rel="me noopener"{% endif %}>
<div class="sidelist-item-icon">
{% if contact.iconIsDomain %}
<img width="16" height="16" src="//icons.duckduckgo.com/ip3/{{ contact.iconDomain }}.ico" alt="">
{% elseif contact.iconIsImage %}
<img width="16" height="16" src="{{ contact.icon }}" alt="">
{% else %}
{{ contact.icon }}
{% endif %}
</div>
<div class="sidelist-item-label">
<span class="sidecontact-site">{{ contact.title }}</span>
<span>/</span>
<span class="sidecontact-handle">{{ contact.display }}</span>
</div>
</a>
{% endfor %}
</div>
</div>
{% endif %}
{% if side_projects is defined %}
<div class="sidelist">
<div class="sidelist-title">Featured Projects</div>
<div class="sidelist-body">
{% for i, project in side_projects %}
<a class="sidelist-item sidelist-item-link" href="/projects#{{ project.info.cleanName }}">
<div class="sidelist-item-icon">{{ i % 2 ? '★' : '☆' }}</div>
<div class="sidelist-item-label">{{ project.info.name }}</div>
</a>
{% endfor %}
</div>
</div>
{% endif %}
<div class="sidelist">
<div class="sidelist-title">Tools</div>
<div class="sidelist-body">
{% for link in globals.siteInfo.toolsMenu %}
<a class="sidelist-item sidelist-item-link" href="{{ link.url }}" {% if link.url|slice(0, 2) == '//' %}target="_blank"{% endif %}>
<div class="sidelist-item-icon">{{ link.icon }}</div>
<div class="sidelist-item-label">{{ link.title }}</div>
</a>
{% endfor %}
</div>
</div>
<div class="js-np-target" data-username="flashwave_"></div>
{% endblock %}

View file

@ -1,5 +0,0 @@
{% extends 'dev/master.twig' %}
{% set header_title = 'now listening' %}
{% set header_full = true %}
{% set header_now_playing = true %}

View file

@ -1,54 +1,42 @@
{% extends 'dev/master.twig' %}
{% set header_title = 'projects' %}
{% set master_breadcrumbs = [{ url: '/projects', text: 'projects' }] %}
{% block container %}
{% for sectionId, section in sections %}
<div class="section" id="section-{{ sectionId }}">
<div class="section-content">
<div class="section-background"></div>
<h1>{{ section.title }}</h1>
{% block column_centre %}
{% for project in projects %}
<div class="project" id="{{ project.info.cleanName }}" style="--project-colour: {{ project.colour }};">
<h2>{{ project.info.name }}</h2>
{% if project.info.hasSummary %}
<p>{{ project.info.summary }}</p>
{% endif %}
{% if project.info.hasDescription %}
{% set lines = project.info.description|split("\n") %}
{% for line in lines %}
<p>{{ line|trim }}</p>
{% endfor %}
{% endif %}
<div class="project-tags">
{% for lang in project.langs %}
<span class="project-tag" style="--tag-colour: {{ lang.colour }};">{{ lang.name }}</span>
{% endfor %}
{% if project.info.hasHomePageUrl %}
<a class="project-tag project-tag-link" href="{{ project.info.homePageUrl }}" rel="noopener" target="_blank">Homepage</a>
{% endif %}
{% if project.info.hasSourceUrl %}
<a class="project-tag project-tag-link" href="{{ project.info.sourceUrl }}" rel="noopener" target="_blank">Source</a>
{% endif %}
{% if project.info.hasDiscussionUrl %}
<a class="project-tag project-tag-link" href="{{ project.info.discussionUrl }}" rel="noopener" target="_blank">Discussion</a>
{% endif %}
</div>
</div>
{% for project in section.items %}
<div class="project project-type-{{ sectionId }}" id="{{ project.info.cleanName }}" style="--project-colour: {{ project.colour }};">
<div class="project-content">
<div class="project-details">
<h2>{{ project.info.name }}<div class="project-languages">
{% for lang in project.langs %}
<div class="project-language" style="--language-colour: {{ lang.colour }};">{{ lang.name }}</div>
{% endfor %}</div>
</h2>
{% if project.info.hasSummary %}
<p class="project-details-summary">{{ project.info.summary }}</p>
{% endif %}
{% if project.info.hasDescription %}
{% set lines = project.info.description|split("\n") %}
{% for line in lines %}
<p>{{ line|trim }}</p>
{% endfor %}
{% endif %}
</div>
<div class="project-links">
{% if project.info.hasHomePageUrl %}
<a class="project-link project-link-homepage" href="{{ project.info.homePageUrl }}" rel="noopener" target="_blank">Homepage</a>
{% endif %}
{% if project.info.hasSourceUrl %}
<a class="project-link project-link-repository" href="{{ project.info.sourceUrl }}" rel="noopener" target="_blank">Source</a>
{% endif %}
{% if project.info.hasDiscussionUrl %}
<a class="project-link project-link-forum" href="{{ project.info.discussionUrl }}" rel="noopener" target="_blank">Discussion</a>
{% endif %}
</div>
</div>
</div>
{% endfor %}
{% endfor %}
{% endblock %}

View file

@ -4,13 +4,16 @@
{% set master_title = error_string ~ ' // flash.moe' %}
{% block master_head %}
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="{{ error_blerb }}">
<link href="{{ globals.assetsInfo.get('errors.css') }}" rel="stylesheet">
<style>
:root {
--error-colour: {{ error_colour }};
}
</style>
{% endblock %}
{% set master_body_attrs = {'style': '--error-colour: ' ~ error_colour} %}
{% block master_body %}
<div class="http-error">
<div class="http-error-container">

Some files were not shown because too many files have changed in this diff Show more