diff --git a/.gitignore b/.gitignore
index 2d0b3cec3..0ad45fa27 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@
# editor related
.idea/
+*.swo
+*.swp
# macOS related
.DS_Store
diff --git a/examples/tutorials/ItWaspsOnMyMachine/src/server/queries.js b/examples/tutorials/ItWaspsOnMyMachine/src/server/queries.js
index dced04be9..531f28e79 100644
--- a/examples/tutorials/ItWaspsOnMyMachine/src/server/queries.js
+++ b/examples/tutorials/ItWaspsOnMyMachine/src/server/queries.js
@@ -1,14 +1,8 @@
import axios from 'axios';
export const getExcuse = async () => {
- return axios
- .get('https://api.devexcus.es/')
- .then(res => {
- return res.data;
- })
- .catch(error => {
- console.error(error);
- });
+ const response = await axios.get('https://api.devexcus.es/')
+ return response.data
}
export const getAllSavedExcuses = async (_args, context) => {
diff --git a/project-page/.eslintrc.json b/project-page/.eslintrc.json
new file mode 100644
index 000000000..bffb357a7
--- /dev/null
+++ b/project-page/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+ "extends": "next/core-web-vitals"
+}
diff --git a/project-page/.gitignore b/project-page/.gitignore
new file mode 100644
index 000000000..c87c9b392
--- /dev/null
+++ b/project-page/.gitignore
@@ -0,0 +1,36 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+.pnpm-debug.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
diff --git a/project-page/README.md b/project-page/README.md
new file mode 100644
index 000000000..b12f3e33e
--- /dev/null
+++ b/project-page/README.md
@@ -0,0 +1,34 @@
+This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
+
+## Getting Started
+
+First, run the development server:
+
+```bash
+npm run dev
+# or
+yarn dev
+```
+
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+
+You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
+
+[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
+
+The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
+
+## Learn More
+
+To learn more about Next.js, take a look at the following resources:
+
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+
+You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
+
+## Deploy on Vercel
+
+The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
diff --git a/project-page/components/Benefits.js b/project-page/components/Benefits.js
new file mode 100644
index 000000000..a19b21590
--- /dev/null
+++ b/project-page/components/Benefits.js
@@ -0,0 +1,102 @@
+import classNames from 'classnames'
+import { Terminal, Layers, Coffee, Code } from 'react-feather'
+
+import SectionContainer from './Layouts/SectionContainer'
+
+import styles from '../styles/index.module.css'
+
+const Lang = () => (
+ <>
+
+ language
+
+ >
+)
+
+const Benefit = ({ Icon, title, description }) => (
+
+
+
+
+
+
+ { title }
+
+
+
+ { description }
+
+
+)
+
+const Benefits = () => {
+ return (
+
+
+
+
+ Yet another web framework. Except it is
+ a .
+
+
+ Don't worry, it takes less than 30 minutes to learn.
+
+
+
+ )
+}
+
+export default DarkModeToggle
diff --git a/project-page/components/Faq.js b/project-page/components/Faq.js
new file mode 100644
index 000000000..8e7d00ccc
--- /dev/null
+++ b/project-page/components/Faq.js
@@ -0,0 +1,92 @@
+import { useState } from 'react'
+import Link from 'next/link'
+import { ChevronDown, ChevronRight } from 'react-feather'
+
+import SectionContainer from './Layouts/SectionContainer'
+
+const faqs = [
+ {
+ question: 'How is Wasp different from Next.js / Nuxt.js / Gatsby?',
+ answer:
+ Next.js is front-end solution only, focused on static websites. This is some
+ longer text so I can see how it behaves.
+
+ Maybe I should put here component so I have freedom in formatting, putting URLs, etc?
+ This is some test url
+
+ },
+ {
+ question: 'How is Wasp different from Ruby on Rails, Django, etc?',
+ answer: 'Those are all back-end frameworks. Wasp is full-stack!'
+ },
+ {
+ question: 'How hard is it to learn Wasp?',
+ answer: 'Well, it is actually really easy!'
+ },
+ {
+ question: 'Do you support only React currently?',
+ answer: 'Well, it is actually really easy!'
+ }
+]
+
+const FaqItem = ({ keyP, faq }) => {
+
+ const [isExpanded, setIsExpanded] = useState(false)
+
+ return (
+
+ Given .wasp and .js(x)/.css/..., source files,
+ Wasp compiler generates the full source of your web app in
+ the target stack - front-end, back-end and deployment.
+
+
+ >
+
+ )
+}
+
+export default Index
diff --git a/project-page/postcss.config.js b/project-page/postcss.config.js
new file mode 100644
index 000000000..33ad091d2
--- /dev/null
+++ b/project-page/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/project-page/public/favicon.ico b/project-page/public/favicon.ico
new file mode 100644
index 000000000..718d6fea4
Binary files /dev/null and b/project-page/public/favicon.ico differ
diff --git a/project-page/public/nodejs-logo-gray.svg b/project-page/public/nodejs-logo-gray.svg
new file mode 100644
index 000000000..1edd9147b
--- /dev/null
+++ b/project-page/public/nodejs-logo-gray.svg
@@ -0,0 +1,6 @@
+
diff --git a/project-page/public/prisma-logo-gray.svg b/project-page/public/prisma-logo-gray.svg
new file mode 100644
index 000000000..bff2892f1
--- /dev/null
+++ b/project-page/public/prisma-logo-gray.svg
@@ -0,0 +1,6 @@
+
diff --git a/project-page/public/react-logo-gray.svg b/project-page/public/react-logo-gray.svg
new file mode 100644
index 000000000..3704ad5db
--- /dev/null
+++ b/project-page/public/react-logo-gray.svg
@@ -0,0 +1,4 @@
+
diff --git a/project-page/public/showcase/amicus-landing.png b/project-page/public/showcase/amicus-landing.png
new file mode 100644
index 000000000..6169dbac9
Binary files /dev/null and b/project-page/public/showcase/amicus-landing.png differ
diff --git a/project-page/public/showcase/farnance-dashboard.png b/project-page/public/showcase/farnance-dashboard.png
new file mode 100644
index 000000000..56d9cbe98
Binary files /dev/null and b/project-page/public/showcase/farnance-dashboard.png differ
diff --git a/project-page/public/showcase/grabbit-hero.png b/project-page/public/showcase/grabbit-hero.png
new file mode 100644
index 000000000..e3bf5ffd5
Binary files /dev/null and b/project-page/public/showcase/grabbit-hero.png differ
diff --git a/project-page/public/vercel.svg b/project-page/public/vercel.svg
new file mode 100644
index 000000000..fbf0e25a6
--- /dev/null
+++ b/project-page/public/vercel.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/project-page/public/wasp-compilation-diagram.png b/project-page/public/wasp-compilation-diagram.png
new file mode 100644
index 000000000..1d6d93600
Binary files /dev/null and b/project-page/public/wasp-compilation-diagram.png differ
diff --git a/project-page/public/wasp-compilation-diagram.svg b/project-page/public/wasp-compilation-diagram.svg
new file mode 100644
index 000000000..c04eb67d2
--- /dev/null
+++ b/project-page/public/wasp-compilation-diagram.svg
@@ -0,0 +1,202 @@
+
+
\ No newline at end of file
diff --git a/project-page/public/wasp-logo.png b/project-page/public/wasp-logo.png
new file mode 100644
index 000000000..f85bb1606
Binary files /dev/null and b/project-page/public/wasp-logo.png differ
diff --git a/project-page/public/yc-logo.png b/project-page/public/yc-logo.png
new file mode 100644
index 000000000..54a668130
Binary files /dev/null and b/project-page/public/yc-logo.png differ
diff --git a/project-page/styles/Home.module.css b/project-page/styles/Home.module.css
new file mode 100644
index 000000000..95adc3991
--- /dev/null
+++ b/project-page/styles/Home.module.css
@@ -0,0 +1,131 @@
+.container {
+ padding: 0 2rem;
+}
+
+.main {
+ min-height: 100vh;
+ padding: 4rem 0;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.footer {
+ display: flex;
+ flex: 1;
+ padding: 2rem 0;
+ border-top: 1px solid #eaeaea;
+ justify-content: center;
+ align-items: center;
+}
+
+.footer a {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-grow: 1;
+}
+
+.title a {
+ color: #0070f3;
+ text-decoration: none;
+}
+
+.title a:hover,
+.title a:focus,
+.title a:active {
+ text-decoration: underline;
+}
+
+.title {
+ margin: 0;
+ line-height: 1.15;
+ font-size: 4rem;
+}
+
+.title,
+.description {
+ text-align: center;
+}
+
+.description {
+ margin: 4rem 0;
+ line-height: 1.5;
+ font-size: 1.5rem;
+}
+
+.code {
+ background: #fafafa;
+ border-radius: 5px;
+ padding: 0.75rem;
+ font-size: 1.1rem;
+ font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
+ Bitstream Vera Sans Mono, Courier New, monospace;
+}
+
+.grid {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-wrap: wrap;
+ max-width: 800px;
+}
+
+.card {
+ margin: 1rem;
+ padding: 1.5rem;
+ text-align: left;
+ color: inherit;
+ text-decoration: none;
+ border: 1px solid #eaeaea;
+ border-radius: 10px;
+ transition: color 0.15s ease, border-color 0.15s ease;
+ max-width: 300px;
+}
+
+.card:hover,
+.card:focus,
+.card:active {
+ color: #0070f3;
+ border-color: #0070f3;
+}
+
+.card h2 {
+ margin: 0 0 1rem 0;
+ font-size: 1.5rem;
+}
+
+.card p {
+ margin: 0;
+ font-size: 1.25rem;
+ line-height: 1.5;
+}
+
+.logo {
+ height: 1em;
+ margin-left: 0.5rem;
+}
+
+@media (max-width: 600px) {
+ .grid {
+ width: 100%;
+ flex-direction: column;
+ }
+}
+
+/*
+@media (prefers-color-scheme: dark) {
+ .card,
+ .footer {
+ border-color: #222;
+ }
+ .code {
+ background: #111;
+ }
+ .logo img {
+ filter: invert(1);
+ }
+}
+*/
diff --git a/project-page/styles/globals.css b/project-page/styles/globals.css
new file mode 100644
index 000000000..003e59e85
--- /dev/null
+++ b/project-page/styles/globals.css
@@ -0,0 +1,70 @@
+@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap');
+
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+/* Removes blue tap box over Button/Link on mobile.
+ * Issue on Tailwind's repo: https://github.com/tailwindlabs/tailwindcss/discussions/2984
+ */
+@layer base {
+ html {
+ -webkit-tap-highlight-color: transparent;
+ }
+}
+
+html,
+body {
+ padding: 0;
+ margin: 0;
+ /*
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
+ Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
+ */
+
+ /*
+ font-family: Inter;
+ */
+
+ /* Fading out dots */
+ /*
+ background: linear-gradient(180deg,hsla(0,0%,100%,0) 0,#fff 300px),
+ fixed 0 0 /20px 20px radial-gradient(#d1d1d1 1px,transparent 0),
+ fixed 10px 10px /20px 20px radial-gradient(#d1d1d1 1px,transparent 0)
+ */
+
+ /** Honeycomb pattern
+ *
+ background:
+ radial-gradient(circle farthest-side at 0% 50%,#fb1 23.5%,rgba(240,166,17,0) 0)21px 30px,
+ radial-gradient(circle farthest-side at 0% 50%,#B71 24%,rgba(240,166,17,0) 0)19px 30px,
+ linear-gradient(#fb1 14%,rgba(240,166,17,0) 0, rgba(240,166,17,0) 85%,#fb1 0)0 0,
+ linear-gradient(150deg,#fb1 24%,#B71 0,#B71 26%,rgba(240,166,17,0) 0,rgba(240,166,17,0) 74%,#B71 0,#B71 76%,#fb1 0)0 0,
+ linear-gradient(30deg,#fb1 24%,#B71 0,#B71 26%,rgba(240,166,17,0) 0,rgba(240,166,17,0) 74%,#B71 0,#B71 76%,#fb1 0)0 0,
+ linear-gradient(90deg,#B71 2%,#fb1 0,#fb1 98%,#B71 0%)0 0 #fb1;
+ background-size: 40px 60px;
+ */
+
+ background-color: #f5f5f5;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+/*
+@media (prefers-color-scheme: dark) {
+ html {
+ color-scheme: dark;
+ }
+ body {
+ color: white;
+ background: black;
+ }
+}
+*/
diff --git a/project-page/styles/index.module.css b/project-page/styles/index.module.css
new file mode 100644
index 000000000..f99c92114
--- /dev/null
+++ b/project-page/styles/index.module.css
@@ -0,0 +1,103 @@
+
+.sectionSkewed {
+ position: relative;
+ height: 100%;
+ width: 100%;
+ top: 0;
+ left: 0;
+ transform-origin: 100% 0;
+ transform: skewY(-2deg);
+ overflow: hidden;
+}
+
+.sectionSkewedContainer {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+}
+
+.leftLights::after {
+ content: "";
+ position: absolute;
+ pointer-events: none;
+ width: 1223px;
+ height: 912px;
+
+ width: 1200px;
+ height: 912px;
+
+ left: calc(50% - 1100px);
+ top: -10%;
+
+ background: radial-gradient(
+ 50% 50% at 50% 50%,
+ rgba(255, 214, 0, 0.2) 0%,
+ rgba(255, 168, 0, 0) 100%
+ );
+ will-change: filter;
+ mix-blend-mode: normal;
+}
+
+.lightsTwo::after {
+ content: "";
+ position: absolute;
+ pointer-events: none;
+ width: 1223px;
+ height: 912px;
+
+ width: 1200px;
+ height: 912px;
+
+ left: calc(50%);
+ top: 0px;
+
+ background: radial-gradient(
+ 50% 50% at 50% 50%,
+ rgba(255, 214, 0, 0.2) 0%,
+ rgba(255, 168, 0, 0) 100%
+ );
+ will-change: filter;
+ mix-blend-mode: normal;
+}
+
+/*
+.leftLights::before {
+ content: "";
+ position: absolute;
+ pointer-events: none;
+ width: 25%;
+ height: 900px;
+ left: -12.5%;
+ top: calc(50% - 900px / 2 + 151px);
+ opacity: 0.2;
+ background: linear-gradient(180deg, #77b8ff 0%, rgba(42, 138, 246, 0.4) 100%);
+ filter: blur(125px);
+ transform: rotate(-15deg);
+ border-bottom-left-radius: 25% 25%;
+ border-bottom-right-radius: 25% 25%;
+ border-top-left-radius: 100% 100%;
+ border-top-right-radius: 100% 100%;
+ z-index: 200;
+ will-change: filter;
+ mix-blend-mode: normal;
+}
+
+.leftLights::after {
+ content: "";
+ position: absolute;
+ pointer-events: none;
+ width: 40%;
+ height: 422px;
+ left: 0px;
+ top: calc(50% - 422px / 2 + 298px);
+ opacity: 0.5;
+ background: linear-gradient(
+ 180deg,
+ rgba(29, 92, 162, 0.2) 0%,
+ rgba(42, 138, 246, 0.4) 100%
+ );
+ filter: blur(125px);
+ will-change: filter;
+ mix-blend-mode: normal;
+}
+*/
diff --git a/project-page/tailwind.config.js b/project-page/tailwind.config.js
new file mode 100644
index 000000000..8c488c526
--- /dev/null
+++ b/project-page/tailwind.config.js
@@ -0,0 +1,16 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: [
+ "./pages/**/*.{js,ts,jsx,tsx}",
+ "./components/**/*.{js,ts,jsx,tsx}",
+ ],
+ darkMode: 'class',
+ theme: {
+ extend: {
+ fontFamily: {
+ sans: ['Inter']
+ }
+ },
+ },
+ plugins: [],
+}
diff --git a/project-page/yarn.lock b/project-page/yarn.lock
new file mode 100644
index 000000000..0769cc2cd
--- /dev/null
+++ b/project-page/yarn.lock
@@ -0,0 +1,2104 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@babel/runtime-corejs3@^7.10.2":
+ "integrity" "sha512-oWNn1ZlGde7b4i/3tnixpH9qI0bOAACiUs+KEES4UUCnsPjVWFlWdLV/iwJuPC2qp3EowbAqsm+0XqNwnwYhxA=="
+ "resolved" "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.19.6.tgz"
+ "version" "7.19.6"
+ dependencies:
+ "core-js-pure" "^3.25.1"
+ "regenerator-runtime" "^0.13.4"
+
+"@babel/runtime@^7.10.2", "@babel/runtime@^7.18.9", "@babel/runtime@^7.3.1":
+ "integrity" "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA=="
+ "resolved" "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz"
+ "version" "7.19.4"
+ dependencies:
+ "regenerator-runtime" "^0.13.4"
+
+"@eslint/eslintrc@^1.3.3":
+ "integrity" "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg=="
+ "resolved" "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz"
+ "version" "1.3.3"
+ dependencies:
+ "ajv" "^6.12.4"
+ "debug" "^4.3.2"
+ "espree" "^9.4.0"
+ "globals" "^13.15.0"
+ "ignore" "^5.2.0"
+ "import-fresh" "^3.2.1"
+ "js-yaml" "^4.1.0"
+ "minimatch" "^3.1.2"
+ "strip-json-comments" "^3.1.1"
+
+"@humanwhocodes/config-array@^0.10.5":
+ "integrity" "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w=="
+ "resolved" "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz"
+ "version" "0.10.7"
+ dependencies:
+ "@humanwhocodes/object-schema" "^1.2.1"
+ "debug" "^4.1.1"
+ "minimatch" "^3.0.4"
+
+"@humanwhocodes/module-importer@^1.0.1":
+ "integrity" "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="
+ "resolved" "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz"
+ "version" "1.0.1"
+
+"@humanwhocodes/object-schema@^1.2.1":
+ "integrity" "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
+ "resolved" "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz"
+ "version" "1.2.1"
+
+"@next/env@12.3.1":
+ "integrity" "sha512-9P9THmRFVKGKt9DYqeC2aKIxm8rlvkK38V1P1sRE7qyoPBIs8l9oo79QoSdPtOWfzkbDAVUqvbQGgTMsb8BtJg=="
+ "resolved" "https://registry.npmjs.org/@next/env/-/env-12.3.1.tgz"
+ "version" "12.3.1"
+
+"@next/eslint-plugin-next@12.3.1":
+ "integrity" "sha512-sw+lTf6r6P0j+g/n9y4qdWWI2syPqZx+uc0+B/fRENqfR3KpSid6MIKqc9gNwGhJASazEQ5b3w8h4cAET213jw=="
+ "resolved" "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-12.3.1.tgz"
+ "version" "12.3.1"
+ dependencies:
+ "glob" "7.1.7"
+
+"@next/swc-darwin-x64@12.3.1":
+ "integrity" "sha512-9S6EVueCVCyGf2vuiLiGEHZCJcPAxglyckTZcEwLdJwozLqN0gtS0Eq0bQlGS3dH49Py/rQYpZ3KVWZ9BUf/WA=="
+ "resolved" "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.3.1.tgz"
+ "version" "12.3.1"
+
+"@nodelib/fs.scandir@2.1.5":
+ "integrity" "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="
+ "resolved" "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz"
+ "version" "2.1.5"
+ dependencies:
+ "@nodelib/fs.stat" "2.0.5"
+ "run-parallel" "^1.1.9"
+
+"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5":
+ "integrity" "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="
+ "resolved" "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
+ "version" "2.0.5"
+
+"@nodelib/fs.walk@^1.2.3":
+ "integrity" "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="
+ "resolved" "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz"
+ "version" "1.2.8"
+ dependencies:
+ "@nodelib/fs.scandir" "2.1.5"
+ "fastq" "^1.6.0"
+
+"@rushstack/eslint-patch@^1.1.3":
+ "integrity" "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg=="
+ "resolved" "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz"
+ "version" "1.2.0"
+
+"@swc/helpers@0.4.11":
+ "integrity" "sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw=="
+ "resolved" "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.11.tgz"
+ "version" "0.4.11"
+ dependencies:
+ "tslib" "^2.4.0"
+
+"@types/hast@^2.0.0":
+ "integrity" "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g=="
+ "resolved" "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz"
+ "version" "2.3.4"
+ dependencies:
+ "@types/unist" "*"
+
+"@types/json5@^0.0.29":
+ "integrity" "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
+ "resolved" "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
+ "version" "0.0.29"
+
+"@types/unist@*":
+ "integrity" "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
+ "resolved" "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz"
+ "version" "2.0.6"
+
+"@typescript-eslint/parser@^5.21.0":
+ "integrity" "sha512-IK6x55va5w4YvXd4b3VrXQPldV9vQTxi5ov+g4pMANsXPTXOcfjx08CRR1Dfrcc51syPtXHF5bgLlMHYFrvQtg=="
+ "resolved" "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.1.tgz"
+ "version" "5.40.1"
+ dependencies:
+ "@typescript-eslint/scope-manager" "5.40.1"
+ "@typescript-eslint/types" "5.40.1"
+ "@typescript-eslint/typescript-estree" "5.40.1"
+ "debug" "^4.3.4"
+
+"@typescript-eslint/scope-manager@5.40.1":
+ "integrity" "sha512-jkn4xsJiUQucI16OLCXrLRXDZ3afKhOIqXs4R3O+M00hdQLKR58WuyXPZZjhKLFCEP2g+TXdBRtLQ33UfAdRUg=="
+ "resolved" "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.1.tgz"
+ "version" "5.40.1"
+ dependencies:
+ "@typescript-eslint/types" "5.40.1"
+ "@typescript-eslint/visitor-keys" "5.40.1"
+
+"@typescript-eslint/types@5.40.1":
+ "integrity" "sha512-Icg9kiuVJSwdzSQvtdGspOlWNjVDnF3qVIKXdJ103o36yRprdl3Ge5cABQx+csx960nuMF21v8qvO31v9t3OHw=="
+ "resolved" "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.1.tgz"
+ "version" "5.40.1"
+
+"@typescript-eslint/typescript-estree@5.40.1":
+ "integrity" "sha512-5QTP/nW5+60jBcEPfXy/EZL01qrl9GZtbgDZtDPlfW5zj/zjNrdI2B5zMUHmOsfvOr2cWqwVdWjobCiHcedmQA=="
+ "resolved" "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.1.tgz"
+ "version" "5.40.1"
+ dependencies:
+ "@typescript-eslint/types" "5.40.1"
+ "@typescript-eslint/visitor-keys" "5.40.1"
+ "debug" "^4.3.4"
+ "globby" "^11.1.0"
+ "is-glob" "^4.0.3"
+ "semver" "^7.3.7"
+ "tsutils" "^3.21.0"
+
+"@typescript-eslint/visitor-keys@5.40.1":
+ "integrity" "sha512-A2DGmeZ+FMja0geX5rww+DpvILpwo1OsiQs0M+joPWJYsiEFBLsH0y1oFymPNul6Z5okSmHpP4ivkc2N0Cgfkw=="
+ "resolved" "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.1.tgz"
+ "version" "5.40.1"
+ dependencies:
+ "@typescript-eslint/types" "5.40.1"
+ "eslint-visitor-keys" "^3.3.0"
+
+"acorn-jsx@^5.3.2":
+ "integrity" "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="
+ "resolved" "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
+ "version" "5.3.2"
+
+"acorn-node@^1.8.2":
+ "integrity" "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A=="
+ "resolved" "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz"
+ "version" "1.8.2"
+ dependencies:
+ "acorn" "^7.0.0"
+ "acorn-walk" "^7.0.0"
+ "xtend" "^4.0.2"
+
+"acorn-walk@^7.0.0":
+ "integrity" "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA=="
+ "resolved" "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz"
+ "version" "7.2.0"
+
+"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", "acorn@^8.8.0":
+ "integrity" "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w=="
+ "resolved" "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz"
+ "version" "8.8.0"
+
+"acorn@^7.0.0":
+ "integrity" "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
+ "resolved" "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz"
+ "version" "7.4.1"
+
+"ajv@^6.10.0", "ajv@^6.12.4":
+ "integrity" "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="
+ "resolved" "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
+ "version" "6.12.6"
+ dependencies:
+ "fast-deep-equal" "^3.1.1"
+ "fast-json-stable-stringify" "^2.0.0"
+ "json-schema-traverse" "^0.4.1"
+ "uri-js" "^4.2.2"
+
+"ansi-regex@^5.0.1":
+ "integrity" "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
+ "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
+ "version" "5.0.1"
+
+"ansi-styles@^4.1.0":
+ "integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="
+ "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
+ "version" "4.3.0"
+ dependencies:
+ "color-convert" "^2.0.1"
+
+"anymatch@~3.1.2":
+ "integrity" "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg=="
+ "resolved" "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz"
+ "version" "3.1.2"
+ dependencies:
+ "normalize-path" "^3.0.0"
+ "picomatch" "^2.0.4"
+
+"arg@^5.0.2":
+ "integrity" "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
+ "resolved" "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz"
+ "version" "5.0.2"
+
+"argparse@^2.0.1":
+ "integrity" "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+ "resolved" "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz"
+ "version" "2.0.1"
+
+"aria-query@^4.2.2":
+ "integrity" "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA=="
+ "resolved" "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz"
+ "version" "4.2.2"
+ dependencies:
+ "@babel/runtime" "^7.10.2"
+ "@babel/runtime-corejs3" "^7.10.2"
+
+"array-includes@^3.1.4", "array-includes@^3.1.5":
+ "integrity" "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ=="
+ "resolved" "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz"
+ "version" "3.1.5"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "define-properties" "^1.1.4"
+ "es-abstract" "^1.19.5"
+ "get-intrinsic" "^1.1.1"
+ "is-string" "^1.0.7"
+
+"array-union@^2.1.0":
+ "integrity" "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="
+ "resolved" "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz"
+ "version" "2.1.0"
+
+"array.prototype.flat@^1.2.5":
+ "integrity" "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw=="
+ "resolved" "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz"
+ "version" "1.3.0"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "define-properties" "^1.1.3"
+ "es-abstract" "^1.19.2"
+ "es-shim-unscopables" "^1.0.0"
+
+"array.prototype.flatmap@^1.3.0":
+ "integrity" "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg=="
+ "resolved" "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz"
+ "version" "1.3.0"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "define-properties" "^1.1.3"
+ "es-abstract" "^1.19.2"
+ "es-shim-unscopables" "^1.0.0"
+
+"ast-types-flow@^0.0.7":
+ "integrity" "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag=="
+ "resolved" "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz"
+ "version" "0.0.7"
+
+"autoprefixer@^10.4.12":
+ "integrity" "sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q=="
+ "resolved" "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.12.tgz"
+ "version" "10.4.12"
+ dependencies:
+ "browserslist" "^4.21.4"
+ "caniuse-lite" "^1.0.30001407"
+ "fraction.js" "^4.2.0"
+ "normalize-range" "^0.1.2"
+ "picocolors" "^1.0.0"
+ "postcss-value-parser" "^4.2.0"
+
+"axe-core@^4.4.3":
+ "integrity" "sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w=="
+ "resolved" "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz"
+ "version" "4.4.3"
+
+"axobject-query@^2.2.0":
+ "integrity" "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA=="
+ "resolved" "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz"
+ "version" "2.2.0"
+
+"balanced-match@^1.0.0":
+ "integrity" "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
+ "version" "1.0.2"
+
+"binary-extensions@^2.0.0":
+ "integrity" "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
+ "resolved" "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz"
+ "version" "2.2.0"
+
+"brace-expansion@^1.1.7":
+ "integrity" "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="
+ "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
+ "version" "1.1.11"
+ dependencies:
+ "balanced-match" "^1.0.0"
+ "concat-map" "0.0.1"
+
+"braces@^3.0.2", "braces@~3.0.2":
+ "integrity" "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A=="
+ "resolved" "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz"
+ "version" "3.0.2"
+ dependencies:
+ "fill-range" "^7.0.1"
+
+"browserslist@^4.21.4", "browserslist@>= 4.21.0":
+ "integrity" "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw=="
+ "resolved" "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz"
+ "version" "4.21.4"
+ dependencies:
+ "caniuse-lite" "^1.0.30001400"
+ "electron-to-chromium" "^1.4.251"
+ "node-releases" "^2.0.6"
+ "update-browserslist-db" "^1.0.9"
+
+"call-bind@^1.0.0", "call-bind@^1.0.2":
+ "integrity" "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA=="
+ "resolved" "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz"
+ "version" "1.0.2"
+ dependencies:
+ "function-bind" "^1.1.1"
+ "get-intrinsic" "^1.0.2"
+
+"callsites@^3.0.0":
+ "integrity" "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
+ "resolved" "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
+ "version" "3.1.0"
+
+"camelcase-css@^2.0.1":
+ "integrity" "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="
+ "resolved" "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz"
+ "version" "2.0.1"
+
+"caniuse-lite@^1.0.30001400", "caniuse-lite@^1.0.30001406", "caniuse-lite@^1.0.30001407":
+ "integrity" "sha512-09iwWGOlifvE1XuHokFMP7eR38a0JnajoyL3/i87c8ZjRWRrdKo1fqjNfugfBD0UDBIOz0U+jtNhJ0EPm1VleQ=="
+ "resolved" "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001423.tgz"
+ "version" "1.0.30001423"
+
+"chalk@^4.0.0":
+ "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="
+ "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
+ "version" "4.1.2"
+ dependencies:
+ "ansi-styles" "^4.1.0"
+ "supports-color" "^7.1.0"
+
+"character-entities-legacy@^1.0.0":
+ "integrity" "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA=="
+ "resolved" "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz"
+ "version" "1.1.4"
+
+"character-entities@^1.0.0":
+ "integrity" "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw=="
+ "resolved" "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz"
+ "version" "1.2.4"
+
+"character-reference-invalid@^1.0.0":
+ "integrity" "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg=="
+ "resolved" "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz"
+ "version" "1.1.4"
+
+"chokidar@^3.5.3":
+ "integrity" "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw=="
+ "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz"
+ "version" "3.5.3"
+ dependencies:
+ "anymatch" "~3.1.2"
+ "braces" "~3.0.2"
+ "glob-parent" "~5.1.2"
+ "is-binary-path" "~2.1.0"
+ "is-glob" "~4.0.1"
+ "normalize-path" "~3.0.0"
+ "readdirp" "~3.6.0"
+ optionalDependencies:
+ "fsevents" "~2.3.2"
+
+"classnames@^2.3.2":
+ "integrity" "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
+ "resolved" "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz"
+ "version" "2.3.2"
+
+"color-convert@^2.0.1":
+ "integrity" "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="
+ "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
+ "version" "2.0.1"
+ dependencies:
+ "color-name" "~1.1.4"
+
+"color-name@^1.1.4", "color-name@~1.1.4":
+ "integrity" "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
+ "version" "1.1.4"
+
+"comma-separated-tokens@^1.0.0":
+ "integrity" "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw=="
+ "resolved" "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz"
+ "version" "1.0.8"
+
+"concat-map@0.0.1":
+ "integrity" "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ "resolved" "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ "version" "0.0.1"
+
+"core-js-pure@^3.25.1":
+ "integrity" "sha512-oml3M22pHM+igfWHDfdLVq2ShWmjM2V4L+dQEBs0DWVIqEm9WHCwGAlZ6BmyBQGy5sFrJmcx+856D9lVKyGWYg=="
+ "resolved" "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.5.tgz"
+ "version" "3.25.5"
+
+"cross-spawn@^7.0.2":
+ "integrity" "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w=="
+ "resolved" "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
+ "version" "7.0.3"
+ dependencies:
+ "path-key" "^3.1.0"
+ "shebang-command" "^2.0.0"
+ "which" "^2.0.1"
+
+"cssesc@^3.0.0":
+ "integrity" "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="
+ "resolved" "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz"
+ "version" "3.0.0"
+
+"damerau-levenshtein@^1.0.8":
+ "integrity" "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="
+ "resolved" "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz"
+ "version" "1.0.8"
+
+"debug@^2.6.9":
+ "integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="
+ "resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
+ "version" "2.6.9"
+ dependencies:
+ "ms" "2.0.0"
+
+"debug@^3.2.7":
+ "integrity" "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="
+ "resolved" "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
+ "version" "3.2.7"
+ dependencies:
+ "ms" "^2.1.1"
+
+"debug@^4.1.1", "debug@^4.3.2", "debug@^4.3.4":
+ "integrity" "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="
+ "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
+ "version" "4.3.4"
+ dependencies:
+ "ms" "2.1.2"
+
+"deep-is@^0.1.3":
+ "integrity" "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
+ "resolved" "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz"
+ "version" "0.1.4"
+
+"define-properties@^1.1.3", "define-properties@^1.1.4":
+ "integrity" "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA=="
+ "resolved" "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz"
+ "version" "1.1.4"
+ dependencies:
+ "has-property-descriptors" "^1.0.0"
+ "object-keys" "^1.1.1"
+
+"defined@^1.0.0":
+ "integrity" "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q=="
+ "resolved" "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz"
+ "version" "1.0.1"
+
+"detective@^5.2.1":
+ "integrity" "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw=="
+ "resolved" "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz"
+ "version" "5.2.1"
+ dependencies:
+ "acorn-node" "^1.8.2"
+ "defined" "^1.0.0"
+ "minimist" "^1.2.6"
+
+"didyoumean@^1.2.2":
+ "integrity" "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="
+ "resolved" "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz"
+ "version" "1.2.2"
+
+"dir-glob@^3.0.1":
+ "integrity" "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="
+ "resolved" "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz"
+ "version" "3.0.1"
+ dependencies:
+ "path-type" "^4.0.0"
+
+"dlv@^1.1.3":
+ "integrity" "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
+ "resolved" "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz"
+ "version" "1.1.3"
+
+"doctrine@^2.1.0":
+ "integrity" "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="
+ "resolved" "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz"
+ "version" "2.1.0"
+ dependencies:
+ "esutils" "^2.0.2"
+
+"doctrine@^3.0.0":
+ "integrity" "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="
+ "resolved" "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz"
+ "version" "3.0.0"
+ dependencies:
+ "esutils" "^2.0.2"
+
+"electron-to-chromium@^1.4.251":
+ "integrity" "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA=="
+ "resolved" "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz"
+ "version" "1.4.284"
+
+"emoji-regex@^9.2.2":
+ "integrity" "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
+ "resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz"
+ "version" "9.2.2"
+
+"es-abstract@^1.19.0", "es-abstract@^1.19.1", "es-abstract@^1.19.2", "es-abstract@^1.19.5":
+ "integrity" "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA=="
+ "resolved" "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz"
+ "version" "1.20.4"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "es-to-primitive" "^1.2.1"
+ "function-bind" "^1.1.1"
+ "function.prototype.name" "^1.1.5"
+ "get-intrinsic" "^1.1.3"
+ "get-symbol-description" "^1.0.0"
+ "has" "^1.0.3"
+ "has-property-descriptors" "^1.0.0"
+ "has-symbols" "^1.0.3"
+ "internal-slot" "^1.0.3"
+ "is-callable" "^1.2.7"
+ "is-negative-zero" "^2.0.2"
+ "is-regex" "^1.1.4"
+ "is-shared-array-buffer" "^1.0.2"
+ "is-string" "^1.0.7"
+ "is-weakref" "^1.0.2"
+ "object-inspect" "^1.12.2"
+ "object-keys" "^1.1.1"
+ "object.assign" "^4.1.4"
+ "regexp.prototype.flags" "^1.4.3"
+ "safe-regex-test" "^1.0.0"
+ "string.prototype.trimend" "^1.0.5"
+ "string.prototype.trimstart" "^1.0.5"
+ "unbox-primitive" "^1.0.2"
+
+"es-shim-unscopables@^1.0.0":
+ "integrity" "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w=="
+ "resolved" "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz"
+ "version" "1.0.0"
+ dependencies:
+ "has" "^1.0.3"
+
+"es-to-primitive@^1.2.1":
+ "integrity" "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA=="
+ "resolved" "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz"
+ "version" "1.2.1"
+ dependencies:
+ "is-callable" "^1.1.4"
+ "is-date-object" "^1.0.1"
+ "is-symbol" "^1.0.2"
+
+"escalade@^3.1.1":
+ "integrity" "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
+ "resolved" "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz"
+ "version" "3.1.1"
+
+"escape-string-regexp@^4.0.0":
+ "integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
+ "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
+ "version" "4.0.0"
+
+"eslint-config-next@12.3.1":
+ "integrity" "sha512-EN/xwKPU6jz1G0Qi6Bd/BqMnHLyRAL0VsaQaWA7F3KkjAgZHi4f1uL1JKGWNxdQpHTW/sdGONBd0bzxUka/DJg=="
+ "resolved" "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-12.3.1.tgz"
+ "version" "12.3.1"
+ dependencies:
+ "@next/eslint-plugin-next" "12.3.1"
+ "@rushstack/eslint-patch" "^1.1.3"
+ "@typescript-eslint/parser" "^5.21.0"
+ "eslint-import-resolver-node" "^0.3.6"
+ "eslint-import-resolver-typescript" "^2.7.1"
+ "eslint-plugin-import" "^2.26.0"
+ "eslint-plugin-jsx-a11y" "^6.5.1"
+ "eslint-plugin-react" "^7.31.7"
+ "eslint-plugin-react-hooks" "^4.5.0"
+
+"eslint-import-resolver-node@^0.3.6":
+ "integrity" "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw=="
+ "resolved" "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz"
+ "version" "0.3.6"
+ dependencies:
+ "debug" "^3.2.7"
+ "resolve" "^1.20.0"
+
+"eslint-import-resolver-typescript@^2.7.1":
+ "integrity" "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ=="
+ "resolved" "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz"
+ "version" "2.7.1"
+ dependencies:
+ "debug" "^4.3.4"
+ "glob" "^7.2.0"
+ "is-glob" "^4.0.3"
+ "resolve" "^1.22.0"
+ "tsconfig-paths" "^3.14.1"
+
+"eslint-module-utils@^2.7.3":
+ "integrity" "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA=="
+ "resolved" "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz"
+ "version" "2.7.4"
+ dependencies:
+ "debug" "^3.2.7"
+
+"eslint-plugin-import@*", "eslint-plugin-import@^2.26.0":
+ "integrity" "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA=="
+ "resolved" "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz"
+ "version" "2.26.0"
+ dependencies:
+ "array-includes" "^3.1.4"
+ "array.prototype.flat" "^1.2.5"
+ "debug" "^2.6.9"
+ "doctrine" "^2.1.0"
+ "eslint-import-resolver-node" "^0.3.6"
+ "eslint-module-utils" "^2.7.3"
+ "has" "^1.0.3"
+ "is-core-module" "^2.8.1"
+ "is-glob" "^4.0.3"
+ "minimatch" "^3.1.2"
+ "object.values" "^1.1.5"
+ "resolve" "^1.22.0"
+ "tsconfig-paths" "^3.14.1"
+
+"eslint-plugin-jsx-a11y@^6.5.1":
+ "integrity" "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q=="
+ "resolved" "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz"
+ "version" "6.6.1"
+ dependencies:
+ "@babel/runtime" "^7.18.9"
+ "aria-query" "^4.2.2"
+ "array-includes" "^3.1.5"
+ "ast-types-flow" "^0.0.7"
+ "axe-core" "^4.4.3"
+ "axobject-query" "^2.2.0"
+ "damerau-levenshtein" "^1.0.8"
+ "emoji-regex" "^9.2.2"
+ "has" "^1.0.3"
+ "jsx-ast-utils" "^3.3.2"
+ "language-tags" "^1.0.5"
+ "minimatch" "^3.1.2"
+ "semver" "^6.3.0"
+
+"eslint-plugin-react-hooks@^4.5.0":
+ "integrity" "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g=="
+ "resolved" "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz"
+ "version" "4.6.0"
+
+"eslint-plugin-react@^7.31.7":
+ "integrity" "sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA=="
+ "resolved" "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz"
+ "version" "7.31.10"
+ dependencies:
+ "array-includes" "^3.1.5"
+ "array.prototype.flatmap" "^1.3.0"
+ "doctrine" "^2.1.0"
+ "estraverse" "^5.3.0"
+ "jsx-ast-utils" "^2.4.1 || ^3.0.0"
+ "minimatch" "^3.1.2"
+ "object.entries" "^1.1.5"
+ "object.fromentries" "^2.0.5"
+ "object.hasown" "^1.1.1"
+ "object.values" "^1.1.5"
+ "prop-types" "^15.8.1"
+ "resolve" "^2.0.0-next.3"
+ "semver" "^6.3.0"
+ "string.prototype.matchall" "^4.0.7"
+
+"eslint-scope@^7.1.1":
+ "integrity" "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw=="
+ "resolved" "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz"
+ "version" "7.1.1"
+ dependencies:
+ "esrecurse" "^4.3.0"
+ "estraverse" "^5.2.0"
+
+"eslint-utils@^3.0.0":
+ "integrity" "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA=="
+ "resolved" "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz"
+ "version" "3.0.0"
+ dependencies:
+ "eslint-visitor-keys" "^2.0.0"
+
+"eslint-visitor-keys@^2.0.0":
+ "integrity" "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw=="
+ "resolved" "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz"
+ "version" "2.1.0"
+
+"eslint-visitor-keys@^3.3.0":
+ "integrity" "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA=="
+ "resolved" "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz"
+ "version" "3.3.0"
+
+"eslint@*", "eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^7.23.0 || ^8.0.0", "eslint@>=5", "eslint@8.25.0":
+ "integrity" "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A=="
+ "resolved" "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz"
+ "version" "8.25.0"
+ dependencies:
+ "@eslint/eslintrc" "^1.3.3"
+ "@humanwhocodes/config-array" "^0.10.5"
+ "@humanwhocodes/module-importer" "^1.0.1"
+ "ajv" "^6.10.0"
+ "chalk" "^4.0.0"
+ "cross-spawn" "^7.0.2"
+ "debug" "^4.3.2"
+ "doctrine" "^3.0.0"
+ "escape-string-regexp" "^4.0.0"
+ "eslint-scope" "^7.1.1"
+ "eslint-utils" "^3.0.0"
+ "eslint-visitor-keys" "^3.3.0"
+ "espree" "^9.4.0"
+ "esquery" "^1.4.0"
+ "esutils" "^2.0.2"
+ "fast-deep-equal" "^3.1.3"
+ "file-entry-cache" "^6.0.1"
+ "find-up" "^5.0.0"
+ "glob-parent" "^6.0.1"
+ "globals" "^13.15.0"
+ "globby" "^11.1.0"
+ "grapheme-splitter" "^1.0.4"
+ "ignore" "^5.2.0"
+ "import-fresh" "^3.0.0"
+ "imurmurhash" "^0.1.4"
+ "is-glob" "^4.0.0"
+ "js-sdsl" "^4.1.4"
+ "js-yaml" "^4.1.0"
+ "json-stable-stringify-without-jsonify" "^1.0.1"
+ "levn" "^0.4.1"
+ "lodash.merge" "^4.6.2"
+ "minimatch" "^3.1.2"
+ "natural-compare" "^1.4.0"
+ "optionator" "^0.9.1"
+ "regexpp" "^3.2.0"
+ "strip-ansi" "^6.0.1"
+ "strip-json-comments" "^3.1.0"
+ "text-table" "^0.2.0"
+
+"espree@^9.4.0":
+ "integrity" "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw=="
+ "resolved" "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz"
+ "version" "9.4.0"
+ dependencies:
+ "acorn" "^8.8.0"
+ "acorn-jsx" "^5.3.2"
+ "eslint-visitor-keys" "^3.3.0"
+
+"esquery@^1.4.0":
+ "integrity" "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w=="
+ "resolved" "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz"
+ "version" "1.4.0"
+ dependencies:
+ "estraverse" "^5.1.0"
+
+"esrecurse@^4.3.0":
+ "integrity" "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="
+ "resolved" "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz"
+ "version" "4.3.0"
+ dependencies:
+ "estraverse" "^5.2.0"
+
+"estraverse@^5.1.0", "estraverse@^5.2.0", "estraverse@^5.3.0":
+ "integrity" "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
+ "resolved" "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz"
+ "version" "5.3.0"
+
+"esutils@^2.0.2":
+ "integrity" "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
+ "resolved" "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz"
+ "version" "2.0.3"
+
+"fast-deep-equal@^3.1.1", "fast-deep-equal@^3.1.3":
+ "integrity" "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ "resolved" "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
+ "version" "3.1.3"
+
+"fast-glob@^3.2.12", "fast-glob@^3.2.9":
+ "integrity" "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w=="
+ "resolved" "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz"
+ "version" "3.2.12"
+ dependencies:
+ "@nodelib/fs.stat" "^2.0.2"
+ "@nodelib/fs.walk" "^1.2.3"
+ "glob-parent" "^5.1.2"
+ "merge2" "^1.3.0"
+ "micromatch" "^4.0.4"
+
+"fast-json-stable-stringify@^2.0.0":
+ "integrity" "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+ "resolved" "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
+ "version" "2.1.0"
+
+"fast-levenshtein@^2.0.6":
+ "integrity" "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
+ "resolved" "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
+ "version" "2.0.6"
+
+"fastq@^1.6.0":
+ "integrity" "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw=="
+ "resolved" "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz"
+ "version" "1.13.0"
+ dependencies:
+ "reusify" "^1.0.4"
+
+"fault@^1.0.0":
+ "integrity" "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA=="
+ "resolved" "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz"
+ "version" "1.0.4"
+ dependencies:
+ "format" "^0.2.0"
+
+"file-entry-cache@^6.0.1":
+ "integrity" "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg=="
+ "resolved" "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz"
+ "version" "6.0.1"
+ dependencies:
+ "flat-cache" "^3.0.4"
+
+"fill-range@^7.0.1":
+ "integrity" "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ=="
+ "resolved" "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz"
+ "version" "7.0.1"
+ dependencies:
+ "to-regex-range" "^5.0.1"
+
+"find-up@^5.0.0":
+ "integrity" "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="
+ "resolved" "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz"
+ "version" "5.0.0"
+ dependencies:
+ "locate-path" "^6.0.0"
+ "path-exists" "^4.0.0"
+
+"flat-cache@^3.0.4":
+ "integrity" "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg=="
+ "resolved" "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz"
+ "version" "3.0.4"
+ dependencies:
+ "flatted" "^3.1.0"
+ "rimraf" "^3.0.2"
+
+"flatted@^3.1.0":
+ "integrity" "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ=="
+ "resolved" "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz"
+ "version" "3.2.7"
+
+"format@^0.2.0":
+ "integrity" "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww=="
+ "resolved" "https://registry.npmjs.org/format/-/format-0.2.2.tgz"
+ "version" "0.2.2"
+
+"fraction.js@^4.2.0":
+ "integrity" "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA=="
+ "resolved" "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz"
+ "version" "4.2.0"
+
+"fs.realpath@^1.0.0":
+ "integrity" "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ "resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
+ "version" "1.0.0"
+
+"fsevents@~2.3.2":
+ "integrity" "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="
+ "resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz"
+ "version" "2.3.2"
+
+"function-bind@^1.1.1":
+ "integrity" "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ "resolved" "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
+ "version" "1.1.1"
+
+"function.prototype.name@^1.1.5":
+ "integrity" "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA=="
+ "resolved" "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz"
+ "version" "1.1.5"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "define-properties" "^1.1.3"
+ "es-abstract" "^1.19.0"
+ "functions-have-names" "^1.2.2"
+
+"functions-have-names@^1.2.2":
+ "integrity" "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="
+ "resolved" "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz"
+ "version" "1.2.3"
+
+"get-intrinsic@^1.0.2", "get-intrinsic@^1.1.0", "get-intrinsic@^1.1.1", "get-intrinsic@^1.1.3":
+ "integrity" "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A=="
+ "resolved" "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz"
+ "version" "1.1.3"
+ dependencies:
+ "function-bind" "^1.1.1"
+ "has" "^1.0.3"
+ "has-symbols" "^1.0.3"
+
+"get-symbol-description@^1.0.0":
+ "integrity" "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw=="
+ "resolved" "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz"
+ "version" "1.0.0"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "get-intrinsic" "^1.1.1"
+
+"glob-parent@^5.1.2":
+ "integrity" "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="
+ "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
+ "version" "5.1.2"
+ dependencies:
+ "is-glob" "^4.0.1"
+
+"glob-parent@^6.0.1", "glob-parent@^6.0.2":
+ "integrity" "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="
+ "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz"
+ "version" "6.0.2"
+ dependencies:
+ "is-glob" "^4.0.3"
+
+"glob-parent@~5.1.2":
+ "integrity" "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="
+ "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
+ "version" "5.1.2"
+ dependencies:
+ "is-glob" "^4.0.1"
+
+"glob@^7.1.3", "glob@^7.2.0":
+ "integrity" "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="
+ "resolved" "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz"
+ "version" "7.2.3"
+ dependencies:
+ "fs.realpath" "^1.0.0"
+ "inflight" "^1.0.4"
+ "inherits" "2"
+ "minimatch" "^3.1.1"
+ "once" "^1.3.0"
+ "path-is-absolute" "^1.0.0"
+
+"glob@7.1.7":
+ "integrity" "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ=="
+ "resolved" "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz"
+ "version" "7.1.7"
+ dependencies:
+ "fs.realpath" "^1.0.0"
+ "inflight" "^1.0.4"
+ "inherits" "2"
+ "minimatch" "^3.0.4"
+ "once" "^1.3.0"
+ "path-is-absolute" "^1.0.0"
+
+"globals@^13.15.0":
+ "integrity" "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw=="
+ "resolved" "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz"
+ "version" "13.17.0"
+ dependencies:
+ "type-fest" "^0.20.2"
+
+"globby@^11.1.0":
+ "integrity" "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="
+ "resolved" "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz"
+ "version" "11.1.0"
+ dependencies:
+ "array-union" "^2.1.0"
+ "dir-glob" "^3.0.1"
+ "fast-glob" "^3.2.9"
+ "ignore" "^5.2.0"
+ "merge2" "^1.4.1"
+ "slash" "^3.0.0"
+
+"grapheme-splitter@^1.0.4":
+ "integrity" "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ=="
+ "resolved" "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz"
+ "version" "1.0.4"
+
+"has-bigints@^1.0.1", "has-bigints@^1.0.2":
+ "integrity" "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ=="
+ "resolved" "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz"
+ "version" "1.0.2"
+
+"has-flag@^4.0.0":
+ "integrity" "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+ "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
+ "version" "4.0.0"
+
+"has-property-descriptors@^1.0.0":
+ "integrity" "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ=="
+ "resolved" "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz"
+ "version" "1.0.0"
+ dependencies:
+ "get-intrinsic" "^1.1.1"
+
+"has-symbols@^1.0.2", "has-symbols@^1.0.3":
+ "integrity" "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
+ "resolved" "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz"
+ "version" "1.0.3"
+
+"has-tostringtag@^1.0.0":
+ "integrity" "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ=="
+ "resolved" "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz"
+ "version" "1.0.0"
+ dependencies:
+ "has-symbols" "^1.0.2"
+
+"has@^1.0.3":
+ "integrity" "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw=="
+ "resolved" "https://registry.npmjs.org/has/-/has-1.0.3.tgz"
+ "version" "1.0.3"
+ dependencies:
+ "function-bind" "^1.1.1"
+
+"hast-util-parse-selector@^2.0.0":
+ "integrity" "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ=="
+ "resolved" "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz"
+ "version" "2.2.5"
+
+"hastscript@^6.0.0":
+ "integrity" "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w=="
+ "resolved" "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz"
+ "version" "6.0.0"
+ dependencies:
+ "@types/hast" "^2.0.0"
+ "comma-separated-tokens" "^1.0.0"
+ "hast-util-parse-selector" "^2.0.0"
+ "property-information" "^5.0.0"
+ "space-separated-tokens" "^1.0.0"
+
+"highlight.js@^10.4.1", "highlight.js@~10.7.0":
+ "integrity" "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="
+ "resolved" "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz"
+ "version" "10.7.3"
+
+"ignore@^5.2.0":
+ "integrity" "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ=="
+ "resolved" "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz"
+ "version" "5.2.0"
+
+"import-fresh@^3.0.0", "import-fresh@^3.2.1":
+ "integrity" "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw=="
+ "resolved" "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
+ "version" "3.3.0"
+ dependencies:
+ "parent-module" "^1.0.0"
+ "resolve-from" "^4.0.0"
+
+"imurmurhash@^0.1.4":
+ "integrity" "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="
+ "resolved" "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz"
+ "version" "0.1.4"
+
+"inflight@^1.0.4":
+ "integrity" "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="
+ "resolved" "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
+ "version" "1.0.6"
+ dependencies:
+ "once" "^1.3.0"
+ "wrappy" "1"
+
+"inherits@2":
+ "integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
+ "version" "2.0.4"
+
+"internal-slot@^1.0.3":
+ "integrity" "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA=="
+ "resolved" "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz"
+ "version" "1.0.3"
+ dependencies:
+ "get-intrinsic" "^1.1.0"
+ "has" "^1.0.3"
+ "side-channel" "^1.0.4"
+
+"is-alphabetical@^1.0.0":
+ "integrity" "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg=="
+ "resolved" "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz"
+ "version" "1.0.4"
+
+"is-alphanumerical@^1.0.0":
+ "integrity" "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A=="
+ "resolved" "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz"
+ "version" "1.0.4"
+ dependencies:
+ "is-alphabetical" "^1.0.0"
+ "is-decimal" "^1.0.0"
+
+"is-bigint@^1.0.1":
+ "integrity" "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg=="
+ "resolved" "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz"
+ "version" "1.0.4"
+ dependencies:
+ "has-bigints" "^1.0.1"
+
+"is-binary-path@~2.1.0":
+ "integrity" "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="
+ "resolved" "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz"
+ "version" "2.1.0"
+ dependencies:
+ "binary-extensions" "^2.0.0"
+
+"is-boolean-object@^1.1.0":
+ "integrity" "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA=="
+ "resolved" "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz"
+ "version" "1.1.2"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "has-tostringtag" "^1.0.0"
+
+"is-callable@^1.1.4", "is-callable@^1.2.7":
+ "integrity" "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="
+ "resolved" "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz"
+ "version" "1.2.7"
+
+"is-core-module@^2.8.1", "is-core-module@^2.9.0":
+ "integrity" "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw=="
+ "resolved" "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz"
+ "version" "2.11.0"
+ dependencies:
+ "has" "^1.0.3"
+
+"is-date-object@^1.0.1":
+ "integrity" "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ=="
+ "resolved" "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz"
+ "version" "1.0.5"
+ dependencies:
+ "has-tostringtag" "^1.0.0"
+
+"is-decimal@^1.0.0":
+ "integrity" "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw=="
+ "resolved" "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz"
+ "version" "1.0.4"
+
+"is-extglob@^2.1.1":
+ "integrity" "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
+ "resolved" "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
+ "version" "2.1.1"
+
+"is-glob@^4.0.0", "is-glob@^4.0.1", "is-glob@^4.0.3", "is-glob@~4.0.1":
+ "integrity" "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="
+ "resolved" "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz"
+ "version" "4.0.3"
+ dependencies:
+ "is-extglob" "^2.1.1"
+
+"is-hexadecimal@^1.0.0":
+ "integrity" "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw=="
+ "resolved" "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz"
+ "version" "1.0.4"
+
+"is-negative-zero@^2.0.2":
+ "integrity" "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA=="
+ "resolved" "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz"
+ "version" "2.0.2"
+
+"is-number-object@^1.0.4":
+ "integrity" "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ=="
+ "resolved" "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz"
+ "version" "1.0.7"
+ dependencies:
+ "has-tostringtag" "^1.0.0"
+
+"is-number@^7.0.0":
+ "integrity" "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+ "resolved" "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
+ "version" "7.0.0"
+
+"is-regex@^1.1.4":
+ "integrity" "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg=="
+ "resolved" "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz"
+ "version" "1.1.4"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "has-tostringtag" "^1.0.0"
+
+"is-shared-array-buffer@^1.0.2":
+ "integrity" "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA=="
+ "resolved" "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz"
+ "version" "1.0.2"
+ dependencies:
+ "call-bind" "^1.0.2"
+
+"is-string@^1.0.5", "is-string@^1.0.7":
+ "integrity" "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg=="
+ "resolved" "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz"
+ "version" "1.0.7"
+ dependencies:
+ "has-tostringtag" "^1.0.0"
+
+"is-symbol@^1.0.2", "is-symbol@^1.0.3":
+ "integrity" "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg=="
+ "resolved" "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz"
+ "version" "1.0.4"
+ dependencies:
+ "has-symbols" "^1.0.2"
+
+"is-weakref@^1.0.2":
+ "integrity" "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ=="
+ "resolved" "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz"
+ "version" "1.0.2"
+ dependencies:
+ "call-bind" "^1.0.2"
+
+"isexe@^2.0.0":
+ "integrity" "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
+ "resolved" "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
+ "version" "2.0.0"
+
+"js-sdsl@^4.1.4":
+ "integrity" "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q=="
+ "resolved" "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz"
+ "version" "4.1.5"
+
+"js-tokens@^3.0.0 || ^4.0.0":
+ "integrity" "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ "resolved" "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
+ "version" "4.0.0"
+
+"js-yaml@^4.1.0":
+ "integrity" "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="
+ "resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz"
+ "version" "4.1.0"
+ dependencies:
+ "argparse" "^2.0.1"
+
+"json-schema-traverse@^0.4.1":
+ "integrity" "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ "resolved" "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz"
+ "version" "0.4.1"
+
+"json-stable-stringify-without-jsonify@^1.0.1":
+ "integrity" "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="
+ "resolved" "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
+ "version" "1.0.1"
+
+"json5@^1.0.1":
+ "integrity" "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow=="
+ "resolved" "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz"
+ "version" "1.0.1"
+ dependencies:
+ "minimist" "^1.2.0"
+
+"jsx-ast-utils@^2.4.1 || ^3.0.0", "jsx-ast-utils@^3.3.2":
+ "integrity" "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw=="
+ "resolved" "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz"
+ "version" "3.3.3"
+ dependencies:
+ "array-includes" "^3.1.5"
+ "object.assign" "^4.1.3"
+
+"language-subtag-registry@~0.3.2":
+ "integrity" "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w=="
+ "resolved" "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz"
+ "version" "0.3.22"
+
+"language-tags@^1.0.5":
+ "integrity" "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ=="
+ "resolved" "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz"
+ "version" "1.0.5"
+ dependencies:
+ "language-subtag-registry" "~0.3.2"
+
+"levn@^0.4.1":
+ "integrity" "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="
+ "resolved" "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz"
+ "version" "0.4.1"
+ dependencies:
+ "prelude-ls" "^1.2.1"
+ "type-check" "~0.4.0"
+
+"lilconfig@^2.0.5", "lilconfig@^2.0.6":
+ "integrity" "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg=="
+ "resolved" "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz"
+ "version" "2.0.6"
+
+"locate-path@^6.0.0":
+ "integrity" "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="
+ "resolved" "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz"
+ "version" "6.0.0"
+ dependencies:
+ "p-locate" "^5.0.0"
+
+"lodash.merge@^4.6.2":
+ "integrity" "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
+ "resolved" "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
+ "version" "4.6.2"
+
+"loose-envify@^1.1.0", "loose-envify@^1.4.0":
+ "integrity" "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="
+ "resolved" "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
+ "version" "1.4.0"
+ dependencies:
+ "js-tokens" "^3.0.0 || ^4.0.0"
+
+"lowlight@^1.17.0":
+ "integrity" "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw=="
+ "resolved" "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz"
+ "version" "1.20.0"
+ dependencies:
+ "fault" "^1.0.0"
+ "highlight.js" "~10.7.0"
+
+"lru-cache@^6.0.0":
+ "integrity" "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="
+ "resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz"
+ "version" "6.0.0"
+ dependencies:
+ "yallist" "^4.0.0"
+
+"merge2@^1.3.0", "merge2@^1.4.1":
+ "integrity" "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
+ "resolved" "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
+ "version" "1.4.1"
+
+"micromatch@^4.0.4":
+ "integrity" "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA=="
+ "resolved" "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz"
+ "version" "4.0.5"
+ dependencies:
+ "braces" "^3.0.2"
+ "picomatch" "^2.3.1"
+
+"minimatch@^3.0.4", "minimatch@^3.1.1", "minimatch@^3.1.2":
+ "integrity" "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="
+ "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
+ "version" "3.1.2"
+ dependencies:
+ "brace-expansion" "^1.1.7"
+
+"minimist@^1.2.0", "minimist@^1.2.6":
+ "integrity" "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g=="
+ "resolved" "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz"
+ "version" "1.2.7"
+
+"ms@^2.1.1":
+ "integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
+ "version" "2.1.3"
+
+"ms@2.0.0":
+ "integrity" "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ "resolved" "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
+ "version" "2.0.0"
+
+"ms@2.1.2":
+ "integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
+ "version" "2.1.2"
+
+"nanoid@^3.3.4":
+ "integrity" "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
+ "resolved" "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz"
+ "version" "3.3.4"
+
+"natural-compare@^1.4.0":
+ "integrity" "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
+ "resolved" "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
+ "version" "1.4.0"
+
+"next@12.3.1":
+ "integrity" "sha512-l7bvmSeIwX5lp07WtIiP9u2ytZMv7jIeB8iacR28PuUEFG5j0HGAPnMqyG5kbZNBG2H7tRsrQ4HCjuMOPnANZw=="
+ "resolved" "https://registry.npmjs.org/next/-/next-12.3.1.tgz"
+ "version" "12.3.1"
+ dependencies:
+ "@next/env" "12.3.1"
+ "@swc/helpers" "0.4.11"
+ "caniuse-lite" "^1.0.30001406"
+ "postcss" "8.4.14"
+ "styled-jsx" "5.0.7"
+ "use-sync-external-store" "1.2.0"
+ optionalDependencies:
+ "@next/swc-android-arm-eabi" "12.3.1"
+ "@next/swc-android-arm64" "12.3.1"
+ "@next/swc-darwin-arm64" "12.3.1"
+ "@next/swc-darwin-x64" "12.3.1"
+ "@next/swc-freebsd-x64" "12.3.1"
+ "@next/swc-linux-arm-gnueabihf" "12.3.1"
+ "@next/swc-linux-arm64-gnu" "12.3.1"
+ "@next/swc-linux-arm64-musl" "12.3.1"
+ "@next/swc-linux-x64-gnu" "12.3.1"
+ "@next/swc-linux-x64-musl" "12.3.1"
+ "@next/swc-win32-arm64-msvc" "12.3.1"
+ "@next/swc-win32-ia32-msvc" "12.3.1"
+ "@next/swc-win32-x64-msvc" "12.3.1"
+
+"node-releases@^2.0.6":
+ "integrity" "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg=="
+ "resolved" "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz"
+ "version" "2.0.6"
+
+"normalize-path@^3.0.0", "normalize-path@~3.0.0":
+ "integrity" "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
+ "resolved" "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz"
+ "version" "3.0.0"
+
+"normalize-range@^0.1.2":
+ "integrity" "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="
+ "resolved" "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz"
+ "version" "0.1.2"
+
+"object-assign@^4.1.1":
+ "integrity" "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
+ "resolved" "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
+ "version" "4.1.1"
+
+"object-hash@^3.0.0":
+ "integrity" "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="
+ "resolved" "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz"
+ "version" "3.0.0"
+
+"object-inspect@^1.12.2", "object-inspect@^1.9.0":
+ "integrity" "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
+ "resolved" "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz"
+ "version" "1.12.2"
+
+"object-keys@^1.1.1":
+ "integrity" "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
+ "resolved" "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz"
+ "version" "1.1.1"
+
+"object.assign@^4.1.3", "object.assign@^4.1.4":
+ "integrity" "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ=="
+ "resolved" "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz"
+ "version" "4.1.4"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "define-properties" "^1.1.4"
+ "has-symbols" "^1.0.3"
+ "object-keys" "^1.1.1"
+
+"object.entries@^1.1.5":
+ "integrity" "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g=="
+ "resolved" "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz"
+ "version" "1.1.5"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "define-properties" "^1.1.3"
+ "es-abstract" "^1.19.1"
+
+"object.fromentries@^2.0.5":
+ "integrity" "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw=="
+ "resolved" "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz"
+ "version" "2.0.5"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "define-properties" "^1.1.3"
+ "es-abstract" "^1.19.1"
+
+"object.hasown@^1.1.1":
+ "integrity" "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A=="
+ "resolved" "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz"
+ "version" "1.1.1"
+ dependencies:
+ "define-properties" "^1.1.4"
+ "es-abstract" "^1.19.5"
+
+"object.values@^1.1.5":
+ "integrity" "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg=="
+ "resolved" "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz"
+ "version" "1.1.5"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "define-properties" "^1.1.3"
+ "es-abstract" "^1.19.1"
+
+"once@^1.3.0":
+ "integrity" "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="
+ "resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
+ "version" "1.4.0"
+ dependencies:
+ "wrappy" "1"
+
+"optionator@^0.9.1":
+ "integrity" "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw=="
+ "resolved" "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz"
+ "version" "0.9.1"
+ dependencies:
+ "deep-is" "^0.1.3"
+ "fast-levenshtein" "^2.0.6"
+ "levn" "^0.4.1"
+ "prelude-ls" "^1.2.1"
+ "type-check" "^0.4.0"
+ "word-wrap" "^1.2.3"
+
+"p-limit@^3.0.2":
+ "integrity" "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="
+ "resolved" "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz"
+ "version" "3.1.0"
+ dependencies:
+ "yocto-queue" "^0.1.0"
+
+"p-locate@^5.0.0":
+ "integrity" "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="
+ "resolved" "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz"
+ "version" "5.0.0"
+ dependencies:
+ "p-limit" "^3.0.2"
+
+"parent-module@^1.0.0":
+ "integrity" "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="
+ "resolved" "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
+ "version" "1.0.1"
+ dependencies:
+ "callsites" "^3.0.0"
+
+"parse-entities@^2.0.0":
+ "integrity" "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ=="
+ "resolved" "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz"
+ "version" "2.0.0"
+ dependencies:
+ "character-entities" "^1.0.0"
+ "character-entities-legacy" "^1.0.0"
+ "character-reference-invalid" "^1.0.0"
+ "is-alphanumerical" "^1.0.0"
+ "is-decimal" "^1.0.0"
+ "is-hexadecimal" "^1.0.0"
+
+"path-exists@^4.0.0":
+ "integrity" "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
+ "resolved" "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz"
+ "version" "4.0.0"
+
+"path-is-absolute@^1.0.0":
+ "integrity" "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
+ "resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
+ "version" "1.0.1"
+
+"path-key@^3.1.0":
+ "integrity" "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
+ "resolved" "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
+ "version" "3.1.1"
+
+"path-parse@^1.0.7":
+ "integrity" "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ "resolved" "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
+ "version" "1.0.7"
+
+"path-type@^4.0.0":
+ "integrity" "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
+ "resolved" "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz"
+ "version" "4.0.0"
+
+"picocolors@^1.0.0":
+ "integrity" "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+ "resolved" "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
+ "version" "1.0.0"
+
+"picomatch@^2.0.4", "picomatch@^2.2.1", "picomatch@^2.3.1":
+ "integrity" "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
+ "resolved" "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
+ "version" "2.3.1"
+
+"pify@^2.3.0":
+ "integrity" "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="
+ "resolved" "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz"
+ "version" "2.3.0"
+
+"postcss-import@^14.1.0":
+ "integrity" "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw=="
+ "resolved" "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz"
+ "version" "14.1.0"
+ dependencies:
+ "postcss-value-parser" "^4.0.0"
+ "read-cache" "^1.0.0"
+ "resolve" "^1.1.7"
+
+"postcss-js@^4.0.0":
+ "integrity" "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ=="
+ "resolved" "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz"
+ "version" "4.0.0"
+ dependencies:
+ "camelcase-css" "^2.0.1"
+
+"postcss-load-config@^3.1.4":
+ "integrity" "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg=="
+ "resolved" "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz"
+ "version" "3.1.4"
+ dependencies:
+ "lilconfig" "^2.0.5"
+ "yaml" "^1.10.2"
+
+"postcss-nested@6.0.0":
+ "integrity" "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w=="
+ "resolved" "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz"
+ "version" "6.0.0"
+ dependencies:
+ "postcss-selector-parser" "^6.0.10"
+
+"postcss-selector-parser@^6.0.10":
+ "integrity" "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="
+ "resolved" "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz"
+ "version" "6.0.10"
+ dependencies:
+ "cssesc" "^3.0.0"
+ "util-deprecate" "^1.0.2"
+
+"postcss-value-parser@^4.0.0", "postcss-value-parser@^4.2.0":
+ "integrity" "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
+ "resolved" "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
+ "version" "4.2.0"
+
+"postcss@^8.0.0", "postcss@^8.1.0", "postcss@^8.2.14", "postcss@^8.3.3", "postcss@^8.4.17", "postcss@^8.4.18", "postcss@>=8.0.9":
+ "integrity" "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA=="
+ "resolved" "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz"
+ "version" "8.4.18"
+ dependencies:
+ "nanoid" "^3.3.4"
+ "picocolors" "^1.0.0"
+ "source-map-js" "^1.0.2"
+
+"postcss@8.4.14":
+ "integrity" "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig=="
+ "resolved" "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz"
+ "version" "8.4.14"
+ dependencies:
+ "nanoid" "^3.3.4"
+ "picocolors" "^1.0.0"
+ "source-map-js" "^1.0.2"
+
+"prelude-ls@^1.2.1":
+ "integrity" "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="
+ "resolved" "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"
+ "version" "1.2.1"
+
+"prismjs@^1.27.0":
+ "integrity" "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q=="
+ "resolved" "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz"
+ "version" "1.29.0"
+
+"prismjs@~1.27.0":
+ "integrity" "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA=="
+ "resolved" "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz"
+ "version" "1.27.0"
+
+"prop-types@^15.7.2", "prop-types@^15.8.1":
+ "integrity" "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="
+ "resolved" "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
+ "version" "15.8.1"
+ dependencies:
+ "loose-envify" "^1.4.0"
+ "object-assign" "^4.1.1"
+ "react-is" "^16.13.1"
+
+"property-information@^5.0.0":
+ "integrity" "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA=="
+ "resolved" "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz"
+ "version" "5.6.0"
+ dependencies:
+ "xtend" "^4.0.0"
+
+"punycode@^2.1.0":
+ "integrity" "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+ "resolved" "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz"
+ "version" "2.1.1"
+
+"queue-microtask@^1.2.2":
+ "integrity" "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
+ "resolved" "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
+ "version" "1.2.3"
+
+"quick-lru@^5.1.1":
+ "integrity" "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="
+ "resolved" "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz"
+ "version" "5.1.1"
+
+"react-dom@^17.0.2 || ^18.0.0-0", "react-dom@18.2.0":
+ "integrity" "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g=="
+ "resolved" "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
+ "version" "18.2.0"
+ dependencies:
+ "loose-envify" "^1.1.0"
+ "scheduler" "^0.23.0"
+
+"react-feather@^2.0.10":
+ "integrity" "sha512-BLhukwJ+Z92Nmdcs+EMw6dy1Z/VLiJTzEQACDUEnWMClhYnFykJCGWQx+NmwP/qQHGX/5CzQ+TGi8ofg2+HzVQ=="
+ "resolved" "https://registry.npmjs.org/react-feather/-/react-feather-2.0.10.tgz"
+ "version" "2.0.10"
+ dependencies:
+ "prop-types" "^15.7.2"
+
+"react-is@^16.13.1":
+ "integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ "resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
+ "version" "16.13.1"
+
+"react-syntax-highlighter@^15.5.0":
+ "integrity" "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg=="
+ "resolved" "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz"
+ "version" "15.5.0"
+ dependencies:
+ "@babel/runtime" "^7.3.1"
+ "highlight.js" "^10.4.1"
+ "lowlight" "^1.17.0"
+ "prismjs" "^1.27.0"
+ "refractor" "^3.6.0"
+
+"react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^17.0.2 || ^18.0.0-0", "react@^18.2.0", "react@>= 0.14.0", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", "react@>=16.8.6", "react@18.2.0":
+ "integrity" "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ=="
+ "resolved" "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
+ "version" "18.2.0"
+ dependencies:
+ "loose-envify" "^1.1.0"
+
+"read-cache@^1.0.0":
+ "integrity" "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="
+ "resolved" "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz"
+ "version" "1.0.0"
+ dependencies:
+ "pify" "^2.3.0"
+
+"readdirp@~3.6.0":
+ "integrity" "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="
+ "resolved" "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz"
+ "version" "3.6.0"
+ dependencies:
+ "picomatch" "^2.2.1"
+
+"refractor@^3.6.0":
+ "integrity" "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA=="
+ "resolved" "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz"
+ "version" "3.6.0"
+ dependencies:
+ "hastscript" "^6.0.0"
+ "parse-entities" "^2.0.0"
+ "prismjs" "~1.27.0"
+
+"regenerator-runtime@^0.13.4":
+ "integrity" "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw=="
+ "resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz"
+ "version" "0.13.10"
+
+"regexp.prototype.flags@^1.4.1", "regexp.prototype.flags@^1.4.3":
+ "integrity" "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA=="
+ "resolved" "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz"
+ "version" "1.4.3"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "define-properties" "^1.1.3"
+ "functions-have-names" "^1.2.2"
+
+"regexpp@^3.2.0":
+ "integrity" "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg=="
+ "resolved" "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz"
+ "version" "3.2.0"
+
+"resolve-from@^4.0.0":
+ "integrity" "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
+ "resolved" "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
+ "version" "4.0.0"
+
+"resolve@^1.1.7", "resolve@^1.20.0", "resolve@^1.22.0", "resolve@^1.22.1":
+ "integrity" "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw=="
+ "resolved" "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz"
+ "version" "1.22.1"
+ dependencies:
+ "is-core-module" "^2.9.0"
+ "path-parse" "^1.0.7"
+ "supports-preserve-symlinks-flag" "^1.0.0"
+
+"resolve@^2.0.0-next.3":
+ "integrity" "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ=="
+ "resolved" "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz"
+ "version" "2.0.0-next.4"
+ dependencies:
+ "is-core-module" "^2.9.0"
+ "path-parse" "^1.0.7"
+ "supports-preserve-symlinks-flag" "^1.0.0"
+
+"reusify@^1.0.4":
+ "integrity" "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
+ "resolved" "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz"
+ "version" "1.0.4"
+
+"rimraf@^3.0.2":
+ "integrity" "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="
+ "resolved" "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz"
+ "version" "3.0.2"
+ dependencies:
+ "glob" "^7.1.3"
+
+"run-parallel@^1.1.9":
+ "integrity" "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="
+ "resolved" "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
+ "version" "1.2.0"
+ dependencies:
+ "queue-microtask" "^1.2.2"
+
+"safe-regex-test@^1.0.0":
+ "integrity" "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA=="
+ "resolved" "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz"
+ "version" "1.0.0"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "get-intrinsic" "^1.1.3"
+ "is-regex" "^1.1.4"
+
+"scheduler@^0.23.0":
+ "integrity" "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw=="
+ "resolved" "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz"
+ "version" "0.23.0"
+ dependencies:
+ "loose-envify" "^1.1.0"
+
+"semver@^6.3.0":
+ "integrity" "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ "resolved" "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
+ "version" "6.3.0"
+
+"semver@^7.3.7":
+ "integrity" "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A=="
+ "resolved" "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz"
+ "version" "7.3.8"
+ dependencies:
+ "lru-cache" "^6.0.0"
+
+"shebang-command@^2.0.0":
+ "integrity" "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="
+ "resolved" "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
+ "version" "2.0.0"
+ dependencies:
+ "shebang-regex" "^3.0.0"
+
+"shebang-regex@^3.0.0":
+ "integrity" "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
+ "resolved" "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
+ "version" "3.0.0"
+
+"side-channel@^1.0.4":
+ "integrity" "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw=="
+ "resolved" "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz"
+ "version" "1.0.4"
+ dependencies:
+ "call-bind" "^1.0.0"
+ "get-intrinsic" "^1.0.2"
+ "object-inspect" "^1.9.0"
+
+"slash@^3.0.0":
+ "integrity" "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
+ "resolved" "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
+ "version" "3.0.0"
+
+"source-map-js@^1.0.2":
+ "integrity" "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
+ "resolved" "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz"
+ "version" "1.0.2"
+
+"space-separated-tokens@^1.0.0":
+ "integrity" "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA=="
+ "resolved" "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz"
+ "version" "1.1.5"
+
+"string.prototype.matchall@^4.0.7":
+ "integrity" "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg=="
+ "resolved" "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz"
+ "version" "4.0.7"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "define-properties" "^1.1.3"
+ "es-abstract" "^1.19.1"
+ "get-intrinsic" "^1.1.1"
+ "has-symbols" "^1.0.3"
+ "internal-slot" "^1.0.3"
+ "regexp.prototype.flags" "^1.4.1"
+ "side-channel" "^1.0.4"
+
+"string.prototype.trimend@^1.0.5":
+ "integrity" "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog=="
+ "resolved" "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz"
+ "version" "1.0.5"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "define-properties" "^1.1.4"
+ "es-abstract" "^1.19.5"
+
+"string.prototype.trimstart@^1.0.5":
+ "integrity" "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg=="
+ "resolved" "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz"
+ "version" "1.0.5"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "define-properties" "^1.1.4"
+ "es-abstract" "^1.19.5"
+
+"strip-ansi@^6.0.1":
+ "integrity" "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="
+ "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
+ "version" "6.0.1"
+ dependencies:
+ "ansi-regex" "^5.0.1"
+
+"strip-bom@^3.0.0":
+ "integrity" "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="
+ "resolved" "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz"
+ "version" "3.0.0"
+
+"strip-json-comments@^3.1.0", "strip-json-comments@^3.1.1":
+ "integrity" "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
+ "resolved" "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz"
+ "version" "3.1.1"
+
+"styled-jsx@5.0.7":
+ "integrity" "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA=="
+ "resolved" "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.7.tgz"
+ "version" "5.0.7"
+
+"supports-color@^7.1.0":
+ "integrity" "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="
+ "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz"
+ "version" "7.2.0"
+ dependencies:
+ "has-flag" "^4.0.0"
+
+"supports-preserve-symlinks-flag@^1.0.0":
+ "integrity" "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
+ "resolved" "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
+ "version" "1.0.0"
+
+"tailwindcss@^3.2.0":
+ "integrity" "sha512-ARh/W0uH5UlWIC2nn02V0+5fyF0k6qZliyt4QYic2upOhPUE/Spu1EURNc9txJ3+4j8OEmdigqfDpw4d2tA4vA=="
+ "resolved" "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.0.tgz"
+ "version" "3.2.0"
+ dependencies:
+ "arg" "^5.0.2"
+ "chokidar" "^3.5.3"
+ "color-name" "^1.1.4"
+ "detective" "^5.2.1"
+ "didyoumean" "^1.2.2"
+ "dlv" "^1.1.3"
+ "fast-glob" "^3.2.12"
+ "glob-parent" "^6.0.2"
+ "is-glob" "^4.0.3"
+ "lilconfig" "^2.0.6"
+ "normalize-path" "^3.0.0"
+ "object-hash" "^3.0.0"
+ "picocolors" "^1.0.0"
+ "postcss" "^8.4.17"
+ "postcss-import" "^14.1.0"
+ "postcss-js" "^4.0.0"
+ "postcss-load-config" "^3.1.4"
+ "postcss-nested" "6.0.0"
+ "postcss-selector-parser" "^6.0.10"
+ "postcss-value-parser" "^4.2.0"
+ "quick-lru" "^5.1.1"
+ "resolve" "^1.22.1"
+
+"text-table@^0.2.0":
+ "integrity" "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="
+ "resolved" "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
+ "version" "0.2.0"
+
+"to-regex-range@^5.0.1":
+ "integrity" "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="
+ "resolved" "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz"
+ "version" "5.0.1"
+ dependencies:
+ "is-number" "^7.0.0"
+
+"tsconfig-paths@^3.14.1":
+ "integrity" "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ=="
+ "resolved" "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz"
+ "version" "3.14.1"
+ dependencies:
+ "@types/json5" "^0.0.29"
+ "json5" "^1.0.1"
+ "minimist" "^1.2.6"
+ "strip-bom" "^3.0.0"
+
+"tslib@^1.8.1":
+ "integrity" "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ "resolved" "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
+ "version" "1.14.1"
+
+"tslib@^2.4.0":
+ "integrity" "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
+ "resolved" "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz"
+ "version" "2.4.0"
+
+"tsutils@^3.21.0":
+ "integrity" "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA=="
+ "resolved" "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz"
+ "version" "3.21.0"
+ dependencies:
+ "tslib" "^1.8.1"
+
+"type-check@^0.4.0", "type-check@~0.4.0":
+ "integrity" "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="
+ "resolved" "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz"
+ "version" "0.4.0"
+ dependencies:
+ "prelude-ls" "^1.2.1"
+
+"type-fest@^0.20.2":
+ "integrity" "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="
+ "resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz"
+ "version" "0.20.2"
+
+"unbox-primitive@^1.0.2":
+ "integrity" "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw=="
+ "resolved" "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz"
+ "version" "1.0.2"
+ dependencies:
+ "call-bind" "^1.0.2"
+ "has-bigints" "^1.0.2"
+ "has-symbols" "^1.0.3"
+ "which-boxed-primitive" "^1.0.2"
+
+"update-browserslist-db@^1.0.9":
+ "integrity" "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ=="
+ "resolved" "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz"
+ "version" "1.0.10"
+ dependencies:
+ "escalade" "^3.1.1"
+ "picocolors" "^1.0.0"
+
+"uri-js@^4.2.2":
+ "integrity" "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="
+ "resolved" "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"
+ "version" "4.4.1"
+ dependencies:
+ "punycode" "^2.1.0"
+
+"use-sync-external-store@1.2.0":
+ "integrity" "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA=="
+ "resolved" "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz"
+ "version" "1.2.0"
+
+"util-deprecate@^1.0.2":
+ "integrity" "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ "resolved" "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ "version" "1.0.2"
+
+"which-boxed-primitive@^1.0.2":
+ "integrity" "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg=="
+ "resolved" "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz"
+ "version" "1.0.2"
+ dependencies:
+ "is-bigint" "^1.0.1"
+ "is-boolean-object" "^1.1.0"
+ "is-number-object" "^1.0.4"
+ "is-string" "^1.0.5"
+ "is-symbol" "^1.0.3"
+
+"which@^2.0.1":
+ "integrity" "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="
+ "resolved" "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
+ "version" "2.0.2"
+ dependencies:
+ "isexe" "^2.0.0"
+
+"word-wrap@^1.2.3":
+ "integrity" "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
+ "resolved" "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz"
+ "version" "1.2.3"
+
+"wrappy@1":
+ "integrity" "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ "resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ "version" "1.0.2"
+
+"xtend@^4.0.0", "xtend@^4.0.2":
+ "integrity" "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
+ "resolved" "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz"
+ "version" "4.0.2"
+
+"yallist@^4.0.0":
+ "integrity" "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ "resolved" "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
+ "version" "4.0.0"
+
+"yaml@^1.10.2":
+ "integrity" "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
+ "resolved" "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz"
+ "version" "1.10.2"
+
+"yocto-queue@^0.1.0":
+ "integrity" "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
+ "resolved" "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"
+ "version" "0.1.0"
diff --git a/waspc/README.md b/waspc/README.md
index 687d312c4..b0e7f5456 100644
--- a/waspc/README.md
+++ b/waspc/README.md
@@ -17,7 +17,7 @@ If you would like to make your first contribution, here is a handy checklist we
## Quick overview
-Wasp compiler is implemented in Haskell, but you will also see a lot of Javascript and other web technologies because Wasp compiler transpiles Wasp code into them.
+Wasp compiler is implemented in Haskell, but you will also see a lot of Javascript and other web technologies because Wasp compiles it's own code into them.
You don't have to be expert in Haskell to contribute or understand the code, since we don't use complicated Haskell features much -> most of the code is relatively simple and straight-forward, and we are happy to help with the part that is not.
diff --git a/web/.gitignore b/web/.gitignore
index b2d6de306..ed3fe720d 100644
--- a/web/.gitignore
+++ b/web/.gitignore
@@ -18,3 +18,4 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+.vercel
diff --git a/web/blog/2021-04-29-discord-bot-introduction.md b/web/blog/2021-04-29-discord-bot-introduction.md
index fbd4d6bff..a81f2ff26 100644
--- a/web/blog/2021-04-29-discord-bot-introduction.md
+++ b/web/blog/2021-04-29-discord-bot-introduction.md
@@ -212,6 +212,12 @@ and if you assign yourself a `Guest` role on the Discord server and then type `!
### Deploying the bot
+:::note
+Heroku used to offer free apps under certain limits. However, as of November 28, 2022, they ended support for their free tier. https://blog.heroku.com/next-chapter
+
+As such, we have updated our Deployment docs with new recommendations: https://wasp-lang.dev/docs/deploying
+:::
+
While there are many ways to deploy the Discord bot, I will shortly describe how we did it via Heroku.
We created a Heroku app `wasp-discord-bot` and set up the "Automatic deploys" feature on Heroku to automatically deploy every push to the `production` branch (our bot is on Github).
diff --git a/web/blog/2022-06-15-jobs-feature-announcement.md b/web/blog/2022-06-15-jobs-feature-announcement.md
index 464739c70..2cb69fb69 100644
--- a/web/blog/2022-06-15-jobs-feature-announcement.md
+++ b/web/blog/2022-06-15-jobs-feature-announcement.md
@@ -1,5 +1,5 @@
---
-title: Feature Release Announcement - Wasp Jobs
+title: Feature Announcement - Wasp Jobs
authors: [shayneczyzewski]
image: /img/jobs-snippet2.png
tags: [webdev, wasp, feature, jobs]
diff --git a/web/blog/2022-06-24-ML-code-gen-vs-coding-by-hand-future.md b/web/blog/2022-06-24-ML-code-gen-vs-coding-by-hand-future.md
index e6c4f5efd..5e4dee907 100644
--- a/web/blog/2022-06-24-ML-code-gen-vs-coding-by-hand-future.md
+++ b/web/blog/2022-06-24-ML-code-gen-vs-coding-by-hand-future.md
@@ -18,6 +18,12 @@ This is on our take on the situation and what we think things might look like in
+:::danger Trending post!
+
+This post was trending on HackerNews - you can see the discussion [here](https://news.ycombinator.com/item?id=32098144).
+
+:::
+
## Why (ML) code generation?
In order to make development faster, we came up with IDE autocompletion - e.g. if you are using React and start typing `componentDid`, IDE will automatically offer to complete it to `componentDidMount()` or `componentDidLoad()`. Besides saving keystrokes, maybe even more valuable is being able to see what methods/properties are available to us within a current scope. IDE being aware of the project structure and code hierarchy also makes refactoring much easier.
diff --git a/web/blog/2022-09-02-how-to-get-started-with-haskell-in-2022.md b/web/blog/2022-09-02-how-to-get-started-with-haskell-in-2022.md
index ef0c6325c..4ca1cba8e 100644
--- a/web/blog/2022-09-02-how-to-get-started-with-haskell-in-2022.md
+++ b/web/blog/2022-09-02-how-to-get-started-with-haskell-in-2022.md
@@ -1,7 +1,6 @@
---
title: How to get started with Haskell in 2022 (the straightforward way)
authors: [martinsos]
-image: /img/filip-headshot-min.jpeg
tags: [webdev, haskell, language]
---
@@ -12,11 +11,11 @@ import WaspIntro from './_wasp-intro.md';
import ImgWithCaption from './components/ImgWithCaption'
-Haskell is a unique and beautiful language that is worth learning, if for nothing else, then just for the concepts it introduces. They will expand your view on programming.
+Haskell is a unique and beautiful language that is worth learning, if for nothing else, then just for the concepts it introduces and their potential to expand your view on programming.
-I have been programming in Haskell on and off since 2011 and professionally for the past 2 years, building a [compiler](https://github.com/wasp-lang/wasp). While in that time Haskell has become much more beginner-friendly, I keep seeing beginners who are overwhelmed by numerous popular options for build tools, installers, introductory educational resources, and similar. [Haskellβs homepage](https://www.haskell.org/) getting a call from the previous decade to give them their UX back also doesnβt help.
+I have been programming in Haskell on and off since 2011 and professionally for the past 2 years, building a [compiler](https://github.com/wasp-lang/wasp). While in that time Haskell has become much more beginner-friendly, I keep seeing beginners who are overwhelmed by numerous popular options for build tools, installers, introductory educational resources, and similar. [Haskellβs homepage](https://www.haskell.org/) getting a call from the previous decade to give them their UX back :D also doesnβt help!
-That is why I decided to write this opinionated and practical post that will tell you exactly **how to get started with Haskell in 2022 in the most standard / common way.** Instead of worrying about decisions that you are not equipped to make at the moment (like βwhat is the best build tool Ifd??β), you can focus on enjoying learning Haskell :)!
+That is why I decided to write this opinionated and practical post that will tell you exactly how to get started with Haskell in 2022 in the most standard / common way. Instead of worrying about decisions that you are not equipped to make at the moment (e.g. βwhat is the best build tool?β), you can focus on enjoying learning Haskell :)!
@@ -76,13 +75,15 @@ If you don't like LYAH, consider other popular books for beginners (none of them
3. [Programming in Haskell](https://www.amazon.com/Programming-Haskell-Graham-Hutton/dp/1316626229)
Whatever book you go with, donβt get stuck for too long on concepts that are confusing to you, especially towards the end of the book. Some concepts will just need time to click; donβt expect to grasp it all on the first try. Whatever you do grasp from the first read will likely be more than enough to get going with your first projects in Haskell. You can always come back to those complex concepts later and understand them better. Also, donβt be shy to ask the community -> there are many Haskellers out there happy to support you in your learning!
-NOTE: When I say "don't get stuck", I don't mean you should skip the difficult concept after first hurdle. No, you should spend some hours experimenting, looking at it from different angles, playing with it, trying to crack it. But you shouldn't spend days trying to understand the same concept (e.g. function as a monad) and then feel defeated due to not grasping it 100%. Instead, if you put proper effort but stuff is not completely clicking, tap yourself on the back and move on for now.
+:::note
+When I say "don't get stuck", I don't mean you should skip the difficult concept after the first hurdle. No, you should spend some hours experimenting, looking at it from different angles, playing with it, trying to crack it. But you shouldn't spend days trying to understand the same concept (e.g. function as a monad) and then feel defeated due to not grasping it 100%. Instead, if you put proper effort but stuff is not completely clicking, tap yourself on the back and move on for now.
+:::
Once you take the first pass through the book, I recommend doing a project or two. You can come up with an idea yourself, or you can follow one of the books that guide you through it.
For example:
-1. [Learn Haskell by building a blog generator](https://lhbg-book.link/) -> free, starts from 0 knowledge, and could even be used as the very first resource
+1. [Learn Haskell by building a blog generator](https://lhbg-book.link/) -> free, starts from 0 knowledge, and could even be used as the very first resource, instead of e.g. LYAH.
2. [The Simple Haskell Handbook](https://marcosampellegrini.com/simple-haskell-book) -> not free, expects you to know the basics of Haskell already
Once you have more experience with projects, I would recommend re-reading your beginner book of choice. This time, you can skip the parts you already know and focus on what was confusing before. You will likely have a much easier time grasping those harder concepts.
diff --git a/web/blog/2022-09-05-dev-excuses-app-tutrial.md b/web/blog/2022-09-05-dev-excuses-app-tutrial.md
index 9161e7b36..e88a818c8 100644
--- a/web/blog/2022-09-05-dev-excuses-app-tutrial.md
+++ b/web/blog/2022-09-05-dev-excuses-app-tutrial.md
@@ -12,6 +12,7 @@ Weβll build a web app to solve every developer's most common problem β findi
Best excuse of all time! [Taken from here.](https://xkcd.com/303/)
+
## The requirements were unclear.
@@ -153,14 +154,8 @@ export const saveExcuse = async (excuse, context) => {
import axios from 'axios';
export const getExcuse = async () => {
- return axios
- .get('https://api.devexcus.es/')
- .then(res => {
- return res.data;
- })
- .catch(error => {
- console.error(error);
- });
+ const response = await axios.get('https://api.devexcus.es/')
+ return response.data
}
export const getAllSavedExcuses = async (_args, context) => {
diff --git a/web/blog/2022-09-29-journey-to-1000-gh-stars.md b/web/blog/2022-09-29-journey-to-1000-gh-stars.md
new file mode 100644
index 000000000..bda2ff8d1
--- /dev/null
+++ b/web/blog/2022-09-29-journey-to-1000-gh-stars.md
@@ -0,0 +1,163 @@
+---
+title: How Wasp reached 1,000 stars on GitHub (detailed stats & timeline)
+authors: [matijasos]
+image: /img/1000-gh-stars/1k_gh_stars_chart.png
+tags: [webdev, wasp, startups, github]
+---
+
+import Link from '@docusaurus/Link';
+import useBaseUrl from '@docusaurus/useBaseUrl';
+import InBlogCta from './components/InBlogCta';
+import WaspIntro from './_wasp-intro.md';
+import ImgWithCaption from './components/ImgWithCaption'
+
+
+Wasp is an open-source configuration language for building full-stack web apps that integrates with React & Node.js. We launched first prototype 2 years ago, currently are at 1.9k stars on GitHub and will be releasing Beta in the coming months.
+
+It was very hard for us to find and be able to learn from early inception stories of successful OSS projects and that's why we want to share what it looked like for Wasp.
+
+
+![1k stars chart](../static/img/1000-gh-stars/1k_gh_stars_chart.png)
+
+
+
+## Before the stars: Is this really a problem? (1 year)
+
+My co-founder and twin brother Martin and I got an initial idea for Wasp in 2018, while developing a web platform for running bioinformatics analysis in the cloud for one London-based startup.
+
+It was our third or fourth time creating a full-stack app from scratch with the latest & hottest stack. This time, it was React/Node.js; for our previous projects, we went through PHP/Java/Node.js on the back-end and jQuery/Backbone/Angular on the front-end. Because Martin and I felt we were spending a lot of time relearning how to use the latest stack just to build the same features all over again (auth, CRUD, forms, async jobs, etc.), we asked ourselves: *Why not abstract these common functionalities in a stack-agnostic, higher-level language (like e.g. SQL does for databases) to never reimplement them again?*
+
+Before we jumped into coding, we wanted to make sure this is a problem that actually exists and that we understand it well (enough). In our previous startup we found Customer Development (aka talking to users) extremely helpful, so we decided to do it again for Wasp.
+
+In a month or so we conducted 25 problem interviews, probing around βWhat is your biggest challenge with web app development?β After we compiled the results, we identified the following four problems as the most significant ones and decided to focus on them in our v1:
+
+- It is hard to **quickly start** a new web app and make sure **the best practices are being followed**.
+- There is a lot of duplication/boilerplate in **managing the state** across front-end, back-end, and the database.
+- A lot of **common features are re-implemented** for every new app.
+- Developers are overwhelmed by the **increasing tool complexity** and don't want to be responsible for managing it.
+
+We also clustered the answers we got by topics, so we could dive deeper and identify the areas that got the most attention:
+
+The reason why we stopped at 25 was that the answers started repeating themselves. We felt that we identified the initial patterns and were ready to move on.
+
+## 0-180 βοΈ: First Contact (7 months)
+After confirming and clarifying the problem with other developers, Martin and I felt we finally deserved to do some coding. (Ok, I admit, we had actually already started, but the interviews made us feel better about it π). We created a new repo on GitHub and started setting up the tooling & playing around with the concept.
+
+For the next couple of months, we treated Wasp as a side project/experiment and didnβt do any marketing. However, we were well aware of how crucial external feedback is. So, once we built a very rudimentary code generation functionality, we also created a project page that we could share with others to explain what weβre working on and ask for feedback.
+
+At that point, we came up with the first βrealβ name for Wasp - **STIC: Specification To Implementation Compiler**, as the big vision for Wasp was to be a stack-agnostic, specification language from which we could generate the actual code in e.g. React & Node.js or even some other stack.
+
+
+
+### Baby steps on Reddit and Hacker News
+
+Our preferred way of distributing STIC project page was through relevant subreddits - r/webdev, r/coding, r/javascript, r/Haskell, r/ProgrammingLanguages, β¦.
+
+[This](https://www.reddit.com/r/javascript/comments/f38h1t/askjs_we_are_developing_a_declarative_dsl_for/) was the first Reddit post weβve ever made about Wasp:
+
+
+
+One important thing we learned is that Reddit doesnβt like self-promotion. Sometimes, even if youβre only asking for feedback, the mods (and bots) will see it as self-promo and ban your post. It depends a lot on the mods, though. Reaching out to them and asking for explanation sometimes helps, but not very often. All subreddits have their own rules and guidelines that describe when or how it is OK to post about your project (e.g., /r/webdev has βShowoff Saturdaysβ), and we tried to follow them as best as we could.
+
+After Reddit, we also launched on HN. This was our first ever launch there! We scored 20 points and received a few motivating comments:
+
+
+
+### Listening to users
+Martin and I also followed up with the people we had previously interviewed about their problems in web dev. We showed them STIC project page and asked for comments. From all the feedback we captured, we identified the following issues:
+
+- **Developers were not familiar with a term βDSL.β** Almost all of us use a DSL on a daily basis (e.g., SQL, HCL (Terraform), HTML), but itβs not a popular term.
+- **Developers feared learning a new programming language**. Although our goal was never to replace e.g. Java or Typescript but to make Wasp work alongside it, we discovered that we had failed to communicate it well. Our messaging made developers feel they have to drop all their previous knowledge and start from scratch if they want to use Wasp.
+- **Nobody could try Wasp yet + there wasnβt any documentation besides the project page**. Our code was public, but we didnβt have a build/distribution system yet. Only a devoted Haskell developer could build it from the source. This made it hard for developers to buy into the high-level vision, as there was nothing they could hold onto. Web frameworks/languages are very βtactileβ β itβs hard to judge one without trying it out.
+
+## 180-300 βοΈ : Anybody can try Wasp out + Docs = Alpha! (3 months)
+After processing this feedback, we realized that the next step for us was to get Wasp into the condition where developers can easily try it out without needing any extra knowledge or facing the trouble of compiling from the source. That meant polishing things a bit, adding a few crucial features, and writing our first documentation, so that users would know how to use it.
+
+To write our docs, we picked [Docusaurus](https://docusaurus.io/) β an OSS writing platform made by Facebook. We saw several other OSS projects using it for their docs + its ability to import React in your markdown was amazing. Docusaurus gave us a lot of initial structure, design and features (e.g., search), saving us from reinventing the wheel.
+
+
+
+Our M.O. at the time was to focus pretty much exclusively on one thing, either development or community. Since Wasp team consisted of only Martin and me, it was really hard to do multiple things at once. After the docs were out and Wasp was ready to be easily downloaded, we called this version βAlphaβ and switched once again into the βcommunityβ mode.
+
+## 300-570 βοΈ : Big break on Reddit and Product Hunt (2 months)
+
+Once Alpha was out, we [launched again on HackerNews](https://news.ycombinator.com/submitted?id=matijash) and drew a bit of attention (34 upvotes and 3 comments). However, that was little compared to our Reddit launches, where we scored 263 upvotes on [r/javascript](https://www.reddit.com/r/javascript/comments/jvv1yg/together_with_my_brother_ive_been_working_on_wasp/) and 365 upvotes on [r/reactjs](https://www.reddit.com/r/reactjs/comments/jx5fyg/together_with_my_brother_ive_been_working_on_wasp/):
+
+
+
+Compared to the volume of attention and feedback weβve been previously receiving, this was a big surprise for us! Here are some of the changes in messaging that we made for the Reddit launches:
+
+- **Put prefix βdeclarativeβ in front of the βlanguageβ** to convey that itβs not a regular programming language like Python or Javascript but rather something much more lightweight and specialized.
+- **Emphasized that Wasp is not a standalone language that will replace your current stack** but rather a βglueβ between your React & Node.js code, allowing you to keep using your favourite stack.
+- **Focused on the benefits like βless boilerplate,β** which is a well known pain in web development.
+
+:::tip Docs made the difference
+
+Once we added the docs, we noticed a peculiar thing: **developers became much less trigger-happy to criticize the project, especially in a non-constructive way**. Our feeling was the majority of developers who were checking Wasp out still didnβt read the docs in detail (or at all), but the sheer existence of them made them feel there is more content they should go through before passing the final judgment.
+
+:::
+
+### Winning #1 Product of The Day on Product Hunt
+
+After HN and Reddit, we continued with the βAlpha launchβ mindset and set ourselves to launch Wasp on Product Hunt. It was our first time ever launching on PH, so we didnβt know what to expect. We googled some advice, did maybe a week of preparation (i.e., wrote the copy, asked a few friends to share their experiences with Wasp once weβre live), and that was it.
+
+We launched [Wasp on PH on Dec 6, 2020](https://www.producthunt.com/products/wasp-lang-alpha#wasp-lang-alpha) and it ended up as Product of the day! That gave us a boost in stars and overall traction. Another benefit of PH was that Wasp also ended up in their daily newsletter, which supposedly has over a million subscribers. All this gave us quite a boost and visibility increase.
+
+
+
+## 570-1000 βοΈ : Wasp joins YC + βOfficialβ HN launch (2.5 months)
+
+Soon after Product Hunt, Wasp joined Y Combinator for their W21 batch. We had applied two times before and always made it to the interviews, but did not get in. This time, the traction tipped the scales in our favour. (You can read more about our journey to YC [here](https://wasp-lang.dev/blog/2021/02/23/journey-to-ycombinator).)
+
+For the first month of YC, there was a lot of admin and setup work to deal with alongside the regular program. That added a third dimension to our existing two areas of effort. Once we went past that, we could again put more focus on product and community development.
+
+Our next milestone was to launch Wasp on Hacker News, but this time βofficiallyβ as a YC-backed company. **Hacker News provides a lot of [good tips](https://news.ycombinator.com/yli.html) on how to successfully launch and 80% of the advice applies even if your product isnβt backed by YC**. I wish I had known about it before. The gist of the advice is to write in a clear and succinct way and to avoid buzzwords, superlatives, and salesy tone above all. Consider HN readers as your peers and explain what you do in a way you would talk to a friend over a drink. It really works that way.
+
+We went through the several iterations of the text, sweated over how itβs gonna go, and when the day finally came β we launched! It went beyond all our expectations. With 222 points and 79 comments, **our HN launch was one of the most successful launches (#9) out of 300+ companies in the W21 batch.** Many developers and VCs that checked our launch afterwards were surprised how much positive feedback Wasp received, especially given how honest and direct HN audience can be.
+
+**HN launch brought us about 200 stars right away**, and the rest came in the following weeks. As it was February and the YC program was nearing its end, we needed to shift gears again and focus on fundraising. This put all the other efforts on the back burner. (You can read about our fundraising learnings from 250+ meetings in 98 days [here](https://wasp-lang.dev/blog/2021/11/22/fundraising-learnings).) But the interest of the community remained and even without much activity from our side they kept coming and trying Wasp out.
+
+
+
+## Conclusion: understanding users > number of stars
+
+Our primary goal was never to reach X stars, but rather to understand how we can make Wasp more helpful so that developers would want to use it for their projects. As you could read above, even well before we started a repository we made sure to talk to developers and learn about their problems.
+
+We also kept continually improving how we present Wasp - had we not pivoted our message from *βWasp is a new programming languageβ* to *βWasp is a simple config language that works alongside React & Node.jsβ* we wouldnβt have been where we are today.
+
+On the other hand, stars have become an unofficial βcurrencyβ of GitHub and developers and VCs alike consider it when evaluating a project. They shouldnβt be disregarded and you should make it easy for users who like your product to express their support by starring your repo (like Iβm doing right [here](https://github.com/wasp-lang/wasp)), but that should always be a second order of concern.
+
+## Good luck!
+
+I hope you found this helpful and that we shed some light on how things can look like in the early stages of an OSS project. Also, keep in mind this was our singular experience and that every story is different, so take everything with a grain of salt and pick only what makes sense for you and your product.
+
+We wish you the best of luck and feel free to reach out if you'll have any questions!
diff --git a/web/blog/2022-10-28-farnance-hackathon-winner.md b/web/blog/2022-10-28-farnance-hackathon-winner.md
new file mode 100644
index 000000000..41129528c
--- /dev/null
+++ b/web/blog/2022-10-28-farnance-hackathon-winner.md
@@ -0,0 +1,75 @@
+---
+title: 'Farnance: How Julian built a SaaS for farmers with Wasp and won a hackathon!'
+authors: [matijasos]
+image: /img/farnance/farnance-hero-shot.png
+tags: [webdev, wasp, startups, github]
+---
+
+import Link from '@docusaurus/Link';
+import useBaseUrl from '@docusaurus/useBaseUrl';
+
+import InBlogCta from './components/InBlogCta';
+import WaspIntro from './_wasp-intro.md';
+import ImgWithCaption from './components/ImgWithCaption'
+
+
+![farnance hero shot](../static/img/farnance/farnance-hero-shot.png)
+
+
+[Julian LaNeve](https://jlaneve.github.io/) is an engineer and data scientist who currently works at [Astronomer.io](http://Astronomer.io) as a Product Manager. In his free time, he enjoys playing poker, chess and [winning](https://www.smudailycampus.com/news/smu-graduate-julian-laneve-wins-100k-grand-prize-from-data-science-competition) data science competitions.
+
+His project, [Farnance](https://farnance.netlify.app/), is a SaaS marketplace that allows farmers to transform their production into a digital asset on blockchain. Julian and his team developed Farnance as a part of the London Business Schoolβs annual hackathon [HackLBS 2021](https://hacklbs.devpost.com/), and ended up as winners among more than 250 participants competing for 6 prizes in total!
+
+Read on to learn why Julian chose Wasp to develop and deploy Farnance and what parts he enjoyed the most.
+
+
+
+## Finding a perfect React & Node.js hackathon setup
+
+Julian had previous experiences with React and Node.js and loved that he could use JavaScript across the stack, but setting up a new project and making sure it uses all the latest packages (and then also figuring out how to deploy it) was always a pain. Since the hackathon only lasted for two days, he needed a quick way to get started but still have the freedom to use his favourite stack.
+
+## The power of one-line auth and No-API approach
+
+Julian first learned about Wasp when it [launched on HN](https://news.ycombinator.com/item?id=26091956) and decided it would be a perfect tool for his case. The whole app setup, across the full stack, is covered out-of-the-box, simply by typing `wasp new farnance`, and he is ready to start writing own React & Node.js code.
+
+Except on the app setup, the team saved a ton of time by not needing to implement the authentication and a typical CRUD API, since it is covered by Wasp as well. They could also deploy everything for free on Heroku and Netlify in just a few steps, which was a perfect fit for a hackathon.
+
+
+
+Farnance is still running and you can [try it out here](https://farnance.netlify.app/)! The source code is also [publicly available](https://github.com/jlaneve/Farnance), although note it is running on older version of Wasp so some things are a bit different.
+
+## Spend more time developing features and less time reinventing the wheel
+
+Julian was amazed by how fast he was able to get Farnance of the ground and share a working web app with the users! He decided to go with Google's material-ui for an UI framework which gave his app an instant professional look, although they didnβt have a dedicated designer on the team.
+
+With all the common web app features (setup, auth, CRUD API) being taken care of by Wasp out-of-the-box they could invest all the time saved in developing and refining their unique features which in the end brought them victory!
+
+> Iβve done plenty of hackathons before where Iβve built small SaaS apps, and thereβs just so much time wasted setting up common utilities - stuff like user management, databases, routing, etc. Wasp handled all that for me and let me build out our web app in record time
+>
+> β Julian LaNeve - Farnance
+
+
+
+
+## Start quickly, but also scale without worries
+
+:::note
+Heroku used to offer free apps under certain limits. However, as of November 28, 2022, they ended support for their free tier. https://blog.heroku.com/next-chapter
+
+As such, we have updated our Deployment docs with new recommendations: https://wasp-lang.dev/docs/deploying
+:::
+
+Since Wasp compiler generates a full-stack React & Node.js app under the hood, there arenβt any technical limitations to scaling Julianβs app as it grows and gets more users in the future. By running `wasp build` inside a project folder, developers gets both frontend files and a Dockerfile for the backend, which can then be deployed as any regular web app to the platform of your choice.
+
+Wasp provides [step-by step instructions](/docs/deploying) on how to do it with Netlify and Fly.io for free, but we plan to add even more examples and more integrated deployment experience in the coming releases!
+
+> Deploying the wasp app was incredibly easy - I didnβt have time to stand up full infrastructure in the 2 day hackathon and donβt have an infra/devops background, but I had something running on Netlify within an hour. Other projects at the hackathon struggled to do this, and putting access in the hands of the judges certainly helped get us 1st place.
+>
+> β Julian LaNeve - Farnance
diff --git a/web/blog/2022-11-15-auth-feature-announcement.md b/web/blog/2022-11-15-auth-feature-announcement.md
new file mode 100644
index 000000000..e98d12851
--- /dev/null
+++ b/web/blog/2022-11-15-auth-feature-announcement.md
@@ -0,0 +1,116 @@
+---
+title: Feature Announcement - New auth method (Google)
+authors: [shayneczyzewski]
+image: /img/auth-hero.png
+tags: [webdev, wasp, feature, auth]
+---
+
+import Link from '@docusaurus/Link';
+import useBaseUrl from '@docusaurus/useBaseUrl';
+import InBlogCta from './components/InBlogCta';
+import WaspIntro from './_wasp-intro.md';
+import ImgWithCaption from './components/ImgWithCaption'
+
+
+
+
+
+
+
+
+
+
+## Prologue
+
+We've all been there. Your app needs to support user authentication with social login, and you must now decide what to do next. Should you eschew the collective experience and wisdom of the crowd and YOLO it by rolling your own, praying you don't get pwned in prod? "Nah, I just ate some week-old sushi and can't take another risk that big anytime soon.", you rightly think.
+
+Ok, surely you can just use a library, right? Open source software, baby! "Hmm, seems Library X, Y, and Z are all somewhat used, each with their pros/cons, nuances, and integration pain points. Oh wait, there are tutorials for each... but each says how hard they are to correctly set up and use. I scoped this feature for one day, not a one-week hair-pulling adventure (Dang scrum! Who likes it anyways? Oh yeah, PMs do. Dang PMs!)." Ok, something else. You need to brainstorm. `You instead start to surf Twitter and see an ad for some unicorn auth startup.`
+
+Eureka, you can go with a third-party SaaS offering! "We shouldn't have to pay for a while (I ~~think?~~ hope!), and it's just another dependency, no biggie... #microservices, right?" "But what about outages, data privacy, mapping users between systems, and all that implicit trust you are placing in them?" you think. "What happens when Elon buys them next?" You gasp as if you walked by a Patagonia vest covered in that hot new *Burnt Hair* cologne.
+
+"All I want is username and password auth with Google login support, why is that so hard in 2022?!? I miss Basic HTTP auth headers. I think I'll move off the grid and become a woodworker."
+
+## Easy auth setup in Wasp
+
+Wasp helps that dev by taking care of the entire auth setup process out of the box. Adding support for username and password auth, plus Google login, is super quick and easy for Wasp apps. We think this makes adding auth fast and convenient, with no external dependencies or frustrating manual configuration. Hereβs how it works:
+
+### Step 1 - Add the appropriate models
+
+We need to store user info and the external mapping association for social logins. Here is an example you can start from and add new fields to:
+
+```sql title="./main.wasp"
+entity User {=psl
+ id Int @id @default(autoincrement())
+ username String @unique
+ password String
+ externalAuthAssociations SocialLogin[]
+psl=}
+
+entity SocialLogin {=psl
+ id Int @id @default(autoincrement())
+ provider String
+ providerId String
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+ userId Int
+ createdAt DateTime @default(now())
+ @@unique([provider, providerId, userId])
+psl=}
+```
+
+### Step 2 - Update `app.auth` to use these items
+
+```css title="./main.wasp"
+app authExample {
+ // ...
+ auth: {
+ userEntity: User,
+ externalAuthEntity: SocialLogin,
+ methods: {
+ usernameAndPassword: {},
+ google: {}
+ },
+ onAuthFailedRedirectTo: "/login"
+ }
+}
+```
+
+### Step 3 - Get Google credentials and add environment variables
+
+Follow the Google setup guide [here](https://wasp-lang.dev/docs/integrations/google) and add the environment variables to your `.env.server` file.
+
+### Step 4 - Make use of the Google login button in your `Login` page component
+
+```jsx title="./src/client/auth/Login.js"
+import React from 'react'
+import { Link } from 'react-router-dom'
+
+import { GoogleSignInButton } from '@wasp/auth/buttons/Google'
+import LoginForm from '@wasp/auth/forms/Login'
+
+const Login = () => {
+ return (
+
+
+
+
+
+ I don't have an account yet (go to signup).
+
+
+
+
+
+ )
+}
+
+export default Login
+```
+
+### Step 5 - Run the app!
+
+## Epilogue
+
+No need to move off the grid out of frustration when adding authentication and social login to your web app. [Here](https://github.com/shayneczyzewski/authExample) is a complete, minimal example if you want to jump right in, and [here](https://wasp-lang.dev/docs/language/features#authentication--authorization) are the full docs for more info. With just a few simple steps above, we've added authentication with best practices baked into our app so we can move on to solving problems that add value to our users!
diff --git a/web/blog/2022-11-16-alpha-testing-program-post-mortem.md b/web/blog/2022-11-16-alpha-testing-program-post-mortem.md
new file mode 100644
index 000000000..dad37ca49
--- /dev/null
+++ b/web/blog/2022-11-16-alpha-testing-program-post-mortem.md
@@ -0,0 +1,170 @@
+---
+title: 'Alpha Testing Program: post-mortem'
+authors: [matijasos]
+image: /img/atp/welcome-to-atp-notion.png
+tags: [webdev, wasp, startups, github]
+---
+
+import Link from '@docusaurus/Link';
+import useBaseUrl from '@docusaurus/useBaseUrl';
+
+import InBlogCta from './components/InBlogCta';
+import WaspIntro from './_wasp-intro.md';
+import ImgWithCaption from './components/ImgWithCaption'
+
+We are working on a new web framework that integrates with React & Node.js, and also happens to be a language. As you can probably imagine, itβs not easy to get people to use a new piece of technology, especially while still in Alpha. On the other hand, without users and their feedback, itβs impossible to know what to build.
+
+That is why we ran Alpha Testing Program for Wasp - here is what we learned and what went both well and wrong along the way.
+
+
+
+
+
+## βOf course I know about Wasp! I just havenβt come around to trying it out yet.β
+
+Although we hit the front page of HN [several](https://news.ycombinator.com/item?id=26091956) [times](https://news.ycombinator.com/item?id=32098144) and are about to reach 2,000 stars on GitHub, there is still a big difference between a person starring a repo and actually sitting down and building something with it.
+
+Talking to people, we realised a lot of them had heard of Wasp, thought it was a neat idea, but hadnβt tried it out. These were the main reasons:
+
+- having to find 30 mins to go through our **Build a Todo App** tutorial - *βI'm busy now, but Iβll do it next week.β*
+- building a bare-bones todo app is not that exciting
+- not having an idea what else to build
+- *βthe product is still in alpha, so I will bookmark it for laterβ*
+
+These are all obvious and understandable reasons. I must admit, Iβm much the same β maybe even worse β when it comes to trying out something new/unproven. It just isnβt a priority, and without a push that will help me overcome all these objections, I usually donβt have an incentive to go through with it.
+
+Having realised all that, we understood we needed to give people a reason to try Wasp out **now**, because thatβs when we needed the feedback, not next week.
+
+## Welcome to Wasp Alpha Testing Program!
+
+
+
+
+
+We quickly put together an admissions page for alpha testers in Notion (you can see it [here](https://wasp-lang.notion.site/Wasp-Alpha-Testing-Program-Admissions-dca25649d63849cb8dfc55881e4f6f82)) and started sharing it around. To counter the hurdles we mentioned above, we time-boxed the program (*βthis is happening now and you have 48 hours to finish once you start*β) and promised a t-shirt to everyone that goes through the tutorial and fills out the feedback form.
+
+
+
+Soon, the first applications started trickling in! For each new applicant, weβd follow up with the [instructions](https://www.notion.so/CLOSED-Welcome-to-Wasp-Alpha-Testing-program-f3a8a350802341abac87fb7831bb1e60) on how to successfully go through the Alpha Testing Program:
+
+- fill out intro form (years of experience, preferred stack, etc)
+- go through our βbuild a Todo appβ tutorial
+- fill out the feedback form - what was good, what was bad etc.
+
+
+
+But, soon after I got the following message on Twitter:
+
+
+
+We got really scared that we would get a ton of folks putting in minimal effort while trying Wasp out just to get the free swag, leaving us empty-handed and having learned nothing! On the other hand, we didnβt have much choice since we didnβt define the βminimum required qualityβ of feedback in advance.
+
+Luckily, it wasnβt the problem in the end, even the opposite -- we did get a surge of applications, but only a portion of them finished the program and the ones that did left really high-quality feedback!
+
+## How it went - test profile & feedback
+
+### Tester profile
+
+We received 210 applications and 53 out of those completed the program β 25% completion rate.
+
+We also surveyed applicants about their preferred stack, years of programming experience, etc:
+
+
+
+### The feedback
+
+The feedback form evaluated testersβ overall experience with Wasp. We asked them what they found to be the best and worst parts of working with Wasp, as well as about the next features theyβd like to see.
+
+
+
+**The bad parts**
+
+What our testers were missing the most was a full-blown IDE and TypeScript support. Both of these are coming in Beta but only JS was supported at the time. Plus, there were some installation problems with Windows (which is not fully supported yet β best to use it through WSL).
+
+
+
+We were already aware that TypeScript support is an important feature, but didnβt have an exact feeling of how much - the feedback was really helpful and helped us prioritise our Beta backlog.
+
+**The good parts**
+
+Testersβ favourite part was the batteries-included experience, particularly the [auth model](/docs/tutorials/todo-app/06-auth).
+
+
+
+## Post-mortem: what didnβt go well
+
+### No threshold for feedback quality
+
+
+
+We didnβt put any kind of restrictions on the feedback form, e.g. minimal length of the feedback. That resulted in ~15%-20% of answers being single words, such as depicted above. Iβm not sure if there is an efficient way to avoid this or just a stat to live with.
+
+### Using free text form for collecting addresses
+
+It never crossed our minds before that validating addresses could be such an important part of shipping swag, but turns out it is. It seems that there are a lot of ways to specify an address, some of which are different from what is expected by our post office, resulting in a number of shipments getting returned.
+
+An ideal solution would be to use a specialized βaddressβ field in a survey that would auto-validate it, but turns out Typeform (which we used) doesnβt have that feature implemented yet, although [itβs been highly requested](https://community.typeform.com/suggestions-feedback-34/address-field-question-type-2950).
+
+
+
+
+
+## The non-obvious benefit of Alpha Testing Program
+
+What went well is that we got a lot of high-quality feedback that steered and fortified our plan for the upcoming Beta release.
+
+The other big benefit is that we finally solved the *βlooks cool but iβll try it out later maybeβ* problem. Overall, our usage went well up during the program, but even after it ended, the baseline increased significantly. This was the second-order effect we didnβt foresee.
+
+Our understanding is that once people finally gave it a try, a portion of them felt the value first-hand and decided to keep using it for other projects as well.
+
+
+
+## Summary & going forward: Beta
+
+The overall conclusion from our Alpha Testing Program is it was a worthy effort which got us valuable feedback and positively affected the overall usage. Moving forward weβll try to focus on ensuring more quality feedback and prioritising 1-to-1 communication to make sure we fully understand what bothers Wasp users and what we can improve. It also might be helpful to do testing in smaller batches so we are not overwhelmed with responses and can focus on the individual testers - thatβs something we might try out in Beta.
+
+As mentioned, the next stop is Beta! It comes out on the 27th of November - [sign up here](/#signup) to get notified.
diff --git a/web/blog/2022-11-16-tailwind-feature-announcement.md b/web/blog/2022-11-16-tailwind-feature-announcement.md
new file mode 100644
index 000000000..2474204fc
--- /dev/null
+++ b/web/blog/2022-11-16-tailwind-feature-announcement.md
@@ -0,0 +1,90 @@
+---
+title: Feature Announcement - Tailwind CSS support
+authors: [shayneczyzewski]
+image: /img/tailwind-2.png
+tags: [webdev, wasp, feature, css]
+---
+
+import Link from '@docusaurus/Link';
+import useBaseUrl from '@docusaurus/useBaseUrl';
+import InBlogCta from './components/InBlogCta';
+import WaspIntro from './_wasp-intro.md';
+import ImgWithCaption from './components/ImgWithCaption'
+
+
+
+
+
+
+
+
+
+
+There are backend devs who can do some frontend, and frontend devs who can do some backend. But the mythical full stack dev is exceedingly rare (or more likely, a lie). Even as someone who falls into the meme category above, we *all* still need to make websites that **look noice**. This is a place where CSS frameworks can help.
+
+But which one should you use? According to our *extensive research*, a statistically-questionable-but-youβre-still-significant-to-us 11 people on Twitter wanted us to add better support for [Tailwind](https://tailwindcss.com/). Which was lucky for us, since we already added it before asking them. π
+
+
+
+
+
+Ok, it wasnβt a huge stretch for us to do so preemptively. Tailwind is one of the most heavily used CSS frameworks out there today and seems to keep growing in popularity. So how do you integrate it into your Wasp apps? Like many things in Wasp, itβs really easy- just drop in two config files into the root of your project and you can then start using it! Here are the defaults:
+
+```jsx title="./tailwind.config.js"
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: [
+ "./src/**/*.{js,jsx,ts,tsx}",
+ ],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+}
+```
+
+```jsx title="./postcss.config.js"
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
+```
+
+When these two files are present, Wasp will make sure all the required NPM dependencies get added, that [PostCSS](https://postcss.org/) plays nicely with Tailwind directives in CSS files, and that your JavaScript files are properly processed so you can use all the CSS selectors you want (provided you are properly equipped :D).
+
+
+
+
+
+With that in place, you can add the Tailwind directives to your CSS files like so:
+
+```css title="./src/client/Main.css"
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+/* rest of content below */
+```
+
+And then start using Tailwind classes in your components:
+
+```jsx
+
+ Hello world!
+
+```
+
+As usual, Wasp will still automatically reload your code and refresh the browser on any changes. π₯³
+
+Lastly, here is a small example that shows how to add a few Tailwind plugins for the adventurous ([wasp file](https://github.com/wasp-lang/wasp/blob/main/waspc/examples/todoApp/todoApp.wasp#L8-L9) and [Tailwind config](https://github.com/wasp-lang/wasp/blob/main/waspc/examples/todoApp/tailwind.config.js#L10-L11)), and [here](/docs/integrations/css-frameworks) are the docs for more details. We canβt wait to see what you make!
diff --git a/web/blog/2022-11-17-hacktoberfest-wrap-up.md b/web/blog/2022-11-17-hacktoberfest-wrap-up.md
new file mode 100644
index 000000000..00a4196e4
--- /dev/null
+++ b/web/blog/2022-11-17-hacktoberfest-wrap-up.md
@@ -0,0 +1,118 @@
+---
+title: 'How Wasp reached all-time high PR count during Hacktoberfest: tips for OSS maintainers'
+authors: [maksym36ua]
+tags: [webdev, wasp, hacktoberfest, github]
+---
+
+import Link from '@docusaurus/Link';
+import useBaseUrl from '@docusaurus/useBaseUrl';
+
+import InBlogCta from './components/InBlogCta';
+import WaspIntro from './_wasp-intro.md';
+import ImgWithCaption from './components/ImgWithCaption'
+
+
+2078 lines of code across 24 PRs were changed in [Wasp repo](https://github.com/wasp-lang/wasp) during [HacktoberFest 2022](https://hacktoberfest.com/) - the most prominent online event for promoting and celebrating OSS culture. October has been a blast, to say the least, and the most active month in the repo's history.
+
+This is the story of our journey along with the tips on leveraging Hacktoberfest to get your repo buzzing! ππ
+
+## How it went: the stats
+
+Let's take a quick look at the charts below (data obtained from [OSS Insight](https://ossinsight.io/analyze/wasp-lang/wasp) platform) π
+
+
+
+
+
+While the number of PRs is at an all-time high, the number of updated lines of code is fewer than usual. If we take a look at the distribution of PR sizes in the first chart, we can see that "xs" and "s" PRs are in the majority (20 out of 24).
+
+**This brings us to our first conclusion: first-time contributors start with small steps!** The main benefit here is getting potential contributors interested and familiar with the project, rather than expecting them to jump in and
+immediately start implementing the next major feature. Efforts like that require investing time to understand and digest codebase architecture, design decisions and the development process.
+
+On the other hand, being able to implement and merge any feature, no matter the size, from beginning to the end, and to get your name on the list of contributors of your favourite project is an amazing feeling! That will make your contributors feel like superheroes and motivate them to keep taking on larger and larger chunks, and maybe eventually even join the core team!
+
+**Thus, the second conclusion would be: donβt underestimate the significance of small PRs!** It's not about reducing your backlog, but rather encouraging developers to get engaged with your project in a friendly way.
+
+:::tip
+
+To make it easier for your new contributors, you can prepare in advance good issues to get started with - e.g. smaller bugs, docs improvements, fun but isolated problems, etc.
+
+We added [`good-first-issue`](https://github.com/wasp-lang/wasp/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label to such issues in Wasp repo, and even added extra context such as `no-haskell`, `webdev`, `example`, `docs`.
+
+:::
+
+With your repo being set, the next question is *"How do I get people to pick my project to work on"*? Relying solely
+on putting "Hacktoberfest" topic on your GitHub repo won't do the trick, not with thousands of other repos doing the same.
+
+If you want to get noticed, **you need to do marketing. A lot of it. The name of the game here is what you put in is what you get back.** Let's talk about this in more detail.
+
+## A thin line between genuine interactions and annoying self-promotion
+
+First and foremost, you'll need to create [an entry point](https://github.com/wasp-lang/wasp/issues/735) with all the necessary information for the participants. We opted for a GitHub issue where we categorized Hacktoberfest issues by type, complexity, etc, but it can be anything - a dedicated landing page, Medium/Dev.to article, or whatever works for you. Once you have that, you can start promoting it.
+
+
+
+Our marketing strategy consisted of the following:
+
+1. Tweeting regularly - what's new, interesting issues, ...
+
+2. Writing meaningful Reddit posts about your achievements
+
+3. Hanging out in HacktoberFest [Discord server](https://discord.com/invite/hacktoberfest), chatting with others and answering their questions
+
+4. Checking posts with [appropriate](https://dev.to/t/hacktoberfest) [tags](https://medium.com/tag/hacktoberfest2022) on different blogging websites like Medium, Dev.to, Hashnode, etc. and participating in conversations.
+
+There are plenty of other ways to advertise your project, like joining events or writing articles. Even [meme contests](https://github.com/dailydotdev/memetoberfest). The activities mentioned above worked the best for us. Letβs dive a bit deeper.
+
+Tweets are pretty obvious - as mentioned, you can share updates on how stuff is going. Tag contributors, inform your followers about available issues and mention those who might be a good fit for tackling them.
+
+Reddit is a much more complex beast. You need to avoid clickbait post titles, comply with subreddit rules on self-promotion and try to give meaningful info to the community simultaneously. Take less than you give, and youβre good.
+
+
+
+
+The Discord server marketing was pretty straightforward. Thereβs even a dedicated channel for self-promotion. In case you're not talkative much, dropping a link to your project is OK, and thatβs it. On the other hand, the server is an excellent platform for discussing Hacktoberfest-related issues, approaches, and ideas. The more you chat, the higher your chances of drawing attention to your project.
+
+The most engaging but also time consuming activity was commenting on blog posts of other Hacktoberfest participants. **Pretending that youβre interested in the topic only to leave a self-promoting comment will not bring you anywhere - it can only result in your comment being removed**. Make sure to provide value: add more information on the topic of the article, address specific points the author may have missed, or mention how youβve dealt with the related issue in your project.
+
+Be consistent and dedicate time to regularly to check new articles and jump into discussions. Share a link to your repo only if it fits into the flow of the conversation.
+
+![Content marketing in a nutshell](../static/img/hacktoberfest-wrap-up/content-marketing-in-a-nutshell.png)
+
+## Was it worth it?
+
+Before joining HacktoberFest as maintainers, we werenβt sure it would be worth the time investment. Our skepticism was reinforced by the following:
+
+1. [Mentions](https://www.reddit.com/r/developersIndia/comments/xvynx9/hacktoberfest_is_ruining_opensource/) of people submitting trivial PRs just to win the award
+
+2. The fact that we're making a relatively complex project (DSL for developing React + Node.js full-stack web apps with less code) and it might be hard for people to get into it
+
+3. The compiler is written is Haskell, with templates in JavaScript - again, not the very common project setup
+
+Fortunately, none of this turned out to be a problem! We've got 24 valid PRs, both Haskell and non-Haskell, a ton of valuable feedback, and several dozen new users and community members.
+
+## Wrap up
+
+Donβt expect magic to happen. HacktoberFest is all about smaller changes and getting community introduced to your project. Be ready to promote your repo genuinely and donβt be afraid to take part in the contest. We hope that helps and wish you the best of luck!
+
+Remember, HacktoberFest is all about the celebration of open source. Stick to that principle, and youβll get the results you could only wish for!
+
+## P.S. - Thanks to our contributors!
+
+Massive shout out to our contributors: [@ussgarci](https://twitter.com/ussgarci), [@h4r1337](https://twitter.com/h4r1337), [@d0m96](https://twitter.com/d0m96), [@EmmanuelCoder](https://twitter.com/EmmanuelCoder), [@gautier_difolco](https://twitter.com/gautier_difolco), [@vaishnav_mk1](https://twitter.com/vaishnav_mk1), [@NeoLight1010](https://twitter.com/NeoLight1010), [@abscubix](https://twitter.com/abscubix), [@JFarayola](https://twitter.com/JFarayola), [@Shahx95](https://twitter.com/Shahx95) and everyone else for making it possible. You rock! π€
diff --git a/web/blog/2022-11-26-erlis-amicus-usecase.md b/web/blog/2022-11-26-erlis-amicus-usecase.md
new file mode 100644
index 000000000..a36edeadc
--- /dev/null
+++ b/web/blog/2022-11-26-erlis-amicus-usecase.md
@@ -0,0 +1,75 @@
+---
+title: 'Amicus: See how Erlis built a SaaS for legal teams with Wasp and got first paying customers!'
+authors: [matijasos]
+image: /img/amicus-usecase/amicus-hero-shot.png
+tags: [webdev, wasp, startups, github]
+---
+
+import Link from '@docusaurus/Link';
+import useBaseUrl from '@docusaurus/useBaseUrl';
+
+import InBlogCta from './components/InBlogCta';
+import WaspIntro from './_wasp-intro.md';
+import ImgWithCaption from './components/ImgWithCaption'
+
+
+![amicus hero shot](../static/img/amicus-usecase/amicus-hero-shot.png)
+
+
+[Erlis Kllogjri](https://github.com/ErlisK) is an engineer based in San Francisco with broad experience ranging from mechanical engineering and C/C++ microcontroller programming to Python and web app development. In his free time, Erlis enjoys working on side projects, which is also how Amicus started out.
+
+Amicus is a SaaS for legal teams - think about it as "Asana for lawyers", but with features and workflows tailored to the domain of law.
+
+Read on to learn how long it took Erlis to develop the first version of his SaaS with Wasp, how he got his first paying customers, and what features he plans to add next!
+
+
+
+## Looking for a full-stack βall-in-oneβ solution, with React & Node.js
+
+Erlis first learned about Wasp on HackerNews and it immediately caught his attention, particularly the configuration language part. One of the companies he worked at in the past had its own internal DSL in the hardware domain, and he understood how helpful it could be for moving fast and avoiding boilerplate.
+
+Erlis also had previous experience in web development, especially on the front-end side in React and Javascript, so that made Wasp a logical choice.
+
+> I was looking at other solutions, but none of them were full-stack and sounded like a lot of work just to stitch everything together and get started. I just wanted to get the job done and didnβt care about picking the stack specifics myself. Wasp was really helpful as it set me up with the best practices and I had everything running in just a few minutes!
+>
+> β Erlis Kllogjri - Amicus
+
+## Building Amicus v1.0 and getting first customers!
+
+The idea for Amicus came from his brother, who is employed at a law firm - talking about their process and challenges in executing them, Erlis thought it would be an interesting side project, especially given there is a real problem to solve.
+
+Soon, the first version of Amicus was live! It was made in a true lean startup fashion, starting with the essential features and immediately being tested with users.
+
+
+
+Erlis used Material-UI as a UI library since it came with one of the example apps built in Wasp (Beta introduced Tailwind support!). Users could track their clients, active legal matters and there was even integrated billing with Stripe! Amicus also extensively used Waspβs [Async Jobs](https://wasp-lang.dev/blog/2022/06/15/jobs-feature-announcement) feature to regularly update invoices, send reminder emails and clear out old data from the database.
+
+After a few iterations with the legal team who were Amicus' test user (e.g. adding support for different types of users via roles), they were ready to get onboarded and become paying customers! More than 20 people from a single company are using Amicus daily for their work, making it an amazing source of continuous feedback for further development.
+
+Erlis enjoyed the most how fast he could progress and ship features with Wasp on a weekly basis. Having both front-end, back-end, and database set and fully configured to work together from the beginning, he could focus on developing features rather than spend time figuring out the intricacies of the specific stack.
+
+> If it weren't for Wasp, Amicus would probably have never been finished. I estimate it saved me 100+ hours from the start and I'm still amazed that I did all this work as a team-of-one. Being able to quickly change existing features and add the new ones is the biggest advantage of Wasp for me.
+>
+> β Erlis Kllogjri - Amicus
+
+## Beyond MVP with Wasp
+
+Although Erlis already has a product running in production, with first paying customers, he wants to see how far he can take it and has a lot of ideas (also requests) for the next features. *(Actually, Erlis had a big kanban board with post-its on a wall behind him as we were chatting, dedicated just to Amicus - that was impressive to see!)*.
+
+Some of the most imminent ones are:
+
+- uploading and sharing files between lawyers and clients
+- usage logging and analytics
+- transactional emails for notifications
+
+Since under the hood Wasp is generating code in today's mainstream, production-tested technologies such as React, Node.js and PostgreSQL (through Prisma), there aren't any technical limitations to scaling Amicus as it grows and attracts more users.
+
+Also, given that the `wasp build` CLI command generates a ready Docker image for the back-end (and static files for the front-end), deployment options are unlimited. Since Heroku is shutting down its free plan, we added guides on how to deploy your project for free on [Fly.io](http://Fly.io) and Railway (freemium).
+
+> I was using Wasp while still in Alpha and was impressed how well everything worked, especially given how much stuff I get. I had just a few minor issues and the team responded super quickly on Discord and helped me resolve it.
+>
+> β Erlis Kllogjri - Amicus
diff --git a/web/blog/2022-11-26-michael-curry-usecase.md b/web/blog/2022-11-26-michael-curry-usecase.md
new file mode 100644
index 000000000..13a81280f
--- /dev/null
+++ b/web/blog/2022-11-26-michael-curry-usecase.md
@@ -0,0 +1,70 @@
+---
+title: 'How Michael Curry chose Wasp to build Grabbit: an internal tool for managing dev resources at StudentBeans'
+authors: [matijasos]
+image: /img/michael-curry-usecase/grabbit-hero-shot.png
+tags: [webdev, wasp, startups, github]
+---
+
+import Link from '@docusaurus/Link';
+import useBaseUrl from '@docusaurus/useBaseUrl';
+
+import InBlogCta from './components/InBlogCta';
+import WaspIntro from './_wasp-intro.md';
+import ImgWithCaption from './components/ImgWithCaption'
+
+
+![grabbit hero shot](../static/img/michael-curry-usecase/grabbit-hero-shot.png)
+
+[Michael Curry](https://github.com/cursorial) is a senior front-end engineer at [Improbable](https://www.improbable.io/), a metaverse and simulation company based in London. In his free time he enjoys learning about compilers.
+
+In his previous position at StudentBeans, he experienced the problem of multiple engineering teams competing for the same dev environment (e.g. testing, staging, β¦). Then he discovered Wasp and decided to do something about it!
+
+Read on to learn why Michael chose Wasp to build and deploy an internal tool for managing development environments at StudentBeans.
+
+
+
+## The problem: the battle for the dev environment
+
+StudentBeans has a microservices-based architecture with multiple environments - test, staging, production, β¦. The team practices CI/CD and deploys multiple times a day. With such a rapid development speed, it would relatively often happen that multiple engineering teams attempt to claim the same dev environment at the same time.
+
+There wasn't an easy way for teams to synchronize on who is using which environment and it would eventually lead to unexpected changes, confusion, and prolonged development times.
+
+## The solution: Grabbit - claim and release dev environments as-you-go
+
+After the incident described above repeated for the n-th time, the team got together for a postmortem. They decided their new development process should look like this:
+
+- merge your changes
+- claim the environment you want to deploy to (e.g. testing, staging, β¦)
+- deploy your changes
+- test your changes
+- release the environment once you are done with it so others are able to claim it
+
+The other requirements were to build the solution in-house to save money and also not to spend more than a few hours on it as they still needed to deliver some important features for the ongoing sprint.
+
+## The power of rapid prototyping with Wasp
+
+Michael learned about Wasp during its [first HackerNews launch](https://news.ycombinator.com/item?id=26091956) and it immediately caught his eye. Being a programming language enthusiast himself, he immediately understood the value of a DSL approach and how it could drastically simplify the development process, while at the same time not preventing him from using his preferred tech stack (React, Node.js) when needed.
+
+Also, although Michael had full-stack experience, his primary strength at the time was on the front-end side. Wasp looked like a great way of not having to deal with the tedious back-end setup and wiring (setting up the database, figuring out API, β¦) and being able to focus on the UX.
+
+> When I first learned about Wasp on HN I was really excited about its DSL approach. It was amazing how fast I could get things running with Wasp - I had the first version within an hour! The language is also fairly simple and straightforward and plays well with React & Node.js + it removes a ton of boilerplate.
+>
+> β Michael Curry - Grabbit
+
+## Out-of-the-box deployment
+
+Once Michael was satisfied with the first version of Grabbit, and confirmed with the team it fits their desired process, the only thing left to do was to deploy it! It is well known this step can get really complicated, especially if you're not yet well-versed in the sea of config options that usually come with it.
+
+Wasp CLI comes with a `wasp build` command that does all the heavy lifting for you - it creates a directory with static front-end files that you can easily deploy to e.g. Netlify, and on the other hand, a Docker image for the back-end. Since Heroku is ending its free plan, our recommendation is to deploy to Fly.io, for which the detailed guide is provided. You can find the [detailed deployment instructions here](https://wasp-lang.dev/docs/deploying).
+
+In Michael's case, he deployed Grabbit behind the VPN since it was an internal tool, and this process was made easy by having a ready-to-go Dockerfile.
+
+## From MVP to a full-fledged SaaS without a rewrite
+
+The presented functionality of Grabbit above is quite simple (create a resource β claim it β release it), and it could have easily been implemented in some no-code tool or, if we really wanted to go simple, with a Trello board. So why use Wasp at all?
+
+One reason is that developers know and prefer their tools and trust code over the no-code solutions, especially when requirements are still evolving and it is not evident they won't get "stuck" in some closed system. Michael had similar thinking - as he identified this problem at his own company, he realized others must be facing the same issue as well. That is why his plan was to keep improving Grabbit and eventually offer it as a standalone SaaS.
+
+This is where Wasp comes in - he could develop and deploy an initial version of Grabbit in a matter of hours, but still end up with a platform that he can extend indefinitely through the power of code with his stack of choice, React & Node.js, while also using the npm packages he is using everyday at work.
+
+Once he starts adding more advanced features, such as multi-user support with authentication, email notifications, and integration with CI/CD, no-code tools won't cut it any more. This way he saved himself and the company from throwing an MVP away and starting everything from scratch (having to learn the new technology and figure out how to set it all up) as the product evolves.
diff --git a/web/blog/2022-11-26-wasp-beta-launch-week.md b/web/blog/2022-11-26-wasp-beta-launch-week.md
new file mode 100644
index 000000000..1f45a8c32
--- /dev/null
+++ b/web/blog/2022-11-26-wasp-beta-launch-week.md
@@ -0,0 +1,118 @@
+---
+title: 'Wasp Beta Launch Week announcement'
+authors: [matijasos]
+image: /img/beta-ann/beta-banner.png
+tags: [webdev, wasp, startups, github]
+---
+
+import Link from '@docusaurus/Link';
+import useBaseUrl from '@docusaurus/useBaseUrl';
+
+import InBlogCta from './components/InBlogCta';
+import WaspIntro from './_wasp-intro.md';
+import ImgWithCaption from './components/ImgWithCaption'
+
+Itβs almost here! After almost two years since our Alpha release, countless apps developed, React and Node versions upgraded, and PRs merged **weβre only a day away from Beta!**
+
+
+
+Weβre going to follow a launch week format, **which means our Beta launch will last for the whole week**! Starting with the Product Hunt launch this Sunday (weβll let you know once weβre live, so sharpen your upvoting fingers!) **weβll highlight a new feature every day**.
+
+Iβll try not to spoil too much in advance but weβre really excited about this - here follows a quick overview of what itβs gonna look like:
+
+
+
+## Sunday, Nov 27 - Product Hunt launch event π + letβs get this party started: **Auth** π
+
+Besides defending our Product Hunt title (we won [#1 Product of the Day](https://www.producthunt.com/products/wasp-lang-alpha#wasp-lang-alpha) last time), this time weβll also have an online party for all of us to celebrate together!
+
+It will be held **on our Discord at 9:00 am EST / 15:00 CET** - [sign up here](https://discord.gg/4kUcXChX?event=1042717917097246720) and make sure to mark yourself as βInterestedβ!
+
+Join us to meet the team, attend a relaxed AMA session to learn everything about Wasp, from how it started to development challenges (having fun with Haskell, web dev and compilers) and ideas and plans for the future.
+
+
+
+The first feature to announce will be authentication in Wasp! Itβs easier and cooler than ever, supports 3rd party providers (hint: starts with βGβ), and works smoother than a jar of peanut butter (not the crunchy one of course)!
+
+## Monday, Nov 28 - TypeScript support!
+
+
+
+When we asked you what was missing in Wasp during our [Alpha Testing Program](/blog/2022/11/16/alpha-testing-program-post-mortem), you were pretty clear:
+
+
+
+We heard you (honestly we were missing it too) and now itβs here! You can write your code in TypeScript and enjoy all the goodies that types bring. Some things already work really well and there are a few for which we still have ideas on how to make them better, but more on that on Tuesday!
+
+## Wednesday, Nov 29 - Tailwind support! πΒ π¨
+
+
+
+Itβs beautiful! Another highly anticipated featured that also comes with Beta - support for Tailwind CSS framework! Since it has an additional build step it didnβt work out-of-the-box with Alpha, but now it works like a breeze (see what I did here?)!
+
+Honestly, having used it for designing our new Beta landing page I can really see why it gained so much popularity. So long, making up names for classes, βcontainersβ, and βwrappersβ!
+
+## Thursday, Nov 30 - Optimistic updates!
+
+
+
+You know that feeling when you move your Trello card βTry Wasp Betaβ from βTodoβ column to βDoneβ column and everything works super smoothly without any glitches? Thatβs because of optimistic updates! You may not need it often but if you needed and it wasnβt possible youβd feel really sad.
+
+Well, thatβs why Alpha is called Alpha and Beta is called Beta π . Long story short, now itβs possible to do it in Wasp and itβs also super easy and clean! We're actually very optimistic youβll feel really good about implementing optimistic updates for your app in Wasp.
+
+## Friday, Dec 1 - Improved IDE support, tooling and Wasp LSP!
+
+
+
+If you like types in TypeScript (and in general), then you will also enjoy Wasp! Our DSL is also a typed language which means it can report errors in compile time, e.g. in case you havenβt configured your route correctly. And now all that happens directly in your editor!
+
+**Beta brings LSP, Language Server for Wasp that works with VS Code** (support for other editors coming soon! Iβm VIM user myself so take a guess :D). That means improved syntax highlighting, code autocompletion and live error reporting - everything youβd expect from a language!
+
+
+
+## Saturday, Dec 2 - Grande Finale + #1 Wasp Hackathon!(WaspathonπΒ ?)
+
+
+
+I donβt want to reveal too much in advance, but yep there will be a hackathon, yep there will be cool rewards (at least we think so) and yep it will be awesome! Weβll officially announce it as we end the launch week, and equipped with all the new features Beta brought weβll switch into the hacking mode!
+
+Itβs our first hackathon and we canβt wait to tell you more about it (ok, I admit, weβre still working on it) and see what you beeld with Wasp!
+
+## Recap
+
+- **We are launching Beta this Sunday, Nov 27, on Product Hunt at 1am PST / 4am EST / 10am CET** - make sure to upvote and comment (anything counts, even βgo guys!β) when you can
+- **Beta brings a ton of new exciting features** - weβll highlight one each day of the following week
+- **On Saturday, Dec 2, weβll announce a hackathon** - our first ever!
+
+Thatβs it, Waspeteers - keep buzzing as always and see you soon on the other side! πΒ Β π ±οΈ
+
+Matija, Martin & the Wasp team
diff --git a/web/blog/components/DiscordLink.js b/web/blog/components/DiscordLink.js
new file mode 100644
index 000000000..0e4061276
--- /dev/null
+++ b/web/blog/components/DiscordLink.js
@@ -0,0 +1,11 @@
+import React from "react";
+
+const DiscordLink = (props) => {
+ return (
+
+ Discord
+
+ );
+};
+
+export default DiscordLink;
\ No newline at end of file
diff --git a/web/docs/contributing.md b/web/docs/contributing.md
index bacc91bef..4dc0a25c5 100644
--- a/web/docs/contributing.md
+++ b/web/docs/contributing.md
@@ -4,9 +4,16 @@ sidebar_label: Contributing
slug: /contributing
---
-Any way you want to contribute is a good way, and we are happy to meet you :)!
+import DiscordLink from '../blog/components/DiscordLink';
-Some typical ways to contribute:
-1. Join us on discord [![Discord](https://img.shields.io/discord/686873244791210014?label=chat%20on%20discord)](https://discord.gg/rzdnErX) and let's talk! We can discuss language design, new/existing features, weather, or you can just tell us how you feel about Wasp :).
-2. If there is something in docs that you think could be improved or clarified, go to [docs Github repo](https://github.com/wasp-lang/wasp) and make an issue/PR! Or, you can do it directly from here by clicking on "edit this page" at the bottom of each page.
-3. Create an issue/PR on [core Wasp repo](https://github.com/wasp-lang/wasp) to contribute directly to the language and/or compiler! Check [wapsc README](https://github.com/wasp-lang/wasp/tree/main/waspc) for more details.
+Any way you want to contribute is a good way, and we'd be happy to meet you! A single entry point for all contributors is the [CONTRIBUTING.md](https://github.com/wasp-lang/wasp/blob/main/CONTRIBUTING.md) file in our Github repo. All the requirements and instructions are there, so please check [CONTRIBUTING.md](https://github.com/wasp-lang/wasp/blob/main/CONTRIBUTING.md) for more details.
+
+Some side notes to make your journey easier:
+
+1. Join us on and let's talk! We can discuss language design, new/existing features, and weather, or you can tell us how you feel about Wasp :).
+
+2. Wasp's compiler is built with Haskell. That means you'll need to be somewhat familiar with this language if you'd like to contribute to the compiler itself. But Haskell is just a part of Wasp, and you can contribute to lot of parts that require web dev skills, either by coding or by suggesting how to improve Wasp and its design as a web framework. If you don't have Haskell knowledge (or any dev experience at all) - no problem. There are a lot of JS-related tasks and documentation updates as well!
+
+3. If there's something you'd like to bring to our attention, go to [docs GitHub repo](https://github.com/wasp-lang/wasp) and make an issue/PR!
+
+Happy hacking!
\ No newline at end of file
diff --git a/web/docs/deploying.md b/web/docs/deploying.md
index 040dd9c9d..0fea5d2a2 100644
--- a/web/docs/deploying.md
+++ b/web/docs/deploying.md
@@ -1,6 +1,7 @@
---
title: Deploying
---
+import useBaseUrl from '@docusaurus/useBaseUrl';
:::info
Wasp is in beta, so keep in mind there might be some kinks / bugs, and possibly a bit bigger changes in the future.
@@ -11,77 +12,193 @@ Right now, deploying of Wasp project is done by generating the code and then dep
In the future, the plan is to have Wasp take care of it completely: you would declaratively define your deployment in .wasp and then just call `wasp deploy` ([github issue](https://github.com/wasp-lang/wasp/issues/169)).
+If you want to deploy your App completely **free** of charge, continue reading below for guides on using Fly.io as your backend (server) provider and Netlify for your frontend (client).
+
+If you prefer to host client and server on **one platform**, and don't mind paying a very small fee for extra features, we suggest following the guide on using [Railway as your provider](#deploying-to-railway-freemium-all-in-one-solution).
+
## Generating deployable code
+
```
wasp build
```
+
generates deployable code for the whole app in the `.wasp/build/` directory. Next, we will deploy this code.
NOTE: You will not be able to build the app if you are using SQLite as a database (which is a default database) -> you will have to [switch to PostgreSQL](/docs/language/features#migrating-from-sqlite-to-postgresql).
## Deploying API server (backend)
+
In `.wasp/build/`, there is a `Dockerfile` describing an image for building the server.
To run server in production, deploy this docker image to your favorite hosting provider, ensure that env vars are correctly set, and that is it.
-Below we will explain the required env vars and also provide detailed instructions for deploying to Heroku.
+Below we will explain the required env vars and also provide detailed instructions for deploying to Fly.io or Heroku.
### Env vars
Server uses following environment variables, so you need to ensure they are set on your hosting provider:
+
- `PORT` -> The port number at which it will listen for requests (e.g. `3001`).
- `DATABASE_URL` -> The URL of the Postgres database it should use (e.g. `postgresql://mydbuser:mypass@localhost:5432/nameofmydb`).
- `WASP_WEB_CLIENT_URL` -> The URL of where the frontend app is running (e.g. `https://.netlify.app`), which is necessary for CORS.
- `JWT_SECRET` -> You need this if you are using Wasp's `auth` feature. Set it to a random string (password), at least 32 characters long.
-### Deploying to Heroku
+### Deploying to Fly.io (free, recommended)
+
+Fly.io offers a variety of free services that are perfect for deploying your first Wasp app! You will need a Fly.io account and the [`flyctl` CLI](https://fly.io/docs/hands-on/install-flyctl/).
+
+:::note
+Fly.io offers support for both locally built Docker containers and remotely built ones. However, for simplicity and reproducability, we will force the use of a remote Fly.io builder.
+
+Additionally, `fly` is a symlink for `flyctl` on most systems and they can be used interchangeably.
+:::
+
+Make sure you are logged in with `flyctl` CLI. You can check if you are logged in with `flyctl auth whoami`, and if you are not, you can log in with `flyctl auth login`.
+
+#### Set up a Fly.io app (only once per Wasp app)
+
+Unless you already have a Fly.io app that you want to deploy to, let's create a new Fly.io app. Position yourself in .wasp/build/ directory (reminder: which you created by running `wasp build` previously):
+
+```bash
+cd .wasp/build
+```
+
+Now from within the `build` directory, run the launch command to set up a new app and create a `fly.toml` file:
+
+```bash
+flyctl launch --remote-only
+```
+
+This will ask a series of questions, including what region to deploy in and if you would like a database.
+
+- Say **yes to "Would you like to set up a Postgresql database now?", and select Development**, and Fly.io will set a `DATABASE_URL` for you.
+- Say **no to "Would you like to deploy now?"**, as well as any additional questions. We still need to set a few environment variables.
+
+:::note
+If your attempts to initiate a new app fail for whatever reason, then you can run `flyctl apps destroy ` before trying again.
+
+
+
+ What does it look like when your DB is deployed correctly?
+
+
+
When your DB is deployed correctly, you will be able to view it in the Fly.io dashboard:
+
+
+
+:::
+
+Next, let's copy the `fly.toml` file up to our Wasp project dir for safekeeping.
+```bash
+cp fly.toml ../../
+```
+
+Next, let's add a few more environment variables:
+
+```bash
+flyctl secrets set PORT=8080
+flyctl secrets set JWT_SECRET=
+flyctl secrets set WASP_WEB_CLIENT_URL=
+```
+
+NOTE: If you do not know what your frontend URL is yet, don't worry. You can set `WASP_WEB_CLIENT_URL` after you deploy your frontend.
+
+If you want to make sure you've added your secrets correctly, run `flyctl secrets list` in the terminal. Note that you will see hashed versions of your secrets to protect your sensitive data.
+
+#### Deploy to a Fly.io app
+
+While still in the .wasp/build/ directory, run:
+
+```bash
+flyctl deploy --remote-only --config ../../fly.toml
+```
+
+This will build and deploy the backend of your Wasp app on Fly.io to `https://.fly.dev`! π€πΈ
+
+Now, if you haven't, you can deploy your frontend -- [we suggest using Netlify](#deploying-web-client-frontend) for this -- and add the client url by running `flyctl secrets set WASP_WEB_CLIENT_URL=`
+
+Additionally, some useful commands include:
+
+```bash
+flyctl logs
+flyctl secrets list
+flyctl ssh console
+```
+
+#### Redeploying after Wasp builds
+
+When you rebuild your Wasp app (with `wasp build`), it will remove your .wasp/build/ directory. In there, you may have a `fly.toml` from any prior Fly.io deployments. While we will improve this process in the future, in the meantime, you have a few options:
+
+1. Copy the `fly.toml` file to a versioned directory, like your Wasp project dir. From there, you can reference it in `flyctl deploy --config ` commands, like above.
+1. Backup the `fly.toml` file somewhere before running `wasp build`, and copy it into .wasp/build/ after. When the `fly.toml` file exists in .wasp/build/ dir, you do not need to specify the `--config `.
+1. Run `flyctl config save -a ` to regenerate the `fly.toml` file from the remote state stored in Fly.io.
+
+### Deploying to Heroku (non-free)
+
+:::note
+Heroku used to offer free apps under certain limits. However, as of November 28, 2022, they ended support for their free tier. https://blog.heroku.com/next-chapter
+
+As such, we recommend using an alternative provider like [Fly.io](#deploying-to-flyio-free-recommended) for your first apps.
+:::
-Heroku is completely free under certain limits, so it is ideal for getting started with deploying a Wasp app.
You will need Heroku account, `heroku` CLI and `docker` CLI installed to follow these instructions.
Make sure you are logged in with `heroku` CLI. You can check if you are logged in with `heroku whoami`, and if you are not, you can log in with `heroku login`.
#### Set up a Heroku app (only once per Wasp app)
+
Unless you already have a heroku app that you want to deploy to, let's create a new Heroku app:
+
```
heroku create
```
Unless you have external Postgres database that you want to use, let's create new database on Heroku and attach it to our app:
+
```
heroku addons:create --app heroku-postgresql:hobby-dev
```
+
Heroku will also set `DATABASE_URL` env var for us at this point. If you are using external database, you will have to set it yourself.
The `PORT` env var will also be provided by Heroku, so the only two left to set are the `JWT_SECRET` and `WASP_WEB_CLIENT_URL` env vars:
+
```
heroku config:set --app JWT_SECRET=
heroku config:set --app WASP_WEB_CLIENT_URL=
```
-NOTE: If you do not know what your frontend URL is yet, don't worry. You can set WASP_WEB_CLIENT_URL after you deploy your frontend.
+NOTE: If you do not know what your frontend URL is yet, don't worry. You can set `WASP_WEB_CLIENT_URL` after you deploy your frontend.
#### Deploy to a Heroku app
+
Position yourself in `.wasp/build/` directory (reminder: which you created by running `wasp build` previously):
+
```
cd .wasp/build
```
+
assuming you were at the root of your Wasp project at that moment.
Log in to Heroku Container Registry:
+
```
heroku container:login
```
Build the docker image and push it to Heroku:
+
```
heroku container:push --app web
```
+
App is still not deployed at this point.
This step might take some time, especially the very first time, since there are no cached docker layers.
:::note
+
#### Note for Apple M1 users
+
Apple M1 users need to build a non-Arm image, so the above step will not work at this time. Instead of `heroku container:push`, users instead should:
```bash
@@ -94,34 +211,49 @@ You are now ready to proceed to the next step.
:::
Deploy the pushed image and restart the app:
+
```
heroku container:release --app web
```
+
This is it, backend is deployed at `https://.herokuapp.com`!
Additionally, you can check out the logs with:
+
```
heroku logs --tail --app
```
:::note
+
#### Note on using pg-boss with Heroku
+
If you wish to deploy an app leveraging Jobs that use pg-boss as the executor to Heroku, you need to set an additional environment variable called `PG_BOSS_NEW_OPTIONS` to `{"connectionString":"","ssl":{"rejectUnauthorized":false}}`. This is because pg-boss uses the `pg` extension, which does not seem to connect to Heroku over SSL by default, which Heroku requires. Additionally, Heroku uses a self-signed cert, so we must handle that as well.
+
- https://devcenter.heroku.com/articles/connecting-heroku-postgres#connecting-in-node-js
:::
## Deploying web client (frontend)
+
Position yourself in `.wasp/build/web-app` directory (reminder: which you created by running `wasp build` previously):
+
```
cd .wasp/build/web-app
```
+
assuming you were at the root of your Wasp project at that moment.
Run
+
```
npm install && REACT_APP_API_URL= npm run build
```
-where is url of the wasp backend that you previously deployed, e.g. `https://wasp-test.herokuapp.com`.
+:::info NO SLASH
+Make sure your API URL does not have a trailing "/" on the end of it:
+β https://backend.example.com β https://backend.example.com/
+:::
+
+where is url of the wasp backend that you previously deployed, e.g. `https://wasp-test.fly.dev`.
This will create `build/` directory, which you can deploy to any static hosting provider.
Check instructions below for deploying to Netlify.
@@ -134,14 +266,131 @@ You will need Netlify account and `netlify` CLI installed to follow these instru
Make sure you are logged in with `netlify` CLI. You can check if you are logged in with `netlify status`, and if you are not, you can log in with `netlify login`.
While positioned in `.wasp/build/web-app/` directory, and after you have created `.wasp/build/web-app/build/` directory as per instructions above, run
+
```
netlify deploy
```
+
and carefully follow their instructions (i.e. do you want to create a new app or use existing one, team under which your app will reside, ..., final step to run `netlify deploy --prod`).
That is it!
-NOTE: Make sure you set this URL as the `WASP_WEB_CLIENT_URL` environment variable in Heroku.
+NOTE: Make sure you set this URL as the `WASP_WEB_CLIENT_URL` environment variable in your server hosting environment (e.g., Fly.io or Heroku).
+
+## Deploying to Railway ("freemium", all-in-one solution)
+
+Railway makes it easy to deploy your entire app -- database, server, and client -- on one platform. You can use the platform for free for a limited time (~21 days) per month. Upgrading to the `Developer` plan will only cost you a few dollays per month per service.
+
+:::danger π
+ Due to Railway's current proxy configuration, Google Auth will not currently work. If you're using Google Auth in your Wasp App, you can still deploy your back-end to Railway, but we suggest you [deploy your front-end to Netlify](#deploying-to-netlify)
+:::
+
+To get started, follow these steps:
+
+1. [Generate deployable code](#generating-deployable-code) (`wasp build`)
+2. Sign up at [Railway.app](https://railway.app) (Tip! Sign up with your GitHub account for $5/month of usage free)
+3. Before creating a new project, install the [Railway CLI](#https://docs.railway.app/develop/cli#install) by running the following command in your terminal:
+ ```shell
+ curl -fsSL https://railway.app/install.sh | sh
+ ```
+4. While still in the terminal, run `railway login` and a browser tab will open to authenticate you.
+
+#### Create New Project
+
+Go back to your [Railway dashboard](https://railway.app/dashboard), click on **+ New Project**, and select `Provision PostgreSQL` from the dropdown menu.
+
+Once it initializes, right click on the `+ New` button in the top right corner and select `>_ Empty Service`. Once it initializes, click on it, go to `Settings > General` and change the name (e.g. `server`).
+
+Go ahead and create another empty service and name it (e.g. `client`).
+
+
+
+ Just in case, here is a helpful screenshot ;)
+
+
+
+
+
+
+#### Deploy to services
+
+Now go back to your terminal and execute the following commands:
+
+ 1. Move into your app's `.wasp/build/` directory, which was created when you ran `wasp build` previously:
+ ```shell
+ cd .wasp/build
+ ```
+ 2. "Link" your app build to your newly created Railway project:
+ ```shell
+ railway link
+ ```
+ 3. Push and deploy the project to railway (make sure you're in `.wasp/build`):
+ ```shell
+ railway up
+ ```
+ Select `server` when prompted with `Select Service`. Press enter.
+ Railway will now locate the Dockerfile and deploy your server π
+
+ When deployment is finished, you will see: `Deployment live at `
+ Copy this URL π. We need it for step 5!
+
+ 4. Next, change into your app's frontend build directory `.wasp/build/web-app`:
+ ```shell
+ cd web-app
+ ```
+ 5. Create the production build, adding the URL from step 3:
+ ```shell
+ npm install && REACT_APP_API_URL= npm run build
+ ```
+ :::info NO SLASH
+ Make sure your API URL does not have a trailing "/" on the end of it:
+ β https://backend.example.com β https://backend.example.com/
+ :::
+
+ 6. Change into the `.wasp/build/web-app/build` directory and deploy:
+ ```shell
+ cd build && railway up
+ ```
+ This time select `client` when prompted with `Select Service`.
+
+ 7. Your apps are deployed π§ββοΈ. Now it's time to add environment variables, so open the project in the browser
+ ```shell
+ railway open
+ ```
+
+#### Add Environment Variables
+
+Back in your [Railway dashboard](https://railway.app/dashboard), click on your project and you should see your newly deployed services: Postgres, Server, and Client.
+
+Now you're going to pass each service the correct [environment variables](#env-vars). To do this, you first need to tell Railway to generate public domains for client and server.
+
+Go to the server instance's `Settings` tab, and click `Generate Domain`. Do the same under the client's `Settings`.
+
+The Postgres database is already initialized with a domain, so click on the Postgres instance, go to the **Connect** tab and copy the `Postgres Connection URL`.
+
+Go back to your `server` instance and navigate to its `Variables` tab. Now add the copied Postgres URL as `DATABASE_URL`, as well as the client's domain as `WASP_WEB_CLIENT_URL`.
+
+Next, copy the server's domain, move over to the client's `Variables` tab and add the generated server domain as a new variable called `REACT_APP_API_URL`.
+
+
+
+ Having trouble finding these settings?
+
+
+
+
+
+
+
+
+And now you should be deployed! π π π
## Customizing the Dockerfile
By default, Wasp will generate a multi-stage Dockerfile that is capable of building an image with your Wasp-generated server code and running it, along with any pending migrations, as in the deployment scenario above. If you need to customize this Dockerfile, you may do so by adding a Dockerfile to your project root directory. If present, Wasp will append the contents of this file to the _bottom_ of our default Dockerfile.
@@ -154,3 +403,6 @@ Since the last definition in a Dockerfile wins, you can override or continue fro
To see what your project's (potentially combined) Dockerfile will look like, run: `wasp dockerfile`
Here are the official docker docs on [multi-stage builds](https://docs.docker.com/build/building/multi-stage/). Please join our Discord if you have any questions, or if the customization hook provided here is not sufficient for your needs!
+
+#### Updates & Redeploying
+When you make updates and need to redeploy, just follow [steps 3-7](#deploy-to-services) above. Remember, you can connect or disconnect your app to any project in your Railway account by using `railway link` or `railway unlink` from within the app's directory.
\ No newline at end of file
diff --git a/web/docs/getting-started.md b/web/docs/getting-started.md
index 2befd9628..d496680ab 100644
--- a/web/docs/getting-started.md
+++ b/web/docs/getting-started.md
@@ -53,17 +53,17 @@ We recommend using [nvm](https://github.com/nvm-sh/nvm) for managing your Node.j
-:::info
+
+
+ Why this version of node?
+
+
+ At Wasp, we focus on supporting the latest LTS ("long-term-support") Node.js version, since it guarantees stability and active maintainance, which is why the official Node.js team recommends it for usage in production.
+ Therefore, a specific Wasp release will usually require the version of Node.js that was LTS at that point of time.
+ Check out https://nodejs.org/en/about/releases/ for more details about Node.js releases.
+
+
-Why does Wasp require this specific `node` range and doesn't support a newer version x.y.z?
-
-At Wasp, we focus on supporting the latest LTS ("long-term-support") Node.js version, since it guarantees stability and active maintainance, which is why the official Node.js team recommends it for usage in production.
-Therefore, a specific Wasp release will usually require the version of Node.js that was LTS at that point of time.
-Check out https://nodejs.org/en/about/releases/ for more details about Node.js releases.
-
-Sometimes we will make an exception to that and additionally limit the Node.js version or postpone switching to the latest LTS if there are certain issues with new Node.js version, in which case we will catch up once those are resolved on Node.js side or we find a workaround on Wasp side.
-
-:::
## 2. Installation
@@ -140,7 +140,7 @@ The extension brings the following functionality:
## 4. What next?
-**Check out the π€ [Todo App tutorial](tutorials/todo-app.md) π€ , which will take you through all the core features of Wasp!**
+**Check out the π€ [Pick a Tutorial page](pick-a-tutorial.md) π€. Choose an app that you'd like to build and it will take you through all the core features of Wasp!**
Also, we would be excited to have you **join our community on [Discord](https://discord.gg/rzdnErX)!** Any feedback or questions you have, we are there for you.
diff --git a/web/docs/language/features.md b/web/docs/language/features.md
index d330e7a92..b4fb5e5ec 100644
--- a/web/docs/language/features.md
+++ b/web/docs/language/features.md
@@ -7,7 +7,7 @@ title: Features
There can be only one declaration of `app` type per Wasp project.
It serves as a starting point and defines global properties of your app.
-```css
+```c
app todoApp {
wasp: {
version: "^0.6.0"
@@ -59,7 +59,7 @@ Check [`app.dependencies`](/docs/language/features#dependencies) for more detail
`page` declaration is the top-level layout abstraction. Your app can have multiple pages.
-```css
+```c
page MainPage {
component: import Main from "@client/pages/Main",
authRequired: false // optional
@@ -80,7 +80,7 @@ If set to `true`, only authenticated users will be able to access this page. Una
If `authRequired` is set to `true`, the React component of a page (specified by `component` property) will be provided `user` object as a prop.
-Check out this [section of our Todo app tutorial](/docs/tutorials/todo-app/auth#updating-main-page-to-check-if-user-is-authenticated) for an example of usage.
+Check out this [section of our Todo app tutorial](/docs/tutorials/todo-app/06-auth#updating-main-page-to-check-if-user-is-authenticated) for an example of usage.
## Route
@@ -622,7 +622,7 @@ Keep in mind that pg-boss jobs run alongside your other server-side code, so the
To declare a `job` in Wasp, simply add a declaration with a reference to an `async` function, like the following:
-```css title="main.wasp"
+```c title="main.wasp"
job mySpecialJob {
executor: PgBoss,
perform: {
@@ -649,7 +649,7 @@ And that is it! Your job will be executed by the job executor (pg-boss, in this
If you have work that needs to be done on some recurring basis, you can add a `schedule` to your job declaration:
-```css {6-9} title="main.wasp"
+```c {6-9} title="main.wasp"
job mySpecialJob {
executor: PgBoss,
perform: {
@@ -667,7 +667,7 @@ In this example, you do _not_ need to invoke anything in JavaScript. You can ima
### Fully specified example
Both `perform` and `schedule` accept `executorOptions`, which we pass directly to the named job executor when you submit jobs. In this example, the scheduled job will have a `retryLimit` set to 0, as `schedule` overrides any similar property from `perform`. Lastly, we add an entity to pass in via the context argument to `perform.fn`.
-```css
+```c
job mySpecialJob {
executor: PgBoss,
entities: [Task],
@@ -799,10 +799,10 @@ In the future, we will add support for picking any version you like, but we have
Wasp provides authentication and authorization support out-of-the-box. Enabling it for your app is optional and can be done by configuring `auth` field of the `app` declaration:
-```css
+```c
app MyApp {
title: "My app",
- // ...
+ //...
auth: {
userEntity: User,
methods: {
@@ -828,7 +828,7 @@ List of authentication methods that Wasp app supports. Currently supported metho
#### `onAuthFailedRedirectTo: String` (required)
Path where an unauthenticated user will be redirected to if they try to access a private page (which is declared by setting `authRequired: true` for a specific page).
-Check out this [section of our Todo app tutorial](/docs/tutorials/todo-app/auth#updating-main-page-to-check-if-user-is-authenticated) to see an example of usage.
+Check out this [section of our Todo app tutorial](/docs/tutorials/todo-app/06-auth#updating-main-page-to-check-if-user-is-authenticated) to see an example of usage.
#### `onAuthSucceededRedirectTo: String` (optional)
Path where a successfully authenticated user will be sent upon successful login/signup.
@@ -856,7 +856,7 @@ The quickest way to get started is by using the following API generated by Wasp:
- `useAuth()` React hook
**NOTE:** If the signup is successful, the Signup form will automatically log in the user.
-Check our [Todo app tutorial](/docs/tutorials/todo-app/auth) to see how it works. See below for detailed specification of each of these methods.
+Check our [Todo app tutorial](/docs/tutorials/todo-app/06-auth) to see how it works. See below for detailed specification of each of these methods.
#### Lower-level API
@@ -867,28 +867,35 @@ If you require more control in your authentication flow, you can achieve that in
The code of your custom sign-up action would look like this (your user entity being `User` in this instance):
```js
export const signUp = async (args, context) => {
- // Your custom code before sign-up.
- // ...
- const newUser = context.entities.User.create({
- data: { username: 'waspeteer', password: 'this will be hashed!' }
- })
+ // Your custom code before sign-up.
+ // ...
- // Your custom code after sign-up.
- // ...
- return newUser
+ const newUser = context.entities.User.create({
+ data: {
+ username: args.username,
+ password: args.password // password hashed automatically by Wasp! π
+ }
+ })
+
+ // Your custom code after sign-up.
+ // ...
+ return newUser
}
```
:::info
-You don't need to worry about hashing the password yourself! Even when you are using Prisma's client directly and calling `create()` with a plain-text password, Wasp put middleware in place that takes care of hashing it before storing it to the database. An additional middleware also performs field validation.
+You don't need to worry about hashing the password yourself! Even when you are using Prisma's client directly and calling `create()` with a plain-text password, Wasp's middleware takes care of hashing it before storing it in the database. An additional middleware also performs field validation.
:::
##### Customizing user entity validations
-To disable/enable default validations, or add your own, you can do:
+To disable/enable default validations, or add your own, you can modify your custom signUp function like so:
```js
const newUser = context.entities.User.create({
- data: { username: 'waspeteer', password: 'this will be hashed!' },
+ data: {
+ username: args.username,
+ password: args.password // password hashed automatically by Wasp! π
+ },
_waspSkipDefaultValidations: false, // can be omitted if false (default), or explicitly set to true
_waspCustomValidations: [
{
@@ -1082,9 +1089,24 @@ import AuthError from '@wasp/core/AuthError.js'
### Google
-`google` authentication makes it possible to use Google's OAuth 2.0 service to sign Google users into your app. To enable it, add `google: {}` to your `auth.methods` dictionary to use it with default settings. If you require custom configuration setup or user entity field assignment, you can override the defaults.
+`google` authentication makes it possible to use Google's OAuth 2.0 service to sign Google users into your app. To enable it, add `google: {}` to your `auth.methods` dictionary to use it with default settings:
+
+```js
+ //...
+
+ auth: {
+ userEntity: User,
+ externalAuthEntity: SocialLogin,
+ methods: {
+ google: {}
+ },
+ //...
+ }
+```
+This method requires also requires that `externalAuthEntity` be specified in `auth` as [described here](features#externalauthentity).
+
+If you require custom configuration setup or user entity field assignment, you can [override the defaults](#overrides).
-This method requires that `externalAuthEntity` specified in `auth` [described here](features#externalauthentity).
#### Default settings
- Configuration:
- By default, Wasp expects you to set two environment variables in order to use Google authentication:
@@ -1093,8 +1115,12 @@ This method requires that `externalAuthEntity` specified in `auth` [described he
- These can be obtained in your Google Cloud Console project dashboard. See [here](/docs/integrations/google#google-auth) for more.
- Sign in:
- When a user signs in for the first time, Wasp will create a new User account and link it to their Google account for future logins. The `username` will default to a random dictionary phrase that does not exist in the database, like "nice-blue-horse-27160".
- - Aside: If you would like to allow the user to select their own username, or some other sign up flow, you could add a boolean property to your User entity which indicates if the account setup is complete. You can then redirect them in your `onAuthSucceededRedirectTo` handler.
-- Here is a link to the default implementations: https://github.com/wasp-lang/wasp/blob/main/waspc/data/Generator/templates/server/src/routes/auth/passport/google/googleDefaults.js These can be overriden as explained below.
+ :::note Changing Random Username
+ If you would like to allow the user to select their own username, or some other sign up flow, you could add a boolean property to your User entity which indicates if the account setup is complete. You can then check this user's property on the client with the [`useAuth()`](#useauth) hook and redirect them when appropriate -- e.g. check on homepage if `user.isAuthSetup === false`, redirect them to `EditUserDetailsPage`.
+
+ Alternatively, you could add a `displayName` property to your User entity and assign it using the details of their Google account, as described in **Overrides** below
+ :::
+- Here is a link to the default implementations: https://github.com/wasp-lang/wasp/blob/release/waspc/data/Generator/templates/server/src/routes/auth/passport/google/googleDefaults.js . These can be overriden as explained below.
#### Overrides
If you require modifications to the above, you can add one or more of the following to your `auth.methods.google` dictionary:
diff --git a/web/docs/pick-a-tutorial.md b/web/docs/pick-a-tutorial.md
new file mode 100644
index 000000000..304b3fe0b
--- /dev/null
+++ b/web/docs/pick-a-tutorial.md
@@ -0,0 +1,32 @@
+---
+title: Pick a Tutorial
+---
+
+import useBaseUrl from '@docusaurus/useBaseUrl';
+import DiscordLink from '../blog/components/DiscordLink';
+
+Congrats, you're now familiar with the basic concepts of Wasp! π₯³
+
+It's time to build something cool and check the capabilities of Wasp in action. Pick one of the tutorials below and let us know your impressions on !
+
+### To-Do app
+
+[The To-Do app](tutorials/todo-app) is a thorough journey covering most of the Wasp's concepts, from very basics to features like auth, dependency management, operations, ... . If you'd like to get familiar with Wasp on a more detailed level - this is a tutorial for you!
+
+Time estimate: ~45 minutes
+
+### Dev excuses app
+
+[Dev excuses app](tutorials/dev-excuses-app) is a fun, quick overview of how you can build a full-stack app with Wasp in a matter of minutes. Do not expect any detailed concept explanations, and refer to this tutorial if you'd like to get a fast overview of Wasp's possibilities.
+
+Time estimate: ~20 minutes
+
+
+
+
+
+P.S: If you decided to build an app on your own - we'd love to see it! If it's simple enough, let's turn it into a tutorial! Please check our [contribution guide](contributing) for detailed instructions and reach us on Discord.
diff --git a/web/docs/tutorials/dev-excuses-app.md b/web/docs/tutorials/dev-excuses-app.md
new file mode 100644
index 000000000..c6263b0e9
--- /dev/null
+++ b/web/docs/tutorials/dev-excuses-app.md
@@ -0,0 +1,25 @@
+---
+title: Introduction
+---
+
+import useBaseUrl from '@docusaurus/useBaseUrl';
+import DiscordLink from '../../blog/components/DiscordLink';
+
+:::info
+Make sure you've set up Wasp! Check out [Getting Started](/getting-started.md) first for installation instructions, and then continue with the tutorial. In case of any issues - please, ping us on .
+:::
+
+Weβll build a web app to solve every developer's most common problem β finding an excuse to justify our messy work! We will start with a single config file that outlines the full-stack architecture of our app plus several dozen lines of code for our specific business logic. There's no faster way to do it, so we canβt excuse ourselves from building it!
+
+Weβll use Michele Gerarduzziβs [open-source project](https://github.com/michelegera/devexcuses-api). It provides a simple API and a solid number of predefined excuses. A perfect fit for our needs. Letβs define the requirements for the project:
+
+- The app must be able to pull excuses data from a public API.
+- Users can save the excuses they like (and your boss doesn't) to the database for future reference.
+- Building an app shouldnβt take more than 15 minutes.
+- Use modern web dev technologies (NodeJS + React)
+
+As a result β weβll get a simple and fun pet project. You can find the complete codebase [here](https://github.com/wasp-lang/wasp/tree/main/examples/tutorials/ItWaspsOnMyMachine).
+
+
\ No newline at end of file
diff --git a/web/docs/tutorials/dev-excuses-app/01-creating-the-project.md b/web/docs/tutorials/dev-excuses-app/01-creating-the-project.md
new file mode 100644
index 000000000..ac67ae1f8
--- /dev/null
+++ b/web/docs/tutorials/dev-excuses-app/01-creating-the-project.md
@@ -0,0 +1,28 @@
+---
+id: 01-creating-the-project
+title: Creating the project
+---
+
+import useBaseUrl from '@docusaurus/useBaseUrl';
+
+By now you've already learned [how to install Wasp and create a new project](/getting-started.md). So letβs create a new web app appropriately named `ItWaspsOnMyMachine`.
+
+```
+wasp new ItWaspsOnMyMachine
+```
+
+Changing the working directory:
+```
+cd ItWaspsOnMyMachine
+```
+
+Starting the app:
+```
+wasp start
+```
+
+Now your default browser should open up with a simple predefined text message. Thatβs it! π₯³ For now β the codebase consists of only two files! `main.wasp` is the config file that defines the applicationβs functionality. And `MainPage.js` is the front-end. You can delete `Main.css`, we won't use that. And don't forget to remove `import './Main.css'` from `MainPage.js` file.
+
+
\ No newline at end of file
diff --git a/web/docs/tutorials/dev-excuses-app/02-modifying-main-wasp-file.md b/web/docs/tutorials/dev-excuses-app/02-modifying-main-wasp-file.md
new file mode 100644
index 000000000..a7fe93871
--- /dev/null
+++ b/web/docs/tutorials/dev-excuses-app/02-modifying-main-wasp-file.md
@@ -0,0 +1,103 @@
+---
+id: 02-modifying-main-wasp-file
+title: Modifying main.wasp file
+---
+
+import useBaseUrl from '@docusaurus/useBaseUrl';
+
+First and foremost, we need to add some dependencies and introduce operations to our project. Weβll add Tailwind to make our UI prettier and Axios for making API requests.
+
+Also, weβll declare a database entity called `Excuse`, queries, and action. The `Excuse` entity consists of the entityβs ID and the text.
+
+`Queries` are here when we need to fetch/read something, while `actions` are here when we need to change/update data. Both query and action declaration consists of two lines β a reference to the file that contains implementation and a data model to operate on. You can find more info [in the docs section below](/docs/language/features#queries-and-actions-aka-operations). Let's move on!
+
+Let's add the following code to the `main.wasp` file's `app` section:
+
+```js title="main.wasp | Adding dependencies"
+ head: [
+ ""
+ ],
+
+ dependencies: [
+ ("axios", "^0.21.1")
+ ]
+```
+
+Next, we'll add an Excuse entity to the bottom of the file. You'll also need to define queries and an action that operates on nit.
+
+```js title="main.wasp | Defining Excuse entity, queries and action"
+entity Excuse {=psl
+ id Int @id @default(autoincrement())
+ text String
+psl=}
+
+query getExcuse {
+ fn: import { getExcuse } from "@ext/queries.js",
+ entities: [Excuse]
+}
+
+query getAllSavedExcuses {
+ fn: import { getAllSavedExcuses } from "@ext/queries.js",
+ entities: [Excuse]
+}
+
+action saveExcuse {
+ fn: import { saveExcuse } from "@ext/actions.js",
+ entities: [Excuse]
+}
+```
+The resulting `main.wasp` file should look like this:
+
+```js title="main.wasp | Final result"
+
+// Main declaration, defines a new web app.
+app ItWaspsOnMyMachine {
+
+ // Used as a browser tab title.
+ title: "It Wasps On My Machine",
+
+ head: [
+ // Adding Tailwind to make our UI prettier
+ ""
+ ],
+
+ dependencies: [
+ // Adding Axios for making HTTP requests
+ ("axios", "^0.21.1")
+ ]
+}
+
+// Render page MainPage on url `/` (default url).
+route RootRoute { path: "/", to: MainPage }
+
+// ReactJS implementation of our page located in `ext/MainPage.js` as a default export
+page MainPage {
+ component: import Main from "@ext/MainPage.js"
+}
+
+// Prisma database entity
+entity Excuse {=psl
+ id Int @id @default(autoincrement())
+ text String
+psl=}
+
+// Query declaration to get a new excuse
+query getExcuse {
+ fn: import { getExcuse } from "@ext/queries.js",
+ entities: [Excuse]
+}
+
+// Query declaration to get all excuses
+query getAllSavedExcuses {
+ fn: import { getAllSavedExcuses } from "@ext/queries.js",
+ entities: [Excuse]
+}
+
+// Action to save current excuse
+action saveExcuse {
+ fn: import { saveExcuse } from "@ext/actions.js",
+ entities: [Excuse]
+}
+```
+
+Perfect! We've set up all the architecture of our app. Now let's add some logic.
diff --git a/web/docs/tutorials/dev-excuses-app/03-adding-operations.md b/web/docs/tutorials/dev-excuses-app/03-adding-operations.md
new file mode 100644
index 000000000..cba4300f0
--- /dev/null
+++ b/web/docs/tutorials/dev-excuses-app/03-adding-operations.md
@@ -0,0 +1,35 @@
+---
+id: 03-adding-operations
+title: Adding operations
+---
+
+import useBaseUrl from '@docusaurus/useBaseUrl';
+
+Now you'll need to create two files: `actions.js` and `queries.js` in the `ext` folder.
+
+Letβs add `saveExcuse()` action to our `actions.js` file. This action will save the text of our excuse to the database.
+
+```js title=".../ext/actions.js | Defining an action"
+export const saveExcuse = async (excuse, context) => {
+ return context.entities.Excuse.create({
+ data: { text: excuse.text }
+ })
+}
+```
+
+Then we need to create two queries in the `queries.js` file. First, one `getExcuse` will call an external API and fetch a new excuse. The second one, named `getAllSavedExcuses`, will pull all the excuses weβve saved to our database.
+
+```js title=".../ext/queries.js | Defining queries"
+import axios from 'axios';
+
+export const getExcuse = async () => {
+ const response = await axios.get('https://api.devexcus.es/')
+ return response.data
+}
+
+export const getAllSavedExcuses = async (_args, context) => {
+ return context.entities.Excuse.findMany()
+}
+```
+
+Thatβs it! We finished our back-end. π Now, letβs use those queries/actions on our UI.
diff --git a/web/docs/tutorials/dev-excuses-app/04-updating-main-page-js-file.md b/web/docs/tutorials/dev-excuses-app/04-updating-main-page-js-file.md
new file mode 100644
index 000000000..a216a66cd
--- /dev/null
+++ b/web/docs/tutorials/dev-excuses-app/04-updating-main-page-js-file.md
@@ -0,0 +1,74 @@
+---
+id: 04-updating-main-page-js-file
+title: Updating MainPage.js file
+---
+
+import useBaseUrl from '@docusaurus/useBaseUrl';
+
+This is the most complex part, but it really comes down to mostly writing React. To make our life easier - letβs erase everything we had in the `MainPage.js` file and substitute it with our new UI markup.
+
+```js title=".../ext/MainPage.js | Updating the UI"
+import React, { useState } from 'react'
+import { useQuery } from '@wasp/queries'
+import getExcuse from '@wasp/queries/getExcuse'
+import getAllSavedExcuses from '@wasp/queries/getAllSavedExcuses'
+import saveExcuse from '@wasp/actions/saveExcuse'
+
+const MainPage = () => {
+ const [currentExcuse, setCurrentExcuse] = useState({ text: "" })
+ const { data: excuses } = useQuery(getAllSavedExcuses)
+
+ const handleGetExcuse = async () => {
+ try {
+ setCurrentExcuse(await getExcuse())
+ } catch (err) {
+ window.alert('Error while getting the excuse: ' + err.message)
+ }
+ }
+
+ const handleSaveExcuse = async () => {
+ if (currentExcuse.text) {
+ try {
+ await saveExcuse(currentExcuse)
+ } catch (err) {
+ window.alert('Error while saving the excuse: ' + err.message)
+ }
+ }
+ }
+
+ return (
+
+
+
+ )
+}
+
+export default DarkModeToggle
diff --git a/web/src/components/Faq.js b/web/src/components/Faq.js
new file mode 100644
index 000000000..254a8c88e
--- /dev/null
+++ b/web/src/components/Faq.js
@@ -0,0 +1,126 @@
+import React, { useState } from 'react'
+import Link from '@docusaurus/Link'
+import { ChevronDown, ChevronRight } from 'react-feather'
+
+import SectionContainer from './Layouts/SectionContainer'
+
+const faqs = [
+ {
+ question: 'How is Wasp different from Next.js / Nuxt.js / Gatsby?',
+ answer:
+ TL;DR - These are frontend-first frameworks, with some limited backend capabilities.
+ Wasp is a full-stack framework.
+
+ The main difference between Wasp and the solutions listed above is that Wasp is a trully full-stack
+ framework, meaning it brings both back-end and database next to front-end. You can think of it as
+ Ruby on Rails, but made for JS (React & Node.js) and full-stack.
+
+ Next.js, Gatsby and others started out as frontend frameworks for static sites. Although some of them
+ now offer an option to use serverless functions, you still have to bring your own database and you'll
+ also need some kind of a server/backend if you'll need to run more complex operations.
+
+ },
+ {
+ question: 'How is Wasp different from Ruby on Rails, Django, etc?',
+ answer:
+ TL;DR - These are backend frameworks, while Wasp covers full-stack, which makes it easier to sync and
+ reuse data models across the stack.
+
+ Back in the day when the whole UI was server-side rendered, Rails and Django were actually full-stack
+ frameworks. But, with the advent of SPAs and frontend frameworks such as React, they are today mostly
+ used as API servers, aka backend frameworks.
+
+ Wasp is a full-stack framework, which means it covers both frontend, backend and database at the same
+ time. That allows us to make it super easy to work with and sync data models across the entire
+ stack. You don't even have to define and deal with any kind of CRUD API - Wasp will do that for
+ you under the hood.
+
+ },
+ {
+ question: 'How hard is it to learn Wasp?',
+ answer:
+ We measured! It takes about 30 minutes to get going, and
+ most users find it pretty straight-forward.
+ Since the majority of your coding will still be done in the tools you're familiar with (currently
+ React & Node.js), it's really a marginal change to what you're used to.
+
+ The reason is for that is that Wasp is a really simple configuration language, without any
+ loops or variables - you can think of it as of a JSON that is easier to read and is a bit smarter.
+
+ Still, although simple (and we plan to keep it that way), it's a real language so you get all the
+ IDE goodies with it - syntax highlighting, auto-completion, live error reporting, ...
+
+ },
+ {
+ question: 'Do you support only React & Node.js currently?',
+ answer:
+ Yes, that is currently the supported stack. But, Wasp is being developed as a language/framework and
+ architecture-agnostic tool, so we plan to add support for more languages and frameworks in the future.
+
+ This is something we're pretty excited about and think could be potentially be a unique opportunity
+ due to the language approach we're taking with Wasp.
+
+ Given .wasp and .js(x)/.css/..., source files,
+ Wasp compiler generates the full source of your web app in
+ the target stack - front-end, back-end and deployment.
+
+
+ {/* Features */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{/* EOF Features */}
+
+
+
+
+
+
+
+
+
+
+ )
+
+}
+
+export default HowItWorks
diff --git a/web/src/components/Layouts/SectionContainer.js b/web/src/components/Layouts/SectionContainer.js
new file mode 100644
index 000000000..952fbde5d
--- /dev/null
+++ b/web/src/components/Layouts/SectionContainer.js
@@ -0,0 +1,18 @@
+import React from 'react'
+import classNames from 'classnames'
+
+const SectionContainer = ({ children, className, id }) => (
+
+ { children }
+
+)
+
+export default SectionContainer
diff --git a/web/src/components/Nav/SocialIcons.js b/web/src/components/Nav/SocialIcons.js
new file mode 100644
index 000000000..c76ed206f
--- /dev/null
+++ b/web/src/components/Nav/SocialIcons.js
@@ -0,0 +1,15 @@
+import React from 'react'
+
+export const DiscordIcon = () => (
+
+)
+
+export const TwitterIcon = () => (
+
+)
diff --git a/web/src/components/Nav/index.js b/web/src/components/Nav/index.js
new file mode 100644
index 000000000..2e1410405
--- /dev/null
+++ b/web/src/components/Nav/index.js
@@ -0,0 +1,216 @@
+import React from 'react'
+import Link from '@docusaurus/Link'
+import { Star, Twitter } from 'react-feather'
+
+import { DiscordIcon, TwitterIcon } from './SocialIcons'
+
+const Nav = () => {
+
+ const Logo = () => (
+
- Describe high-level features with Wasp DSL and write the rest of your logic
- in React, Node.js and Prisma.
-
-
-
-
-
-
-
-
-
{/* End of col. */}
-
-
-
-
-
{/* End of col. */}
-
-
{/* End of row. */}
-
-
-
-
-
-
- curl -sSL https://get.wasp-lang.dev/installer.sh | sh
-
-
- {/* TODO: Martin commented tihs out because both buttons started showing up on desktop after upgrading to newer docusaurus. This happens when built for deployment, not during serving for development. Instead, he replaced it with just one version of button, below, instead of having one button for mobile and one for desktop.
-
-
-
-
-
-
- Try Wasp in 5 minutes β
-
-
- */}
-
-
-
- Try Wasp in 5 minutes β
-
-
-
-
-
-
- Using Windows? Check the instructions here.
-
-
-
-
-
-
-
-
-
1. Open your terminal and run:
-
- curl -sSL https://get.wasp-lang.dev/installer.sh | sh
-
-
-
2. Create a new project:
-
- wasp new MyFirstApp
-
-
-
3. Run your first app:
-
- cd MyFirstApp && wasp start
-
-
- That's it!
- Open http://localhost:3000 and see how it looks like!
-
-
-
-
- You ran into problems or want more details? Refer to the docs.
-
-
- Wasp is an open source, declarative DSL for devs who want to use modern web dev stack
-
-
- (React ,
- Node.js ,
- Prisma ,
- ...)
-
-
- without writing boilerplate.
-
-
-
Frontend, backend and deployment - all unified with one concise language.
-
Zero configuration, all best practices.
-
-
-
-
-
-
-
-
- {/* Wasp compilation */}
-
-
-
-
-
-
How it works
-
-
- Given .wasp + .js, .css, ... files as an input, Wasp compiler behind the scene
- generates the full
- source code of your web app - front-end, back-end and deployment.
-
-
- )}
-
-
-
- {/* Quick to start, easy to scale */}
-
-
-
-
-
Quick to start, easy to scale
-
-
- Wasp aims to be at least as flexible as the traditional web frameworks like Ruby on Rails.
-
- Start your project quickly with the best defaults and customize and scale it as it grows.
-
-
-
-
As an example, we used Wasp to implement a copy of Medium: