feat: replace mcfly site with starlight docs

This commit is contained in:
Ayo Ayco 2025-03-26 21:10:27 +01:00
parent 3358e7c805
commit 519573916c
28 changed files with 38 additions and 1558 deletions

View file

@ -1,32 +0,0 @@
image: alpine/edge
packages:
- nodejs
- npm
- pnpm
secrets:
- 291f0e35-9b8d-43ff-844c-77c5f29c1876
- bbfcb6dc-7c4a-42ee-a11a-022f0339a133
environment:
NETLIFY_SITE_ID: bfd69adf-f754-433c-9690-63426f0d2fa0
REPO: wcb
GH_USER: ayoayco
tasks:
- push-mirror: |
cd ~/"${REPO}"
git config --global credential.helper store
git push --mirror "https://github.com/${GH_USER}/${REPO}"
- install-deps: |
cd ~/"${REPO}"
pnpm i
- build: |
cd ~/"${REPO}"
pnpm -F site run build
- deploy: |
cd ~/"${REPO}"
{
set +x
. ~/.buildsecrets
set -x
}
export NETLIFY_AUTH_TOKEN
pnpm -F site run deploy

View file

@ -4,9 +4,6 @@ import starlight from '@astrojs/starlight'
// https://astro.build/config
export default defineConfig({
redirects: {
'/': '/guides',
},
integrations: [
starlight({
title: 'WCB',

View file

@ -0,0 +1,36 @@
---
title: Web Component Base
description: Web components in Easy Mode
template: splash
hero:
tagline: A simple reactivity system for web components
# image:
# file: ../../assets/houston.webp
actions:
- text: Example Guide
link: /guides/example/
icon: right-arrow
- text: Read the Starlight docs
link: https://starlight.astro.build
icon: external
variant: minimal
---
import { Card, CardGrid } from '@astrojs/starlight/components';
## Next steps
<CardGrid stagger>
<Card title="Update content" icon="pencil">
Edit `src/content/docs/index.mdx` to see this page change.
</Card>
<Card title="Add new content" icon="add-document">
Add Markdown or MDX files to `src/content/docs` to create new pages.
</Card>
<Card title="Configure your site" icon="setting">
Edit your `sidebar` and other config in `astro.config.mjs`.
</Card>
<Card title="Read the docs" icon="open-book">
Learn more in [the Starlight Docs](https://starlight.astro.build/).
</Card>
</CardGrid>

View file

@ -1,3 +1,3 @@
[build]
base = "site"
base = "docs"
publish = "dist"

View file

@ -31,7 +31,6 @@
"test": "vitest --run",
"test:watch": "vitest",
"demo": "npx simple-server .",
"site": "pnpm -F site start",
"docs": "pnpm -F docs start",
"build": "pnpm run clean && tsc && pnpm run copy:source",
"size-limit": "pnpm run build && size-limit",

View file

@ -1,4 +1,3 @@
packages:
# include packages in subfolders (e.g. apps/ and packages/)
- 'site'
- 'docs'
- 'docs/'

View file

@ -1,5 +0,0 @@
dist
node-modules
.output
public

10
site/.gitignore vendored
View file

@ -1,10 +0,0 @@
dist
node_modules
*.log*
.nitro
.cache
.output
.env
*~
*swp
*swo

View file

@ -1 +0,0 @@
*

View file

@ -1,67 +0,0 @@
# McFly Starter Project
## Background
This project was generated from the basic template for **McFly** -- a no-framework framework that assists in leveraging the web platform.
![template-basic](https://raw.githubusercontent.com/ayoayco/McFly/main/assets/template-basic.png)
It contains example files to get you started using vanilla web technologies in a modern way. See the [Special Directories](#special-directories) section for more information.
## Features
The time has come for vanilla Web tech. 🎉
✅ Create web apps with vanilla custom elements<br>
✅ Write real .HTML files<br>
✅ Have no frameworks or reactivity libraries on the browser<br>
✅ Use server-side rendering<br>
✅ Deploy anywhere<br>
## Special directories
**1. `./src/pages/`**
- file-based routing for `.html` files
- directly use custom elements & static fragments (no imports or registry maintenance needed)
- use `<script server:setup>` to define logic that runs on the server, which then gets stripped away
**2. `./src/components/`**
- custom element constructor files (only `.js` files for now)
- all components are automatically registered using their file names; a `hello-world.js` component can be used as `<hello-world>`
- static `.html` fragments; a `my-header.html` fragment can be directly used as `<my-header>`
**3. `./routes/api/`**
- file-based routing for REST API endpoints
- e.g., `./routes/api/users.ts` can be accessed via `http://<domain>/api/users`
- TypeScript or JavaScript welcome!
## McFly config
To tell McFly you want to use components, pass the mode (only `"js"` for now) to the `components` prop mcfly.config.ts
```js
import defineConfig from './packages/define-config'
export default defineConfig({
components: 'js',
})
```
## Commands
The following commands are available to you on this project. Add more, or modify them as needed in your `./package.json` file.
| Command | Action |
| --------------- | ---------------------------------------------------- |
| npm start | Start the development server |
| npm run prepare | Prepare the workspace |
| npm run build | Locally generate the app's build files to `./output` |
| npm run preview | Preview the built app locally |
---
_Just keep building_<br />
_A project by [Ayo Ayco](https://ayco.io)_

View file

@ -1,7 +0,0 @@
import { defineMcFlyConfig } from '@mcflyjs/config'
export default defineMcFlyConfig({
components: 'js',
nitro: {
preset: 'netlify'
}
})

View file

@ -1,21 +0,0 @@
{
"name": "site",
"description": "McFly starter project; see more on https://ayco.io/gh/McFly",
"scripts": {
"start": "mcfly serve",
"prepare": "mcfly prepare",
"dev": "mcfly serve",
"build": "mcfly build",
"preview": "node .output/server/index.mjs",
"build:preview": "pnpm run build && pnpm run preview",
"deploy": "netlify deploy --site=$NETLIFY_SITE_ID --dir=dist --prod"
},
"dependencies": {
"@mcflyjs/config": "^0.2.7",
"@mcflyjs/core": "^0.8.6"
},
"version": "0.0.1",
"main": "index.js",
"author": "Ayo Ayco",
"license": "MIT"
}

View file

@ -1,31 +0,0 @@
<header class="my-header">
<h1><slot /></h1>
<slot name="description" />
</header>
<style>
.my-header {
border-radius: 5px;
background: linear-gradient(45deg, var(--color-primary), var(--color-fade));
color: white;
margin: 1em 0;
padding: 1.5em;
& a {
color: white;
}
}
@media only screen and (max-device-width: 400px) {
.my-header {
& h1 {
font-size: 1.5em;
line-clamp: 1;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
}
}
</style>

View file

@ -1,47 +0,0 @@
<div class="call-to-action">
<a id="primary" href="https://ayco.io/sh/wcb#readme">
Learn More
</a>
<a
href="https://codepen.io/ayoayco-the-styleful/pen/PoVegBK?editors=1010"
target="_blank"
>Playground &rarr;</a
>
</div>
<style>
.call-to-action {
display: flex;
gap: 1em;
justify-content: center;
margin: 1em 0;
width: 100%;
& a {
border: 3px solid var(--color-fade);
padding: 0.5em 0.75em;
border-radius: 5px;
text-align: center;
text-decoration: none;
&:hover {
box-shadow: 0 0 0 3px var(--color-fade);
}
&#primary {
background: #3054bf;
color: white;
min-width: 35%;
}
}
}
@media only screen and (max-device-width: 430px) {
.call-to-action {
flex-direction: column;
& a {
width: 100% !important;
}
}
}
</style>

View file

@ -1,41 +0,0 @@
class CodeBlockComponent extends HTMLElement {
connectedCallback() {
const trimmed = this.innerHTML.trim()
const lang = this.getAttribute('language')
const inline = this.getAttribute('inline') !== null
this.innerHTML = `
<pre><code id="code">${trimmed}</code></pre>
`
/**
* @type {HTMLPreElement}
*/
const pre = this.querySelector('pre')
if (lang) {
pre.className = `language-${lang}`
}
/**
* @type {Partial<CSSStyleDeclaration>}
*/
const style = {
background: '#f5f2f0',
padding: '1em',
margin: '1em 0',
fontSize: 'large',
overflow: 'auto',
borderRadius: '5px',
}
if (inline) {
style.display = 'inline'
style.padding = '0.25em 0.3em'
}
Object.keys(style).forEach((rule) => {
pre.style[rule] = style[rule]
})
}
}

View file

@ -1,85 +0,0 @@
class FeatureSet extends WebComponent {
#features = [
{
icon: '️🔄',
title: 'Reactive.',
description:
"A robust API for synchronizing your component's UI and properties",
},
{
icon: '️🤏',
title: 'Tiny.',
description:
'~1 kB base class (minified, compressed) with versatile utilities',
},
{
icon: '😌',
title: 'Easy.',
description: 'Sensible life-cycle hooks that you understand and remember',
url: '',
},
{
icon: '️💡',
title: 'Familiar.',
description:
'Use the built-in JSX-like syntax or bring your own custom templating',
url: 'https://codepen.io/ayoayco-the-styleful/pen/ZEwNJBR?editors=1010',
},
]
/**
* @type {Array<HTMLArticleElement>}
*/
get articleEl() {
return this.querySelectorAll('article')
}
afterViewInit() {
/**
* @type {Partial<CSSStyleDeclaration>}
*/
const articleStyles = {
border: '1px solid #ccc',
borderRadius: '5px',
padding: '30px',
margin: '0 auto 1em',
boxShadow: '5px 25px 10px -25px rgba(34, 34, 34, 0.15)',
}
Object.keys(articleStyles).forEach((rule) =>
this.articleEl.forEach((el) => (el.style[rule] = articleStyles[rule]))
)
/**
* @type {Partial<CSSStyleDeclaration>}
*/
const ftrStyles = {
maxWidth: '800px',
margin: '0 auto',
padding: '30px',
gap: '1em',
}
const featureWrapper = this.querySelector('.feature-wrapper')
Object.keys(ftrStyles).forEach(
(rule) => (featureWrapper.style[rule] = ftrStyles[rule])
)
}
get template() {
return html`
<div class="feature-wrapper">
${this.#features.map(
(feature) => html`
<article>
<h3 style="margin-bottom: 1em" class="feature-title">
<span>${feature.icon}</span> ${feature.title}
</h3>
<p style="margin:0" class="feature-description">
${feature.description}
</p>
</article>
`
)}
</div>
`
}
}

View file

@ -1,10 +0,0 @@
class Counter extends WebComponent {
static props = {
count: 0,
}
get template() {
return html`<button onClick=${() => ++this.props.count}>
${this.props.count}
</button>`
}
}

View file

@ -1,3 +0,0 @@
<footer style="text-align: center; font-style: italic; padding: 0.5em 1em 1em">
<slot />
</footer>

View file

@ -1,53 +0,0 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/reset.css" />
<meta name="generator" content="McFly v0.0.1" />
<meta name="theme-color" content="#3054bf" />
<meta
name="description"
content="🤷‍♂️ zero-dependency, 🤏 tiny JS base class for creating reactive custom elements easily ✨"
/>
<meta name="author" content="Ayo Ayco" />
<meta name="origin" content="https://mc-fly.vercel.app/" />
<!-- Open Graph data -->
<meta property="og:site_name" content="WebComponent.io" />
<meta property="og:type" content="website" />
<meta
property="og:title"
content="WebComponent.io: Web Components in Easy Mode"
/>
<meta
property="og:description"
content="🤷‍♂️ zero-dependency, 🤏 tiny JS base class for creating reactive custom elements easily ✨"
/>
<style>
:root {
--color-primary: #3054bf;
--color-fade: #416fff;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 1em;
}
body > * {
padding: 0.5em 1em;
}
h1 {
padding: 0;
margin: 0;
}
h2,
p,
ul,
ol {
margin-bottom: 1em;
}
</style>
<slot />
</head>

View file

@ -1,22 +0,0 @@
class HelloWorld extends HTMLElement {
static get observedAttributes() {
return ['my-name']
}
connectedCallback() {
let count = 0
const currentName = this.getAttribute('my-name')
if (!currentName) {
this.setAttribute('my-name', 'World')
}
this.onclick = () => this.setAttribute('my-name', `Clicked ${++count}x`)
}
attributeChangedCallback(property, previousValue, currentValue) {
if (property === 'my-name' && previousValue !== currentValue) {
this.innerHTML = `<button style="cursor:pointer">Hello ${currentValue}!</button>`
}
}
}

View file

@ -1,12 +0,0 @@
<quote
style="
background-color: beige;
border-radius: 5px;
border: 1px solid gray;
padding: 1em;
margin: 1em 0;
display: block;
"
>
<span id="icon">⚠️</span> <slot />
</quote>

View file

@ -1,152 +0,0 @@
<!doctype html>
<html lang="en">
<!--
Hello! This page is an example McFly page.
See more on https://ayco.io/gh/McFly
-->
<my-head>
<title>WebComponent.io: Web Components in Easy Mode</title>
<link rel="stylesheet" href="prism.css" />
<script src="prism.js" defer></script>
<script server:setup>
const project = {
name: 'WebComponent.io',
description: 'A simple reactivity system for web components',
};
const author = {
name: 'Ayo Ayco',
url: 'https://ayco.io',
year: '2023',
};
</script>
<style>
@counter-style publish-icons {
system: cyclic;
symbols: '️✅';
suffix: ' ';
}
main {
font-size: large;
& section ul {
list-style: publish-icons;
& li {
margin-bottom: 0.5em;
}
}
& section.jumbo {
& .hero-statement {
font-size: 2em;
text-align: center;
}
}
& code-block {
overflow: auto;
}
}
</style>
</my-head>
<body>
<awesome-header>
<span>{{ project.name }}</span>
<span slot="description">{{ project.description }}</span>
</awesome-header>
<main>
<section class="jumbo">
<p class="hero-statement">
Build lightweight custom elements that browsers &
<em>you</em> understand.
</p>
<call-to-action></call-to-action>
<div>
<feature-set>
<h2>Features</h2>
<ul>
<li>
A robust API for synchronizing your component's UI and
properties
</li>
<li>
~1 kB base class (minified, compressed) with versatile utilities
</li>
<li>
Sensible life-cycle hooks that you understand and remember
</li>
<li>
Use the built-in JSX-like syntax or bring your own custom
templating
</li>
</ul>
</feature-set>
</div>
</section>
<section>
<h2>Why use this base class?</h2>
<p>
Often times, when simple websites need a quick
<a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Components/Using_custom_elements"
target="_blank">custom element</a>, the best way is still to create one extending from
<code-block inline>HTMLElement</code-block>. However, it can quickly
reach a point where writing the code from scratch can seem confusing
and hard to maintain especially when compared to other projects with
more advanced setups.
</p>
<p>
Also, when coming from frameworks with an easy declarative coding
experience (using templates), the default imperative way (e.g.,
creating instances of elements, manually attaching event handlers, and
other DOM manipulations) is a frequent pain point we see.
</p>
<p>
This project aims to address these with virtually zero tooling
required and thin abstractions from vanilla custom element APIs
giving you only the bare minimum code to be productive.
</p>
<p>
It works on current-day browsers without needing compilers,
transpilers, or polyfills.
</p>
<p>
Here's an interactive custom element:
<my-counter></my-counter>
</p>
<code-block language="js">
<pre>
import { WebComponent, html } from &quot;https://esm.sh/web-component-base&quot;;
export class Counter extends WebComponent {
static props = {
count: 0
}
onInit() {
// do something...
}
get template() {
return html`
&lt;button onClick=${() => ++this.props.count}&gt;
${this.props.count}
&lt;/button&gt;
`;
}
}
customElements.define(&quot;my-counter&quot;, Counter);</pre>
</code-block>
</section>
</main>
<my-footer>
<small>
<a href="https://ayco.io/sh/wcb/tree/main/site">Website</a>
built with <a href="https://mcfly.js.org">McFly</a>.<br />
Copyright &copy; {{author.year}}
<a href="{{ author.url }}">{{ author.name }}</a>.
</small>
</my-footer>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,118 +0,0 @@
/* PrismJS 1.29.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
code[class*='language-'],
pre[class*='language-'] {
color: #000;
background: 0 0;
text-shadow: 0 1px #fff;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
font-size: 1em;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
code[class*='language-'] ::-moz-selection,
code[class*='language-']::-moz-selection,
pre[class*='language-'] ::-moz-selection,
pre[class*='language-']::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
code[class*='language-'] ::selection,
code[class*='language-']::selection,
pre[class*='language-'] ::selection,
pre[class*='language-']::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*='language-'],
pre[class*='language-'] {
text-shadow: none;
}
}
pre[class*='language-'] {
padding: 1em;
margin: 0.5em 0;
overflow: auto;
}
:not(pre) > code[class*='language-'],
pre[class*='language-'] {
background: #f5f2f0;
}
:not(pre) > code[class*='language-'] {
padding: 0.1em;
border-radius: 0.3em;
white-space: normal;
}
.token.cdata,
.token.comment,
.token.doctype,
.token.prolog {
color: #708090;
}
.token.punctuation {
color: #999;
}
.token.namespace {
opacity: 0.7;
}
.token.boolean,
.token.constant,
.token.deleted,
.token.number,
.token.property,
.token.symbol,
.token.tag {
color: #905;
}
.token.attr-name,
.token.builtin,
.token.char,
.token.inserted,
.token.selector,
.token.string {
color: #690;
}
.language-css .token.string,
.style .token.string,
.token.entity,
.token.operator,
.token.url {
color: #9a6e3a;
background: hsla(0, 0%, 100%, 0.5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.class-name,
.token.function {
color: #dd4a68;
}
.token.important,
.token.regex,
.token.variable {
color: #e90;
}
.token.bold,
.token.important {
font-weight: 700;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

View file

@ -1,753 +0,0 @@
/* PrismJS 1.29.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
var _self =
'undefined' != typeof window
? window
: 'undefined' != typeof WorkerGlobalScope &&
self instanceof WorkerGlobalScope
? self
: {},
Prism = (function (e) {
var n = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,
t = 0,
r = {},
a = {
manual: e.Prism && e.Prism.manual,
disableWorkerMessageHandler:
e.Prism && e.Prism.disableWorkerMessageHandler,
util: {
encode: function e(n) {
return n instanceof i
? new i(n.type, e(n.content), n.alias)
: Array.isArray(n)
? n.map(e)
: n
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/\u00a0/g, ' ')
},
type: function (e) {
return Object.prototype.toString.call(e).slice(8, -1)
},
objId: function (e) {
return (
e.__id || Object.defineProperty(e, '__id', { value: ++t }), e.__id
)
},
clone: function e(n, t) {
var r, i
switch (((t = t || {}), a.util.type(n))) {
case 'Object':
if (((i = a.util.objId(n)), t[i])) return t[i]
for (var l in ((r = {}), (t[i] = r), n))
n.hasOwnProperty(l) && (r[l] = e(n[l], t))
return r
case 'Array':
return (
(i = a.util.objId(n)),
t[i]
? t[i]
: ((r = []),
(t[i] = r),
n.forEach(function (n, a) {
r[a] = e(n, t)
}),
r)
)
default:
return n
}
},
getLanguage: function (e) {
for (; e; ) {
var t = n.exec(e.className)
if (t) return t[1].toLowerCase()
e = e.parentElement
}
return 'none'
},
setLanguage: function (e, t) {
;(e.className = e.className.replace(RegExp(n, 'gi'), '')),
e.classList.add('language-' + t)
},
currentScript: function () {
if ('undefined' == typeof document) return null
if ('currentScript' in document) return document.currentScript
try {
throw new Error()
} catch (r) {
var e = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(r.stack) ||
[])[1]
if (e) {
var n = document.getElementsByTagName('script')
for (var t in n) if (n[t].src == e) return n[t]
}
return null
}
},
isActive: function (e, n, t) {
for (var r = 'no-' + n; e; ) {
var a = e.classList
if (a.contains(n)) return !0
if (a.contains(r)) return !1
e = e.parentElement
}
return !!t
},
},
languages: {
plain: r,
plaintext: r,
text: r,
txt: r,
extend: function (e, n) {
var t = a.util.clone(a.languages[e])
for (var r in n) t[r] = n[r]
return t
},
insertBefore: function (e, n, t, r) {
var i = (r = r || a.languages)[e],
l = {}
for (var o in i)
if (i.hasOwnProperty(o)) {
if (o == n)
for (var s in t) t.hasOwnProperty(s) && (l[s] = t[s])
t.hasOwnProperty(o) || (l[o] = i[o])
}
var u = r[e]
return (
(r[e] = l),
a.languages.DFS(a.languages, function (n, t) {
t === u && n != e && (this[n] = l)
}),
l
)
},
DFS: function e(n, t, r, i) {
i = i || {}
var l = a.util.objId
for (var o in n)
if (n.hasOwnProperty(o)) {
t.call(n, o, n[o], r || o)
var s = n[o],
u = a.util.type(s)
'Object' !== u || i[l(s)]
? 'Array' !== u || i[l(s)] || ((i[l(s)] = !0), e(s, t, o, i))
: ((i[l(s)] = !0), e(s, t, null, i))
}
},
},
plugins: {},
highlightAll: function (e, n) {
a.highlightAllUnder(document, e, n)
},
highlightAllUnder: function (e, n, t) {
var r = {
callback: t,
container: e,
selector:
'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code',
}
a.hooks.run('before-highlightall', r),
(r.elements = Array.prototype.slice.apply(
r.container.querySelectorAll(r.selector)
)),
a.hooks.run('before-all-elements-highlight', r)
for (var i, l = 0; (i = r.elements[l++]); )
a.highlightElement(i, !0 === n, r.callback)
},
highlightElement: function (n, t, r) {
var i = a.util.getLanguage(n),
l = a.languages[i]
a.util.setLanguage(n, i)
var o = n.parentElement
o && 'pre' === o.nodeName.toLowerCase() && a.util.setLanguage(o, i)
var s = { element: n, language: i, grammar: l, code: n.textContent }
function u(e) {
;(s.highlightedCode = e),
a.hooks.run('before-insert', s),
(s.element.innerHTML = s.highlightedCode),
a.hooks.run('after-highlight', s),
a.hooks.run('complete', s),
r && r.call(s.element)
}
if (
(a.hooks.run('before-sanity-check', s),
(o = s.element.parentElement) &&
'pre' === o.nodeName.toLowerCase() &&
!o.hasAttribute('tabindex') &&
o.setAttribute('tabindex', '0'),
!s.code)
)
return a.hooks.run('complete', s), void (r && r.call(s.element))
if ((a.hooks.run('before-highlight', s), s.grammar))
if (t && e.Worker) {
var c = new Worker(a.filename)
;(c.onmessage = function (e) {
u(e.data)
}),
c.postMessage(
JSON.stringify({
language: s.language,
code: s.code,
immediateClose: !0,
})
)
} else u(a.highlight(s.code, s.grammar, s.language))
else u(a.util.encode(s.code))
},
highlight: function (e, n, t) {
var r = { code: e, grammar: n, language: t }
if ((a.hooks.run('before-tokenize', r), !r.grammar))
throw new Error('The language "' + r.language + '" has no grammar.')
return (
(r.tokens = a.tokenize(r.code, r.grammar)),
a.hooks.run('after-tokenize', r),
i.stringify(a.util.encode(r.tokens), r.language)
)
},
tokenize: function (e, n) {
var t = n.rest
if (t) {
for (var r in t) n[r] = t[r]
delete n.rest
}
var a = new s()
return (
u(a, a.head, e),
o(e, a, n, a.head, 0),
(function (e) {
for (var n = [], t = e.head.next; t !== e.tail; )
n.push(t.value), (t = t.next)
return n
})(a)
)
},
hooks: {
all: {},
add: function (e, n) {
var t = a.hooks.all
;(t[e] = t[e] || []), t[e].push(n)
},
run: function (e, n) {
var t = a.hooks.all[e]
if (t && t.length) for (var r, i = 0; (r = t[i++]); ) r(n)
},
},
Token: i,
}
function i(e, n, t, r) {
;(this.type = e),
(this.content = n),
(this.alias = t),
(this.length = 0 | (r || '').length)
}
function l(e, n, t, r) {
e.lastIndex = n
var a = e.exec(t)
if (a && r && a[1]) {
var i = a[1].length
;(a.index += i), (a[0] = a[0].slice(i))
}
return a
}
function o(e, n, t, r, s, g) {
for (var f in t)
if (t.hasOwnProperty(f) && t[f]) {
var h = t[f]
h = Array.isArray(h) ? h : [h]
for (var d = 0; d < h.length; ++d) {
if (g && g.cause == f + ',' + d) return
var v = h[d],
p = v.inside,
m = !!v.lookbehind,
y = !!v.greedy,
k = v.alias
if (y && !v.pattern.global) {
var x = v.pattern.toString().match(/[imsuy]*$/)[0]
v.pattern = RegExp(v.pattern.source, x + 'g')
}
for (
var b = v.pattern || v, w = r.next, A = s;
w !== n.tail && !(g && A >= g.reach);
A += w.value.length, w = w.next
) {
var E = w.value
if (n.length > e.length) return
if (!(E instanceof i)) {
var P,
L = 1
if (y) {
if (!(P = l(b, A, e, m)) || P.index >= e.length) break
var S = P.index,
O = P.index + P[0].length,
j = A
for (j += w.value.length; S >= j; )
j += (w = w.next).value.length
if (((A = j -= w.value.length), w.value instanceof i))
continue
for (
var C = w;
C !== n.tail && (j < O || 'string' == typeof C.value);
C = C.next
)
L++, (j += C.value.length)
L--, (E = e.slice(A, j)), (P.index -= A)
} else if (!(P = l(b, 0, E, m))) continue
S = P.index
var N = P[0],
_ = E.slice(0, S),
M = E.slice(S + N.length),
W = A + E.length
g && W > g.reach && (g.reach = W)
var z = w.prev
if (
(_ && ((z = u(n, z, _)), (A += _.length)),
c(n, z, L),
(w = u(n, z, new i(f, p ? a.tokenize(N, p) : N, k, N))),
M && u(n, w, M),
L > 1)
) {
var I = { cause: f + ',' + d, reach: W }
o(e, n, t, w.prev, A, I),
g && I.reach > g.reach && (g.reach = I.reach)
}
}
}
}
}
}
function s() {
var e = { value: null, prev: null, next: null },
n = { value: null, prev: e, next: null }
;(e.next = n), (this.head = e), (this.tail = n), (this.length = 0)
}
function u(e, n, t) {
var r = n.next,
a = { value: t, prev: n, next: r }
return (n.next = a), (r.prev = a), e.length++, a
}
function c(e, n, t) {
for (var r = n.next, a = 0; a < t && r !== e.tail; a++) r = r.next
;(n.next = r), (r.prev = n), (e.length -= a)
}
if (
((e.Prism = a),
(i.stringify = function e(n, t) {
if ('string' == typeof n) return n
if (Array.isArray(n)) {
var r = ''
return (
n.forEach(function (n) {
r += e(n, t)
}),
r
)
}
var i = {
type: n.type,
content: e(n.content, t),
tag: 'span',
classes: ['token', n.type],
attributes: {},
language: t,
},
l = n.alias
l &&
(Array.isArray(l)
? Array.prototype.push.apply(i.classes, l)
: i.classes.push(l)),
a.hooks.run('wrap', i)
var o = ''
for (var s in i.attributes)
o +=
' ' +
s +
'="' +
(i.attributes[s] || '').replace(/"/g, '&quot;') +
'"'
return (
'<' +
i.tag +
' class="' +
i.classes.join(' ') +
'"' +
o +
'>' +
i.content +
'</' +
i.tag +
'>'
)
}),
!e.document)
)
return e.addEventListener
? (a.disableWorkerMessageHandler ||
e.addEventListener(
'message',
function (n) {
var t = JSON.parse(n.data),
r = t.language,
i = t.code,
l = t.immediateClose
e.postMessage(a.highlight(i, a.languages[r], r)), l && e.close()
},
!1
),
a)
: a
var g = a.util.currentScript()
function f() {
a.manual || a.highlightAll()
}
if (
(g &&
((a.filename = g.src),
g.hasAttribute('data-manual') && (a.manual = !0)),
!a.manual)
) {
var h = document.readyState
'loading' === h || ('interactive' === h && g && g.defer)
? document.addEventListener('DOMContentLoaded', f)
: window.requestAnimationFrame
? window.requestAnimationFrame(f)
: window.setTimeout(f, 16)
}
return a
})(_self)
'undefined' != typeof module && module.exports && (module.exports = Prism),
'undefined' != typeof global && (global.Prism = Prism)
;(Prism.languages.markup = {
comment: { pattern: /<!--(?:(?!<!--)[\s\S])*?-->/, greedy: !0 },
prolog: { pattern: /<\?[\s\S]+?\?>/, greedy: !0 },
doctype: {
pattern:
/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
greedy: !0,
inside: {
'internal-subset': {
pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
lookbehind: !0,
greedy: !0,
inside: null,
},
string: { pattern: /"[^"]*"|'[^']*'/, greedy: !0 },
punctuation: /^<!|>$|[[\]]/,
'doctype-tag': /^DOCTYPE/i,
name: /[^\s<>'"]+/,
},
},
cdata: { pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i, greedy: !0 },
tag: {
pattern:
/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
greedy: !0,
inside: {
tag: {
pattern: /^<\/?[^\s>\/]+/,
inside: { punctuation: /^<\/?/, namespace: /^[^\s>\/:]+:/ },
},
'special-attr': [],
'attr-value': {
pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
inside: {
punctuation: [
{ pattern: /^=/, alias: 'attr-equals' },
{ pattern: /^(\s*)["']|["']$/, lookbehind: !0 },
],
},
},
punctuation: /\/?>/,
'attr-name': {
pattern: /[^\s>\/]+/,
inside: { namespace: /^[^\s>\/:]+:/ },
},
},
},
entity: [
{ pattern: /&[\da-z]{1,8};/i, alias: 'named-entity' },
/&#x?[\da-f]{1,8};/i,
],
}),
(Prism.languages.markup.tag.inside['attr-value'].inside.entity =
Prism.languages.markup.entity),
(Prism.languages.markup.doctype.inside['internal-subset'].inside =
Prism.languages.markup),
Prism.hooks.add('wrap', function (a) {
'entity' === a.type &&
(a.attributes.title = a.content.replace(/&amp;/, '&'))
}),
Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
value: function (a, e) {
var s = {}
;(s['language-' + e] = {
pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
lookbehind: !0,
inside: Prism.languages[e],
}),
(s.cdata = /^<!\[CDATA\[|\]\]>$/i)
var t = {
'included-cdata': { pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i, inside: s },
}
t['language-' + e] = { pattern: /[\s\S]+/, inside: Prism.languages[e] }
var n = {}
;(n[a] = {
pattern: RegExp(
'(<__[^>]*>)(?:<!\\[CDATA\\[(?:[^\\]]|\\](?!\\]>))*\\]\\]>|(?!<!\\[CDATA\\[)[^])*?(?=</__>)'.replace(
/__/g,
function () {
return a
}
),
'i'
),
lookbehind: !0,
greedy: !0,
inside: t,
}),
Prism.languages.insertBefore('markup', 'cdata', n)
},
}),
Object.defineProperty(Prism.languages.markup.tag, 'addAttribute', {
value: function (a, e) {
Prism.languages.markup.tag.inside['special-attr'].push({
pattern: RegExp(
'(^|["\'\\s])(?:' +
a +
')\\s*=\\s*(?:"[^"]*"|\'[^\']*\'|[^\\s\'">=]+(?=[\\s>]))',
'i'
),
lookbehind: !0,
inside: {
'attr-name': /^[^\s=]+/,
'attr-value': {
pattern: /=[\s\S]+/,
inside: {
value: {
pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
lookbehind: !0,
alias: [e, 'language-' + e],
inside: Prism.languages[e],
},
punctuation: [{ pattern: /^=/, alias: 'attr-equals' }, /"|'/],
},
},
},
})
},
}),
(Prism.languages.html = Prism.languages.markup),
(Prism.languages.mathml = Prism.languages.markup),
(Prism.languages.svg = Prism.languages.markup),
(Prism.languages.xml = Prism.languages.extend('markup', {})),
(Prism.languages.ssml = Prism.languages.xml),
(Prism.languages.atom = Prism.languages.xml),
(Prism.languages.rss = Prism.languages.xml)
!(function (s) {
var e =
/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/
;(s.languages.css = {
comment: /\/\*[\s\S]*?\*\//,
atrule: {
pattern: RegExp(
'@[\\w-](?:[^;{\\s"\']|\\s+(?!\\s)|' + e.source + ')*?(?:;|(?=\\s*\\{))'
),
inside: {
rule: /^@[\w-]+/,
'selector-function-argument': {
pattern:
/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
lookbehind: !0,
alias: 'selector',
},
keyword: {
pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
lookbehind: !0,
},
},
},
url: {
pattern: RegExp(
'\\burl\\((?:' + e.source + '|(?:[^\\\\\r\n()"\']|\\\\[^])*)\\)',
'i'
),
greedy: !0,
inside: {
function: /^url/i,
punctuation: /^\(|\)$/,
string: { pattern: RegExp('^' + e.source + '$'), alias: 'url' },
},
},
selector: {
pattern: RegExp(
'(^|[{}\\s])[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' +
e.source +
')*(?=\\s*\\{)'
),
lookbehind: !0,
},
string: { pattern: e, greedy: !0 },
property: {
pattern:
/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
lookbehind: !0,
},
important: /!important\b/i,
function: { pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i, lookbehind: !0 },
punctuation: /[(){};:,]/,
}),
(s.languages.css.atrule.inside.rest = s.languages.css)
var t = s.languages.markup
t && (t.tag.addInlined('style', 'css'), t.tag.addAttribute('style', 'css'))
})(Prism)
Prism.languages.clike = {
comment: [
{ pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, lookbehind: !0, greedy: !0 },
{ pattern: /(^|[^\\:])\/\/.*/, lookbehind: !0, greedy: !0 },
],
string: {
pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
greedy: !0,
},
'class-name': {
pattern:
/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,
lookbehind: !0,
inside: { punctuation: /[.\\]/ },
},
keyword:
/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,
boolean: /\b(?:false|true)\b/,
function: /\b\w+(?=\()/,
number: /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
operator: /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
punctuation: /[{}[\];(),.:]/,
}
;(Prism.languages.javascript = Prism.languages.extend('clike', {
'class-name': [
Prism.languages.clike['class-name'],
{
pattern:
/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
lookbehind: !0,
},
],
keyword: [
{ pattern: /((?:^|\})\s*)catch\b/, lookbehind: !0 },
{
pattern:
/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
lookbehind: !0,
},
],
function:
/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
number: {
pattern: RegExp(
'(^|[^\\w$])(?:NaN|Infinity|0[bB][01]+(?:_[01]+)*n?|0[oO][0-7]+(?:_[0-7]+)*n?|0[xX][\\dA-Fa-f]+(?:_[\\dA-Fa-f]+)*n?|\\d+(?:_\\d+)*n|(?:\\d+(?:_\\d+)*(?:\\.(?:\\d+(?:_\\d+)*)?)?|\\.\\d+(?:_\\d+)*)(?:[Ee][+-]?\\d+(?:_\\d+)*)?)(?![\\w$])'
),
lookbehind: !0,
},
operator:
/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/,
})),
(Prism.languages.javascript['class-name'][0].pattern =
/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/),
Prism.languages.insertBefore('javascript', 'keyword', {
regex: {
pattern: RegExp(
'((?:^|[^$\\w\\xA0-\\uFFFF."\'\\])\\s]|\\b(?:return|yield))\\s*)/(?:(?:\\[(?:[^\\]\\\\\r\n]|\\\\.)*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}|(?:\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.|\\[(?:[^[\\]\\\\\r\n]|\\\\.)*\\])*\\])*\\]|\\\\.|[^/\\\\\\[\r\n])+/[dgimyus]{0,7}v[dgimyus]{0,7})(?=(?:\\s|/\\*(?:[^*]|\\*(?!/))*\\*/)*(?:$|[\r\n,.;:})\\]]|//))'
),
lookbehind: !0,
greedy: !0,
inside: {
'regex-source': {
pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
lookbehind: !0,
alias: 'language-regex',
inside: Prism.languages.regex,
},
'regex-delimiter': /^\/|\/$/,
'regex-flags': /^[a-z]+$/,
},
},
'function-variable': {
pattern:
/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
alias: 'function',
},
parameter: [
{
pattern:
/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
lookbehind: !0,
inside: Prism.languages.javascript,
},
{
pattern:
/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
lookbehind: !0,
inside: Prism.languages.javascript,
},
{
pattern:
/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
lookbehind: !0,
inside: Prism.languages.javascript,
},
{
pattern:
/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,
lookbehind: !0,
inside: Prism.languages.javascript,
},
],
constant: /\b[A-Z](?:[A-Z_]|\dx?)*\b/,
}),
Prism.languages.insertBefore('javascript', 'string', {
hashbang: { pattern: /^#!.*/, greedy: !0, alias: 'comment' },
'template-string': {
pattern:
/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
greedy: !0,
inside: {
'template-punctuation': { pattern: /^`|`$/, alias: 'string' },
interpolation: {
pattern:
/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
lookbehind: !0,
inside: {
'interpolation-punctuation': {
pattern: /^\$\{|\}$/,
alias: 'punctuation',
},
rest: Prism.languages.javascript,
},
},
string: /[\s\S]+/,
},
},
'string-property': {
pattern:
/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
lookbehind: !0,
greedy: !0,
alias: 'property',
},
}),
Prism.languages.insertBefore('javascript', 'operator', {
'literal-property': {
pattern:
/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
lookbehind: !0,
alias: 'property',
},
}),
Prism.languages.markup &&
(Prism.languages.markup.tag.addInlined('script', 'javascript'),
Prism.languages.markup.tag.addAttribute(
'on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)',
'javascript'
)),
(Prism.languages.js = Prism.languages.javascript)

View file

@ -1,76 +0,0 @@
/**
THANKS TO JOSH COMEAU FOR HIS CUSTOM CSS RESET
👉 https://www.joshwcomeau.com/css/custom-css-reset/
**/
/*
1. Use a more-intuitive box-sizing model.
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
/*
2. Remove default margin
*/
* {
margin: 0;
}
/*
3. Allow percentage-based heights in the application
*/
html,
body {
height: 100%;
}
/*
Typographic tweaks!
4. Add accessible line-height
5. Improve text rendering
*/
body {
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
/*
6. Improve media defaults
*/
img,
picture,
video,
canvas,
svg,
iframe {
display: block;
max-width: 100%;
margin: 0 auto;
}
/*
7. Remove built-in form typography styles
*/
input,
button,
textarea,
select {
font: inherit;
}
/*
8. Avoid text overflows
*/
p,
h1,
h2,
h3,
h4,
h5,
h6 {
overflow-wrap: break-word;
}
/*
9. Create a root stacking context
*/
#root,
#__next {
isolation: isolate;
}

View file

@ -1,2 +0,0 @@
User-agent: *
Disallow:

View file

@ -1,3 +0,0 @@
{
"extends": "./.nitro/types/tsconfig.json"
}