From 107e9901a0b6762b490d8be98cb248a99bf7872d Mon Sep 17 00:00:00 2001
From: Paul Copplestone
Date: Thu, 2 Jul 2020 08:28:18 +0800
Subject: [PATCH 01/91] Adds June Updates
---
web/blog/2020-06-15-supabase-steve-chavez.md | 18 +
.../2020-07-01-supabase-alpha-june-2020.md | 67 +++
...20-02-26-basic-slack-clone-react-hooks.mdx | 453 ------------------
...20-04-03-basic-slack-clone-react-hooks.mdx | 68 ---
4 files changed, 85 insertions(+), 521 deletions(-)
create mode 100644 web/blog/2020-06-15-supabase-steve-chavez.md
create mode 100644 web/blog/2020-07-01-supabase-alpha-june-2020.md
delete mode 100644 web/blog/DRAFT-2020-02-26-basic-slack-clone-react-hooks.mdx
delete mode 100644 web/blog/DRAFT-2020-04-03-basic-slack-clone-react-hooks.mdx
diff --git a/web/blog/2020-06-15-supabase-steve-chavez.md b/web/blog/2020-06-15-supabase-steve-chavez.md
new file mode 100644
index 00000000000..df616aad07f
--- /dev/null
+++ b/web/blog/2020-06-15-supabase-steve-chavez.md
@@ -0,0 +1,18 @@
+---
+title: Steve Chavez has joined Supabase
+description: Steve joins Supabase to help build Auth.
+author: Paul Copplestone
+author_title: Supabase
+author_url: https://github.com/kiwicopple
+author_image_url: https://avatars2.githubusercontent.com/u/10214025?s=400&u=c6775be2ae667e2acae3ccd347fed62bb3f5b3e7&v=4
+authorURL: https://github.com/kiwicopple
+---
+
+This month we welcome [Steve Chavez](https://github.com/steve-chavez) to the team. Steve is a maintainer of PostgREST, one of the core tools which makes Supabase possible.
+
+
+
+Steve and I have been in contact since he [added one of my old blog posts](https://github.com/PostgREST/postgrest-docs/commit/3dde972d31519d3afc319015bce1dc0f73adeb8e#commitcomment-35312841) to the PostgREST docs. He has a rich history in open source and we're excited to have him in our team.
+
+Steve is helping us build one of our most demanded features - our Auth system. We will support him to build some exciting features which he has planned for PostgREST, including enhanced PostGIS support.
+
diff --git a/web/blog/2020-07-01-supabase-alpha-june-2020.md b/web/blog/2020-07-01-supabase-alpha-june-2020.md
new file mode 100644
index 00000000000..bdff1b381f8
--- /dev/null
+++ b/web/blog/2020-07-01-supabase-alpha-june-2020.md
@@ -0,0 +1,67 @@
+---
+title: Supabase Alpha June 2020
+description: Four months of building
+author: Paul Copplestone
+author_title: Supabase
+author_url: https://github.com/kiwicopple
+author_image_url: https://avatars2.githubusercontent.com/u/10214025?s=400&u=c6775be2ae667e2acae3ccd347fed62bb3f5b3e7&v=4
+authorURL: https://github.com/kiwicopple
+---
+
+We're now 4 months into building [Supabase](https://supabase.io), which means another major update. Here's a few things we think you'll love in this release.
+
+
+
+### 4 minute demo
+
+Watch a full demo:
+
+
+
+### View relational data
+
+We're sometimes asked how we will make Postgres as simple as Firebase, since Postgres is a relational database. This month we're making our first steps to prove that relational databases can be even easier to use than document stores. We're releasing an excel-like editing interface which can drill down into your relational data.
+
+
+
+### Manage JSON data
+
+Postgres is an amazing database, giving the flexibility of a document store with the power of a RDBMS. If you use `JSON` data in Postgres, then we want to make that easy too. Supabase detects when your column is `JSON` or `JSONB`, and provides an easy way to edit and view your data. More improvements coming soon for this feature!
+
+
+
+### Choose your region
+
+If you noticed a bit of latency on Supabase, it's because your projects were previously set up in Singapore. It was always our intention that you'd be able to choose your database region, and this month we've delivered it. In the next releases we'll even allow you to go multi-region, instantly replicating your database close to your customers.
+
+
+
+### Backups
+
+A guiding principle at Supabase is zero lock-in. So this month we are exposing your daily database backups on the dashboard, giving you a simple way to migrate off Supabase. We have a lot more to build in this space (`WAL-G!`), so watch this space.
+
+
+
+### Kaizen
+
+We have a number of small improvements:
+
+- Improved SQL editor - with better syntax highlighting
+- Improved API docs - with more code snippets
+- UX improvements - with a simplified and consistent UX
+
+### Hiring
+
+- This month we [welcome Steve Chavez to the team](/blog/2020/06/15/supabase-steve-chavez). Steve is a maintainer of PostgREST, one of the core tools which makes Supabase possible.
+- We're hiring a part-time designer or UX expert. See more [here](https://news.ycombinator.com/item?id=23708351).
+
+### Get started
+
+- Start using Supabase today: [app.supabase.io](https://app.supabase.io)
+- Make sure to [star us on GitHub](https://github.com/supabase/supabase)
+- Follow us [on Twitter](https://twitter.com/supabase_io)
+- Become a [sponsor]()
+
+
+
+
\ No newline at end of file
diff --git a/web/blog/DRAFT-2020-02-26-basic-slack-clone-react-hooks.mdx b/web/blog/DRAFT-2020-02-26-basic-slack-clone-react-hooks.mdx
deleted file mode 100644
index 8d51f416cca..00000000000
--- a/web/blog/DRAFT-2020-02-26-basic-slack-clone-react-hooks.mdx
+++ /dev/null
@@ -1,453 +0,0 @@
----
-title: DRAFT - Slack clone
-description: Building a basic Slack clone with Postgres and React Hooks
-author: Paul Copplestone
-author_title: Supabase
-author_url: https://github.com/kiwicopple
-author_image_url: https://avatars2.githubusercontent.com/u/10214025?s=400&u=c6775be2ae667e2acae3ccd347fed62bb3f5b3e7&v=4
-authorURL: https://github.com/kiwicopple
-tags: [postgres, react]
-draft: true
----
-
-import Figure from '../src/components/Figure'
-import Mermaid from '../src/components/Mermaid'
-import CustomCodeBlock from '../src/components/CustomCodeBlock'
-import * as Snippets from '../support/blogBasicSlackClone'
-
-
-This guide uses Docker Compose to simplify Postgres setup and data loading.
-We won't go over how to use Docker, but as long as you have it installed and running it will be simple to follow along.
-
-
-[Full code](https://github.com/supabase/supabase/blob/master/examples/slack-clone-basic/README.md) |
-[HN Discussion](https://new.ycombinator.com) |
-[Dev Article](https://dev.to)
-
-
-
-
-## Introduction
-
-This is a thorough guide that will step you through four useful technologies which can scale up to production-ready realtime applications:
-
-- [PostgreSQL](https://www.postgresql.org) - an extremely scalable relational database
-- [Supabase](https://supabase.io) - a JS wrapper for Postgres for instant realtime and RESTful APIs
-- [Next.js](https://nextjs.org/) - a JS framework for building server-rendered React apps
-- [Tailwind](https://tailwindcss.com/) - a CSS framework for quickly styling our frontend app
-
-NextJs-->Supabase
-Postgres-->Supabase-->Postgres
-NextJs-.-Tailwind
-subgraph Frontend
-NextJs
-Tailwind
-end
-subgraph Backend
-Postgres
-Supabase
-end
-`}
-/>
-
-
-## Stage 1: Setup the project
-
-
-
-
-### Create the application
-
-We will create a new Next.js app called `slack-clone-basic`, using the [Next.js SASS example](https://github.com/zeit/next.js/tree/master/examples/with-next-sass) to get us started:
-
-
-
-
-
-This comes with [SASS](https://duckduckgo.com/?q=sass+css&t=ffab&ia=web) built in. You don't need to know anything about SASS, except that it will be useful for Tailwind later on.
-
-
-### Install dependencies
-
-Now let's install our dependencies inside the `./slack-clone-basic` folder:
-
-
-
-- `@supabase/supabase-js` - for interacting with the database. This will handle all the APIs and realtime functionality
-- `tailwindcss` - for making our frontend look great
-
-
-### Setup all the files
-
-```bash
-mkdir components && touch components/MessageInput.js && \
-mkdir db && touch db/schema.sql && \
-touch pages/{[channelId].js} && \
-touch Store.js && \
-touch docker-compose.yml
-```
-
-You will now have the following boilerplate, ready to fill in with code.
-
-```bash
-├── components
-│ └── MessageInput.js # The text input for writing new messages
-├── db
-│ └── schema.sql # Basic schema and dummy data
-├── pages
-│ ├── [channelId].js # Page for showing all the messages in a channel
-│ └── index.js # Home page
-├── styles
-│ └── style.scss # SASS file for styling our app
-├── next.config.js # For passing ENV variables to our app
-├── Store.js # A basic data store using React Hooks
-└── docker-compose.yml # Docker compose for Postgres and Supabase
-```
-
-By now you can get a simle app running
-
-```
-npm run dev
-```
-
-Visit http://localhost:3000 and you should see a page with a nice green "Hello World!"
-
-## Stage 2: Setup the backend
-
-
-
-All the code for this section can be found in stage-2-backend
-
-
-### Setting up Postgres
-
-Let's sketch out the simplest possible database schema we can use.
-
-
-
-Save the corresponding schema in `./db/schema.sql`:
-
-
-
-This schema will be automatically created when we start our Docker Compose.
-
-### Setting up the APIs
-
-This is the easiest step of all - you don't have to do anything!
-
-Supabase will introspect your database and provide you with APIs and websockets once we start Docker Compose.
-
-
-### Fire up the Backend
-
-Now lets start Docker Compose. Fill in the docker compose file with the following code:
-
-
-
-Now run `docker-compose up`. If you set everything up correctly, you should be able to visit
-[http://localhost:8000/rest/v1/messages?apikey=examplekey](http://localhost:8000/rest/v1/messages?apikey=examplekey)
-where you will see some of the messages that were created in the database.
-
-From now on you can forget about this route! Supabase will take care of everything when working with the database.
-
-Let's leave this running for the remainder of the tutorial.
-
-### Add ENV variables to Next JS
-
-Let Next.js know how to access Supabase.
-
-
-
-
-## Stage 3: Setup the Frontend
-
-
-
-
-
-### Building a basic store with React hooks
-
-
-
-
-### Displaying our messages
-
-
-
-
-Visit http://localhost:3000/2 and you will see a page with 2 buttons, and the channel ID displayed.
-
-## Stage 4: Making it look like Slack
-
-
-All the code for this section can be found ..
-
-
-
-Now we get to see the power of Tailwind to quickly prototype a frontend.
-
-### Import Tailwind
-
-Add the following code:
-
-
-
-### Updating the channels page
-
-Add the following changes to `./pages/[channelId].js`.
-Ignore anything annotated with comments, which is just done to abbreviate the code snippets.
-You won't delete any code in this section, you just need to add classNames to all JSX!
-
-#### Import the stylesheet
-
-```js
-import '../styles/style.scss'
-```
-
-#### Layout the sidebar and main content
-
-```js {1,2,5}
-
-
- {/* Sidebar content */}
-
-
- {/* Message content */}
-
-
-```
-
-#### Style the messages
-
-```js {3,6}
-{messages.map(message => (
-
-
- {message.author.username}
-
-
- {message.message}
-
-
-))}
-```
-
-#### "New Channel" button
-
-```js {1}
-
- New Channel
-
-```
-
-#### Channel list
-
-```js {1,7}
-Channels
-
-```
-
-
-
-## Stage 5: Adding realtime functionality
-
-Make the following changes to the store.
-
-
-
-### Handle new messages
-
-```js
-const [newMessage, handleNewMessage] = useState(null)
-
-// New message recieved from Postgres
-useEffect(() => {
- if (newMessage) {
- let author = users.get(newMessage.user_id)
- setMessages(messages.concat({...newMessage, author }))
- }
-}, [newMessage])
-
-```
-
-### Lisen to the database
-
-```js {5-16}
-useEffect(() => {
- fetchChannels(setChannels)
- fetchMessages(setMessages)
-
- // Listen for new messages
- const messageListener = supabase
- .from('messages')
- .eq('channel_id', channelId)
- .on('*', payload => handleNewMessage(payload.new))
- .subscribe()
-
-
- return () => {
- // Cleanup on unmount
- messageListener.unsubscribe()
- }
-})
-```
-
-## Stage 6: Sending new messages
-
-For now we will assume that we are user 2 (tonystark).
-
-### Add to store
-
-
-```js
-export const addMessage = async (message, channel_id, user_id) => {
- try {
- let { body } = await supabase.from('messages').insert([{ message, channel_id, user_id }])
- return body
- } catch (error) {
- console.log('error', error)
- }
-}
-```
-
-### Add message component
-
-
-Create component
-
-```js
-import { useState } from 'react'
-import { addMessage } from '~/lib/Store'
-
-const MessageInput = ({ channelId }) => {
- const [messageText, setMessageText] = useState('')
-
- const submitOnEnter = event => {
- // Watch for enter key
- if (event.keyCode === 13) {
- addMessage(messageText, channelId, 2)
- setMessageText('')
- }
- }
-
- return (
- <>
- setMessageText(e.target.value)}
- onKeyDown={e => submitOnEnter(e)}
- />
- >
- )}
-
-export default MessageInput
-```
-
-Add to Channel Page
-
-```js
-// @todo
-
-```
-
-## Wrapping up
-
-- You now have a realtime application. Open on multiple browsers to see realtime.
-- The combination of Docker + Postgres + Supabase made it quick and easy to get going on our local machines so that we could spend most of the time building the product.
-- Link to the example with user auth, adding channels
-
-
-If you liked this tutorial, make sure to sign up for [Supabase](http://supabase.io) as we continue to bring all the functionality of Firebase to Postgres.
diff --git a/web/blog/DRAFT-2020-04-03-basic-slack-clone-react-hooks.mdx b/web/blog/DRAFT-2020-04-03-basic-slack-clone-react-hooks.mdx
deleted file mode 100644
index 3768ca6b965..00000000000
--- a/web/blog/DRAFT-2020-04-03-basic-slack-clone-react-hooks.mdx
+++ /dev/null
@@ -1,68 +0,0 @@
----
-title: Building a basic Slack clone with Postgres and React Hooks
-description: Building a basic Slack clone with Postgres and React Hooks
-author: Paul Copplestone
-author_title: Supabase
-author_url: https://github.com/kiwicopple
-author_image_url: https://avatars2.githubusercontent.com/u/10214025?s=400&u=c6775be2ae667e2acae3ccd347fed62bb3f5b3e7&v=4
-authorURL: https://github.com/kiwicopple
-draft: true
----
-
-import Figure from '../src/components/Figure'
-import Mermaid from '../src/components/Mermaid'
-import CustomCodeBlock from '../src/components/CustomCodeBlock'
-import * as Snippets from '../support/blogBasicSlackClone'
-
-
-This is the first of a multi-part series that will show you how to build a simple Slack clone.
-
-[Full code](https://github.com/supabase/supabase/blob/master/examples/slack-clone-basic/README.md) |
-[Subscribe](http://eepurl.com/gPWkwn)
-
-
-
-
-
-
-- [Building a basic Slack clone with Postgres and React Hooks](/blog/2020/04/03/basic-slack-clone-react-hooks)
-- Building a Slack backend [COMING SOON]
-- Building a Slack frontend [COMING SOON]
-- Adding realtime functionality [COMING SOON]
-
-
-Throughout the series you'll learn how to use four amazing technologies that scale up to production-ready realtime applications:
-
-- [PostgreSQL](https://www.postgresql.org) - an extremely scalable relational database
-- [Supabase](https://supabase.io) - a JS wrapper for Postgres for instant realtime and RESTful APIs
-- [Next.js](https://nextjs.org/) - a JS framework for building server-rendered React apps
-- [Tailwind](https://tailwindcss.com/) - a CSS framework for quickly styling our frontend app
-
-NextJs-->Supabase
-Postgres-->Supabase-->Postgres
-NextJs-.-Tailwind
-subgraph Frontend
-NextJs
-Tailwind
-end
-subgraph Backend
-Postgres
-Supabase
-end
-`}
-/>
-
-## Subscribe to this series
-
-Make sure you [subscribe to our newsletter](http://eepurl.com/gPWkwn) if you want to get notified when we release the next post in this series.
\ No newline at end of file
From 800e00b2e37db6862e40a6bbaf9d913624769647 Mon Sep 17 00:00:00 2001
From: Paul Copplestone
Date: Thu, 2 Jul 2020 09:38:35 +0800
Subject: [PATCH 02/91] fix: adds missing sponsors link
---
web/blog/2020-07-01-supabase-alpha-june-2020.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/blog/2020-07-01-supabase-alpha-june-2020.md b/web/blog/2020-07-01-supabase-alpha-june-2020.md
index bdff1b381f8..74e4f77ac6f 100644
--- a/web/blog/2020-07-01-supabase-alpha-june-2020.md
+++ b/web/blog/2020-07-01-supabase-alpha-june-2020.md
@@ -60,7 +60,7 @@ We have a number of small improvements:
- Start using Supabase today: [app.supabase.io](https://app.supabase.io)
- Make sure to [star us on GitHub](https://github.com/supabase/supabase)
- Follow us [on Twitter](https://twitter.com/supabase_io)
-- Become a [sponsor]()
+- Become a [sponsor](https://github.com/sponsors/supabase)
From 4000fd2d519b4b6d10576972cbedbf36c64e4841 Mon Sep 17 00:00:00 2001
From: Paul Copplestone
Date: Fri, 3 Jul 2020 19:42:40 +0800
Subject: [PATCH 03/91] fix: broken "Learn more" link after upgrading
docusaurus
---
web/src/pages/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/src/pages/index.js b/web/src/pages/index.js
index bf25d58ec32..3e47bc49ff5 100755
--- a/web/src/pages/index.js
+++ b/web/src/pages/index.js
@@ -157,7 +157,7 @@ function Home() {
'button hero--button button--md button--secondary button--outline responsive-button',
styles.button
)}
- to={useBaseUrl('docs/about')}
+ to={useBaseUrl('docs')}
style={{ marginLeft: 0, marginTop: 10 }}
>
Learn More
From 4647a9b134cfe5af81523db4c4886ba1cc349a78 Mon Sep 17 00:00:00 2001
From: Paul Copplestone
Date: Sun, 5 Jul 2020 10:11:22 +0800
Subject: [PATCH 04/91] fix: attempt to fix the strange bug where sponsors
links go to the same user
---
web/src/pages/oss.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/web/src/pages/oss.js b/web/src/pages/oss.js
index fee5a5cc3d3..0f5d4307921 100644
--- a/web/src/pages/oss.js
+++ b/web/src/pages/oss.js
@@ -84,8 +84,8 @@ export default function Oss() {
Thanks to these contributors for their sponsorship:{' '}
- @reverie ,{' '}
- @saphp
+ @reverie ,{' '}
+ @saphp
From 84b7ae20d6423474ea716054a2bc000eddc85af1 Mon Sep 17 00:00:00 2001
From: Paul Copplestone
Date: Sun, 5 Jul 2020 10:50:58 +0800
Subject: [PATCH 05/91] fix: very annoying. React build doesnt seem to handle
links well when they are in the same dom block. I've made the sponsor links a
list to mitigate the sponsor links pointing to the same github profile
---
web/src/pages/oss.js | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/web/src/pages/oss.js b/web/src/pages/oss.js
index 0f5d4307921..e2ce2cf0427 100644
--- a/web/src/pages/oss.js
+++ b/web/src/pages/oss.js
@@ -9,12 +9,12 @@ import { repos } from '../data/github'
export default function Oss() {
const context = useDocusaurusContext()
const { siteConfig = {} } = context
-
+
// Take only the start of each month
const monthlySummary = stargazers.filter((x) => {
const currentDate = new Date(x.name)
const dayOfWeek = currentDate.getDate()
- if (dayOfWeek == 1) return true
+ if (dayOfWeek == 1) return true
else return false
})
@@ -84,8 +84,18 @@ export default function Oss() {
Thanks to these contributors for their sponsorship:{' '}
- @reverie ,{' '}
- @saphp
+
From ec8e0b64ab62378ac08c9316c23d05cabcf2e48f Mon Sep 17 00:00:00 2001
From: awalias
Date: Mon, 6 Jul 2020 17:16:09 +0800
Subject: [PATCH 06/91] typo
---
web/docs/about.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/docs/about.md b/web/docs/about.md
index 8cae1a9c807..d5a19c9bc59 100755
--- a/web/docs/about.md
+++ b/web/docs/about.md
@@ -36,7 +36,7 @@ For all Restful functionality, we introspect your database to provide an instant
- You own your data. Realtime can be pointed at any PostgreSQL database that has replication enabled.
- Listening to data changes on client side solves stale data problems and update collisions.
- Many systems that give you realtime functionality require you to update via the same interface that the listener is on. Supabase is source agnostic. Update your database from anywhere and you'll still get the changes.
-- Scale the realtime servers without putting any additional load on your DB. All you need is one connection to your database, and you can handle thousands (or millions) or users
+- Scale the realtime servers without putting any additional load on your DB. All you need is one connection to your database, and you can handle thousands (or millions) of users
## Where it is
From 013c6668b2d9f9b3665afaba5d1e9904b2a30aa3 Mon Sep 17 00:00:00 2001
From: Paul Copplestone
Date: Thu, 9 Jul 2020 16:48:28 +0800
Subject: [PATCH 07/91] blog: adds the post "What are PostgreSQL templates?"
---
web/blog/2020-07-09-postgresql-templates.md | 82 +++++++++++++++++++++
1 file changed, 82 insertions(+)
create mode 100644 web/blog/2020-07-09-postgresql-templates.md
diff --git a/web/blog/2020-07-09-postgresql-templates.md b/web/blog/2020-07-09-postgresql-templates.md
new file mode 100644
index 00000000000..7688d6ea6c0
--- /dev/null
+++ b/web/blog/2020-07-09-postgresql-templates.md
@@ -0,0 +1,82 @@
+---
+title: What are PostgreSQL templates?
+description: What are PostgreSQL templates and what are they used for?
+author: Angelico de los Reyes
+author_title: Supabase
+author_url: https://github.com/dragarcia
+author_image_url: https://avatars0.githubusercontent.com/u/26374889?s=400&u=f5e35e9b47a50fa2b4d8c4bb96babd921071bcf1&v=4
+authorURL: https://github.com/dragarcia
+---
+
+Whenever you create a new database in Postgres, you are actually [basing it off an already present database](https://www.postgresql.org/docs/current/manage-ag-templatedbs.html) in your cluster.
+
+
+
+This database, `template1`, and another, called `template0`, are standard system databases that exist in every newly created database cluster. Don't believe me? Why not quickly [spin up a database](/docs/postgres/postgres-intro) and see it for yourself with this query:
+```sql
+SELECT * FROM pg_database;
+```
+
+In this post, we'll explore these template databases and see how we can make full use of their potential. We'll even look into creating a template database of our own.
+
+## template1
+By default, running:
+```sql
+CREATE DATABASE new_db_name;
+```
+simply copies everything from the database `template1`. We can modify this template database in any way: add a table, insert some data, create new extensions, or install procedural languages. Any of these actions would be propagated to subsequently created databases.
+
+This, however, is **not** advisable. Removing any one of these modifications would need you to manually uninstall or drop these changes from `template1`. You do have the option to drop and recreate the entire `template1` database altogether. This unfortunately comes at the risk of committing a mistake along the way, effectively breaking `CREATE DATABASE`. It would be better to leave `template1` alone and create a template database of your own.
+
+
+## Custom Template Databases
+
+To set an existing database as a template database:
+```sql
+ALTER DATABASE template_db_name WITH is_template TRUE;
+```
+Doing this allows any user or role with the `CREATEDB` privilege to utilize it as a template. If not, only superusers or owners of the database would be allowed to do so.
+
+To create a new database with this template:
+
+```sql
+CREATE DATABASE new_db_name TEMPLATE template_db_name;
+```
+
+### Advantages
+
+- With this, you can now have customized templates without the need to worry about polluting `template1`.
+- You can safely drop the entire custom template database without the risk of breaking `CREATE DATABASE`.
+- If you wish, you can create multiple template databases for various use cases.
+
+### Limitations
+
+- To properly create a database from a custom template database, there should be no other connections present. `CREATE DATABASE` immediately fails if any connections exist at the start of the query.
+- As such, if you are looking to replicate a database while maintaining your connections (eg. a production database), it would be more ideal to use the Postgres utility [pg_dump](https://www.postgresql.org/docs/12/app-pgdump.html).
+
+
+## template0
+
+`template0` contains the same data as `template1`. We could think of this template database as a fallback if anything irreversible happens to `template1`. As such, this template database should never be modified in any way as soon as the database cluster has been initialized. To create a database with `template0` as the template database:
+```sql
+CREATE DATABASE new_db_name TEMPLATE template0;
+```
+
+### Applications
+- If anything goes wrong with `template1`, It can be dropped and recreated with `template0` as the template database.
+- We can also create a clean database that does not contain any modifications present in `template1`. This would be useful when restoring from pg_dump. Any conflicts brought about by modifications not present in the dump are eliminated.
+- `template0` can be used to specify new encodings. As pointed out in this [article](https://hashrocket.com/blog/posts/exploring-the-default-postgres-template-databases#:~:text=we%20can't%20edit%20the%20locale%20or%20encoding%20of%20a%20database%20copied%20from%20template1), creating a new database with `template1` and new encodings would result in an error.
+```sql
+-- Will succeed
+CREATE DATABASE new_db_name TEMPLATE template0 ENCODING 'SQL_ASCII';
+
+-- Will return an error
+CREATE DATABASE new_db_name ENCODING 'SQL_ASCII';
+```
+
+
+## Conclusion
+
+To quickly sum things up, we found out that new databases are, by default, created from a template database called `template1`. `template1` can be modified in any way we please and the changes would be present in any database created afterward. We can also create custom template databases and base new databases from them instead. If things go awry, `template0` is always there to help.
+
+
From 30d50c9f98575a69deefb4c6033365423fcb47cd Mon Sep 17 00:00:00 2001
From: Paul Copplestone
Date: Sat, 11 Jul 2020 10:31:06 +0800
Subject: [PATCH 08/91] Adds a new blog post, newsletter subscription link, and
image plugin
---
.../2020-05-01-supabase-alpha-april-2020.md | 2 +
.../2020-06-01-supabase-alpha-may-2020.md | 2 +
web/blog/2020-06-15-supabase-steve-chavez.md | 3 +
.../2020-07-01-supabase-alpha-june-2020.md | 2 +
web/blog/2020-07-09-postgresql-templates.md | 2 +
web/blog/2020-07-10-surviving-hacker-news.md | 107 +++
web/docusaurus.config.js | 1 +
web/package-lock.json | 864 +++++++++++++++++-
web/package.json | 1 +
web/src/theme/BlogPostItem/index.js | 22 +-
.../img/digital-ocean-emails-errors.png | Bin 0 -> 408744 bytes
web/static/img/hn-launch.png | Bin 0 -> 16301 bytes
web/static/img/supabase-github-stars-june.png | Bin 0 -> 52538 bytes
web/static/img/supabase-middleware-docker.png | Bin 0 -> 1771237 bytes
web/static/img/supabase-traffic-may.png | Bin 0 -> 39108 bytes
15 files changed, 995 insertions(+), 11 deletions(-)
create mode 100644 web/blog/2020-07-10-surviving-hacker-news.md
create mode 100644 web/static/img/digital-ocean-emails-errors.png
create mode 100644 web/static/img/hn-launch.png
create mode 100644 web/static/img/supabase-github-stars-june.png
create mode 100644 web/static/img/supabase-middleware-docker.png
create mode 100644 web/static/img/supabase-traffic-may.png
diff --git a/web/blog/2020-05-01-supabase-alpha-april-2020.md b/web/blog/2020-05-01-supabase-alpha-april-2020.md
index 52f15c39ece..f61f77c6b4a 100644
--- a/web/blog/2020-05-01-supabase-alpha-april-2020.md
+++ b/web/blog/2020-05-01-supabase-alpha-april-2020.md
@@ -6,6 +6,8 @@ author_title: Supabase
author_url: https://github.com/kiwicopple
author_image_url: https://avatars2.githubusercontent.com/u/10214025?s=400&u=c6775be2ae667e2acae3ccd347fed62bb3f5b3e7&v=4
authorURL: https://github.com/kiwicopple
+tags:
+ - supabase
---
Now in [Supabase](https://app.supabase.io):
diff --git a/web/blog/2020-06-01-supabase-alpha-may-2020.md b/web/blog/2020-06-01-supabase-alpha-may-2020.md
index 75d7da7b623..acd599d2e45 100644
--- a/web/blog/2020-06-01-supabase-alpha-may-2020.md
+++ b/web/blog/2020-06-01-supabase-alpha-may-2020.md
@@ -6,6 +6,8 @@ author_title: Supabase
author_url: https://github.com/kiwicopple
author_image_url: https://avatars2.githubusercontent.com/u/10214025?s=400&u=c6775be2ae667e2acae3ccd347fed62bb3f5b3e7&v=4
authorURL: https://github.com/kiwicopple
+tags:
+ - supabase
---
It has been a monster month at [Supabase](https://supabase.io) and we're back with a video update. It's a longer video this month because we have a couple of housekeeping items.
diff --git a/web/blog/2020-06-15-supabase-steve-chavez.md b/web/blog/2020-06-15-supabase-steve-chavez.md
index df616aad07f..5884778d7c3 100644
--- a/web/blog/2020-06-15-supabase-steve-chavez.md
+++ b/web/blog/2020-06-15-supabase-steve-chavez.md
@@ -6,6 +6,9 @@ author_title: Supabase
author_url: https://github.com/kiwicopple
author_image_url: https://avatars2.githubusercontent.com/u/10214025?s=400&u=c6775be2ae667e2acae3ccd347fed62bb3f5b3e7&v=4
authorURL: https://github.com/kiwicopple
+tags:
+ - supabase
+ - hiring
---
This month we welcome [Steve Chavez](https://github.com/steve-chavez) to the team. Steve is a maintainer of PostgREST, one of the core tools which makes Supabase possible.
diff --git a/web/blog/2020-07-01-supabase-alpha-june-2020.md b/web/blog/2020-07-01-supabase-alpha-june-2020.md
index 74e4f77ac6f..a17c2481756 100644
--- a/web/blog/2020-07-01-supabase-alpha-june-2020.md
+++ b/web/blog/2020-07-01-supabase-alpha-june-2020.md
@@ -6,6 +6,8 @@ author_title: Supabase
author_url: https://github.com/kiwicopple
author_image_url: https://avatars2.githubusercontent.com/u/10214025?s=400&u=c6775be2ae667e2acae3ccd347fed62bb3f5b3e7&v=4
authorURL: https://github.com/kiwicopple
+tags:
+ - supabase
---
We're now 4 months into building [Supabase](https://supabase.io), which means another major update. Here's a few things we think you'll love in this release.
diff --git a/web/blog/2020-07-09-postgresql-templates.md b/web/blog/2020-07-09-postgresql-templates.md
index 7688d6ea6c0..ad0f758f0d6 100644
--- a/web/blog/2020-07-09-postgresql-templates.md
+++ b/web/blog/2020-07-09-postgresql-templates.md
@@ -6,6 +6,8 @@ author_title: Supabase
author_url: https://github.com/dragarcia
author_image_url: https://avatars0.githubusercontent.com/u/26374889?s=400&u=f5e35e9b47a50fa2b4d8c4bb96babd921071bcf1&v=4
authorURL: https://github.com/dragarcia
+tags:
+ - postgres
---
Whenever you create a new database in Postgres, you are actually [basing it off an already present database](https://www.postgresql.org/docs/current/manage-ag-templatedbs.html) in your cluster.
diff --git a/web/blog/2020-07-10-surviving-hacker-news.md b/web/blog/2020-07-10-surviving-hacker-news.md
new file mode 100644
index 00000000000..49209131333
--- /dev/null
+++ b/web/blog/2020-07-10-surviving-hacker-news.md
@@ -0,0 +1,107 @@
+---
+title: Surviving Hacker News
+description: Everything that went wrong with Supabase's launch
+author: Paul Copplestone
+author_title: Supabase
+author_url: https://github.com/kiwicopple
+author_image_url: https://avatars2.githubusercontent.com/u/10214025?s=400&u=c6775be2ae667e2acae3ccd347fed62bb3f5b3e7&v=4
+authorURL: https://github.com/kiwicopple
+tags:
+ - supabase
+---
+
+import Image from '@theme/IdealImage';
+
+On May 27 Supabase hit the [top of Hacker News](https://news.ycombinator.com/item?id=23319901) and stayed on the front page for more than 24 hours.
+
+
+
+Since then, Supabase has been featured on the [Stack Overflow podcast](https://stackoverflow.blog/2020/06/05/podcast-241-new-tools-for-new-times/), hit the [trending page](https://twitter.com/supabase_io/status/1268062559023685633) on GitHub, and scaled to over 1000 databases.
+
+Here is everything that went wrong along the way.
+
+## Quick stats - launch week
+
+Before we get into the details, here are some high-level numbers for the week following the launch.
+
+We had 30,000 new website visitors to [supabase.io](http://supabase.io):
+
+
+
+We had over 1400 signups in 7 days:
+
+
+
+Github stars rocketed for our two main repos, [supabase](https://github.com/supabase/supabase) and [realtime](https://github.com/supabase/realtime).
+
+
+
+## The good
+
+Here are the things that survived well.
+
+### Middleware: docker-compose up
+
+This was the most surprising survivor. Our middleware was served from a single Ubuntu server with 4 CPUs and 8GB of RAM. This server was running our middleware using `docker-compose up`:
+
+
+
+
+In case you're wondering why any sane company would use that in production, it's because we weren't planning to launch - the HackerNews post was created by an early GitHub follower, while we were alpha testing, and it was too scary to migrate the middleware while it was servicing the thundering herd. All Supabase projects use the same middleware stack (sans docker-compose), so I guess this counts as as a successful load test.
+
+We have since migrated our middleware to multiple ECS clusters, globally load-balanced using AWS's [Global Accelerator](https://aws.amazon.com/global-accelerator/).
+
+### Frontend: Netlify, Vercel, Auth0
+
+We serve our marketing site ([supabase.io](http://supabase.io)) from Netlify. It's a [Docusaurus (v2)](https://v2.docusaurus.io/) site, which is a static build so it had no problems (apart from one developer in Russia who couldn't access the site - it looks like some of Netlify's IP addresses are blocked there).
+
+We serve our app ([app.supabase.io](http://app.supabase.io)) using Vercel, and the login system uses Auth0. These were both rock-solid. Before the launch we noticed that Vercel was extremely slow on their free plan, and once we upgraded to their Pro Plan for multi-region deploys and it solved all of our issues. It looks like they are changing their plans again so buyer beware.
+
+## The Bad
+
+### Cloud limits: Digital Ocean
+
+In May we were using Digital Ocean to serve all of our customer databases. We hit the first server limit (400 servers) in the space of a few hours. They bumped our limit up to 1000 and we hit that again a few hours later.
+
+Digital Ocean were very responsive when we asked for increases, each time responding in 30 minutes or less.
+
+### Cloudflare cloud limits
+
+Each Supabase project gets a unique URL for their API and database. This is set up using Cloudflare's API. This was a seamless process until we hit the 1000 subdomain limit, at 4am in the morning. My cofounder was awake at this time, and managed to identify the problem early,and reached out to the support to increase the limit.
+
+Cloudflare support advised him to upgrade the account to increase the limit, but the upgrade could only be done by the owner (me). Unfortunately my phone was on silent, so for 3 hours our systems were down.
+
+This seems like a flaw in the Cloudflare process. Ideally any one of our team could have upgraded our account.
+
+## The Ugly - migrating 1800 servers
+
+Let me start this section by saying that Digital Ocean have been pretty good for getting up and running. The experience was great to start with, but ended painfully.
+
+### Production errors
+
+The first sign of problems were the frequent production errors. This is a screenshot of emails from Digital ocean for the month of June.
+
+
+
+
+Each of these emails represents one or more servers that has a server issue - most of the time it was 2 servers.
+
+> We have identified an issue on the physical machine hosting one or more of your Droplets. In the event that we are not able to perform a live migration of a Droplet, we will perform an offline migration during which the Droplet will be powered off and migrated offline during the window.
+
+Luckily we are in alpha, and our community has been extremely patient.
+
+### Credit limits
+
+The next issue came with the credits. We were generously granted $10,000 Digital Ocean credits in February through Stripe Atlas, and so they became our primary cloud provider.
+
+Digital Ocean have another (more generous) credits package for YC companies. Unfortunately when we applied for this we were told we weren't eligible because it was a "Partner switch" from Stripe to YC. This was frustrating because a "Partner switch" is completely arbitrary to us as a customer.
+
+Also we had conveniently just run out of credits. We don’t expect cloud providers to fund our inefficiencies, but we needed time to optimize our infrastructure after our surprise launch. We decided to migrate away from Digital Ocean.
+
+## Going Forward: AWS t3a
+
+In the past 3 weeks we have migrated 1800 servers over to AWS.
+
+The AWS team at YC were super helpful, suggesting how we could run our VMs more efficiently using their new `t3a` instances. We're already starting to see massive improvements, with database startup times almost halved from ~90s to ~50s. From our research, this is the fastest Postgres setup in the market.
+
+We will release a detailed write-up on these instances in the next few weeks. Sign up to our newsletter if you want to be notified when we release the post.
\ No newline at end of file
diff --git a/web/docusaurus.config.js b/web/docusaurus.config.js
index b85ea8d09f4..27ecec314fe 100755
--- a/web/docusaurus.config.js
+++ b/web/docusaurus.config.js
@@ -136,6 +136,7 @@ module.exports = {
copyright: `Copyright © ${new Date().getFullYear()} Supabase.`,
},
},
+ plugins: ['@docusaurus/plugin-ideal-image'],
presets: [
[
'@docusaurus/preset-classic',
diff --git a/web/package-lock.json b/web/package-lock.json
index a98641a253b..5f4f90a4b13 100644
--- a/web/package-lock.json
+++ b/web/package-lock.json
@@ -1327,6 +1327,18 @@
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.0.0-alpha.58.tgz",
"integrity": "sha512-t+B6K2/EvRofygDK5edeQAg2l069aU7H3sViG/3USpJSaY9bWNWRKjZk6BEOypC+mCW6g5HQgewQZ/bTkV+aDA=="
},
+ "@docusaurus/plugin-ideal-image": {
+ "version": "2.0.0-alpha.39",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-ideal-image/-/plugin-ideal-image-2.0.0-alpha.39.tgz",
+ "integrity": "sha512-mkRTyC1gCr06M5m7GeKyNNz8ULSFN7gcpjuRZHdJqrmCF69qHGH+oL71Zy2Dz5R3e+Mvd/gwA0wjp+lrMYCi2g==",
+ "requires": {
+ "@endiliey/lqip-loader": "^3.0.2",
+ "@endiliey/react-ideal-image": "^0.0.11",
+ "@endiliey/responsive-loader": "^1.3.2",
+ "react-waypoint": "^9.0.2",
+ "sharp": "^0.22.1"
+ }
+ },
"@docusaurus/plugin-sitemap": {
"version": "2.0.0-alpha.58",
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.0.0-alpha.58.tgz",
@@ -1411,6 +1423,70 @@
}
}
},
+ "@endiliey/lqip-loader": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@endiliey/lqip-loader/-/lqip-loader-3.0.2.tgz",
+ "integrity": "sha512-Kx8te/ZrXR1EqNxBn4hfBHlVCCovm8Fu1fTpYjLSIvcGSEC2+OYFgT7dwPzvh7HyADhMl3lizOgtWbDhtM5djA==",
+ "requires": {
+ "loader-utils": "^1.2.3",
+ "lodash.sortby": "^4.7.0",
+ "node-vibrant": "^3.1.4",
+ "sharp": "^0.22.1"
+ },
+ "dependencies": {
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
+ "loader-utils": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+ "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^1.0.1"
+ }
+ }
+ }
+ },
+ "@endiliey/react-ideal-image": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/@endiliey/react-ideal-image/-/react-ideal-image-0.0.11.tgz",
+ "integrity": "sha512-QxMjt/Gvur/gLxSoCy7VIyGGGrGmDN+VHcXkN3R2ApoWX0EYUE+hMgPHSW/PV6VVebZ1Nd4t2UnGRBDihu16JQ=="
+ },
+ "@endiliey/responsive-loader": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@endiliey/responsive-loader/-/responsive-loader-1.3.2.tgz",
+ "integrity": "sha512-j77koHZIW8L6s7kw/VdZhORamdP7laW4+Gcu7Ddt7iRSXniADDk9HtKUZrBXC90hMYo+Kb4XdlqMizvMI8JGrA==",
+ "requires": {
+ "loader-utils": "^1.2.3"
+ },
+ "dependencies": {
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
+ "loader-utils": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+ "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^1.0.1"
+ }
+ }
+ }
+ },
"@endiliey/static-site-generator-webpack-plugin": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@endiliey/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.0.tgz",
@@ -1457,6 +1533,202 @@
"@hapi/hoek": "^8.3.0"
}
},
+ "@jimp/bmp": {
+ "version": "0.9.8",
+ "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.9.8.tgz",
+ "integrity": "sha512-CZYQPEC3iUBMuaGWrtIG+GKNl93q/PkdudrCKJR/B96dfNngsmoosEm3LuFgJHEcJIfvnJkNqKw74l+zEiqCbg==",
+ "requires": {
+ "@babel/runtime": "^7.7.2",
+ "@jimp/utils": "^0.9.8",
+ "bmp-js": "^0.1.0",
+ "core-js": "^3.4.1"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ }
+ }
+ },
+ "@jimp/core": {
+ "version": "0.9.8",
+ "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.9.8.tgz",
+ "integrity": "sha512-N4GCjcXb0QwR5GBABDK2xQ3cKyaF7LlCYeJEG9mV7G/ynBoRqJe4JA6YKU9Ww9imGkci/4A594nQo8tUIqdcBw==",
+ "requires": {
+ "@babel/runtime": "^7.7.2",
+ "@jimp/utils": "^0.9.8",
+ "any-base": "^1.1.0",
+ "buffer": "^5.2.0",
+ "core-js": "^3.4.1",
+ "exif-parser": "^0.1.12",
+ "file-type": "^9.0.0",
+ "load-bmfont": "^1.3.1",
+ "mkdirp": "^0.5.1",
+ "phin": "^2.9.1",
+ "pixelmatch": "^4.0.2",
+ "tinycolor2": "^1.4.1"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "core-js": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ }
+ }
+ },
+ "@jimp/custom": {
+ "version": "0.9.8",
+ "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.9.8.tgz",
+ "integrity": "sha512-1UpJjI7fhX02BWLJ/KEqPwkHH60eNkCNeD6hEd+IZdTwLXfZCfFiM5BVlpgiZYZJSsVoRiAL4ne2Q5mCiKPKyw==",
+ "requires": {
+ "@babel/runtime": "^7.7.2",
+ "@jimp/core": "^0.9.8",
+ "core-js": "^3.4.1"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ }
+ }
+ },
+ "@jimp/gif": {
+ "version": "0.9.8",
+ "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.9.8.tgz",
+ "integrity": "sha512-LEbfpcO1sBJIQCJHchZjNlyNxzPjZQQ4X32klpQHZJG58n9FvL7Uuh1rpkrJRbqv3cU3P0ENNtTrsBDxsYwcfA==",
+ "requires": {
+ "@babel/runtime": "^7.7.2",
+ "@jimp/utils": "^0.9.8",
+ "core-js": "^3.4.1",
+ "omggif": "^1.0.9"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ }
+ }
+ },
+ "@jimp/jpeg": {
+ "version": "0.9.8",
+ "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.9.8.tgz",
+ "integrity": "sha512-5u29SUzbZ32ZMmOaz3gO0hXatwSCnsvEAXRCKZoPPgbsPoyFAiZKVxjfLzjkeQF6awkvJ8hZni5chM15SNMg+g==",
+ "requires": {
+ "@babel/runtime": "^7.7.2",
+ "@jimp/utils": "^0.9.8",
+ "core-js": "^3.4.1",
+ "jpeg-js": "^0.3.4"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ }
+ }
+ },
+ "@jimp/plugin-resize": {
+ "version": "0.9.8",
+ "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.9.8.tgz",
+ "integrity": "sha512-L80NZ+HKsiKFyeDc6AfneC4+5XACrdL2vnyAVfAAsb3pmamgT/jDInWvvGhyI0Y76vx2w6XikplzEznW/QQvWg==",
+ "requires": {
+ "@babel/runtime": "^7.7.2",
+ "@jimp/utils": "^0.9.8",
+ "core-js": "^3.4.1"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ }
+ }
+ },
+ "@jimp/png": {
+ "version": "0.9.8",
+ "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.9.8.tgz",
+ "integrity": "sha512-9CqR8d40zQCDhbnXHqcwkAMnvlV0vk9xSyE6LHjkYHS7x18Unsz5txQdsaEkEcXxCrOQSoWyITfLezlrWXRJAA==",
+ "requires": {
+ "@babel/runtime": "^7.7.2",
+ "@jimp/utils": "^0.9.8",
+ "core-js": "^3.4.1",
+ "pngjs": "^3.3.3"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ }
+ }
+ },
+ "@jimp/tiff": {
+ "version": "0.9.8",
+ "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.9.8.tgz",
+ "integrity": "sha512-eMxcpJivJqMByn2dZxUHLeh6qvVs5J/52kBF3TFa3C922OJ97D9l1C1h0WKUCBqFMWzMYapQQ4vwnLgpJ5tkow==",
+ "requires": {
+ "@babel/runtime": "^7.7.2",
+ "core-js": "^3.4.1",
+ "utif": "^2.0.1"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ }
+ }
+ },
+ "@jimp/types": {
+ "version": "0.9.8",
+ "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.9.8.tgz",
+ "integrity": "sha512-H5y/uqt0lqJ/ZN8pWqFG+pv8jPAppMKkTMByuC8YBIjWSsornwv44hjiWl93sbYhduLZY8ubz/CbX9jH2X6EwA==",
+ "requires": {
+ "@babel/runtime": "^7.7.2",
+ "@jimp/bmp": "^0.9.8",
+ "@jimp/gif": "^0.9.8",
+ "@jimp/jpeg": "^0.9.8",
+ "@jimp/png": "^0.9.8",
+ "@jimp/tiff": "^0.9.8",
+ "core-js": "^3.4.1",
+ "timm": "^1.6.1"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ }
+ }
+ },
+ "@jimp/utils": {
+ "version": "0.9.8",
+ "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.9.8.tgz",
+ "integrity": "sha512-UK0Fu0eevQlpRXq5ff4o/71HJlpX9wJMddJjMYg9vUqCCl8ZnumRAljfShHFhGyO+Vc9IzN6dd8Y5JZZTp1KOw==",
+ "requires": {
+ "@babel/runtime": "^7.7.2",
+ "core-js": "^3.4.1"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ }
+ }
+ },
"@kiwicopple/prism-react-renderer": {
"version": "github:kiwicopple/prism-react-renderer#19510838907117ccf3d24f078fae2174e0f719c7",
"from": "github:kiwicopple/prism-react-renderer"
@@ -1705,6 +1977,11 @@
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz",
"integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ=="
},
+ "@types/lodash": {
+ "version": "4.14.157",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.157.tgz",
+ "integrity": "sha512-Ft5BNFmv2pHDgxV5JDsndOWTRJ+56zte0ZpYLowp03tW+K+t8u8YMOzAnpuqPgzX6WO1XpDIUm7u04M8vdDiVQ=="
+ },
"@types/mdast": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz",
@@ -2134,6 +2411,11 @@
"color-convert": "^1.9.0"
}
},
+ "any-base": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz",
+ "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="
+ },
"anymatch": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
@@ -2148,6 +2430,39 @@
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
},
+ "are-we-there-yet": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
+ "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -2581,11 +2896,37 @@
"file-uri-to-path": "1.0.0"
}
},
+ "bl": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz",
+ "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==",
+ "requires": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ }
+ }
+ },
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
},
+ "bmp-js": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz",
+ "integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM="
+ },
"bn.js": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
@@ -2772,6 +3113,11 @@
"isarray": "^1.0.0"
}
},
+ "buffer-equal": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz",
+ "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs="
+ },
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@@ -3307,6 +3653,11 @@
}
}
},
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+ },
"collapse-white-space": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz",
@@ -3482,6 +3833,16 @@
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
"integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA=="
},
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
+ },
+ "consolidated-events": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/consolidated-events/-/consolidated-events-2.0.2.tgz",
+ "integrity": "sha512-2/uRVMdRypf5z/TW/ncD/66l75P5hH2vM/GR8Jf8HLc2xnfJtmina6F6du8+v4Z2vTrMo7jC+W1tmEEuuELgkQ=="
+ },
"constants-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
@@ -4485,6 +4846,14 @@
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
},
+ "decompress-response": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
+ "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
+ "requires": {
+ "mimic-response": "^2.0.0"
+ }
+ },
"deep-equal": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
@@ -4498,6 +4867,11 @@
"regexp.prototype.flags": "^1.2.0"
}
},
+ "deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
+ },
"default-gateway": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
@@ -4593,6 +4967,11 @@
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
"optional": true
},
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
+ },
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@@ -4620,6 +4999,11 @@
"repeat-string": "^1.5.4"
}
},
+ "detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
+ },
"detect-node": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
@@ -5187,6 +5571,11 @@
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
},
+ "exif-parser": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz",
+ "integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI="
+ },
"expand-brackets": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
@@ -5224,6 +5613,11 @@
}
}
},
+ "expand-template": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="
+ },
"express": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
@@ -5421,6 +5815,11 @@
"escape-string-regexp": "^1.0.5"
}
},
+ "file-type": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz",
+ "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw=="
+ },
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
@@ -5760,6 +6159,16 @@
}
}
},
+ "fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+ },
+ "fs-copy-file-sync": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/fs-copy-file-sync/-/fs-copy-file-sync-1.1.1.tgz",
+ "integrity": "sha512-2QY5eeqVv4m2PfyMiEuy9adxNP+ajf+8AR05cEi+OAzPcOj90hvFImeZhTmKLBgSd9EvG33jsD7ZRxsx9dThkQ=="
+ },
"fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
@@ -5829,6 +6238,41 @@
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
+ "gauge": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ },
+ "dependencies": {
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ }
+ }
+ },
"generic-names": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/generic-names/-/generic-names-1.0.3.tgz",
@@ -5906,6 +6350,11 @@
"assert-plus": "^1.0.0"
}
},
+ "github-from-package": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+ "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4="
+ },
"github-slugger": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.3.0.tgz",
@@ -6116,6 +6565,11 @@
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
},
+ "has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
+ },
"has-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
@@ -7065,6 +7519,11 @@
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
+ "is-function": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz",
+ "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ=="
+ },
"is-glob": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
@@ -7245,6 +7704,11 @@
}
}
},
+ "jpeg-js": {
+ "version": "0.3.7",
+ "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.3.7.tgz",
+ "integrity": "sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ=="
+ },
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -7363,6 +7827,21 @@
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
"integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA="
},
+ "load-bmfont": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz",
+ "integrity": "sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==",
+ "requires": {
+ "buffer-equal": "0.0.1",
+ "mime": "^1.3.4",
+ "parse-bmfont-ascii": "^1.0.3",
+ "parse-bmfont-binary": "^1.0.5",
+ "parse-bmfont-xml": "^1.1.4",
+ "phin": "^2.9.1",
+ "xhr": "^2.0.1",
+ "xtend": "^4.0.0"
+ }
+ },
"load-script": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz",
@@ -7825,6 +8304,11 @@
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
},
+ "mimic-response": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
+ "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA=="
+ },
"min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
@@ -7959,6 +8443,25 @@
"minipass": "^3.0.0"
}
},
+ "minizlib": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+ "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+ "requires": {
+ "minipass": "^2.9.0"
+ },
+ "dependencies": {
+ "minipass": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+ "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+ "requires": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ }
+ }
+ },
"mississippi": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
@@ -8019,6 +8522,11 @@
"minimist": "^1.2.5"
}
},
+ "mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
+ },
"moment-mini": {
"version": "2.24.0",
"resolved": "https://registry.npmjs.org/moment-mini/-/moment-mini-2.24.0.tgz",
@@ -8064,8 +8572,7 @@
"nan": {
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
- "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==",
- "optional": true
+ "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
},
"nanomatch": {
"version": "1.2.13",
@@ -8104,6 +8611,11 @@
}
}
},
+ "napi-build-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
+ },
"negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
@@ -8128,6 +8640,21 @@
"tslib": "^1.10.0"
}
},
+ "node-abi": {
+ "version": "2.18.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.18.0.tgz",
+ "integrity": "sha512-yi05ZoiuNNEbyT/xXfSySZE+yVnQW6fxPZuFbLyS1s6b5Kw3HzV2PHOM4XR+nsjzkHxByK+2Wg+yCQbe35l8dw==",
+ "requires": {
+ "semver": "^5.4.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ }
+ }
+ },
"node-emoji": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz",
@@ -8202,6 +8729,32 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz",
"integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg=="
},
+ "node-vibrant": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/node-vibrant/-/node-vibrant-3.1.5.tgz",
+ "integrity": "sha512-Gk+iyBzPSN1SF5qL818QaBtuA38206Z8iPNa0PcLUPyIbZL4+i14VmYxkGCL0n/5Q1721CRSktqtACgkx7Qodg==",
+ "requires": {
+ "@jimp/custom": "^0.9.3",
+ "@jimp/plugin-resize": "^0.9.3",
+ "@jimp/types": "^0.9.3",
+ "@types/lodash": "^4.14.53",
+ "@types/node": "^10.11.7",
+ "lodash": "^4.17.4",
+ "url": "^0.11.0"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "10.17.27",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.27.tgz",
+ "integrity": "sha512-J0oqm9ZfAXaPdwNXMMgAhylw5fhmXkToJd06vuDUSAgEDZ/n/69/69UmyBZbc+zT34UnShuDSBqvim3SPnozJg=="
+ }
+ }
+ },
+ "noop-logger": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
+ "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI="
+ },
"nopt": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
@@ -8246,6 +8799,17 @@
}
}
},
+ "npmlog": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
+ }
+ },
"nprogress": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz",
@@ -8303,6 +8867,11 @@
"resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
"integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4="
},
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+ },
"oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@@ -8412,6 +8981,11 @@
"resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg=="
},
+ "omggif": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz",
+ "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw=="
+ },
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@@ -8608,6 +9182,25 @@
"safe-buffer": "^5.1.1"
}
},
+ "parse-bmfont-ascii": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz",
+ "integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU="
+ },
+ "parse-bmfont-binary": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz",
+ "integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY="
+ },
+ "parse-bmfont-xml": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz",
+ "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==",
+ "requires": {
+ "xml-parse-from-string": "^1.0.0",
+ "xml2js": "^0.4.5"
+ }
+ },
"parse-entities": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
@@ -8621,6 +9214,11 @@
"is-hexadecimal": "^1.0.0"
}
},
+ "parse-headers": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz",
+ "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA=="
+ },
"parse-json": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz",
@@ -8723,6 +9321,11 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
+ "phin": {
+ "version": "2.9.3",
+ "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz",
+ "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA=="
+ },
"picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
@@ -8746,6 +9349,14 @@
"pinkie": "^2.0.0"
}
},
+ "pixelmatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz",
+ "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=",
+ "requires": {
+ "pngjs": "^3.0.0"
+ }
+ },
"pkg-dir": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
@@ -8762,6 +9373,11 @@
"find-up": "^3.0.0"
}
},
+ "pngjs": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
+ "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="
+ },
"pnp-webpack-plugin": {
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz",
@@ -9808,6 +10424,28 @@
"uniq": "^1.0.1"
}
},
+ "prebuild-install": {
+ "version": "5.3.5",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.5.tgz",
+ "integrity": "sha512-YmMO7dph9CYKi5IR/BzjOJlRzpxGGVo1EsLSUZ0mt/Mq0HWZIHOKHHcHdT69yG54C9m6i45GpItwRHpk0Py7Uw==",
+ "requires": {
+ "detect-libc": "^1.0.3",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp": "^0.5.1",
+ "napi-build-utils": "^1.0.1",
+ "node-abi": "^2.7.0",
+ "noop-logger": "^0.1.1",
+ "npmlog": "^4.0.1",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^3.0.3",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0",
+ "which-pm-runs": "^1.0.0"
+ }
+ },
"prepend-http": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
@@ -10032,6 +10670,17 @@
"unpipe": "1.0.0"
}
},
+ "rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "requires": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ }
+ },
"react": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz",
@@ -10539,6 +11188,16 @@
"react-lifecycles-compat": "^3.0.4"
}
},
+ "react-waypoint": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/react-waypoint/-/react-waypoint-9.0.3.tgz",
+ "integrity": "sha512-NRmyjW8CUBNNl4WpvBqLDgBs18rFUsixeHVHrRrFlWTdOlWP7eiDjptqlR/cJAPLD6RwP5XFCm3bi9OiofN3nA==",
+ "requires": {
+ "consolidated-events": "^1.1.0 || ^2.0.0",
+ "prop-types": "^15.0.0",
+ "react-is": "^16.6.3"
+ }
+ },
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
@@ -11378,6 +12037,23 @@
}
}
},
+ "sharp": {
+ "version": "0.22.1",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.22.1.tgz",
+ "integrity": "sha512-lXzSk/FL5b/MpWrT1pQZneKe25stVjEbl6uhhJcTULm7PhmJgKKRbTDM/vtjyUuC/RLqL2PRyC4rpKwbv3soEw==",
+ "requires": {
+ "color": "^3.1.1",
+ "detect-libc": "^1.0.3",
+ "fs-copy-file-sync": "^1.1.1",
+ "nan": "^2.13.2",
+ "npmlog": "^4.1.2",
+ "prebuild-install": "^5.3.0",
+ "semver": "^6.0.0",
+ "simple-get": "^3.0.3",
+ "tar": "^4.4.8",
+ "tunnel-agent": "^0.6.0"
+ }
+ },
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -11411,6 +12087,21 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
},
+ "simple-concat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
+ "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY="
+ },
+ "simple-get": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
+ "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
+ "requires": {
+ "decompress-response": "^4.2.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
"simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
@@ -11968,6 +12659,11 @@
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="
},
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
+ },
"style-to-object": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz",
@@ -12073,6 +12769,62 @@
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
},
+ "tar": {
+ "version": "4.4.13",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
+ "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
+ "requires": {
+ "chownr": "^1.1.1",
+ "fs-minipass": "^1.2.5",
+ "minipass": "^2.8.6",
+ "minizlib": "^1.2.1",
+ "mkdirp": "^0.5.0",
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.3"
+ },
+ "dependencies": {
+ "fs-minipass": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
+ "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
+ "requires": {
+ "minipass": "^2.6.0"
+ }
+ },
+ "minipass": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+ "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+ "requires": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ }
+ }
+ },
+ "tar-fs": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz",
+ "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==",
+ "requires": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.0.0"
+ }
+ },
+ "tar-stream": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz",
+ "integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==",
+ "requires": {
+ "bl": "^4.0.1",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ }
+ },
"terser": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
@@ -12272,6 +13024,11 @@
"setimmediate": "^1.0.4"
}
},
+ "timm": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/timm/-/timm-1.6.2.tgz",
+ "integrity": "sha512-IH3DYDL1wMUwmIlVmMrmesw5lZD6N+ZOAFWEyLrtpoL9Bcrs9u7M/vyOnHzDD2SMs4irLkVjqxZbHrXStS/Nmw=="
+ },
"timsort": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
@@ -12293,6 +13050,11 @@
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
},
+ "tinycolor2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
+ "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g="
+ },
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -12778,6 +13540,14 @@
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
},
+ "utif": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz",
+ "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==",
+ "requires": {
+ "pako": "^1.0.5"
+ }
+ },
"util": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
@@ -13919,6 +14689,48 @@
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
},
+ "which-pm-runs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
+ "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
+ },
+ "wide-align": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+ "requires": {
+ "string-width": "^1.0.2 || 2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
"worker-farm": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
@@ -13993,6 +14805,33 @@
"async-limiter": "~1.0.0"
}
},
+ "xhr": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz",
+ "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==",
+ "requires": {
+ "global": "~4.3.0",
+ "is-function": "^1.0.1",
+ "parse-headers": "^2.0.0",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "global": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
+ "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
+ "requires": {
+ "min-document": "^2.19.0",
+ "process": "~0.5.1"
+ }
+ },
+ "process": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
+ "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8="
+ }
+ }
+ },
"xml-js": {
"version": "1.6.11",
"resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz",
@@ -14001,6 +14840,27 @@
"sax": "^1.2.4"
}
},
+ "xml-parse-from-string": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz",
+ "integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig="
+ },
+ "xml2js": {
+ "version": "0.4.23",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
+ "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+ "requires": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~11.0.0"
+ },
+ "dependencies": {
+ "xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
+ }
+ }
+ },
"xmlbuilder": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
diff --git a/web/package.json b/web/package.json
index 3ac16ca260a..ff6f6fb8314 100644
--- a/web/package.json
+++ b/web/package.json
@@ -10,6 +10,7 @@
},
"dependencies": {
"@docusaurus/core": "^2.0.0-alpha.58",
+ "@docusaurus/plugin-ideal-image": "^2.0.0-alpha.39",
"@docusaurus/preset-classic": "^2.0.0-alpha.58",
"@kiwicopple/prism-react-renderer": "github:kiwicopple/prism-react-renderer",
"classnames": "^2.2.6",
diff --git a/web/src/theme/BlogPostItem/index.js b/web/src/theme/BlogPostItem/index.js
index 5cb13f6e62f..834a8c6543a 100755
--- a/web/src/theme/BlogPostItem/index.js
+++ b/web/src/theme/BlogPostItem/index.js
@@ -100,16 +100,22 @@ function BlogPostItem(props) {
+
{(tags.length > 0 || truncated) && (
{tags.length > 0 && (
Tags:
- {tags.map(({label, permalink: tagPermalink}) => (
-
+ {tags.map(({ label, permalink: tagPermalink }) => (
+
{label}
))}
@@ -117,9 +123,7 @@ function BlogPostItem(props) {
)}
{truncated && (
-
+
Read More
@@ -127,7 +131,7 @@ function BlogPostItem(props) {
)}
- );
+ )
}
export default BlogPostItem;
diff --git a/web/static/img/digital-ocean-emails-errors.png b/web/static/img/digital-ocean-emails-errors.png
new file mode 100644
index 0000000000000000000000000000000000000000..aec2f7a5d828d22d638fce5ee3fbe7a6fabaecba
GIT binary patch
literal 408744
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