diff --git a/.eslintrc.json b/.eslintrc.json
index fac5da5..4a62ec9 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -20,7 +20,9 @@
"react/jsx-filename-extension": [1, { "extensions": [".js", ".ts", "tsx"] }],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-member-accessibility": "off",
- "@typescript-eslint/member-delimiter-style": "off"
+ "@typescript-eslint/member-delimiter-style": "off",
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/ban-ts-ignore": "off"
},
"overrides": [
{
diff --git a/.gitignore b/.gitignore
index 20fccdd..fd07293 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,3 +28,5 @@ yarn-error.log*
.env.development.local
.env.test.local
.env.production.local
+
+.now
\ No newline at end of file
diff --git a/.storybook/logo.png b/.storybook/logo.png
index 9c5b9ac..0b09ba2 100644
Binary files a/.storybook/logo.png and b/.storybook/logo.png differ
diff --git a/.storybook/main.js b/.storybook/main.js
index d8754b5..44cf475 100644
--- a/.storybook/main.js
+++ b/.storybook/main.js
@@ -8,7 +8,17 @@ module.exports = {
// Make whatever fine-grained changes you need
baseConfig.module.rules.push({
test: /\.scss$/,
- use: ['style-loader', 'css-loader', 'sass-loader'],
+ use: [
+ 'style-loader',
+ {
+ loader: 'css-loader',
+ options: {
+ importLoaders: 1,
+ modules: true,
+ },
+ },
+ 'sass-loader',
+ ],
include: path.resolve(__dirname, '../'),
})
diff --git a/.storybook/preview-body.html b/.storybook/preview-body.html
new file mode 100644
index 0000000..c2938b6
--- /dev/null
+++ b/.storybook/preview-body.html
@@ -0,0 +1 @@
+
diff --git a/.storybook/styles.css b/.storybook/styles.css
index b7739c2..5d020a0 100644
--- a/.storybook/styles.css
+++ b/.storybook/styles.css
@@ -1,4 +1,12 @@
.sb-show-main {
margin: 0;
background: inherit;
+ transition: background 0.2s ease;
+}
+
+.sb-show-main.light-mode {
+ background: #fff;
+}
+.sb-show-main.dark-mode {
+ background: #191a1f;
}
diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js
index a4ff0b3..a8717b6 100644
--- a/.storybook/webpack.config.js
+++ b/.storybook/webpack.config.js
@@ -26,6 +26,7 @@ module.exports = ({ config, mode }) => {
config.resolve.alias['components'] = path.join(__dirname, '../components')
config.resolve.alias['pages'] = path.join(__dirname, '../pages')
config.resolve.alias['styles'] = path.join(__dirname, '../styles')
+ config.resolve.alias['utils'] = path.join(__dirname, '../utils')
config.resolve.alias['hooks'] = path.join(__dirname, '../hooks')
if (mode === 'DEVELOPMENT') {
diff --git a/.stylelintrc.json b/.stylelintrc.json
index 99f9f2c..f52b8ef 100644
--- a/.stylelintrc.json
+++ b/.stylelintrc.json
@@ -1,5 +1,10 @@
{
- "extends": ["stylelint-config-recess-order", "stylelint-config-standard", "stylelint-config-prettier"],
+ "extends": [
+ "stylelint-config-recess-order",
+ "stylelint-config-standard",
+ "stylelint-config-css-modules",
+ "stylelint-config-prettier"
+ ],
"plugins": ["stylelint-prettier"],
"rules": {
"prettier/prettier": true
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 7428127..a2d1840 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,17 +1,13 @@
{
- "editor.formatOnSave": true,
- "eslint.validate": [
- "javascript",
- "javascriptreact",
- "typescript",
- "typescriptreact"
- ],
- "eslint.run": "onType",
- "editor.codeActionsOnSave": {
- "source.fixAll.eslint": true,
- "source.fixAll.stylelint": true
- },
- "css.validate": false,
- "less.validate": false,
- "scss.validate": false
+ "editor.formatOnSave": true,
+ "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
+ "eslint.run": "onType",
+ "editor.codeActionsOnSave": {
+ "source.fixAll.eslint": true,
+ "source.fixAll.stylelint": true
+ },
+ "css.validate": false,
+ "less.validate": false,
+ "scss.validate": false,
+ "cssModules.camelCase": true
}
diff --git a/README.md b/README.md
index bb9ba64..18f2794 100644
--- a/README.md
+++ b/README.md
@@ -20,25 +20,25 @@ Favicon generator tool
## Favicon recommended sizes
-| | apple-touch-icon | icon | msapplication |
-| ------- | ---------------- | ---- | ------------- |
-| 57x57 | ✅ | | |
-| 60x60 | ✅ | | |
-| 72x72 | ✅ | | |
-| 76x76 | ✅ | | |
-| 114x114 | ✅ | | |
-| 120x120 | ✅ | | |
-| 144x144 | ✅ | | ✅ |
-| 152x152 | ✅ | | |
-| 180x180 | ✅ | | |
-| 16x16 | | ✅ | |
-| 32x32 | | ✅ | |
-| 96x96 | | ✅ | |
-| 192x192 | | ✅ | |
-| 70x70 | | | ✅ |
-| 150x150 | | | ✅ |
-| 310x150 | | | ✅ |
-| 310x310 | | | ✅ |
+| | apple-icon | favicon | ms-icon |
+| ------- | ---------- | ------- | ------- |
+| 57x57 | ✅ | | |
+| 60x60 | ✅ | | |
+| 72x72 | ✅ | | |
+| 76x76 | ✅ | | |
+| 114x114 | ✅ | | |
+| 120x120 | ✅ | | |
+| 144x144 | ✅ | | ✅ |
+| 152x152 | ✅ | | |
+| 180x180 | ✅ | | |
+| 16x16 | | ✅ | |
+| 32x32 | | ✅ | |
+| 96x96 | | ✅ | |
+| 192x192 | | ✅ | |
+| 70x70 | | | ✅ |
+| 150x150 | | | ✅ |
+| 310x150 | | | ✅ |
+| 310x310 | | | ✅ |
## HTML tags to add for all favicon sizes
@@ -58,7 +58,7 @@ Favicon generator tool
-
+
```
@@ -67,16 +67,28 @@ This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next
## Getting Started
-First, run the development server:
+First, install the project dependencies:
+
+```bash
+yarn install
+```
+
+Then, 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.
+Also, you can run the Storybook server:
+
+```bash
+yarn storybook
+```
+
+Open [http://localhost:6006](http://localhost:6006) with your browser to see all stories.
+
## Contributors ✨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
diff --git a/components/base-layout/index.module.scss b/components/base-layout/index.module.scss
new file mode 100644
index 0000000..5d4185b
--- /dev/null
+++ b/components/base-layout/index.module.scss
@@ -0,0 +1,16 @@
+@import '../../styles/variables.scss';
+
+.root {
+ padding: 0;
+}
+
+.container {
+ max-width: 1440px;
+ padding: 20px;
+}
+
+.header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
diff --git a/components/base-layout/index.tsx b/components/base-layout/index.tsx
new file mode 100644
index 0000000..c2bbb3e
--- /dev/null
+++ b/components/base-layout/index.tsx
@@ -0,0 +1,26 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import { DarkModeToggle } from 'components/dark-mode-toggle'
+
+import styles from './index.module.scss'
+import { Typography } from 'components/typography'
+
+type BaseLayoutProps = {
+ children: PropTypes.ReactNodeLike
+}
+
+const BaseLayout = ({ children }: BaseLayoutProps) => {
+ return (
+
+ )
+}
+
+export { BaseLayout }
diff --git a/components/button/index.module.scss b/components/button/index.module.scss
new file mode 100644
index 0000000..198eea1
--- /dev/null
+++ b/components/button/index.module.scss
@@ -0,0 +1,61 @@
+@import '../../styles/variables.scss';
+
+.base {
+ padding: 6px 12px;
+ font-size: $font-size-medium-body;
+ line-height: $line-height-medium-body;
+ color: $black;
+ cursor: pointer;
+ border-radius: 4px;
+}
+
+.primary {
+ composes: base;
+ background-color: $off-white;
+ border: 1px solid $light-grey;
+ box-shadow: 0 2px 4px 0 rgba($black, 0.12);
+ transition: all 0.2s ease;
+
+ &:focus {
+ outline: none;
+ }
+
+ &:disabled {
+ color: $grey;
+ }
+}
+
+.noClick {
+ cursor: default;
+}
+
+.transparent {
+ composes: base;
+ border: 1px solid transparent;
+}
+
+.dark {
+ color: $white;
+ background-color: $darker-grey;
+ border: 1px solid $darker-grey;
+
+ &:disabled {
+ color: $grey;
+ }
+}
+
+.regular {
+ font-weight: 400;
+}
+
+.medium {
+ font-weight: 500;
+}
+
+.semiBold {
+ font-weight: 600;
+}
+
+.bold {
+ font-weight: 700;
+}
diff --git a/components/button/index.stories.tsx b/components/button/index.stories.tsx
new file mode 100644
index 0000000..9177853
--- /dev/null
+++ b/components/button/index.stories.tsx
@@ -0,0 +1,31 @@
+import React from 'react'
+import { withKnobs, text, select, boolean } from '@storybook/addon-knobs'
+import { Button } from '.'
+import useDarkMode from 'use-dark-mode'
+
+export default {
+ title: 'Button',
+ decorators: [withKnobs],
+}
+
+export const ButtonDesktop = () => {
+ const { toggle } = useDarkMode()
+ const variant = select('variant', ['primary', 'transparent'], 'primary')
+ const weight = select('weight', ['regular', 'medium', 'semiBold', 'bold'], 'bold')
+ const body = text('body', 'Mac app coming soon')
+ const disabled = boolean('disabled', false)
+ return (
+
+
+ {body}
+
+
+
+ Toggle Dark Mode
+
+ )
+}
+
+ButtonDesktop.story = {
+ name: 'Desktop',
+}
diff --git a/components/button/index.tsx b/components/button/index.tsx
new file mode 100644
index 0000000..af2c84d
--- /dev/null
+++ b/components/button/index.tsx
@@ -0,0 +1,38 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import classNames from 'classnames'
+import useDarkMode from 'use-dark-mode'
+
+import styles from './index.module.scss'
+
+type ButtonProps = {
+ children: PropTypes.ReactNodeLike
+ variant: 'primary' | 'transparent'
+ weight: 'regular' | 'medium' | 'semiBold' | 'bold'
+}
+
+const Button = ({
+ children,
+ variant,
+ weight,
+ ...props
+}: ButtonProps & React.DetailedHTMLProps, HTMLButtonElement>) => {
+ const { value: isDark } = useDarkMode(false)
+ const className = classNames(styles[variant], styles[weight], {
+ [styles.dark]: isDark,
+ [styles.noClick]: !props.onClick,
+ })
+
+ return (
+
+ {children}
+
+ )
+}
+
+Button.defaultProps = {
+ variant: 'primary',
+ weight: 'bold',
+}
+
+export { Button }
diff --git a/components/dark-mode-toggle/index.module.scss b/components/dark-mode-toggle/index.module.scss
new file mode 100644
index 0000000..ad95fe5
--- /dev/null
+++ b/components/dark-mode-toggle/index.module.scss
@@ -0,0 +1,31 @@
+@import '../../styles/variables.scss';
+
+.root {
+ position: relative;
+}
+
+.label {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ cursor: pointer;
+ user-select: none;
+}
+
+.checkbox {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ overflow: hidden;
+ cursor: pointer;
+ visibility: hidden;
+ outline: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ -webkit-tap-highlight-color: transparent;
+}
diff --git a/components/dark-mode-toggle/index.stories.tsx b/components/dark-mode-toggle/index.stories.tsx
new file mode 100644
index 0000000..f843fae
--- /dev/null
+++ b/components/dark-mode-toggle/index.stories.tsx
@@ -0,0 +1,24 @@
+import React from 'react'
+import { DarkModeToggle } from '.'
+import useDarkMode from 'use-dark-mode'
+import { Typography } from 'components/typography'
+
+export default {
+ title: 'Dark Mode Toggle',
+}
+
+export const ToggleDesktop = () => {
+ const darkMode = useDarkMode(false)
+
+ return (
+
+
+
+ dark mode: {darkMode.value ? 'enabled' : 'disabled'}
+
+ )
+}
+
+ToggleDesktop.story = {
+ name: 'Desktop',
+}
diff --git a/components/dark-mode-toggle/index.tsx b/components/dark-mode-toggle/index.tsx
new file mode 100644
index 0000000..ac629c2
--- /dev/null
+++ b/components/dark-mode-toggle/index.tsx
@@ -0,0 +1,27 @@
+import React from 'react'
+import useDarkMode from 'use-dark-mode'
+import { SvgSun } from 'components/svgs/svg-sun'
+import { SvgMoon } from 'components/svgs/svg-moon'
+
+import styles from './index.module.scss'
+
+const DarkModeToggle = () => {
+ const darkMode = useDarkMode(false)
+
+ return (
+
+
+
+ {darkMode.value ? : }
+
+
+ )
+}
+
+export { DarkModeToggle }
diff --git a/components/drag-and-drop/index.module.scss b/components/drag-and-drop/index.module.scss
new file mode 100644
index 0000000..c415eac
--- /dev/null
+++ b/components/drag-and-drop/index.module.scss
@@ -0,0 +1,101 @@
+@import '../../styles/variables.scss';
+
+.root {
+ width: 100%;
+ max-width: 476px;
+ padding: 24px 24px 20px;
+ background: $white;
+ border-radius: 8px;
+ box-shadow: 0 2px 4px rgba($black, 0.12);
+ transition: background 0.2s ease;
+
+ &.dark {
+ background: $darker-grey;
+ }
+}
+
+.dropZoneWrapper {
+ position: relative;
+ height: 244px;
+ margin-bottom: 16px;
+ text-align: center;
+ background: $off-white;
+ border-radius: 6px;
+ transition: background 0.2s ease;
+
+ &.dark {
+ background: $dark-grey;
+ }
+}
+
+.dashed {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1;
+ border-radius: 6px;
+
+ rect {
+ transition: stroke 0.2s ease;
+ animation: dash 0.75s linear infinite forwards;
+ animation-play-state: paused;
+ }
+
+ &.dragActive rect {
+ animation-play-state: running;
+ }
+}
+
+@keyframes dash {
+ 0% {
+ stroke-dashoffset: 0;
+ }
+ 100% {
+ stroke-dashoffset: -20;
+ }
+}
+
+.dropZone {
+ position: relative;
+ z-index: 2;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
+
+ &:focus {
+ outline: none;
+ }
+}
+
+.imageUpload {
+ margin-bottom: 20px;
+}
+
+.imageUploadText {
+ u {
+ font-weight: 700;
+ color: $link;
+ cursor: pointer;
+ transition: color 0.2s ease;
+ }
+
+ &.dark u {
+ color: $link-dark;
+ }
+}
+
+.info {
+ display: flex;
+ align-items: center;
+ margin-top: 8px;
+
+ svg {
+ flex: 0 0 20px;
+ margin-right: 8px;
+ }
+}
diff --git a/components/drag-and-drop/index.stories.tsx b/components/drag-and-drop/index.stories.tsx
new file mode 100644
index 0000000..65bf73e
--- /dev/null
+++ b/components/drag-and-drop/index.stories.tsx
@@ -0,0 +1,27 @@
+import React from 'react'
+import useDarkMode from 'use-dark-mode'
+import { DragAndDrop } from '.'
+import { Button } from 'components/button'
+
+export default {
+ title: 'Drag & Drop',
+}
+
+export const DragAndDropDesktop = () => {
+ const { toggle } = useDarkMode(false)
+ const onDrop = (acceptedFiles: File[]) => {
+ console.log('acceptedFiles[0]', acceptedFiles[0])
+ }
+
+ return (
+
+
+
+ Toggle Dark Mode
+
+ )
+}
+
+DragAndDropDesktop.story = {
+ name: 'Desktop',
+}
diff --git a/components/drag-and-drop/index.tsx b/components/drag-and-drop/index.tsx
new file mode 100644
index 0000000..8e804bc
--- /dev/null
+++ b/components/drag-and-drop/index.tsx
@@ -0,0 +1,48 @@
+import React from 'react'
+import classnames from 'classnames'
+import useDarkMode from 'use-dark-mode'
+import { useDropzone } from 'react-dropzone'
+import { Typography } from 'components/typography'
+import { SvgDropZone } from 'components/svgs/svg-drop-zone'
+import { SvgImageUpload } from 'components/svgs/svg-image-upload'
+import { SvgInfo } from 'components/svgs/svg-info'
+
+import styles from './index.module.scss'
+
+type DragAndDropProps = {
+ onDrop: (acceptedFiles: File[]) => void
+}
+
+const DragAndDrop = ({ onDrop }: DragAndDropProps) => {
+ const { value: isDark } = useDarkMode(false)
+ const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop })
+ return (
+
+
+
+
+
+
+
+
+
+ Drag & drop a .png file or
+
+ click here to upload it .
+
+
+
+
+ We recommend a square png image with at least 310px
+
+
+ No data or images are stored
+
+
+ )
+}
+
+export { DragAndDrop }
diff --git a/components/lazy-image/index.module.scss b/components/lazy-image/index.module.scss
new file mode 100644
index 0000000..9388e59
--- /dev/null
+++ b/components/lazy-image/index.module.scss
@@ -0,0 +1,29 @@
+@import '../../styles/variables.scss';
+
+.root {
+ position: relative;
+ width: 100%;
+}
+
+.image {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ font-family: 'object-fit: cover; object-position: center;', sans-serif;
+ object-fit: cover;
+ object-position: center;
+}
+
+.placeholder {
+ composes: image;
+ transition: opacity 0.2s linear 0.2s;
+}
+
+.normal {
+ composes: image;
+ transition: opacity 0.2s linear;
+}
diff --git a/components/lazy-image/index.tsx b/components/lazy-image/index.tsx
new file mode 100644
index 0000000..3e302ca
--- /dev/null
+++ b/components/lazy-image/index.tsx
@@ -0,0 +1,54 @@
+import React, { useRef, useEffect } from 'react'
+import { LazyImageFull, ImageState } from 'react-lazy-images'
+import objectFitImages from 'object-fit-images'
+
+import styles from './index.module.scss'
+
+type LazyImageProps = {
+ src: string
+ srcRetina: string
+ srcPlaceholder: string
+ alt: string
+ aspectRatio: string
+}
+
+const LazyImage = ({ src, srcRetina, srcPlaceholder, alt, aspectRatio }: LazyImageProps) => {
+ const [widthString, heightString] = aspectRatio.split('/')
+ const width = parseInt(widthString)
+ const height = parseInt(heightString)
+
+ const imgRef = useRef(null)
+
+ useEffect(() => {
+ if (imgRef.current) {
+ objectFitImages(imgRef.current)
+ }
+ }, [imgRef])
+
+ return (
+
+ {({ imageProps, imageState, ref }) => {
+ const loaded = imageState === ImageState.LoadSuccess
+ return (
+
+
+
+
+ )
+ }}
+
+ )
+}
+
+export { LazyImage }
diff --git a/components/seo/index.tsx b/components/seo/index.tsx
new file mode 100644
index 0000000..9ed8096
--- /dev/null
+++ b/components/seo/index.tsx
@@ -0,0 +1,30 @@
+import React from 'react'
+import Head from 'next/head'
+
+type SEOProps = {
+ title: string
+ description: string
+}
+
+const SEO = ({ title, description }: SEOProps) => (
+
+ {title}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+)
+
+export { SEO }
diff --git a/components/svgs/svg-appycon.tsx b/components/svgs/svg-appycon.tsx
new file mode 100644
index 0000000..977551e
--- /dev/null
+++ b/components/svgs/svg-appycon.tsx
@@ -0,0 +1,45 @@
+import React from 'react'
+import { uniqueId } from 'utils/ids'
+
+const SvgAppycon: React.FC> = (props) => {
+ const idPrefix = uniqueId('svg-')
+ return (
+
+ Appycon logo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export { SvgAppycon }
diff --git a/components/svgs/svg-arrow-down.tsx b/components/svgs/svg-arrow-down.tsx
new file mode 100644
index 0000000..5231ea1
--- /dev/null
+++ b/components/svgs/svg-arrow-down.tsx
@@ -0,0 +1,16 @@
+import React from 'react'
+import useDarkMode from 'use-dark-mode'
+import { uniqueId } from 'utils/ids'
+
+const SvgArrowDown: React.FC> = (props) => {
+ const { value: isDark } = useDarkMode(false)
+ const idPrefix = uniqueId('svg-')
+ return (
+
+ Arrow down
+
+
+ )
+}
+
+export { SvgArrowDown }
diff --git a/components/svgs/svg-drop-zone.tsx b/components/svgs/svg-drop-zone.tsx
new file mode 100644
index 0000000..128786c
--- /dev/null
+++ b/components/svgs/svg-drop-zone.tsx
@@ -0,0 +1,29 @@
+import React from 'react'
+import useDarkMode from 'use-dark-mode'
+
+const SvgDropZone: React.FC> = (props) => {
+ const { value: isDark } = useDarkMode(false)
+ return (
+
+
+
+
+ )
+}
+
+export { SvgDropZone }
diff --git a/components/svgs/svg-favycon.tsx b/components/svgs/svg-favycon.tsx
new file mode 100644
index 0000000..bdb75ea
--- /dev/null
+++ b/components/svgs/svg-favycon.tsx
@@ -0,0 +1,45 @@
+import React from 'react'
+import { uniqueId } from 'utils/ids'
+
+const SvgFavycon: React.FC> = (props) => {
+ const idPrefix = uniqueId('svg-')
+ return (
+
+ Favycon logo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export { SvgFavycon }
diff --git a/components/svgs/svg-image-upload.tsx b/components/svgs/svg-image-upload.tsx
new file mode 100644
index 0000000..009624d
--- /dev/null
+++ b/components/svgs/svg-image-upload.tsx
@@ -0,0 +1,33 @@
+import React from 'react'
+import useDarkMode from 'use-dark-mode'
+import { uniqueId } from 'utils/ids'
+
+const SvgImageUpload: React.FC> = (props) => {
+ const { value: isDark } = useDarkMode(false)
+ const idPrefix = uniqueId('svg-')
+ return (
+
+ Image Upload
+
+
+
+
+
+
+ )
+}
+
+export { SvgImageUpload }
diff --git a/components/svgs/svg-info.tsx b/components/svgs/svg-info.tsx
new file mode 100644
index 0000000..718f0b9
--- /dev/null
+++ b/components/svgs/svg-info.tsx
@@ -0,0 +1,30 @@
+import React from 'react'
+import useDarkMode from 'use-dark-mode'
+import { uniqueId } from 'utils/ids'
+
+const SvgInfo: React.FC> = (props) => {
+ const { value: isDark } = useDarkMode(false)
+ const idPrefix = uniqueId('svg-')
+ return (
+
+ Info
+
+
+
+
+ )
+}
+
+export { SvgInfo }
diff --git a/components/svgs/svg-moon.tsx b/components/svgs/svg-moon.tsx
new file mode 100644
index 0000000..8569721
--- /dev/null
+++ b/components/svgs/svg-moon.tsx
@@ -0,0 +1,17 @@
+import React from 'react'
+import { uniqueId } from 'utils/ids'
+
+const SvgMoon: React.FC> = (props) => {
+ const idPrefix = uniqueId('svg-')
+ return (
+
+ Activate dark mode
+
+
+ )
+}
+
+export { SvgMoon }
diff --git a/components/svgs/svg-sun.tsx b/components/svgs/svg-sun.tsx
new file mode 100644
index 0000000..21721c1
--- /dev/null
+++ b/components/svgs/svg-sun.tsx
@@ -0,0 +1,17 @@
+import React from 'react'
+import { uniqueId } from 'utils/ids'
+
+const SvgSun: React.FC> = (props) => {
+ const idPrefix = uniqueId('svg-')
+ return (
+
+ Activate light mode
+
+
+ )
+}
+
+export { SvgSun }
diff --git a/components/tool-title/index.module.scss b/components/tool-title/index.module.scss
new file mode 100644
index 0000000..a8dc65b
--- /dev/null
+++ b/components/tool-title/index.module.scss
@@ -0,0 +1,6 @@
+@import '../../styles/variables.scss';
+
+.root {
+ display: flex;
+ align-items: flex-start;
+}
diff --git a/components/tool-title/index.stories.tsx b/components/tool-title/index.stories.tsx
new file mode 100644
index 0000000..e5ccd3d
--- /dev/null
+++ b/components/tool-title/index.stories.tsx
@@ -0,0 +1,26 @@
+import React from 'react'
+import { withKnobs, text } from '@storybook/addon-knobs'
+import useDarkMode from 'use-dark-mode'
+import { Button } from 'components/button'
+import { ToolTitle } from '.'
+
+export default {
+ title: 'Tool Title',
+ decorators: [withKnobs],
+}
+
+export const ToolTitleDesktop = () => {
+ const { toggle } = useDarkMode(false)
+ const body = text('body', 'Favycon')
+ return (
+
+ {body}
+
+ Toggle Dark Mode
+
+ )
+}
+
+ToolTitleDesktop.story = {
+ name: 'desktop',
+}
diff --git a/components/tool-title/index.tsx b/components/tool-title/index.tsx
new file mode 100644
index 0000000..2e1e13b
--- /dev/null
+++ b/components/tool-title/index.tsx
@@ -0,0 +1,21 @@
+import React from 'react'
+import { Typography } from 'components/typography'
+
+import styles from './index.module.scss'
+
+type ToolTitleProps = {
+ children: string
+}
+
+const ToolTitle = ({ children }: ToolTitleProps) => (
+
+
+ {children}
+
+
+ TOOL
+
+
+)
+
+export { ToolTitle }
diff --git a/components/typography/index.module.scss b/components/typography/index.module.scss
index b86a4c3..5753995 100644
--- a/components/typography/index.module.scss
+++ b/components/typography/index.module.scss
@@ -28,6 +28,16 @@
.footer {
font-size: $font-size-footer;
line-height: $line-height-footer;
+
+ a {
+ color: inherit;
+
+ &:focus,
+ &:active,
+ &:hover {
+ color: inherit;
+ }
+ }
}
.superscript {
@@ -53,12 +63,22 @@
.black {
color: $black;
+ transition: color 0.2s ease;
+
+ &.dark {
+ color: $white;
+ }
}
.gray {
- color: $gray;
+ color: $grey;
}
.white {
color: $white;
+ transition: color 0.2s ease;
+
+ &.dark {
+ color: $black;
+ }
}
diff --git a/components/typography/index.stories.tsx b/components/typography/index.stories.tsx
new file mode 100644
index 0000000..46545e9
--- /dev/null
+++ b/components/typography/index.stories.tsx
@@ -0,0 +1,35 @@
+import React from 'react'
+import { withKnobs, text, select } from '@storybook/addon-knobs'
+import useDarkMode from 'use-dark-mode'
+import { Button } from 'components/button'
+import { Typography } from '.'
+
+export default {
+ title: 'Typography',
+ decorators: [withKnobs],
+}
+
+export const TypographyDesktop = () => {
+ const { toggle } = useDarkMode(false)
+ const variant = select(
+ 'variant',
+ ['h1', 'smallBody', 'regularBody', 'mediumBody', 'largeBody', 'footer', 'superscript'],
+ 'h1'
+ )
+ const weight = select('weight', ['regular', 'medium', 'semiBold', 'bold'], 'regular')
+ const color = select('color', ['black', 'gray', 'white'], 'black')
+ const body = text('body', 'Some text')
+ return (
+
+
+ {body}
+
+
+ Toggle Dark Mode
+
+ )
+}
+
+TypographyDesktop.story = {
+ name: 'Desktop',
+}
diff --git a/components/typography/index.tsx b/components/typography/index.tsx
index 3f6d19d..1d7a7f0 100644
--- a/components/typography/index.tsx
+++ b/components/typography/index.tsx
@@ -1,6 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
+import useDarkMode from 'use-dark-mode'
import styles from './index.module.scss'
@@ -10,13 +11,20 @@ type TypographyProps = {
weight: 'regular' | 'medium' | 'semiBold' | 'bold'
color: 'black' | 'gray' | 'white'
tag?: string
-}
+} & React.DetailedHTMLProps, HTMLParagraphElement>
-const Typography = ({ children, variant, weight, color, tag }: TypographyProps) => {
- const className = classNames(styles[variant], styles[color], styles[weight])
+const Typography = ({ children, variant, weight, color, tag, ...props }: TypographyProps) => {
+ const { value: isDark } = useDarkMode(false)
+ const className = classNames(
+ styles[variant],
+ styles[color],
+ styles[weight],
+ { [styles.dark]: isDark },
+ props.className
+ )
const componentType = ['h1'].includes(variant) ? variant : 'p'
- return React.createElement(tag || componentType, { className }, children)
+ return React.createElement(tag || componentType, { ...props, className }, children)
}
Typography.defaultProps = {
diff --git a/next.config.js b/next.config.js
index 91559f1..754efb3 100644
--- a/next.config.js
+++ b/next.config.js
@@ -27,6 +27,9 @@ module.exports = {
}
config.resolve.alias['components'] = path.join(__dirname, 'components')
+ config.resolve.alias['pages'] = path.join(__dirname, 'pages')
+ config.resolve.alias['styles'] = path.join(__dirname, 'styles')
+ config.resolve.alias['utils'] = path.join(__dirname, 'utils')
config.resolve.alias['hooks'] = path.join(__dirname, 'hooks')
config.resolve.alias['react'] = 'preact/compat'
config.resolve.alias['react-dom'] = 'preact/compat'
diff --git a/package.json b/package.json
index d16a6b8..4d7d178 100644
--- a/package.json
+++ b/package.json
@@ -38,14 +38,22 @@
"commit": "git-cz"
},
"dependencies": {
+ "@fiahfy/ico-convert": "0.0.7",
+ "adm-zip": "0.4.14",
"classnames": "2.2.6",
+ "multer": "1.4.2",
"next": "9.3.4",
+ "object-fit-images": "3.2.4",
"preact": "10.4.0",
"preact-render-to-string": "5.1.6",
"preact-ssr-prepass": "1.0.1",
"prop-types": "15.7.2",
"react": "16.13.1",
- "react-dom": "16.13.1"
+ "react-dom": "16.13.1",
+ "react-dropzone": "10.2.2",
+ "react-lazy-images": "1.1.0",
+ "sharp": "0.25.2",
+ "use-dark-mode": "2.3.1"
},
"devDependencies": {
"@babel/core": "7.9.0",
@@ -61,9 +69,13 @@
"@storybook/addons": "5.3.18",
"@storybook/react": "5.3.18",
"@storybook/source-loader": "5.3.18",
+ "@types/adm-zip": "0.4.33",
"@types/classnames": "2.2.10",
+ "@types/multer": "1.4.2",
"@types/node": "13.11.1",
+ "@types/object-fit-images": "3.2.0",
"@types/react": "16.9.34",
+ "@types/sharp": "0.24.0",
"@typescript-eslint/eslint-plugin": "2.27.0",
"@typescript-eslint/parser": "2.27.0",
"all-contributors-cli": "6.14.1",
@@ -92,6 +104,7 @@
"sass-loader": "8.0.2",
"semantic-release": "17.0.4",
"stylelint": "13.3.1",
+ "stylelint-config-css-modules": "2.2.0",
"stylelint-config-prettier": "8.0.1",
"stylelint-config-recess-order": "2.0.4",
"stylelint-config-standard": "20.0.0",
diff --git a/pages/_document.tsx b/pages/_document.tsx
new file mode 100644
index 0000000..630dcf2
--- /dev/null
+++ b/pages/_document.tsx
@@ -0,0 +1,19 @@
+import React from 'react'
+import Document, { Html, Head, Main, NextScript } from 'next/document'
+
+class MyDocument extends Document {
+ render() {
+ return (
+
+
+
+
+
+
+
+
+ )
+ }
+}
+
+export default MyDocument
diff --git a/pages/api/favycon.ts b/pages/api/favycon.ts
new file mode 100644
index 0000000..244f3f9
--- /dev/null
+++ b/pages/api/favycon.ts
@@ -0,0 +1,59 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+import sharp from 'sharp'
+import { convert } from '@fiahfy/ico-convert'
+import multer from 'multer'
+import AdmZip from 'adm-zip'
+
+import { runMiddleware } from 'utils/api'
+import { faviconSizesPrefixes, browserConfigTemplate, tutorialTemplate } from 'utils/favicon'
+
+const storage = multer.memoryStorage()
+const upload = multer({ storage })
+
+export const config = {
+ api: {
+ bodyParser: false,
+ },
+}
+
+export default async (req: NextApiRequest, res: NextApiResponse) => {
+ switch (req.method) {
+ case 'POST':
+ await runMiddleware(req, res, upload.single('icon'))
+
+ const zip = new AdmZip()
+ // add folder
+ zip.addFile('icons/', Buffer.alloc(0))
+ const file: Buffer = (req as any).file.buffer
+
+ Object.keys(faviconSizesPrefixes).map(async (size) => {
+ const [width, height] = size.split('x')
+ const scaledPng = await sharp(file)
+ .resize(parseInt(width), parseInt(height), { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })
+ .png()
+ .toBuffer()
+ // @ts-ignore
+ faviconSizesPrefixes[size].forEach((prefix) => {
+ zip.addFile(`icons/${prefix}-${size}.png`, scaledPng)
+ })
+ })
+
+ const scaledPng = await sharp(file)
+ .resize(256, 256, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })
+ .png()
+ .toBuffer()
+ const ico = await convert(scaledPng)
+ zip.addFile('icons/favicon.ico', ico)
+
+ zip.addFile('icons/browserconfig.xml', Buffer.alloc(browserConfigTemplate.length, browserConfigTemplate))
+ zip.addFile('readme.txt', Buffer.alloc(tutorialTemplate.length, tutorialTemplate))
+
+ res.setHeader('Content-disposition', 'attachment; filename=favicons.zip')
+ res.setHeader('Content-type', 'application/zip')
+ res.status(200).end(zip.toBuffer())
+ break
+ default:
+ res.setHeader('Allow', ['POST'])
+ res.status(405).end(`Method ${req.method} Not Allowed`)
+ }
+}
diff --git a/pages/index.module.scss b/pages/index.module.scss
new file mode 100644
index 0000000..4a432df
--- /dev/null
+++ b/pages/index.module.scss
@@ -0,0 +1,56 @@
+@import '../styles/variables.scss';
+
+.container {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ width: 100%;
+ max-width: 960px;
+ padding: 52px 20px;
+ margin: 0 auto;
+}
+
+.info {
+ width: 100%;
+ max-width: 350px;
+}
+
+.firstParagraph {
+ margin-top: 8px;
+}
+
+.secondParagraph {
+ margin-top: 16px;
+ margin-bottom: 60px;
+}
+
+.dragAndDrop {
+ position: relative;
+ display: flex;
+ align-items: flex-start;
+ justify-content: center;
+ width: 100%;
+ max-width: 540px;
+ padding: 41px 0 38px;
+}
+
+.background {
+ position: absolute;
+ top: 10px;
+ right: 0;
+ left: 0;
+ z-index: -1;
+ width: 100%;
+ overflow: hidden;
+ border-radius: 8px;
+ transform: rotate(2deg);
+}
+
+.image {
+ position: absolute;
+ top: 57px;
+ right: 15px;
+ width: 184px;
+ height: 108px;
+ transform: translate(100%, -100%);
+}
diff --git a/pages/index.tsx b/pages/index.tsx
index c6bb5ec..2c0d365 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -1,65 +1,79 @@
import React from 'react'
import { NextPage } from 'next'
-import Head from 'next/head'
-import { Typography } from '../components/typography'
+import useDarkMode from 'use-dark-mode'
+import { LazyImage } from 'components/lazy-image'
+import { BaseLayout } from 'components/base-layout'
+import { Typography } from 'components/typography'
+import { SEO } from 'components/seo'
+import { ToolTitle } from 'components/tool-title'
+import { DragAndDrop } from 'components/drag-and-drop'
-const Home: NextPage = () => (
-
-
-
Favycon
-
-
-
-
+import styles from './index.module.scss'
-
-
-
- Favycon
-
-
- TOOL
-
-
-
- A small online tool to help you generate your favicon in all the sizes and formats you need.
-
- Just drag & drop an image and you will then get a downloadable file alongside some documentation on how to
- add the favicons.
-
-
-
- Created by 4 people on their 2020’s worldwide quarantine. Background image from Unsplash .
-
-
+const getRandomNumber = (min = 1, max = 3) => Math.floor(Math.random() * max) + min
-
-
-)
+ return (
+
+
+
+
+
Favycon
+
+ A small online tool to help you generate your favicon in all the sizes and formats you need.
+
+
+ Just drag & drop an image and you will then get a downloadable file alongside some documentation on how
+ to add the favicons.
+
+
+
+ Created by 4 people on their 2020’s worldwide quarantine. Background image from{' '}
+
+ Unsplash
+
+ .
+
+
+
+
+
+ )
+}
export default Home
diff --git a/public/favicon.ico b/public/favicon.ico
index df4c39a..5831830 100644
Binary files a/public/favicon.ico and b/public/favicon.ico differ
diff --git a/public/favicon.png b/public/favicon.png
index 9bef3ea..d83f969 100644
Binary files a/public/favicon.png and b/public/favicon.png differ
diff --git a/public/favicon.svg b/public/favicon.svg
index fdd050a..1b06a34 100644
--- a/public/favicon.svg
+++ b/public/favicon.svg
@@ -1,11 +1,11 @@
-
-
-
-
+
+
+
+
-
-
-
+
+
+
diff --git a/public/images/dnd-dark@1x.png b/public/images/dnd-dark@1x.png
new file mode 100644
index 0000000..36d9402
Binary files /dev/null and b/public/images/dnd-dark@1x.png differ
diff --git a/public/images/dnd-dark@2x.png b/public/images/dnd-dark@2x.png
new file mode 100644
index 0000000..b5ca27e
Binary files /dev/null and b/public/images/dnd-dark@2x.png differ
diff --git a/public/images/dnd-light@1x.png b/public/images/dnd-light@1x.png
new file mode 100644
index 0000000..89934ec
Binary files /dev/null and b/public/images/dnd-light@1x.png differ
diff --git a/public/images/dnd-light@2x.png b/public/images/dnd-light@2x.png
new file mode 100644
index 0000000..3dc4b02
Binary files /dev/null and b/public/images/dnd-light@2x.png differ
diff --git a/public/images/unsplash-1@1x.jpg b/public/images/unsplash-1@1x.jpg
new file mode 100644
index 0000000..06e870b
Binary files /dev/null and b/public/images/unsplash-1@1x.jpg differ
diff --git a/public/images/unsplash-1@2x.jpg b/public/images/unsplash-1@2x.jpg
new file mode 100644
index 0000000..fad1fb1
Binary files /dev/null and b/public/images/unsplash-1@2x.jpg differ
diff --git a/public/images/unsplash-1@placeholder.jpg b/public/images/unsplash-1@placeholder.jpg
new file mode 100644
index 0000000..600cc90
Binary files /dev/null and b/public/images/unsplash-1@placeholder.jpg differ
diff --git a/public/images/unsplash-2@1x.jpg b/public/images/unsplash-2@1x.jpg
new file mode 100644
index 0000000..b8b30d2
Binary files /dev/null and b/public/images/unsplash-2@1x.jpg differ
diff --git a/public/images/unsplash-2@2x.jpg b/public/images/unsplash-2@2x.jpg
new file mode 100644
index 0000000..7efbfd2
Binary files /dev/null and b/public/images/unsplash-2@2x.jpg differ
diff --git a/public/images/unsplash-2@placeholder.jpg b/public/images/unsplash-2@placeholder.jpg
new file mode 100644
index 0000000..3fb9efe
Binary files /dev/null and b/public/images/unsplash-2@placeholder.jpg differ
diff --git a/public/images/unsplash-3@1x.jpg b/public/images/unsplash-3@1x.jpg
new file mode 100644
index 0000000..d62d949
Binary files /dev/null and b/public/images/unsplash-3@1x.jpg differ
diff --git a/public/images/unsplash-3@2x.jpg b/public/images/unsplash-3@2x.jpg
new file mode 100644
index 0000000..c5a5b20
Binary files /dev/null and b/public/images/unsplash-3@2x.jpg differ
diff --git a/public/images/unsplash-3@placeholder.jpg b/public/images/unsplash-3@placeholder.jpg
new file mode 100644
index 0000000..ef90d59
Binary files /dev/null and b/public/images/unsplash-3@placeholder.jpg differ
diff --git a/public/js/noflash.js b/public/js/noflash.js
new file mode 100644
index 0000000..745e3e9
--- /dev/null
+++ b/public/js/noflash.js
@@ -0,0 +1,41 @@
+/* eslint-disable */
+// Insert this script in your index.html right after the tag.
+// This will help to prevent a flash if dark mode is the default.
+
+;(function () {
+ // Change these if you use something different in your hook.
+ var storageKey = 'darkMode'
+ var classNameDark = 'dark-mode'
+ var classNameLight = 'light-mode'
+
+ function setClassOnDocumentBody(darkMode) {
+ document.body.classList.add(darkMode ? classNameDark : classNameLight)
+ document.body.classList.remove(darkMode ? classNameLight : classNameDark)
+ }
+
+ var preferDarkQuery = '(prefers-color-scheme: dark)'
+ var mql = window.matchMedia(preferDarkQuery)
+ var supportsColorSchemeQuery = mql.media === preferDarkQuery
+ var localStorageTheme = null
+ try {
+ localStorageTheme = localStorage.getItem(storageKey)
+ } catch (err) {}
+ var localStorageExists = localStorageTheme !== null
+ if (localStorageExists) {
+ localStorageTheme = JSON.parse(localStorageTheme)
+ }
+
+ // Determine the source of truth
+ if (localStorageExists) {
+ // source of truth from localStorage
+ setClassOnDocumentBody(localStorageTheme)
+ } else if (supportsColorSchemeQuery) {
+ // source of truth from system
+ setClassOnDocumentBody(mql.matches)
+ localStorage.setItem(storageKey, mql.matches)
+ } else {
+ // source of truth from document.body
+ var isDarkMode = document.body.classList.contains(classNameDark)
+ localStorage.setItem(storageKey, JSON.stringify(isDarkMode))
+ }
+})()
diff --git a/public/share.png b/public/share.png
new file mode 100644
index 0000000..f0e2824
Binary files /dev/null and b/public/share.png differ
diff --git a/styles/main.scss b/styles/main.scss
index 19f8cb6..edde9ac 100644
--- a/styles/main.scss
+++ b/styles/main.scss
@@ -10,11 +10,20 @@ body {
/* https://gist.github.com/hsleonis/55712b0eafc9b25f1944 */
font-size: 100%;
- text-shadow: rgba(0, 0, 0, 0.01) 0 0 1px;
+ text-shadow: rgba($black, 0.01) 0 0 1px;
font-variant-ligatures: none;
text-rendering: optimizeLegibility;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
+ transition: background 0.2s ease;
+
+ &.light-mode {
+ background: $white;
+ }
+
+ &.dark-mode {
+ background: $dark-black;
+ }
}
* {
@@ -24,6 +33,6 @@ body {
hr {
height: 1px;
margin: 16px 0;
- background-color: $light-gray-two;
+ background-color: $light-grey;
border: none;
}
diff --git a/styles/variables.scss b/styles/variables.scss
index 00abbf0..ffd0254 100644
--- a/styles/variables.scss
+++ b/styles/variables.scss
@@ -1,22 +1,16 @@
$white: #fff;
$off-white: #fafafa;
-$gray: #8f8f8f;
-$dar-gray: #2f303a;
-$light-gray-one: #e5e5e5;
-$light-gray-two: #ebebeb;
-$light-gray-three: #ccc;
+$grey: #9698a3;
+$light-grey: #ebebeb;
+$dark-grey: #3d3f47;
+$darker-grey: #33353d;
$black: #000;
+$dark-black: #191a1f;
-$blue: #4c66d5;
-$light-blue: #e7ecff;
-
-$orange: #d5824c;
-$light-orange: #fff0e7;
-
-$dark-purple: #363743;
-$light-purple: #4f5263;
+$link: #4c66d5;
+$link-dark: #7083ff;
$font-size-h1: 52px;
$line-height-h1: 64px;
diff --git a/tsconfig.json b/tsconfig.json
index 51af429..f81e070 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,23 +1,31 @@
{
- "compilerOptions": {
- "target": "esnext",
- "lib": ["dom", "dom.iterable", "esnext"],
- "strict": true,
- "allowJs": true,
- "skipLibCheck": true,
- "forceConsistentCasingInFileNames": true,
- "noEmit": true,
- "esModuleInterop": true,
- "module": "esnext",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "jsx": "preserve",
- "alwaysStrict": true,
- "noFallthroughCasesInSwitch": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true
- },
- "exclude": ["node_modules"],
- "include": ["**/*.ts", "**/*.tsx", "./*.js"]
+ "compilerOptions": {
+ "target": "esnext",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "strict": true,
+ "allowJs": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "alwaysStrict": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "baseUrl": ".",
+ "paths": {
+ "components/*": ["components/*"],
+ "pages/*": ["pages/*"],
+ "theme/*": ["styles/*"],
+ "utils/*": ["utils/*"],
+ "hooks/*": ["hooks/*"]
+ }
+ },
+ "exclude": ["node_modules"],
+ "include": ["**/*.ts", "**/*.tsx", "./*.js", "./public/**/*.js"]
}
diff --git a/utils/api.ts b/utils/api.ts
new file mode 100644
index 0000000..5bbdbc9
--- /dev/null
+++ b/utils/api.ts
@@ -0,0 +1,14 @@
+import { NextApiRequest, NextApiResponse } from 'next'
+
+// Helper method to wait for a middleware to execute before continuing
+// And to throw an error when an error happens in a middleware
+export const runMiddleware = (req: NextApiRequest, res: NextApiResponse, fn: any) => {
+ return new Promise((resolve, reject) => {
+ fn(req, res, (result: any) => {
+ if (result instanceof Error) {
+ return reject(result)
+ }
+ return resolve(result)
+ })
+ })
+}
diff --git a/utils/favicon.ts b/utils/favicon.ts
new file mode 100644
index 0000000..9c97161
--- /dev/null
+++ b/utils/favicon.ts
@@ -0,0 +1,62 @@
+export const faviconSizesPrefixes = {
+ '57x57': ['apple-icon'],
+ '60x60': ['apple-icon'],
+ '72x72': ['apple-icon'],
+ '76x76': ['apple-icon'],
+ '114x114': ['apple-icon'],
+ '120x120': ['apple-icon'],
+ '144x144': ['apple-icon', 'ms-icon'],
+ '152x152': ['apple-icon'],
+ '180x180': ['apple-icon'],
+ '16x16': ['favicon'],
+ '32x32': ['favicon'],
+ '96x96': ['favicon'],
+ '192x192': ['favicon'],
+ '70x70': ['ms-icon'],
+ '150x150': ['ms-icon'],
+ '310x150': ['ms-icon'],
+ '310x310': ['ms-icon'],
+}
+
+export const browserConfigTemplate = `
+
+
+
+
+
+
+
+
+ #ffffff
+
+
+
+`
+
+export const tutorialTemplate = `
+Thank you for using Favycon!
+
+Now that you have all favicon files generator, you can copy all files
+from the icons folder into your project public folder.
+
+Last but not least add the following HTML tags to your index.html file.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`
diff --git a/utils/ids.ts b/utils/ids.ts
new file mode 100644
index 0000000..ef4f9b4
--- /dev/null
+++ b/utils/ids.ts
@@ -0,0 +1,14 @@
+const idCounter: { [key: string]: number } = {}
+
+export const uniqueId = (prefix = '$unique$') => {
+ if (!idCounter[prefix]) {
+ idCounter[prefix] = 0
+ }
+
+ const id = ++idCounter[prefix]
+ if (prefix === '$unique$') {
+ return `${id}`
+ }
+
+ return `${prefix}${id}`
+}
diff --git a/yarn.lock b/yarn.lock
index fce199e..51ce2f5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1203,7 +1203,7 @@
dependencies:
regenerator-runtime "^0.13.4"
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
version "7.9.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06"
integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==
@@ -1493,6 +1493,22 @@
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46"
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
+"@fiahfy/ico-convert@0.0.7":
+ version "0.0.7"
+ resolved "https://registry.yarnpkg.com/@fiahfy/ico-convert/-/ico-convert-0.0.7.tgz#deabfe949ecc58cc68cfd0dc4f26b815908190bc"
+ integrity sha512-OXbb0C7w99qhr1sL22qmCVs7o84VxElvysb2FcQIJ7U/WnVdP9bPEQMD287vWeoYpaB3WsHag5mtHts+FZQUmg==
+ dependencies:
+ "@fiahfy/ico" "^0.0.4"
+ meow "^6.0.0"
+ sharp "^0.23.4"
+
+"@fiahfy/ico@^0.0.4":
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/@fiahfy/ico/-/ico-0.0.4.tgz#ff675a75368e004fb0efd5dc86d0aa348f809c19"
+ integrity sha512-+w3DHtz9pN3x2ToVOYuhisRki8XOLBFX3yfdvl0BBCxFW0Dxv3osKdbExe+t9DcAFc6Z5l7l3Tps28Bvs7kD5g==
+ dependencies:
+ pngjs "^3.4.0"
+
"@iarna/cli@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@iarna/cli/-/cli-1.2.0.tgz#0f7af5e851afe895104583c4ca07377a8094d641"
@@ -2316,11 +2332,26 @@
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.0.0.tgz#9c13c2574c92d4503b005feca8f2e16cc1611506"
integrity sha512-KYyTT/T6ALPkIRd2Ge080X/BsXvy9O0hcWTtMWkPvwAwF99+vn6Dv4GzrFT/Nn1LePr+FFDbRXXlqmsy9lw2zA==
+"@types/adm-zip@0.4.33":
+ version "0.4.33"
+ resolved "https://registry.yarnpkg.com/@types/adm-zip/-/adm-zip-0.4.33.tgz#ea5b94f771443f655613b64f920c0555867200dd"
+ integrity sha512-WM0DCWFLjXtddl0fu0+iN2ZF+qz8RF9RddG5OSy/S90AQz01Fu8lHn/3oTIZDxvG8gVcnBLAHMHOdBLbV6m6Mw==
+ dependencies:
+ "@types/node" "*"
+
"@types/anymatch@*":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a"
integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==
+"@types/body-parser@*":
+ version "1.19.0"
+ resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f"
+ integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==
+ dependencies:
+ "@types/connect" "*"
+ "@types/node" "*"
+
"@types/classnames@2.2.10":
version "2.2.10"
resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.10.tgz#cc658ca319b6355399efc1f5b9e818f1a24bf999"
@@ -2331,11 +2362,36 @@
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
+"@types/connect@*":
+ version "3.4.33"
+ resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546"
+ integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==
+ dependencies:
+ "@types/node" "*"
+
"@types/eslint-visitor-keys@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
+"@types/express-serve-static-core@*":
+ version "4.17.4"
+ resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.4.tgz#157c79c2d28b632d6418497c57c93185e392e444"
+ integrity sha512-dPs6CaRWxsfHbYDVU51VjEJaUJEcli4UI0fFMT4oWmgCvHj+j7oIxz5MLHVL0Rv++N004c21ylJNdWQvPkkb5w==
+ dependencies:
+ "@types/node" "*"
+ "@types/range-parser" "*"
+
+"@types/express@*":
+ version "4.17.6"
+ resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.6.tgz#6bce49e49570507b86ea1b07b806f04697fac45e"
+ integrity sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w==
+ dependencies:
+ "@types/body-parser" "*"
+ "@types/express-serve-static-core" "*"
+ "@types/qs" "*"
+ "@types/serve-static" "*"
+
"@types/history@*":
version "4.7.5"
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.5.tgz#527d20ef68571a4af02ed74350164e7a67544860"
@@ -2356,11 +2412,23 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339"
integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==
+"@types/mime@*":
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d"
+ integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==
+
"@types/minimist@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6"
integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=
+"@types/multer@1.4.2":
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/@types/multer/-/multer-1.4.2.tgz#f73e9eab7d8e0ff2842630e7968b88336cbb7e1c"
+ integrity sha512-pVcPwuC0FbVcLhopJHx8Ro3WSXjvVvEpJMfy+DFAL/3DwNYAQH+hf/Vq+PqoS5kM4mng7L/4upzXhP/12yWh4w==
+ dependencies:
+ "@types/express" "*"
+
"@types/node@*", "@types/node@13.11.1", "@types/node@>= 8":
version "13.11.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7"
@@ -2376,6 +2444,11 @@
resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.2.tgz#d070fe6a6b78755d1092a3dc492d34c3d8f871c4"
integrity sha512-4QQmOF5KlwfxJ5IGXFIudkeLCdMABz03RcUXu+LCb24zmln8QW6aDjuGl4d4XPVLf2j+FnjelHTP7dvceAFbhA==
+"@types/object-fit-images@3.2.0":
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/@types/object-fit-images/-/object-fit-images-3.2.0.tgz#ffa0b3243ade3b89a2b12a08e92dbbea75b825f4"
+ integrity sha512-ordonpqL1HiYEHDIGxDo/MvyDvGZiNmPpw9bYxys7TXPcCN5WBejOR1Mj/KPCPyjMeaXyLQu7JP5tVi4GBRoWA==
+
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
@@ -2391,6 +2464,16 @@
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8"
integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==
+"@types/qs@*":
+ version "6.9.1"
+ resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.1.tgz#937fab3194766256ee09fcd40b781740758617e7"
+ integrity sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw==
+
+"@types/range-parser@*":
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
+ integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
+
"@types/reach__router@^1.2.3":
version "1.3.4"
resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.3.4.tgz#98ef393d06f59d296b5c021ba94b94e5fc463245"
@@ -2433,6 +2516,21 @@
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d"
integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==
+"@types/serve-static@*":
+ version "1.13.3"
+ resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.3.tgz#eb7e1c41c4468272557e897e9171ded5e2ded9d1"
+ integrity sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==
+ dependencies:
+ "@types/express-serve-static-core" "*"
+ "@types/mime" "*"
+
+"@types/sharp@0.24.0":
+ version "0.24.0"
+ resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.24.0.tgz#28abfeac45b4dcb472305503105322e97a6c2672"
+ integrity sha512-+0WeyJajTSoIacBzonsq856whNJC+cN9FNEs0yZ6hFq/V1CZmlqM8vBRy7TKZunH+gIO7SwDCzgXYWRRbzqfDA==
+ dependencies:
+ "@types/node" "*"
+
"@types/source-list-map@*":
version "0.1.2"
resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
@@ -2524,6 +2622,11 @@
semver "^6.3.0"
tsutils "^3.17.1"
+"@use-it/event-listener@^0.1.2":
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/@use-it/event-listener/-/event-listener-0.1.3.tgz#a9920b2819d211cf55e68e830997546eec6886d3"
+ integrity sha512-UCHkLOVU+xj3/1R8jXz8GzDTowkzfIDPESOBlVC2ndgwUSBEqiFdwCoUEs2lcGhJOOiEdmWxF+T23C5+60eEew==
+
"@webassemblyjs/ast@1.8.5":
version "1.8.5"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
@@ -2877,6 +2980,11 @@ adjust-sourcemap-loader@2.0.0:
object-path "0.11.4"
regex-parser "2.2.10"
+adm-zip@0.4.14:
+ version "0.4.14"
+ resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.14.tgz#2cf312bcc9f8875df835b0f6040bd89be0a727a9"
+ integrity sha512-/9aQCnQHF+0IiCl0qhXoK7qs//SwYE7zX8lsr/DNk1BRAHYxeLZPL4pguwK29gUEqasYQjqPtEpDRSWEkdHn9g==
+
agent-base@4, agent-base@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
@@ -3091,6 +3199,11 @@ app-root-dir@^1.0.2:
resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118"
integrity sha1-OBh+wt6nV3//Az/8sSFyaS/24Rg=
+append-field@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56"
+ integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=
+
aproba@^1.0.3, aproba@^1.1.1, aproba@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@@ -3323,6 +3436,11 @@ atob@^2.1.2:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
+attr-accept@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.1.0.tgz#a231a854385d36ff7a99647bb77b33c8a5175aee"
+ integrity sha512-sLzVM3zCCmmDtDNhI0i96k6PUztkotSOXqE4kDGQt/6iDi5M+H0srjeF+QC6jN581l4X/Zq3Zu/tgcErEssavg==
+
autoprefixer@^9.7.2, autoprefixer@^9.7.5:
version "9.7.6"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.6.tgz#63ac5bbc0ce7934e6997207d5bb00d68fa8293a4"
@@ -3768,6 +3886,15 @@ bindings@^1.5.0:
dependencies:
file-uri-to-path "1.0.0"
+bl@^4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.2.tgz#52b71e9088515d0606d9dd9cc7aa48dc1f98e73a"
+ integrity sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==
+ dependencies:
+ buffer "^5.5.0"
+ inherits "^2.0.4"
+ readable-stream "^3.4.0"
+
bluebird@^3.3.5, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5:
version "3.7.2"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
@@ -3973,6 +4100,14 @@ buffer@^4.3.0:
ieee754 "^1.1.4"
isarray "^1.0.0"
+buffer@^5.5.0:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.5.0.tgz#9c3caa3d623c33dd1c7ef584b89b88bf9c9bc1ce"
+ integrity sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww==
+ dependencies:
+ base64-js "^1.0.2"
+ ieee754 "^1.1.4"
+
builtin-status-codes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
@@ -3983,6 +4118,14 @@ builtins@^1.0.3:
resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88"
integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og=
+busboy@^0.2.11:
+ version "0.2.14"
+ resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453"
+ integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=
+ dependencies:
+ dicer "0.2.5"
+ readable-stream "1.1.x"
+
byline@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1"
@@ -4271,7 +4414,7 @@ chokidar@^2.0.4, chokidar@^2.1.8:
optionalDependencies:
fsevents "^1.2.7"
-chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.4:
+chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.3, chownr@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
@@ -4500,7 +4643,7 @@ collection-visit@^1.0.0:
map-visit "^1.0.0"
object-visit "^1.0.0"
-color-convert@^1.9.0:
+color-convert@^1.9.0, color-convert@^1.9.1:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
@@ -4519,11 +4662,27 @@ color-name@1.1.3:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
-color-name@~1.1.4:
+color-name@^1.0.0, color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+color-string@^1.5.2:
+ version "1.5.3"
+ resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc"
+ integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==
+ dependencies:
+ color-name "^1.0.0"
+ simple-swizzle "^0.2.2"
+
+color@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10"
+ integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==
+ dependencies:
+ color-convert "^1.9.1"
+ color-string "^1.5.2"
+
colors@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
@@ -4620,7 +4779,7 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
-concat-stream@^1.5.0:
+concat-stream@^1.5.0, concat-stream@^1.5.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
@@ -5216,6 +5375,13 @@ decode-uri-component@^0.2.0:
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
+decompress-response@^4.2.0:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986"
+ integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==
+ dependencies:
+ mimic-response "^2.0.0"
+
dedent@0.7.0, dedent@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
@@ -5337,6 +5503,11 @@ detect-indent@~5.0.0:
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50=
+detect-libc@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
+ integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
+
detect-newline@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
@@ -5371,6 +5542,14 @@ dezalgo@^1.0.0, dezalgo@~1.0.3:
asap "^2.0.0"
wrappy "1"
+dicer@0.2.5:
+ version "0.2.5"
+ resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f"
+ integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=
+ dependencies:
+ readable-stream "1.1.x"
+ streamsearch "0.1.2"
+
didyoumean@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff"
@@ -5686,7 +5865,7 @@ encoding@^0.1.11:
dependencies:
iconv-lite "~0.4.13"
-end-of-stream@^1.0.0, end-of-stream@^1.1.0:
+end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
@@ -6179,6 +6358,11 @@ expand-brackets@^2.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
+expand-template@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"
+ integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==
+
expand-tilde@^2.0.0, expand-tilde@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
@@ -6394,6 +6578,13 @@ file-loader@^4.2.0:
loader-utils "^1.2.3"
schema-utils "^2.5.0"
+file-selector@^0.1.12:
+ version "0.1.12"
+ resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.1.12.tgz#fe726547be219a787a9dcc640575a04a032b1fd0"
+ integrity sha512-Kx7RTzxyQipHuiqyZGf+Nz4vY9R1XGxuQl/hLoJwq+J4avk/9wxxgZyHKtbyIPJmbD4A66DWGYfyykWNpcYutQ==
+ dependencies:
+ tslib "^1.9.0"
+
file-system-cache@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-1.0.5.tgz#84259b36a2bbb8d3d6eb1021d3132ffe64cfff4f"
@@ -6642,6 +6833,11 @@ from2@^2.1.0, from2@^2.3.0:
inherits "^2.0.1"
readable-stream "^2.0.0"
+fs-constants@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
+ integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
+
fs-extra@8.1.0, fs-extra@^8.0.1:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
@@ -6872,6 +7068,11 @@ git-raw-commits@^2.0.0:
split2 "^2.0.0"
through2 "^3.0.0"
+github-from-package@0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
+ integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=
+
glob-base@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
@@ -7742,6 +7943,11 @@ is-arrayish@^0.2.1:
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
+is-arrayish@^0.3.1:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
+ integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
+
is-binary-path@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
@@ -9174,7 +9380,7 @@ meow@5.0.0, meow@^5.0.0:
trim-newlines "^2.0.0"
yargs-parser "^10.0.0"
-meow@^6.1.0:
+meow@^6.0.0, meow@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/meow/-/meow-6.1.0.tgz#4ff4641818d3502afcddc631f94cb6971a581cb3"
integrity sha512-iIAoeI01v6pmSfObAAWFoITAA4GgiT45m4SmJgoxtZfvI0fyZwhV4d0lTwiUXvAKIPlma05Feb2Xngl52Mj5Cg==
@@ -9297,6 +9503,11 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
+mimic-response@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43"
+ integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==
+
min-document@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
@@ -9415,6 +9626,14 @@ minizlib@^1.2.1:
dependencies:
minipass "^2.9.0"
+minizlib@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.0.tgz#fd52c645301ef09a63a2c209697c294c6ce02cf3"
+ integrity sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==
+ dependencies:
+ minipass "^3.0.0"
+ yallist "^4.0.0"
+
mississippi@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022"
@@ -9447,6 +9666,11 @@ mixin-object@^2.0.1:
for-in "^0.1.3"
is-extendable "^0.1.1"
+mkdirp-classic@^0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz#54c441ce4c96cd7790e10b41a87aa51068ecab2b"
+ integrity sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g==
+
mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@~0.5.0, mkdirp@~0.5.1:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
@@ -9454,6 +9678,11 @@ mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@~0.5.0, mkdir
dependencies:
minimist "^1.2.5"
+mkdirp@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
+ integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
+
modify-values@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
@@ -9486,6 +9715,20 @@ ms@^2.0.0, ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+multer@1.4.2:
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.2.tgz#2f1f4d12dbaeeba74cb37e623f234bf4d3d2057a"
+ integrity sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==
+ dependencies:
+ append-field "^1.0.0"
+ busboy "^0.2.11"
+ concat-stream "^1.5.2"
+ mkdirp "^0.5.1"
+ object-assign "^4.1.1"
+ on-finished "^2.3.0"
+ type-is "^1.6.4"
+ xtend "^4.0.0"
+
mute-stream@0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
@@ -9496,7 +9739,7 @@ mute-stream@0.0.8, mute-stream@~0.0.4:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
-nan@^2.12.1:
+nan@^2.12.1, nan@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
@@ -9518,6 +9761,11 @@ nanomatch@^1.2.9:
snapdragon "^0.8.1"
to-regex "^3.0.1"
+napi-build-utils@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
+ integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==
+
native-url@0.2.6:
version "0.2.6"
resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.2.6.tgz#ca1258f5ace169c716ff44eccbddb674e10399ae"
@@ -9609,6 +9857,18 @@ no-case@^3.0.3:
lower-case "^2.0.1"
tslib "^1.10.0"
+node-abi@^2.7.0:
+ version "2.15.0"
+ resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.15.0.tgz#51d55cc711bd9e4a24a572ace13b9231945ccb10"
+ integrity sha512-FeLpTS0F39U7hHZU1srAK4Vx+5AHNVOTP+hxBNQknR/54laTHSFIJkDWDqiquY1LeLUgTfPN7sLPhMubx0PLAg==
+ dependencies:
+ semver "^5.4.1"
+
+node-addon-api@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.0.tgz#f9afb8d777a91525244b01775ea0ddbe1125483b"
+ integrity sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==
+
node-dir@^0.1.10:
version "0.1.17"
resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5"
@@ -9699,6 +9959,11 @@ node-releases@^1.1.29, node-releases@^1.1.44, node-releases@^1.1.53:
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4"
integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==
+noop-logger@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2"
+ integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=
+
nopt@^4.0.1, nopt@~4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
@@ -10015,7 +10280,7 @@ npm@^6.10.3:
worker-farm "^1.7.0"
write-file-atomic "^2.4.3"
-npmlog@^4.1.2, npmlog@~4.1.2:
+npmlog@^4.0.1, npmlog@^4.1.2, npmlog@~4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
@@ -10061,6 +10326,11 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
+object-fit-images@3.2.4:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/object-fit-images/-/object-fit-images-3.2.4.tgz#6c299d38fdf207746e5d2d46c2877f6f25d15b52"
+ integrity sha512-G+7LzpYfTfqUyrZlfrou/PLLLAPNC52FTy5y1CBywX+1/FkxIloOyQXBmZ3Zxa2AWO+lMF0JTuvqbr7G5e5CWg==
+
object-inspect@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"
@@ -10143,7 +10413,7 @@ object.values@^1.1.0, object.values@^1.1.1:
function-bind "^1.1.1"
has "^1.0.3"
-on-finished@~2.3.0:
+on-finished@^2.3.0, on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
@@ -10693,6 +10963,11 @@ please-upgrade-node@^3.2.0:
dependencies:
semver-compare "^1.0.0"
+pngjs@^3.4.0:
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
+ integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
+
pnp-webpack-plugin@1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.5.0.tgz#62a1cd3068f46d564bb33c56eb250e4d586676eb"
@@ -10893,6 +11168,27 @@ preact@10.4.0:
resolved "https://registry.yarnpkg.com/preact/-/preact-10.4.0.tgz#90e10264a221690484a56344437a353ffac08600"
integrity sha512-34iqY2qPWKAmsi+tNNwYCstta93P+zF1f4DLtsOUPh32uYImNzJY7h7EymCva+6RoJL01v3W3phSRD8jE0sFLg==
+prebuild-install@^5.3.3:
+ version "5.3.3"
+ resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.3.tgz#ef4052baac60d465f5ba6bf003c9c1de79b9da8e"
+ integrity sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==
+ dependencies:
+ detect-libc "^1.0.3"
+ expand-template "^2.0.3"
+ github-from-package "0.0.0"
+ minimist "^1.2.0"
+ 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"
+
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
@@ -11239,7 +11535,7 @@ raw-loader@^3.1.0:
loader-utils "^1.1.0"
schema-utils "^2.0.1"
-rc@^1.0.1, rc@^1.1.6, rc@^1.2.8:
+rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
@@ -11331,6 +11627,15 @@ react-draggable@^4.0.3:
classnames "^2.2.5"
prop-types "^15.6.0"
+react-dropzone@10.2.2:
+ version "10.2.2"
+ resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-10.2.2.tgz#67b4db7459589a42c3b891a82eaf9ade7650b815"
+ integrity sha512-U5EKckXVt6IrEyhMMsgmHQiWTGLudhajPPG77KFSvgsMqNEHSyGpqWvOMc5+DhEah/vH4E1n+J5weBNLd5VtyA==
+ dependencies:
+ attr-accept "^2.0.0"
+ file-selector "^0.1.12"
+ prop-types "^15.7.2"
+
react-error-overlay@^6.0.3:
version "6.0.7"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108"
@@ -11387,6 +11692,14 @@ react-inspector@^4.0.0:
is-dom "^1.0.9"
prop-types "^15.6.1"
+react-intersection-observer@^6.1.0:
+ version "6.4.2"
+ resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-6.4.2.tgz#a061add707c37ea14e1308c77c2e286719347928"
+ integrity sha512-gL6YrkhniA0tIbyDbUterzBwKh61vHR520rsKULel5T37gG4YP07wnWI3WoqOcKK5bKAu0PZB2FHD7/OjawN+w==
+ dependencies:
+ "@babel/runtime" "^7.2.0"
+ invariant "^2.2.4"
+
react-is@16.8.6:
version "16.8.6"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
@@ -11397,6 +11710,14 @@ react-is@^16.7.0, react-is@^16.8.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+react-lazy-images@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/react-lazy-images/-/react-lazy-images-1.1.0.tgz#c865445c96e568a6249db03a2bb2dccd49cb6f50"
+ integrity sha512-h5DHFhkMJyh2qsDl3hXWu6d+On10FsgHtRJ+BH7xjgsFOvsqaii9CEwEESqPJrrAiHo1qrN1LgzrV8X3zctHKA==
+ dependencies:
+ react-intersection-observer "^6.1.0"
+ unionize "^2.1.2"
+
react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
@@ -11607,16 +11928,7 @@ read@1, read@~1.0.1, read@~1.0.7:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
-"readable-stream@2 || 3", readable-stream@^3.1.1, readable-stream@^3.6.0:
- version "3.6.0"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
- integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
- dependencies:
- inherits "^2.0.3"
- string_decoder "^1.1.1"
- util-deprecate "^1.0.1"
-
-readable-stream@~1.1.10:
+readable-stream@1.1.x, readable-stream@~1.1.10:
version "1.1.14"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
@@ -11626,6 +11938,15 @@ readable-stream@~1.1.10:
isarray "0.0.1"
string_decoder "~0.10.x"
+"readable-stream@2 || 3", readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
+ integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
+ dependencies:
+ inherits "^2.0.3"
+ string_decoder "^1.1.1"
+ util-deprecate "^1.0.1"
+
readdir-scoped-modules@^1.0.0, readdir-scoped-modules@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309"
@@ -12276,7 +12597,7 @@ semver@7.0.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
-semver@^7.1.1, semver@^7.1.2:
+semver@^7.1.1, semver@^7.1.2, semver@^7.1.3:
version "7.2.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.2.2.tgz#d01432d74ed3010a20ffaf909d63a691520521cd"
integrity sha512-Zo84u6o2PebMSK3zjJ6Zp5wi8VnQZnEaCP13Ul/lt1ANsLACxnJxq4EEm1PY94/por1Hm9+7xpIswdS5AkieMA==
@@ -12393,6 +12714,36 @@ shallowequal@^1.1.0:
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
+sharp@0.25.2:
+ version "0.25.2"
+ resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.25.2.tgz#f9003d73be50e9265e98f79f04fe53d8c66a3967"
+ integrity sha512-l1GN0kFNtJr3U9i9pt7a+vo2Ij0xv4tTKDIPx8W6G9WELhPwrMyZZJKAAQNBSI785XB4uZfS5Wpz8C9jWV4AFQ==
+ dependencies:
+ color "^3.1.2"
+ detect-libc "^1.0.3"
+ node-addon-api "^2.0.0"
+ npmlog "^4.1.2"
+ prebuild-install "^5.3.3"
+ semver "^7.1.3"
+ simple-get "^3.1.0"
+ tar "^6.0.1"
+ tunnel-agent "^0.6.0"
+
+sharp@^0.23.4:
+ version "0.23.4"
+ resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.23.4.tgz#ca36067cb6ff7067fa6c77b01651cb9a890f8eb3"
+ integrity sha512-fJMagt6cT0UDy9XCsgyLi0eiwWWhQRxbwGmqQT6sY8Av4s0SVsT/deg8fobBQCTDU5iXRgz0rAeXoE2LBZ8g+Q==
+ dependencies:
+ color "^3.1.2"
+ detect-libc "^1.0.3"
+ nan "^2.14.0"
+ npmlog "^4.1.2"
+ prebuild-install "^5.3.3"
+ semver "^6.3.0"
+ simple-get "^3.1.0"
+ tar "^5.0.5"
+ tunnel-agent "^0.6.0"
+
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
@@ -12467,6 +12818,27 @@ signale@^1.2.1:
figures "^2.0.0"
pkg-conf "^2.1.0"
+simple-concat@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6"
+ integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=
+
+simple-get@^3.0.3, simple-get@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3"
+ integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==
+ dependencies:
+ decompress-response "^4.2.0"
+ once "^1.3.1"
+ simple-concat "^1.0.0"
+
+simple-swizzle@^0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
+ integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=
+ dependencies:
+ is-arrayish "^0.3.1"
+
simplebar-react@^1.0.0-alpha.6:
version "1.2.3"
resolved "https://registry.yarnpkg.com/simplebar-react/-/simplebar-react-1.2.3.tgz#bd81fa9827628470e9470d06caef6ece15e1c882"
@@ -12828,6 +13200,11 @@ stream-shift@^1.0.0:
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
+streamsearch@0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
+ integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
+
strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
@@ -13099,6 +13476,11 @@ styled-jsx@3.2.5:
stylis "3.5.4"
stylis-rule-sheet "0.0.10"
+stylelint-config-css-modules@2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/stylelint-config-css-modules/-/stylelint-config-css-modules-2.2.0.tgz#8ed2a54b1bdf637219e37cdeea1950405fd022ff"
+ integrity sha512-+zjcDbot+zbuxy1UA31k4G2lUG+nHUwnLyii3uT2F09B8kT2YrT9LZYNfMtAWlDidrxr7sFd5HX9EqPHGU3WKA==
+
stylelint-config-prettier@8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/stylelint-config-prettier/-/stylelint-config-prettier-8.0.1.tgz#ec7cdd7faabaff52ebfa56c28fed3d995ebb8cab"
@@ -13301,6 +13683,27 @@ tapable@^1.0.0, tapable@^1.1.3:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
+tar-fs@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.1.tgz#e44086c1c60d31a4f0cf893b1c4e155dabfae9e2"
+ integrity sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==
+ dependencies:
+ chownr "^1.1.1"
+ mkdirp-classic "^0.5.2"
+ pump "^3.0.0"
+ tar-stream "^2.0.0"
+
+tar-stream@^2.0.0:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.2.tgz#6d5ef1a7e5783a95ff70b69b97455a5968dc1325"
+ integrity sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==
+ dependencies:
+ bl "^4.0.1"
+ end-of-stream "^1.4.1"
+ fs-constants "^1.0.0"
+ inherits "^2.0.3"
+ readable-stream "^3.1.1"
+
tar@^4.4.10, tar@^4.4.12, tar@^4.4.13:
version "4.4.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
@@ -13314,6 +13717,30 @@ tar@^4.4.10, tar@^4.4.12, tar@^4.4.13:
safe-buffer "^5.1.2"
yallist "^3.0.3"
+tar@^5.0.5:
+ version "5.0.5"
+ resolved "https://registry.yarnpkg.com/tar/-/tar-5.0.5.tgz#03fcdb7105bc8ea3ce6c86642b9c942495b04f93"
+ integrity sha512-MNIgJddrV2TkuwChwcSNds/5E9VijOiw7kAc1y5hTNJoLDSuIyid2QtLYiCYNnICebpuvjhPQZsXwUL0O3l7OQ==
+ dependencies:
+ chownr "^1.1.3"
+ fs-minipass "^2.0.0"
+ minipass "^3.0.0"
+ minizlib "^2.1.0"
+ mkdirp "^0.5.0"
+ yallist "^4.0.0"
+
+tar@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.1.tgz#7b3bd6c313cb6e0153770108f8d70ac298607efa"
+ integrity sha512-bKhKrrz2FJJj5s7wynxy/fyxpE0CmCjmOQ1KV4KkgXFWOgoIT/NbTMnB1n+LFNrNk0SSBVGGxcK5AGsyC+pW5Q==
+ dependencies:
+ chownr "^1.1.3"
+ fs-minipass "^2.0.0"
+ minipass "^3.0.0"
+ minizlib "^2.1.0"
+ mkdirp "^1.0.3"
+ yallist "^4.0.0"
+
telejson@^3.2.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/telejson/-/telejson-3.3.0.tgz#6d814f3c0d254d5c4770085aad063e266b56ad03"
@@ -13633,7 +14060,7 @@ type-fest@^0.8.1:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
-type-is@~1.6.17, type-is@~1.6.18:
+type-is@^1.6.4, type-is@~1.6.17, type-is@~1.6.18:
version "1.6.18"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
@@ -13749,6 +14176,11 @@ union-value@^1.0.0:
is-extendable "^0.1.1"
set-value "^2.0.1"
+unionize@^2.1.2:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/unionize/-/unionize-2.2.0.tgz#ce88635aa0793f28ab617abeac36172ba0aeb7bc"
+ integrity sha512-lHXiL6LPVuRYBGCLOdUd4GMHoAGqM0HtYHAZcA6pUEiwN1nk+LEYlh8bud7saeL0bkFntJzCPEPVVJeFm3Cqsg==
+
uniq@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
@@ -13949,6 +14381,21 @@ use-callback-ref@^1.2.1:
dependencies:
"@types/react" "^16.9.11"
+use-dark-mode@2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/use-dark-mode/-/use-dark-mode-2.3.1.tgz#d506349c7b7e09e9977cb8a6ab4470896aa3779a"
+ integrity sha512-hmcdJR96tTustRQdaQwe6jMrZHnmPqXBxgy4jaQ4gsfhwajsCpjECuq9prgDe9XxMx/f9r96o2/md6O4Lwhwjg==
+ dependencies:
+ "@use-it/event-listener" "^0.1.2"
+ use-persisted-state "^0.3.0"
+
+use-persisted-state@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/use-persisted-state/-/use-persisted-state-0.3.0.tgz#f8e3d2fd8eee67e0c86fd596c3ea3e8121c07402"
+ integrity sha512-UlWEq0JYg7NbvcRBZ1g6Bwe4SEbYfr1wr/D5mrmfCzSxXSwsPRYygGLlsxHcW58Rf7gGwRPBT23sNVvyVn4WYg==
+ dependencies:
+ "@use-it/event-listener" "^0.1.2"
+
use-sidecar@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.0.2.tgz#e72f582a75842f7de4ef8becd6235a4720ad8af6"