Merge in 4.0.0 (#850)

* merge in 4.0

* dev mode with firebase impl

* useReducer for toasts state
main
Michael Fix 5 years ago committed by repo-ranger[bot]
parent 54fdf2fe46
commit e0ed4bebdc

1
.gitignore vendored

@ -9,3 +9,4 @@ cypress/screenshots
packaged packaged
coverage coverage
public/service-worker.js public/service-worker.js
private-key.json

@ -0,0 +1,93 @@
import React from 'react'
const key = 'CARBON_CTA_1'
class Toast extends React.Component {
state = {
open: false
}
close = () => {
this.setState({ open: false })
window.localStorage.setItem(key, true)
}
componentDidMount() {
window.localStorage.removeItem('CARBON_CTA')
if (!window.localStorage.getItem(key)) {
this.setState({ open: true })
}
}
render() {
if (process.env.NODE_ENV !== 'production') {
return null
}
if (!this.state.open) {
return null
}
return (
<div className="toast mb4">
<div className="toast-content">
<p>Never lose a Carbon again - save your work automatically!</p>
Click &quot;Sign up&quot; to try it out!
<button className="close-toast" onClick={this.close}>
&times;
</button>
</div>
<style jsx>
{`
@keyframes slide {
from {
transform: translateY(-128px);
}
to {
transform: translateY(0px);
}
}
.toast {
padding: 8px 16px;
color: #fff;
border: 1px solid #fff;
border-radius: 2px;
margin-top: calc(var(--x4) * -1);
animation-name: slide;
animation-duration: 600ms;
}
.toast-content {
display: flex;
align-items: center;
}
a {
text-decoration: underline;
}
.close-toast {
padding-left: 0;
padding-right: 0;
background: transparent;
color: white;
border: none;
font-size: 100%;
margin-left: 32px;
text-decoration: none;
cursor: pointer;
}
p {
margin: 0;
margin-right: 12px;
}
`}
</style>
</div>
)
}
}
export default Toast

@ -1,4 +1,10 @@
import React from 'react' import React from 'react'
import api from '../lib/api' import api from '../lib/api'
export default React.createContext(api) const Context = React.createContext(api)
export function useAPI() {
return React.useContext(Context)
}
export default Context

@ -0,0 +1,34 @@
import React from 'react'
import firebase from '../lib/client'
// IDEA: just read from firebase store at request time?
import { client } from '../lib/api'
export const Context = React.createContext(null)
export function useAuth() {
return React.useContext(Context)
}
function AuthContext(props) {
const [user, setState] = React.useState(null)
React.useEffect(() => {
if (firebase) {
firebase.auth().onAuthStateChanged(newUser => setState(newUser))
}
}, [])
React.useEffect(() => {
if (user) {
user.getIdToken().then(jwt => {
client.defaults.headers['Authorization'] = jwt ? `Bearer ${jwt}` : undefined
})
} else {
delete client.defaults.headers['Authorization']
}
}, [user])
return <Context.Provider value={user}>{props.children}</Context.Provider>
}
export default AuthContext

@ -21,6 +21,7 @@ const Button = ({
margin = 0, margin = 0,
title, title,
Component = 'button', Component = 'button',
display,
...props ...props
}) => ( }) => (
<Component id={id} onClick={onClick} disabled={disabled} {...props}> <Component id={id} onClick={onClick} disabled={disabled} {...props}>
@ -29,7 +30,7 @@ const Button = ({
<style jsx> <style jsx>
{` {`
${Component} { ${Component} {
display: flex; display: ${display || 'flex'};
flex: ${flex}; flex: ${flex};
background-color: ${background}; background-color: ${background};
color: ${color}; color: ${color};

@ -2,6 +2,8 @@
import React from 'react' import React from 'react'
import domtoimage from 'dom-to-image' import domtoimage from 'dom-to-image'
import Dropzone from 'dropperx' import Dropzone from 'dropperx'
import debounce from 'lodash.debounce'
import dynamic from 'next/dynamic'
// Ours // Ours
import ApiContext from './ApiContext' import ApiContext from './ApiContext'
@ -14,6 +16,9 @@ import Carbon from './Carbon'
import ExportMenu from './ExportMenu' import ExportMenu from './ExportMenu'
import Themes from './Themes' import Themes from './Themes'
import TweetButton from './TweetButton' import TweetButton from './TweetButton'
import LoginButton from './LoginButton'
import FontFace from './FontFace'
import LanguageIcon from './svg/Language'
import { import {
LANGUAGES, LANGUAGES,
LANGUAGE_MIME_HASH, LANGUAGE_MIME_HASH,
@ -30,10 +35,13 @@ import {
} from '../lib/constants' } from '../lib/constants'
import { serializeState, getRouteState } from '../lib/routing' import { serializeState, getRouteState } from '../lib/routing'
import { getSettings, unescapeHtml, formatCode, omit } from '../lib/util' import { getSettings, unescapeHtml, formatCode, omit } from '../lib/util'
import LanguageIcon from './svg/Language'
const languageIcon = <LanguageIcon /> const languageIcon = <LanguageIcon />
const SnippetToolbar = dynamic(() => import('./SnippetToolbar'), {
loading: () => null
})
const getConfig = omit(['code']) const getConfig = omit(['code'])
class Editor extends React.Component { class Editor extends React.Component {
@ -43,6 +51,7 @@ class Editor extends React.Component {
super(props) super(props)
this.state = { this.state = {
...DEFAULT_SETTINGS, ...DEFAULT_SETTINGS,
...this.props.snippet,
loading: true loading: true
} }
@ -57,22 +66,13 @@ class Editor extends React.Component {
} }
async componentDidMount() { async componentDidMount() {
const { queryState, parameter } = getRouteState(this.props.router) const { queryState } = getRouteState(this.props.router)
// TODO we could create an interface for loading this config, so that it looks identical
// whether config is loaded from localStorage, gist, or even something like IndexDB
let gistState
if (this.context.gist && parameter) {
const { config, ...gist } = (await this.context.gist.get(parameter)) || {}
if (typeof config === 'object') {
this.gist = gist
gistState = config
}
}
const newState = { const newState = {
// TODO we could create an interface for loading this config, so that it looks identical
// whether config is loaded from localStorage, gist, or even something like IndexDB
// Load options from gist or localStorage // Load options from gist or localStorage
...(gistState ? gistState : getSettings(localStorage)), ...(this.props.snippet ? null : getSettings(localStorage)),
// and then URL params // and then URL params
...queryState, ...queryState,
loading: false loading: false
@ -87,7 +87,7 @@ class Editor extends React.Component {
newState.fontFamily = DEFAULT_SETTINGS.fontFamily newState.fontFamily = DEFAULT_SETTINGS.fontFamily
} }
this.updateState(newState) this.setState(newState)
this.isSafari = this.isSafari =
window.navigator && window.navigator &&
@ -103,13 +103,11 @@ class Editor extends React.Component {
getTheme = () => this.props.themes.find(t => t.id === this.state.theme) || DEFAULT_THEME getTheme = () => this.props.themes.find(t => t.id === this.state.theme) || DEFAULT_THEME
updateState = updates => { onUpdate = debounce(updates => this.props.onUpdate(updates), 750, {
this.setState(updates, () => { trailing: true,
if (!this.gist) { leading: true
this.props.onUpdate(this.state) })
} updateState = updates => this.setState(updates, () => this.onUpdate(this.state))
})
}
updateCode = code => this.updateState({ code }) updateCode = code => this.updateState({ code })
@ -313,6 +311,28 @@ class Editor extends React.Component {
// create toast here in the future // create toast here in the future
}) })
handleSnippetCreate = () =>
this.context.snippet
.create(this.state)
.then(data => this.props.setSnippet(data))
.then(() =>
this.props.setToasts({
type: 'SET',
toasts: [{ children: 'Snippet duplicated!', timeout: 3000 }]
})
)
handleSnippetDelete = () =>
this.context.snippet
.delete(this.props.snippet.id)
.then(() => this.props.setSnippet(null))
.then(() =>
this.props.setToasts({
type: 'SET',
toasts: [{ children: 'Snippet deleted', timeout: 3000 }]
})
)
render() { render() {
const { const {
highlights, highlights,
@ -331,6 +351,7 @@ class Editor extends React.Component {
return ( return (
<div className="editor"> <div className="editor">
<Toolbar> <Toolbar>
<LoginButton />
<Themes <Themes
theme={theme} theme={theme}
highlights={highlights} highlights={highlights}
@ -398,6 +419,13 @@ class Editor extends React.Component {
</Overlay> </Overlay>
)} )}
</Dropzone> </Dropzone>
{this.props.snippet && (
<SnippetToolbar
snippet={this.props.snippet}
onCreate={this.handleSnippetCreate}
onDelete={this.handleSnippetDelete}
/>
)}
<FontFace {...config} /> <FontFace {...config} />
<style jsx> <style jsx>
{` {`
@ -419,20 +447,6 @@ class Editor extends React.Component {
} }
} }
function FontFace(config) {
return (
<style jsx global>
{`
@font-face {
font-family: ${config.fontUrl ? config.fontFamily : ''};
src: url(${config.fontUrl || ''}) format('woff');
font-display: swap;
}
`}
</style>
)
}
function isImage(file) { function isImage(file) {
return file.type.split('/')[0] === 'image' return file.type.split('/')[0] === 'image'
} }

@ -2,11 +2,47 @@
import React from 'react' import React from 'react'
import Editor from './Editor' import Editor from './Editor'
import { THEMES } from '../lib/constants' import Toasts from './Toasts'
import { getThemes, saveThemes } from '../lib/util' import { THEMES, DEFAULT_CODE } from '../lib/constants'
import { updateRouteState } from '../lib/routing'
import { getThemes, saveThemes, clearSettings, saveSettings } from '../lib/util'
import { useAPI } from './ApiContext'
import { useAuth } from './AuthContext'
import { useAsyncCallback } from '@dawnlabs/tacklebox'
function onReset() {
clearSettings()
if (window.navigator && navigator.serviceWorker) {
navigator.serviceWorker.getRegistrations().then(registrations => {
for (let registration of registrations) {
registration.unregister()
}
})
}
}
function toastsReducer(curr, action) {
switch (action.type) {
case 'ADD': {
if (!curr.find(t => t.children === action.toast.children)) {
return curr.concat(action.toast)
}
return curr
}
case 'SET': {
return action.toasts
}
}
throw new Error('Unsupported action')
}
function EditorContainer(props) { function EditorContainer(props) {
const [themes, updateThemes] = React.useState(THEMES) const [themes, updateThemes] = React.useState(THEMES)
const api = useAPI()
const user = useAuth()
const [update, { loading }] = useAsyncCallback(api.snippet.update)
React.useEffect(() => { React.useEffect(() => {
const storedThemes = getThemes(localStorage) || [] const storedThemes = getThemes(localStorage) || []
@ -19,7 +55,67 @@ function EditorContainer(props) {
saveThemes(themes.filter(({ custom }) => custom)) saveThemes(themes.filter(({ custom }) => custom))
}, [themes]) }, [themes])
return <Editor {...props} themes={themes} updateThemes={updateThemes} /> // XXX use context
const [snippet, setSnippet] = React.useState(props.snippet || null)
const [toasts, setToasts] = React.useReducer(toastsReducer, [])
const snippetId = snippet && snippet.id
React.useEffect(() => {
if ('/' + (snippetId || '') === props.router.asPath) {
return
}
props.router.replace('/', '/' + (snippetId || ''), { shallow: true })
}, [snippetId, props.router])
function onEditorUpdate(state) {
if (loading) {
return
}
if (!user) {
updateRouteState(props.router, state)
saveSettings(state)
} else {
const updates = {
...state,
code: state.code != null ? state.code : DEFAULT_CODE
}
if (!snippet) {
update(snippetId, updates).then(newSnippet => {
if (newSnippet && newSnippet.id) {
setSnippet(newSnippet)
setToasts({
type: 'ADD',
toast: { children: 'Snippet saved!', closable: true }
})
}
})
} else if (snippet.userId === user.uid) {
update(snippetId, updates).then(() => {
setToasts({
type: 'ADD',
toast: { children: 'Snippet saved!', closable: true }
})
})
}
}
}
return (
<>
<Toasts toasts={toasts} />
<Editor
{...props}
themes={themes}
updateThemes={updateThemes}
snippet={snippet}
setSnippet={setSnippet}
setToasts={setToasts}
onUpdate={onEditorUpdate}
onReset={onReset}
/>
</>
)
} }
export default EditorContainer export default EditorContainer

@ -141,7 +141,7 @@ function ExportMenu({
</div> </div>
</div> </div>
<div className="save-container"> <div className="save-container">
<span>Save as</span> <span>Export as</span>
<div> <div>
{!disablePNG && ( {!disablePNG && (
<Button <Button

@ -0,0 +1,15 @@
import React from 'react'
export default function FontFace(config) {
return (
<style jsx global>
{`
@font-face {
font-family: ${config.fontUrl ? config.fontFamily : ''};
src: url(${config.fontUrl || ''}) format('woff');
font-display: swap;
}
`}
</style>
)
}

@ -19,14 +19,21 @@ const Footer = () => (
sponsor sponsor
</a> </a>
<a className="link" href="https://github.com/carbon-app/carbon/issues/new"> <a className="link" href="https://github.com/carbon-app/carbon/issues/new">
send feedback feedback
</a> </a>
<a className="link" href="https://github.com/carbon-app/carbon"> <a className="link" href="https://github.com/carbon-app/carbon">
source source
</a> </a>
<a className="link" href="/terms">
terms
</a>
<a className="link" href="/privacy">
privacy
</a>
</nav> </nav>
<div className="mt3 mb2">
a project by{' '} <div className="mt2 mb2">
created by{' '}
<a className="author-link" href="https://twitter.com/carbon_app"> <a className="author-link" href="https://twitter.com/carbon_app">
@carbon_app @carbon_app
</a>{' '} </a>{' '}
@ -43,8 +50,13 @@ const Footer = () => (
color: ${COLORS.GRAY}; color: ${COLORS.GRAY};
} }
nav {
display: flex;
align-items: center;
}
a { a {
margin-right: 16px; margin-right: 1rem;
} }
a:last-child { a:last-child {

@ -33,7 +33,7 @@ class ListSetting extends React.Component {
key={item.id} key={item.id}
onClick={this.select.bind(null, item.id)} onClick={this.select.bind(null, item.id)}
> >
{this.props.children(item)} {this.props.children(item, this.props.selected)}
{this.props.selected === item.id ? <Checkmark /> : null} {this.props.selected === item.id ? <Checkmark /> : null}
<style jsx> <style jsx>
{` {`

@ -0,0 +1,96 @@
import React from 'react'
// import Link from 'next/link'
import firebase, { login, logout } from '../lib/client'
import Button from './Button'
import Popout, { managePopout } from './Popout'
import { useAuth } from './AuthContext'
function Drawer(props) {
return (
<Popout hidden={!props.isVisible} pointerLeft="14px" style={{ width: '180px', left: 0 }}>
<div className="flex">
{/* <Link href="/settings">
<Button large center padding="8px 0">
Settings
</Button>
</Link> */}
<Button large center padding="8px 0" onClick={logout}>
Sign Out
</Button>
</div>
<style jsx>
{`
.flex {
display: flex;
height: 100%;
}
`}
</style>
</Popout>
)
}
function LoginButton({ isVisible, toggleVisibility }) {
const user = useAuth()
if (!firebase) {
return null
}
return (
<div>
<Button
center
border
large
padding="0 16px"
color="white"
className="profile-button"
onClick={() => {
if (!user) {
const provider = new firebase.auth.GithubAuthProvider()
provider.setCustomParameters({
allow_signup: 'true'
})
login(provider)
} else {
toggleVisibility()
}
}}
>
<img
height={20}
src={user ? user.photoURL : '/static/github.svg'}
alt={user ? user.displayName : 'GitHub'}
/>
<span>{user ? user.displayName : 'Sign in/up'}</span>
</Button>
<Drawer isVisible={user && isVisible} />
<style jsx>
{`
div,
div :global(.profile-button) {
position: relative;
height: 100%;
}
div :global(.profile-button) {
max-width: 142px;
min-height: 40px;
}
span {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
img {
border-radius: 50%;
margin-right: 16px;
}
`}
</style>
</div>
)
}
export default managePopout(LoginButton)

@ -0,0 +1,47 @@
import React from 'react'
import Button from './Button'
import { COLORS } from '../lib/constants'
import * as Arrows from './svg/Arrows'
const MenuButton = React.memo(({ name, select, selected, noArrows }) => {
return (
<div className="menu-button">
<Button
padding="8px"
onClick={select(name)}
background={selected === name ? COLORS.BLACK : COLORS.DARK_GRAY}
>
{name}
{!noArrows && (
<div className="arrow-icon">
<Arrows.Right />
</div>
)}
</Button>
<style jsx>
{`
.menu-button {
display: flex;
height: 33px;
border-bottom: 1px solid ${COLORS.SECONDARY};
position: relative;
align-items: center;
}
.menu-button:last-child {
${selected === 'Window' ? '' : 'border-bottom: none;'};
}
.arrow-icon {
position: absolute;
right: 14px;
top: 11px;
}
`}
</style>
</div>
)
})
export default MenuButton

@ -1,7 +1,9 @@
import React from 'react' import React from 'react'
import AuthContext from './AuthContext'
import Meta from './Meta' import Meta from './Meta'
import Header from './Header' import Header from './Header'
import Footer from './Footer' import Footer from './Footer'
import Announcement from './Announcement'
class Page extends React.Component { class Page extends React.Component {
render() { render() {
@ -9,8 +11,11 @@ class Page extends React.Component {
return ( return (
<main className="main mt4 mb4"> <main className="main mt4 mb4">
<Meta /> <Meta />
<Announcement />
<Header enableHeroText={enableHeroText} /> <Header enableHeroText={enableHeroText} />
<div className="page">{children}</div> <AuthContext>
<div className="page">{children}</div>
</AuthContext>
<Footer /> <Footer />

@ -2,13 +2,13 @@ import React from 'react'
import Spinner from 'react-spinner' import Spinner from 'react-spinner'
import { useAsyncCallback } from '@dawnlabs/tacklebox' import { useAsyncCallback } from '@dawnlabs/tacklebox'
import ApiContext from './ApiContext' import { useAPI } from './ApiContext'
import PhotoCredit from './PhotoCredit' import PhotoCredit from './PhotoCredit'
function RandomImage(props) { function RandomImage(props) {
const cacheRef = React.useRef([]) const cacheRef = React.useRef([])
const [cacheIndex, updateIndex] = React.useState(0) const [cacheIndex, updateIndex] = React.useState(0)
const api = React.useContext(ApiContext) const api = useAPI()
const [selectImage, { loading: selecting }] = useAsyncCallback(() => { const [selectImage, { loading: selecting }] = useAsyncCallback(() => {
const image = cacheRef.current[cacheIndex] const image = cacheRef.current[cacheIndex]

@ -9,10 +9,10 @@ import Toggle from './Toggle'
import Popout, { managePopout } from './Popout' import Popout, { managePopout } from './Popout'
import Button from './Button' import Button from './Button'
import Presets from './Presets' import Presets from './Presets'
import MenuButton from './MenuButton'
import { COLORS, DEFAULT_PRESETS } from '../lib/constants' import { COLORS, DEFAULT_PRESETS } from '../lib/constants'
import { toggle, getPresets, savePresets, generateId, fileToJSON } from '../lib/util' import { toggle, getPresets, savePresets, generateId, fileToJSON } from '../lib/util'
import SettingsIcon from './svg/Settings' import SettingsIcon from './svg/Settings'
import * as Arrows from './svg/Arrows'
const WindowSettings = React.memo( const WindowSettings = React.memo(
({ ({
@ -182,7 +182,6 @@ const MiscSettings = React.memo(({ format, reset, applyPreset, settings }) => {
}} }}
/> />
<Button <Button
width="50%"
center center
style={{ borderRight: `1px solid ${COLORS.SECONDARY}` }} style={{ borderRight: `1px solid ${COLORS.SECONDARY}` }}
onClick={() => input.current.click()} onClick={() => input.current.click()}
@ -219,44 +218,6 @@ const MiscSettings = React.memo(({ format, reset, applyPreset, settings }) => {
) )
}) })
const MenuButton = React.memo(({ name, select, selected }) => {
return (
<div className="menu-button">
<Button
padding="8px"
onClick={select(name)}
background={selected === name ? COLORS.BLACK : COLORS.DARK_GRAY}
>
{name}
<div className="arrow-icon">
<Arrows.Right />
</div>
</Button>
<style jsx>
{`
.menu-button {
display: flex;
height: 33px;
border-bottom: 1px solid ${COLORS.SECONDARY};
position: relative;
align-items: center;
}
.menu-button:last-child {
${selected === 'Window' ? '' : 'border-bottom: none;'};
}
.arrow-icon {
position: absolute;
right: 14px;
top: 11px;
}
`}
</style>
</div>
)
})
const settingButtonStyle = { const settingButtonStyle = {
width: '40px', width: '40px',
height: '100%' height: '100%'

@ -0,0 +1,104 @@
import React from 'react'
import { useAsyncCallback, useOnline } from '@dawnlabs/tacklebox'
import Button from './Button'
import { useAuth } from './AuthContext'
import Toolbar from './Toolbar'
function ConfirmButton(props) {
const [confirmed, setConfirmed] = React.useState(false)
return (
<Button
{...props}
onClick={e => {
if (confirmed) {
props.onClick(e)
setConfirmed(false)
} else {
setConfirmed(true)
}
}}
onBlur={() => setConfirmed(false)}
>
{confirmed ? 'Are you sure?' : props.children}
</Button>
)
}
function DeleteButton(props) {
const [onClick, { loading }] = useAsyncCallback(props.onClick)
return (
<ConfirmButton
display="block"
padding="0 16px"
flex="unset"
center
border
large
color="#fff"
onClick={onClick}
style={{ color: '#ff5f56' }}
>
{loading ? 'Deleting...' : 'Delete'}
</ConfirmButton>
)
}
function ForkButton(props) {
const [onClick, { loading }] = useAsyncCallback(props.onClick)
// TODO call it duplicate or fork?
return (
<Button
display="block"
padding="0 16px"
margin="0 0 0 1rem"
flex="unset"
center
border
large
color="#37b589"
onClick={onClick}
>
{loading ? 'Duplicating...' : 'Duplicate'}
</Button>
)
}
function SnippetToolbar(props) {
const user = useAuth()
const online = useOnline()
if (!online) {
return null
}
if (!user) {
return null
}
if (!props.snippet) {
return null
}
const sameUser = user.uid === props.snippet.userId
return (
<Toolbar
style={{
marginTop: 16,
marginBottom: 0,
flexDirection: 'row-reverse',
// justifyContent: 'space-between',
zIndex: 1
}}
>
<ForkButton onClick={props.onCreate} />
{sameUser && <DeleteButton onClick={props.onDelete} />}
</Toolbar>
)
}
export default SnippetToolbar

@ -0,0 +1,116 @@
import React from 'react'
function Toast(props) {
const [display, on] = React.useState(true)
function off() {
return on(false)
}
React.useEffect(() => {
if (props.timeout) {
const to = setTimeout(off, props.timeout)
return () => clearTimeout(to)
}
}, [props.timeout])
return (
<div className={`toast mb2 ${display ? '' : 'out'}`}>
<div className="toast-content">
{props.children}
{props.closable && (
<button className="close" onClick={off}>
&times;
</button>
)}
</div>
<style jsx>
{`
@keyframes in {
from {
transform: translateX(16rem);
}
to {
transform: translateX(0rem);
}
}
@keyframes out {
from {
transform: translateX(0rem);
}
97% {
transform: translateX(20rem);
}
to {
transform: translateX(20rem);
display: none;
height: 0;
padding: 0;
margin: 0;
}
}
.toast {
padding: 8px 16px;
color: #fff;
border: 1px solid #fff;
border-radius: 2px;
background: #000;
font-size: 14px;
animation-name: in;
animation-duration: 600ms;
animation-direction: forwards;
animation-fill-mode: both;
animation-timing-function: ease-out;
}
.toast.out {
animation-name: out;
}
.toast-content {
display: flex;
align-items: center;
}
.toast :global(.close) {
padding-left: 0;
padding-right: 0;
background: transparent;
color: white;
border: none;
font-size: 100%;
margin-left: 1rem;
text-decoration: none;
cursor: pointer;
}
`}
</style>
</div>
)
}
function ToastContainer(props) {
return (
<div className="toast">
{props.toasts
.slice()
.reverse()
.map(toast => (
<Toast key={toast.children} {...toast} />
))}
<style jsx>
{`
.toast {
position: fixed;
z-index: 9999;
top: 2rem;
right: 1rem;
}
`}
</style>
</div>
)
}
export default ToastContainer

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
const Toolbar = props => ( const Toolbar = props => (
<div className="toolbar"> <div className="toolbar" style={props.style}>
{props.children} {props.children}
<style jsx> <style jsx>
{` {`

@ -1,11 +1,11 @@
import React from 'react' import React from 'react'
import { useAsyncCallback, useOnline as useOnlineListener } from '@dawnlabs/tacklebox' import { useAsyncCallback, useOnline as useOnlineListener } from '@dawnlabs/tacklebox'
import ApiContext from './ApiContext' import { useAPI } from './ApiContext'
import Button from './Button' import Button from './Button'
function TweetButton(props) { function TweetButton(props) {
const api = React.useContext(ApiContext) const api = useAPI()
const online = useOnlineListener() const online = useOnlineListener()
const [onClick, { loading }] = useAsyncCallback(props.onClick) const [onClick, { loading }] = useAsyncCallback(props.onClick)

@ -4,18 +4,10 @@ import ms from 'ms'
import { fileToDataURL } from './util' import { fileToDataURL } from './util'
const client = axios.create({ export const client = axios.create({
baseURL: `${process.env.API_URL || ''}/api` baseURL: `${process.env.API_URL || ''}/api`,
})
const RATE_LIMIT_CODE = 420
const gistClient = axios.create({
baseURL: 'https://api.github.com',
timeout: 5000,
headers: { headers: {
Accept: 'application/vnd.github.v3+json', Accept: 'application/json'
'Content-Type': 'application/json'
} }
}) })
@ -28,54 +20,28 @@ function tweet(content, encodedImage) {
altText: content altText: content
}) })
.then(res => res.data.url) .then(res => res.data.url)
.then(url => encodeURIComponent(`Built with @carbon_app ${url}`)) .then(url => encodeURIComponent(`Created with @carbon_app ${url}`))
.then(uri => `https://twitter.com/intent/tweet?text=${uri}`) .then(uri => `https://twitter.com/intent/tweet?text=${uri}`)
.then(openTwitterUrl) .then(openTwitterUrl)
.catch(checkIfRateLimited) .catch(checkIfRateLimited)
} }
function image(state) { const RATE_LIMIT_CODE = 420
return client.post('/image', { state }).then(res => res.data) function checkIfRateLimited(err) {
} if (err.response.status === RATE_LIMIT_CODE) {
alert(
// ~ makes the file come later alphabetically, which is how gists are sorted "Oh no! Looks like to many people are trying to tweet right now and we've been rate limited. Try again soon or save and upload manually!"
const CARBON_STORAGE_KEY = '~carbon.json' )
async function getGist(uid) { return
try { }
return await gistClient
.get(`/gists/${uid}`)
.then(res => res.data)
.then(({ id, owner, files }) => {
let config
if (files[CARBON_STORAGE_KEY]) {
try {
config = JSON.parse(files[CARBON_STORAGE_KEY].content)
} catch (error) {
// pass
}
}
const otherFiles = Object.keys(files).filter(key => key !== CARBON_STORAGE_KEY)
const snippet = files[otherFiles[0]] throw err
}
return { function image(state) {
id, return client.post('/image', { state }).then(res => res.data)
owner,
config: {
...config,
code: snippet.content,
language: snippet.language && snippet.language.toLowerCase()
}
}
})
} catch (e) {
console.error(e)
return null
}
} }
// private
function openTwitterUrl(twitterUrl) { function openTwitterUrl(twitterUrl) {
const width = 575 const width = 575
const height = 400 const height = 400
@ -86,17 +52,6 @@ function openTwitterUrl(twitterUrl) {
window.open(twitterUrl, 'twitter', opts) window.open(twitterUrl, 'twitter', opts)
} }
function checkIfRateLimited(err) {
if (err.response.status === RATE_LIMIT_CODE) {
alert(
"Oh no! Looks like to many people are trying to tweet right now and we've been rate limited. Try again soon or save and upload manually!"
)
return
}
throw err
}
const downloadThumbnailImage = img => { const downloadThumbnailImage = img => {
return client return client
.get(img.url.replace('http://', 'https://'), { responseType: 'blob' }) .get(img.url.replace('http://', 'https://'), { responseType: 'blob' })
@ -115,9 +70,51 @@ const unsplash = {
} }
} }
function getSnippet(uid, { host } = {}) {
return client
.get(`/snippets/${uid}`, host ? { baseURL: `https://${host}/api` } : undefined)
.then(res => res.data)
.catch(e => {
console.error(e)
return null
})
}
function updateSnippet(uid, data) {
if (uid) {
return client
.patch(`/snippets/${uid}`, data)
.then(res => res.data)
.catch(e => {
console.error(e)
return null
})
}
return client
.post(`/snippets`, data)
.then(res => res.data)
.catch(e => {
console.error(e)
return null
})
}
function deleteSnippet(uid) {
return client
.delete(`/snippets/${uid}`)
.then(res => res.data)
.catch(e => {
console.error(e)
return null
})
}
export default { export default {
gist: { snippet: {
get: getGist get: getSnippet,
update: debounce(updateSnippet, ms('1s'), { leading: true, trailing: true }),
create: data => updateSnippet(null, data),
delete: id => deleteSnippet(id)
}, },
tweet: debounce(tweet, ms('5s'), { leading: true, trailing: false }), tweet: debounce(tweet, ms('5s'), { leading: true, trailing: false }),
image: debounce(image, ms('5s'), { leading: true, trailing: false }), image: debounce(image, ms('5s'), { leading: true, trailing: false }),

@ -0,0 +1,33 @@
import * as firebase from 'firebase/app'
import 'firebase/auth'
if (firebase.apps.length === 0) {
if (process.env.FIREBASE_API_KEY && process.env.FIREBASE_FE_APP_ID) {
firebase.initializeApp({
apiKey: process.env.FIREBASE_API_KEY,
authDomain: `${process.env.FIREBASE_PROJECT_ID}.firebaseapp.com`,
databaseURL: `https://${process.env.FIREBASE_PROJECT_ID}.firebaseio.com`,
projectId: process.env.FIREBASE_PROJECT_ID,
storageBucket: `${process.env.FIREBASE_PROJECT_ID}.appspot.com`,
messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.FIREBASE_FE_APP_ID
})
}
}
export function logout() {
return firebase
.auth()
.signOut()
.catch(console.error)
}
export function login(provider) {
return firebase
.auth()
.setPersistence(firebase.auth.Auth.Persistence.LOCAL)
.then(() => firebase.auth().signInWithPopup(provider))
.catch(console.error)
}
export default firebase.apps.length ? firebase : null

@ -121,7 +121,13 @@ export const getRouteState = router => {
const { asPath = '' } = router const { asPath = '' } = router
const { query, pathname } = url.parse(asPath, true) const { query, pathname } = url.parse(asPath, true)
const queryState = getQueryStringState(query) const queryState = getQueryStringState(query)
const path = escapeHtml(pathname.split('/').pop()) const path = escapeHtml(
pathname
// remove trailing slash
.replace(/\/$/, '')
.split('/')
.pop()
)
// TODO fix this hack // TODO fix this hack
const parameter = path.length >= 19 && path.indexOf('.') === -1 && path const parameter = path.length >= 19 && path.indexOf('.') === -1 && path
@ -148,7 +154,6 @@ export const updateRouteState = (router, state) => {
) )
} }
// private
const getQueryStringObject = query => { const getQueryStringObject = query => {
if (query.state) { if (query.state) {
return deserializeState(query.state) return deserializeState(query.state)

@ -23,6 +23,12 @@ const config = withOffline({
} }
} }
] ]
},
env: {
FIREBASE_PROJECT_ID: process.env.FIREBASE_PROJECT_ID,
FIREBASE_MESSAGING_SENDER_ID: process.env.FIREBASE_MESSAGING_SENDER_ID,
FIREBASE_FE_APP_ID: process.env.FIREBASE_FE_APP_ID,
FIREBASE_API_KEY: process.env.FIREBASE_API_KEY
} }
}) })

@ -4,6 +4,20 @@
"public": true, "public": true,
"builds": [{ "src": "package.json", "use": "@now/next" }], "builds": [{ "src": "package.json", "use": "@now/next" }],
"routes": [ "routes": [
{
"src": "^/privacy/?",
"status": 307,
"headers": {
"Location": "https://www.notion.so/PRIVACY-POLICY-e9847a7777714eb08ba15a7a8eaee937"
}
},
{
"src": "^/terms/?",
"status": 307,
"headers": {
"Location": "https://www.notion.so/TERMS-OF-USE-ff2ce22a7e9848c89c6be46b44297583"
}
},
{ "src": "^/embed(.*)", "dest": "/embed.html" }, { "src": "^/embed(.*)", "dest": "/embed.html" },
{ {
"src": "^/service-worker.js$", "src": "^/service-worker.js$",
@ -19,12 +33,26 @@
"cache-control": "public, max-age=43200, immutable" "cache-control": "public, max-age=43200, immutable"
} }
}, },
{ "handle": "filesystem" }, {
{ "src": "^/(.*)", "dest": "/index.html" } "src": "^/(.*)/?",
"continue": true,
"headers": {
"X-Frame-Options": "SAMEORIGIN",
"X-XSS-Protection": "1; mode=block",
"X-Content-Type-Options": "nosniff",
"Referrer-Policy": "no-referrer-when-downgrade",
"Feature-Policy": "geolocation 'self'; microphone 'self'; camera 'self'"
}
},
{ "handle": "filesystem" }
], ],
"build": { "build": {
"env": { "env": {
"NODE_ENV": "production" "NODE_ENV": "production",
"FIREBASE_PROJECT_ID": "@carbon-firebase-project-id",
"FIREBASE_MESSAGING_SENDER_ID": "@carbon-firebase-messaging-sender-id",
"FIREBASE_FE_APP_ID": "@carbon-firebase-fe-app-id",
"FIREBASE_API_KEY": "@carbon-firebase-api-key"
} }
}, },
"github": { "github": {

@ -27,17 +27,18 @@
"codemirror-mode-elixir": "^1.1.2", "codemirror-mode-elixir": "^1.1.2",
"codemirror-solidity": "^0.1.6", "codemirror-solidity": "^0.1.6",
"cross-env": "^5.2.0", "cross-env": "^5.2.0",
"dom-to-image": "^2.5.2", "dom-to-image": "^2.6.0",
"downshift": "^3.2.12", "downshift": "^3.2.12",
"dropperx": "^1.0.1", "dropperx": "^1.0.1",
"eitherx": "^1.0.2", "eitherx": "^1.0.2",
"escape-goat": "^2.1.0", "escape-goat": "^2.1.0",
"firebase": "^6.2.0",
"graphql": "^14.3.1", "graphql": "^14.3.1",
"highlight.js": "^9.15.9", "highlight.js": "^9.15.9",
"lodash.debounce": "^4.0.8", "lodash.debounce": "^4.0.8",
"lodash.omitby": "^4.6.0", "lodash.omitby": "^4.6.0",
"match-sorter": "^4.0.0", "match-sorter": "^4.0.0",
"morphmorph": "^0.1.0", "morphmorph": "^0.1.2",
"ms": "^2.1.2", "ms": "^2.1.2",
"next": "^9.0.3", "next": "^9.0.3",
"next-offline": "^4.0.3", "next-offline": "^4.0.3",
@ -52,8 +53,7 @@
"react-is": "^16.9.0", "react-is": "^16.9.0",
"react-spinner": "^0.2.7", "react-spinner": "^0.2.7",
"react-syntax-highlight": "^15.3.1", "react-syntax-highlight": "^15.3.1",
"tohash": "^1.0.2", "tohash": "^1.0.2"
"url": "^0.11.0"
}, },
"devDependencies": { "devDependencies": {
"@applitools/eyes-cypress": "^3.6.48", "@applitools/eyes-cypress": "^3.6.48",
@ -106,7 +106,6 @@
"type": "git", "type": "git",
"url": "git+https://github.com/carbon-app/carbon.git" "url": "git+https://github.com/carbon-app/carbon.git"
}, },
"author": "Carbon <@carbon-app>",
"bugs": { "bugs": {
"url": "https://github.com/carbon-app/carbon/issues" "url": "https://github.com/carbon-app/carbon/issues"
}, },

@ -0,0 +1,42 @@
import React from 'react'
import Router from 'next/router'
import IndexPage from './index'
import ApiContext from '../components/ApiContext'
import api from '../lib/api'
class IdPage extends React.PureComponent {
static contextType = ApiContext
static async getInitialProps({ req, res, query }) {
const path = query.id
const parameter = path && path.length >= 19 && path.indexOf('.') < 0 && path
let snippet
if (parameter) {
const host = req ? req.headers.host : undefined
snippet = await api.snippet.get(parameter, { host })
if (snippet) {
return { snippet }
}
// 404 Not found
if (res) {
res.writeHead(302, {
Location: '/'
})
res.end()
} else {
Router.push('/')
}
}
return {}
}
render() {
return <IndexPage {...this.props} />
}
}
export default IdPage

@ -4,15 +4,13 @@ import Document, { Head, Main, NextScript } from 'next/document'
export default class extends Document { export default class extends Document {
render() { render() {
return ( return (
<React.StrictMode> <html lang="en">
<html lang="en"> <Head />
<Head /> <body>
<body> <Main />
<Main /> <NextScript />
<NextScript /> </body>
</body> </html>
</html>
</React.StrictMode>
) )
} }
} }

@ -42,18 +42,21 @@ class Embed extends React.Component {
readOnly: true readOnly: true
} }
snippet = {}
async componentDidMount() { async componentDidMount() {
const { queryState, parameter } = getRouteState(this.props.router) const { queryState, parameter } = getRouteState(this.props.router)
let gistState if (parameter) {
if (this.context.gist && parameter) { const snippet = await this.context.snippet.get(parameter)
const gist = await this.context.gist.get(parameter) if (snippet) {
gistState = gist && gist.config this.snippet = snippet
}
} }
this.setState( this.setState(
{ {
...gistState, ...this.snippet,
...queryState, ...queryState,
copyable: queryState.copy !== false, copyable: queryState.copy !== false,
readOnly: queryState.readonly !== false, readOnly: queryState.readonly !== false,

@ -2,15 +2,12 @@
import React from 'react' import React from 'react'
import { withRouter } from 'next/router' import { withRouter } from 'next/router'
import { register, unregister } from 'next-offline/runtime' import { register, unregister } from 'next-offline/runtime'
import debounce from 'lodash.debounce'
import Either from 'eitherx' import Either from 'eitherx'
// Ours // Ours
import EditorContainer from '../components/EditorContainer' import EditorContainer from '../components/EditorContainer'
import Page from '../components/Page' import Page from '../components/Page'
import { MetaLinks } from '../components/Meta' import { MetaLinks } from '../components/Meta'
import { updateRouteState } from '../lib/routing'
import { saveSettings, clearSettings } from '../lib/util'
class Index extends React.Component { class Index extends React.Component {
componentDidMount() { componentDidMount() {
@ -22,25 +19,12 @@ class Index extends React.Component {
shouldComponentUpdate = () => false shouldComponentUpdate = () => false
onEditorUpdate = debounce(
state => {
updateRouteState(this.props.router, state)
saveSettings(state)
},
750,
{ trailing: true, leading: true }
)
render() { render() {
return ( return (
<Page enableHeroText={true}> <Page enableHeroText={true}>
<MetaLinks /> <MetaLinks />
<Either> <Either>
<EditorContainer <EditorContainer router={this.props.router} snippet={this.props.snippet} />
router={this.props.router}
onUpdate={this.onEditorUpdate}
onReset={onReset}
/>
<p> <p>
An unexpected error has occurred. Please{' '} An unexpected error has occurred. Please{' '}
<u> <u>
@ -54,16 +38,4 @@ class Index extends React.Component {
} }
} }
function onReset() {
clearSettings()
if (window.navigator && navigator.serviceWorker) {
navigator.serviceWorker.getRegistrations().then(registrations => {
for (let registration of registrations) {
registration.unregister()
}
})
}
}
export default withRouter(Index) export default withRouter(Index)

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="white" d="M256 32C132.3 32 32 134.9 32 261.7c0 101.5 64.2 187.5 153.2 217.9 1.4.3 2.6.4 3.8.4 8.3 0 11.5-6.1 11.5-11.4 0-5.5-.2-19.9-.3-39.1-8.4 1.9-15.9 2.7-22.6 2.7-43.1 0-52.9-33.5-52.9-33.5-10.2-26.5-24.9-33.6-24.9-33.6-19.5-13.7-.1-14.1 1.4-14.1h.1c22.5 2 34.3 23.8 34.3 23.8 11.2 19.6 26.2 25.1 39.6 25.1 10.5 0 20-3.4 25.6-6 2-14.8 7.8-24.9 14.2-30.7-49.7-5.8-102-25.5-102-113.5 0-25.1 8.7-45.6 23-61.6-2.3-5.8-10-29.2 2.2-60.8 0 0 1.6-.5 5-.5 8.1 0 26.4 3.1 56.6 24.1 17.9-5.1 37-7.6 56.1-7.7 19 .1 38.2 2.6 56.1 7.7 30.2-21 48.5-24.1 56.6-24.1 3.4 0 5 .5 5 .5 12.2 31.6 4.5 55 2.2 60.8 14.3 16.1 23 36.6 23 61.6 0 88.2-52.4 107.6-102.3 113.3 8 7.1 15.2 21.1 15.2 42.5 0 30.7-.3 55.5-.3 63 0 5.4 3.1 11.5 11.4 11.5 1.2 0 2.6-.1 4-.4C415.9 449.2 480 363.1 480 261.7 480 134.9 379.7 32 256 32z"/></svg>

After

Width:  |  Height:  |  Size: 882 B

@ -931,6 +931,177 @@
react-click-outside "^3.0.1" react-click-outside "^3.0.1"
react-fast-compare "2.0.4" react-fast-compare "2.0.4"
"@firebase/app-types@0.4.0":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.4.0.tgz#bb2c651f3b275fef549050cff28af752839c75c0"
integrity sha512-8erNMHc0V26gA6Nj4W9laVrQrXHsj9K2TEM7eL2IQogGSHLL4vet3UNekYfcGQ2cjfvwUjMzd+BNS/8S7GnfiA==
"@firebase/app@0.4.10":
version "0.4.10"
resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.4.10.tgz#3897a8ef4baa3faa39298e62488aa489b03921e0"
integrity sha512-w1Dc3zNNluDq4IYzTSKoO2kgNgVMiaBB3ki2OfHwhnfPh0H5WbIGOF5dLepk56iBsZjiRvpmHgDQbjLyI9foEQ==
dependencies:
"@firebase/app-types" "0.4.0"
"@firebase/logger" "0.1.18"
"@firebase/util" "0.2.21"
dom-storage "2.1.0"
tslib "1.9.3"
xmlhttprequest "1.8.0"
"@firebase/auth-types@0.7.0":
version "0.7.0"
resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.7.0.tgz#8aac4b9c04aff61362827c35b5ad36db16a837ba"
integrity sha512-QEG9azYwssGWcb4NaKFHe3Piez0SG46nRlu76HM4/ob0sjjNpNTY1Z5C3IoeJYknp2kMzuQi0TTW8tjEgkUAUA==
"@firebase/auth@0.11.4":
version "0.11.4"
resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.11.4.tgz#13e47bded49f49bb590684c190891e43eb76c984"
integrity sha512-wYWmqYiP7nsH9LE0lMFDgea/TbTNpQi6Ilx/CaTMiaBMGnbDIeUGsTFQ0lrk5STvEL5UOGVyxG0ZPEgpc98mbQ==
dependencies:
"@firebase/auth-types" "0.7.0"
"@firebase/database-types@0.4.0":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-0.4.0.tgz#71a711a3f666fac905422e130731930e2bcca582"
integrity sha512-2piRYW7t+2s/P1NPpcI/3+8Y5l2WnJhm9KACoXW5zmoAPlya8R1aEaR2dNHLNePTMHdg04miEDD9fEz4xUqzZA==
"@firebase/database@0.4.7":
version "0.4.7"
resolved "https://registry.yarnpkg.com/@firebase/database/-/database-0.4.7.tgz#9ca0d94b3090cf87bdc3d6f5b6be934100611462"
integrity sha512-ZMnn3cliGzz/P2/lCDhZQK2q/wh1THWu6/kYMAO9QnaZGL5842iPKVIvl8D4rOxfZga0bNLGqkZW7zPb3LHCDw==
dependencies:
"@firebase/database-types" "0.4.0"
"@firebase/logger" "0.1.18"
"@firebase/util" "0.2.21"
faye-websocket "0.11.3"
tslib "1.9.3"
"@firebase/firestore-types@1.4.2":
version "1.4.2"
resolved "https://registry.yarnpkg.com/@firebase/firestore-types/-/firestore-types-1.4.2.tgz#006041fc914a200c48780e9339e0ff5f9bcaaabd"
integrity sha512-Kypan1Ch7u3otPAnZ4M5ugeN64IG1kjXRrc8bgGy3hN2bWzoLZ8DeiF/2PmdswlnEvD77koLyyz2zpagWFe8YA==
"@firebase/firestore@1.4.4":
version "1.4.4"
resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-1.4.4.tgz#8a56b35eff14a514bd13af8131577c4ee473d90a"
integrity sha512-WFuKYOsOlYowyHjazUkzVhmPTuqDXbGv1AAgncPVfuioEoAGCK2KY4OGQkmyAfbg6juYU3nUNcmcY3yQSHfy+w==
dependencies:
"@firebase/firestore-types" "1.4.2"
"@firebase/logger" "0.1.18"
"@firebase/util" "0.2.21"
"@firebase/webchannel-wrapper" "0.2.21"
"@grpc/proto-loader" "^0.5.0"
grpc "1.20.3"
tslib "1.9.3"
"@firebase/functions-types@0.3.6":
version "0.3.6"
resolved "https://registry.yarnpkg.com/@firebase/functions-types/-/functions-types-0.3.6.tgz#27516f986ec0fad71d39797a8869d08b970c4123"
integrity sha512-OIWXsaUBNSA7ifkrTFKwNMDgs1DCk6dC7xwofRBIrJP3ZxLPxRV79KyKKqcThe5Ie6JeG6oyFAIK5CMTYa5Ebg==
"@firebase/functions@0.4.11":
version "0.4.11"
resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.4.11.tgz#973a3cc6af6a54c6fab04447911036b7aca7ff6c"
integrity sha512-p/Al2EmMpwMZapG6bDr1C/eTOqSyLJbNTB8HDrfzoSHHhvCKHGBZIUC03j/6h4kMJNwWGSxqt9fhkTS7xvZgZQ==
dependencies:
"@firebase/functions-types" "0.3.6"
"@firebase/messaging-types" "0.3.0"
isomorphic-fetch "2.2.1"
tslib "1.9.3"
"@firebase/installations-types@0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@firebase/installations-types/-/installations-types-0.1.1.tgz#630a57705f84df206af7f3b51781898864e97dbd"
integrity sha512-M+plQIOt6p+/j/ExUgsfXe1JFAKymhBU0K3+cp7hzj52vLSpklOqNJi4LkFl41pgRFPZeKf7MrTkMhVowg3Ukw==
"@firebase/installations@0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.2.0.tgz#692c2c81a18a02b6d4141a64a83623fc4da3aacc"
integrity sha512-bjpOc02WMZT5z2tNqqLgOBWcbm9mU40vWfJXZc4B+Y6///shmR4EPmUmacjkCBzYjVJy//aBLi4u9P7SuqV7ag==
dependencies:
"@firebase/installations-types" "0.1.1"
"@firebase/util" "0.2.21"
idb "3.0.2"
tslib "1.9.3"
"@firebase/logger@0.1.18":
version "0.1.18"
resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.1.18.tgz#5b0a849e32dfc0fdb7be9043cf1ae5584902949a"
integrity sha512-/2l28mC9xPXi3Kqe/xUJ/vQ8h4NalwAiYkNihE/JogkzluhqON17ton8OezcZ+gjq12mF9Oq2Xd9WxplMXK6vA==
"@firebase/messaging-types@0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@firebase/messaging-types/-/messaging-types-0.3.0.tgz#915eca1a6c1e0ceacf82e5086724cf054976b997"
integrity sha512-xCFMPy4C+WXFcshTnQEyddmqM6ZkzpTeJq7RUhrAvUnjlfFzOB92HOfKtjT6IpNk5W+jNbTTrqgrgReuPXsM2A==
"@firebase/messaging@0.4.4":
version "0.4.4"
resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.4.4.tgz#c7dd696db52b4221eda38e22797f98dfc2fcc390"
integrity sha512-j50hwkXxQh2fEsncGkfqMk+PgSNUHtZPE5mlCTpiANS24zqelO/V19NRmhYdYeC3wTsh79cgAHlJFSvN2KIXZA==
dependencies:
"@firebase/messaging-types" "0.3.0"
"@firebase/util" "0.2.21"
tslib "1.9.3"
"@firebase/performance-types@0.0.2":
version "0.0.2"
resolved "https://registry.yarnpkg.com/@firebase/performance-types/-/performance-types-0.0.2.tgz#4e37183f99c937cda7683ef3831e723c5cbf7e5f"
integrity sha512-nIZMVqc3tAGqRmNUU43yQ/WKY5Sypysa4Xg6J5F0q+QqxPpgwDh5xiPLEvD+/k6rswVTYQ9tsuIWqcJNpbA9zw==
"@firebase/performance@0.2.11":
version "0.2.11"
resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.2.11.tgz#89b971ab25be1138f0df2997ee4089d00eed35a8"
integrity sha512-xr2KTGn9MiHXt4FbaSYPsWe3qkm1qYelFPUPaooXPlBc6sdkyMyko8JqwXST4Pa5F/Fgm0Mvxiu2V0LhRXmbow==
dependencies:
"@firebase/installations" "0.2.0"
"@firebase/logger" "0.1.18"
"@firebase/performance-types" "0.0.2"
"@firebase/util" "0.2.21"
tslib "1.9.3"
"@firebase/polyfill@0.3.15":
version "0.3.15"
resolved "https://registry.yarnpkg.com/@firebase/polyfill/-/polyfill-0.3.15.tgz#ec44ebdc63d51d93ce707ccf9f7df0b4d1a11961"
integrity sha512-SDeH1UTQRtVUYQbbC9hiqZ3y8fDbsbYV9+Z8JN2NB8OL3ahh4hBhIwQwzBac5A/EqCBNJUMNeUEU4rLcC3uG3A==
dependencies:
core-js "3.0.1"
promise-polyfill "8.1.0"
whatwg-fetch "2.0.4"
"@firebase/storage-types@0.3.1":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@firebase/storage-types/-/storage-types-0.3.1.tgz#a85f115b6c51fc3a75bca5858061f6c84c0b845c"
integrity sha512-Vuf7/nSTWrvPmoZiwfQjI3ThqAKQXVLpozhoGVxoGM1qtITsnw+Oe/Fa+CW1/ZkelVBcy8ZWEB2aaHXaDu3h+Q==
"@firebase/storage@0.3.5":
version "0.3.5"
resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.3.5.tgz#d9f774c6a9db1416c823c90d986598ac3c6c35ab"
integrity sha512-1zgmLaHNRSA/ukYLeYRfqr7PsSrJe0OsF0X5Fu0TsDagV78qrSyJqMljKaGr9t3PTvBo0LEgVEBJUkpAgp+fwA==
dependencies:
"@firebase/storage-types" "0.3.1"
"@firebase/util" "0.2.21"
tslib "1.9.3"
"@firebase/util@0.2.21":
version "0.2.21"
resolved "https://registry.yarnpkg.com/@firebase/util/-/util-0.2.21.tgz#b9a592d6381efbc526ea8b07ec94875800935f64"
integrity sha512-80ZblYuorX4Udr4wPzht1upQzk99xS2SIRfl4gvTNiu5WXKTSKKk5WbpiR8IL2bYVSo/dd634B2L7BOTEjHcqA==
dependencies:
tslib "1.9.3"
"@firebase/webchannel-wrapper@0.2.21":
version "0.2.21"
resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.21.tgz#1116075d3d821e058a8c321385552c51fa3a6680"
integrity sha512-eL4xPPjTBceYKa27tN3SahSD/7k5ioKFGeZZZX67+aLuxxFts2eTCcotRAeKcjGu1xTz7GnWUkMsj4NZZTIGXg==
"@grpc/proto-loader@^0.5.0":
version "0.5.1"
resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.5.1.tgz#48492b53cdda353110b51a4b02f465974729c76f"
integrity sha512-3y0FhacYAwWvyXshH18eDkUI40wT/uGio7MAegzY8lO5+wVsc19+1A7T0pPptae4kl7bdITL+0cHpnAPmryBjQ==
dependencies:
lodash.camelcase "^4.3.0"
protobufjs "^6.8.6"
"@hapi/address@2.x.x": "@hapi/address@2.x.x":
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.0.0.tgz#9f05469c88cb2fd3dcd624776b54ee95c312126a" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.0.0.tgz#9f05469c88cb2fd3dcd624776b54ee95c312126a"
@ -1147,6 +1318,59 @@
"@nodelib/fs.scandir" "2.1.1" "@nodelib/fs.scandir" "2.1.1"
fastq "^1.6.0" fastq "^1.6.0"
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78=
"@protobufjs/base64@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735"
integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==
"@protobufjs/codegen@^2.0.4":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb"
integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==
"@protobufjs/eventemitter@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A=
"@protobufjs/fetch@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=
dependencies:
"@protobufjs/aspromise" "^1.1.1"
"@protobufjs/inquire" "^1.1.0"
"@protobufjs/float@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=
"@protobufjs/inquire@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=
"@protobufjs/path@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=
"@protobufjs/pool@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=
"@protobufjs/utf8@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=
"@reach/visually-hidden@^0.1.4": "@reach/visually-hidden@^0.1.4":
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/@reach/visually-hidden/-/visually-hidden-0.1.4.tgz#0dc4ecedf523004337214187db70a46183bd945b" resolved "https://registry.yarnpkg.com/@reach/visually-hidden/-/visually-hidden-0.1.4.tgz#0dc4ecedf523004337214187db70a46183bd945b"
@ -1226,6 +1450,11 @@
"@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-coverage" "*"
"@types/istanbul-lib-report" "*" "@types/istanbul-lib-report" "*"
"@types/long@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef"
integrity sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==
"@types/minimatch@*": "@types/minimatch@*":
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
@ -1236,6 +1465,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c"
integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg== integrity sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==
"@types/node@^10.1.0":
version "10.14.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.12.tgz#0eec3155a46e6c4db1f27c3e588a205f767d622f"
integrity sha512-QcAKpaO6nhHLlxWBvpc4WeLrTvPqlHOvaj0s5GriKkA1zq+bsFBPpfYCvQhLqLgYlIko8A9YrPdaMHCo5mBcpg==
"@types/normalize-package-data@^2.4.0": "@types/normalize-package-data@^2.4.0":
version "2.4.0" version "2.4.0"
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
@ -1738,6 +1972,14 @@ asap@~2.0.3:
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
ascli@~1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ascli/-/ascli-1.0.1.tgz#bcfa5974a62f18e81cabaeb49732ab4a88f906bc"
integrity sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=
dependencies:
colour "~0.7.1"
optjs "~3.2.2"
asn1.js@^4.0.0: asn1.js@^4.0.0:
version "4.10.1" version "4.10.1"
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
@ -2248,6 +2490,13 @@ builtin-status-codes@^3.0.0:
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
bytebuffer@~5:
version "5.0.1"
resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd"
integrity sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=
dependencies:
long "~3"
bytes@3.0.0: bytes@3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
@ -2343,6 +2592,11 @@ callsites@^3.0.0:
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
camelcase@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=
camelcase@^5.0.0: camelcase@^5.0.0:
version "5.3.1" version "5.3.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
@ -2506,6 +2760,15 @@ clipboardy@^1.2.3:
arch "^2.1.0" arch "^2.1.0"
execa "^0.8.0" execa "^0.8.0"
cliui@^3.0.3:
version "3.2.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=
dependencies:
string-width "^1.0.1"
strip-ansi "^3.0.1"
wrap-ansi "^2.0.0"
cliui@^4.0.0: cliui@^4.0.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49"
@ -2584,6 +2847,11 @@ colors@1.1.2:
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM=
colour@~0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778"
integrity sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=
combined-stream@^1.0.6, combined-stream@~1.0.6: combined-stream@^1.0.6, combined-stream@~1.0.6:
version "1.0.8" version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@ -2766,6 +3034,11 @@ core-js-pure@3.1.4:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.1.4.tgz#5fa17dc77002a169a3566cc48dc774d2e13e3769" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.1.4.tgz#5fa17dc77002a169a3566cc48dc774d2e13e3769"
integrity sha512-uJ4Z7iPNwiu1foygbcZYJsJs1jiXrTTCvxfLDXNhI/I+NHbSIEyr548y4fcsCEyWY0XgfAG/qqaunJ1SThHenA== integrity sha512-uJ4Z7iPNwiu1foygbcZYJsJs1jiXrTTCvxfLDXNhI/I+NHbSIEyr548y4fcsCEyWY0XgfAG/qqaunJ1SThHenA==
core-js@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.1.tgz#1343182634298f7f38622f95e73f54e48ddf4738"
integrity sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew==
core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5: core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5:
version "2.6.9" version "2.6.9"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
@ -3010,7 +3283,7 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
dependencies: dependencies:
ms "^2.1.1" ms "^2.1.1"
decamelize@^1.2.0: decamelize@^1.1.1, decamelize@^1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
@ -3185,7 +3458,12 @@ doctrine@^3.0.0:
dependencies: dependencies:
esutils "^2.0.2" esutils "^2.0.2"
dom-to-image@^2.5.2: dom-storage@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/dom-storage/-/dom-storage-2.1.0.tgz#00fb868bc9201357ea243c7bcfd3304c1e34ea39"
integrity sha512-g6RpyWXzl0RR6OTElHKBl7nwnK87GUyZMYC7JWsB/IA73vpqK2K6LT39x4VepLxlSsWBFrPVLnsSR5Jyty0+2Q==
dom-to-image@^2.6.0:
version "2.6.0" version "2.6.0"
resolved "https://registry.yarnpkg.com/dom-to-image/-/dom-to-image-2.6.0.tgz#8a503608088c87b1c22f9034ae032e1898955867" resolved "https://registry.yarnpkg.com/dom-to-image/-/dom-to-image-2.6.0.tgz#8a503608088c87b1c22f9034ae032e1898955867"
integrity sha1-ilA2CAiMh7HCL5A0rgMuGJiVWGc= integrity sha1-ilA2CAiMh7HCL5A0rgMuGJiVWGc=
@ -3295,6 +3573,13 @@ encodeurl@~1.0.1, encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
encoding@^0.1.11:
version "0.1.12"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=
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:
version "1.4.1" version "1.4.1"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
@ -3924,6 +4209,13 @@ fastq@^1.6.0:
dependencies: dependencies:
reusify "^1.0.0" reusify "^1.0.0"
faye-websocket@0.11.3:
version "0.11.3"
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e"
integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==
dependencies:
websocket-driver ">=0.5.1"
fb-watchman@^2.0.0: fb-watchman@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58"
@ -4066,6 +4358,24 @@ find-up@^4.0.0:
locate-path "^5.0.0" locate-path "^5.0.0"
path-exists "^4.0.0" path-exists "^4.0.0"
firebase@^6.2.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/firebase/-/firebase-6.3.0.tgz#1998c111f2d6c80ccec432e7b89010a2d553ca5e"
integrity sha512-yXes80Z//0Dpnet7OfpcUkvyJpBtVaqTHqqMAZ4QrINuKfNOyjF5E/Xpbw8DMVHTJ5netjTLKfmUNvXQJLGs8A==
dependencies:
"@firebase/app" "0.4.10"
"@firebase/app-types" "0.4.0"
"@firebase/auth" "0.11.4"
"@firebase/database" "0.4.7"
"@firebase/firestore" "1.4.4"
"@firebase/functions" "0.4.11"
"@firebase/installations" "0.2.0"
"@firebase/messaging" "0.4.4"
"@firebase/performance" "0.2.11"
"@firebase/polyfill" "0.3.15"
"@firebase/storage" "0.3.5"
"@firebase/util" "0.2.21"
flat-cache@^2.0.1: flat-cache@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0"
@ -4317,7 +4627,7 @@ glob-to-regexp@^0.4.1:
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.3: glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.3:
version "7.1.4" version "7.1.4"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
@ -4458,6 +4768,17 @@ growly@^1.3.0:
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=
grpc@1.20.3:
version "1.20.3"
resolved "https://registry.yarnpkg.com/grpc/-/grpc-1.20.3.tgz#a74d36718f1e89c4a64f2fb9441199c3c8f78978"
integrity sha512-GsEsi0NVj6usS/xor8pF/xDbDiwZQR59aZl5NUZ59Sy2bdPQFZ3UePr5wevZjHboirRCIQCKRI1cCgvSWUe2ag==
dependencies:
lodash.camelcase "^4.3.0"
lodash.clone "^4.5.0"
nan "^2.13.2"
node-pre-gyp "^0.13.0"
protobufjs "^5.0.3"
gzip-size@^5.0.0: gzip-size@^5.0.0:
version "5.1.1" version "5.1.1"
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274"
@ -4649,6 +4970,11 @@ http-errors@~1.7.2:
statuses ">= 1.5.0 < 2" statuses ">= 1.5.0 < 2"
toidentifier "1.0.0" toidentifier "1.0.0"
"http-parser-js@>=0.4.0 <0.4.11":
version "0.4.10"
resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4"
integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=
http-signature@~1.2.0: http-signature@~1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
@ -4687,13 +5013,18 @@ husky@^3.0.3:
run-node "^1.0.0" run-node "^1.0.0"
slash "^3.0.0" slash "^3.0.0"
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
version "0.4.24" version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
dependencies: dependencies:
safer-buffer ">= 2.1.2 < 3" safer-buffer ">= 2.1.2 < 3"
idb@3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/idb/-/idb-3.0.2.tgz#c8e9122d5ddd40f13b60ae665e4862f8b13fa384"
integrity sha512-+FLa/0sTXqyux0o6C+i2lOR0VoS60LU/jzUo5xjfY6+7sEEgy4Gz1O7yFBXvjd7N0NyIGWIRg8DcQSLEG+VSPw==
ieee754@^1.1.4: ieee754@^1.1.4:
version "1.1.13" version "1.1.13"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
@ -4826,6 +5157,11 @@ invariant@^2.2.2, invariant@^2.2.4:
dependencies: dependencies:
loose-envify "^1.0.0" loose-envify "^1.0.0"
invert-kv@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY=
invert-kv@^2.0.0: invert-kv@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
@ -5087,7 +5423,7 @@ is-regexp@^1.0.0:
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk=
is-stream@^1.1.0: is-stream@^1.0.1, is-stream@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
@ -5141,6 +5477,14 @@ isobject@^3.0.0, isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
isomorphic-fetch@2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=
dependencies:
node-fetch "^1.0.1"
whatwg-fetch ">=0.10.0"
isstream@~0.1.2: isstream@~0.1.2:
version "0.1.2" version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@ -5778,6 +6122,13 @@ lazy-ass@1.6.0:
resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513"
integrity sha1-eZllXoZGwX8In90YfRUNMyTVRRM= integrity sha1-eZllXoZGwX8In90YfRUNMyTVRRM=
lcid@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=
dependencies:
invert-kv "^1.0.0"
lcid@^2.0.0: lcid@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf"
@ -5979,6 +6330,16 @@ lodash._reinterpolate@^3.0.0:
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY=
lodash.clone@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6"
integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=
lodash.debounce@^4.0.8: lodash.debounce@^4.0.8:
version "4.0.8" version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
@ -6082,6 +6443,16 @@ log-update@^2.3.0:
cli-cursor "^2.0.0" cli-cursor "^2.0.0"
wrap-ansi "^3.0.1" wrap-ansi "^3.0.1"
long@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
long@~3:
version "3.2.0"
resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b"
integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@ -6402,7 +6773,7 @@ moment@2.24.0:
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
morphmorph@^0.1.0: morphmorph@^0.1.2:
version "0.1.2" version "0.1.2"
resolved "https://registry.yarnpkg.com/morphmorph/-/morphmorph-0.1.2.tgz#d95dcf68b112c0e89506fff3b4bed4f907bc7700" resolved "https://registry.yarnpkg.com/morphmorph/-/morphmorph-0.1.2.tgz#d95dcf68b112c0e89506fff3b4bed4f907bc7700"
integrity sha512-8DPqe7bKUjaWRWGG6x9hVcW2FvuPQH0PpPkHs7Gi8mtTjyYkvf2yA2UlULKFuvjpkkcef2TixXEYDG949CJnug== integrity sha512-8DPqe7bKUjaWRWGG6x9hVcW2FvuPQH0PpPkHs7Gi8mtTjyYkvf2yA2UlULKFuvjpkkcef2TixXEYDG949CJnug==
@ -6439,7 +6810,7 @@ mute-stream@0.0.7:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
nan@^2.12.1: nan@^2.12.1, nan@^2.13.2:
version "2.14.0" version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
@ -6584,6 +6955,14 @@ node-fetch@2.6.0, node-fetch@^2.3.0, node-fetch@^2.6.0:
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
node-fetch@^1.0.1:
version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==
dependencies:
encoding "^0.1.11"
is-stream "^1.0.1"
node-int64@^0.4.0: node-int64@^0.4.0:
version "0.4.0" version "0.4.0"
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
@ -6650,6 +7029,22 @@ node-pre-gyp@^0.12.0:
semver "^5.3.0" semver "^5.3.0"
tar "^4" tar "^4"
node-pre-gyp@^0.13.0:
version "0.13.0"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz#df9ab7b68dd6498137717838e4f92a33fc9daa42"
integrity sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==
dependencies:
detect-libc "^1.0.2"
mkdirp "^0.5.1"
needle "^2.2.1"
nopt "^4.0.1"
npm-packlist "^1.1.6"
npmlog "^4.0.2"
rc "^1.2.7"
rimraf "^2.6.1"
semver "^5.3.0"
tar "^4"
node-releases@^1.1.25: node-releases@^1.1.25:
version "1.1.25" version "1.1.25"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.25.tgz#0c2d7dbc7fed30fbe02a9ee3007b8c90bf0133d3" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.25.tgz#0c2d7dbc7fed30fbe02a9ee3007b8c90bf0133d3"
@ -6906,6 +7301,11 @@ optionator@^0.8.1, optionator@^0.8.2:
type-check "~0.3.2" type-check "~0.3.2"
wordwrap "~1.0.0" wordwrap "~1.0.0"
optjs@~3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/optjs/-/optjs-3.2.2.tgz#69a6ce89c442a44403141ad2f9b370bd5bb6f4ee"
integrity sha1-aabOicRCpEQDFBrS+bNwvVu29O4=
ora@^0.2.3: ora@^0.2.3:
version "0.2.3" version "0.2.3"
resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4"
@ -6926,6 +7326,13 @@ os-homedir@^1.0.0, os-homedir@^1.0.1:
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
os-locale@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9"
integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=
dependencies:
lcid "^1.0.0"
os-locale@^3.0.0: os-locale@^3.0.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
@ -7364,6 +7771,11 @@ promise-inflight@^1.0.1:
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
promise-polyfill@8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.1.0.tgz#30059da54d1358ce905ac581f287e184aedf995d"
integrity sha512-OzSf6gcCUQ01byV4BgwyUCswlaQQ6gzXc23aLQWhicvfX9kfsUiUhgt3CCQej8jDnl8/PhGF31JdHX2/MzF3WA==
promise@7.1.1: promise@7.1.1:
version "7.1.1" version "7.1.1"
resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf" resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf"
@ -7405,6 +7817,35 @@ prop-types@15.7.2, prop-types@>=15.5.8, prop-types@^15.5.10, prop-types@^15.5.8,
object-assign "^4.1.1" object-assign "^4.1.1"
react-is "^16.8.1" react-is "^16.8.1"
protobufjs@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-5.0.3.tgz#e4dfe9fb67c90b2630d15868249bcc4961467a17"
integrity sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==
dependencies:
ascli "~1"
bytebuffer "~5"
glob "^7.0.5"
yargs "^3.10.0"
protobufjs@^6.8.6:
version "6.8.8"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c"
integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==
dependencies:
"@protobufjs/aspromise" "^1.1.2"
"@protobufjs/base64" "^1.1.2"
"@protobufjs/codegen" "^2.0.4"
"@protobufjs/eventemitter" "^1.1.0"
"@protobufjs/fetch" "^1.1.0"
"@protobufjs/float" "^1.0.2"
"@protobufjs/inquire" "^1.1.0"
"@protobufjs/path" "^1.1.2"
"@protobufjs/pool" "^1.1.0"
"@protobufjs/utf8" "^1.1.0"
"@types/long" "^4.0.0"
"@types/node" "^10.1.0"
long "^4.0.0"
proxy-addr@~2.0.5: proxy-addr@~2.0.5:
version "2.0.5" version "2.0.5"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34"
@ -8031,7 +8472,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2:
version "5.2.0" version "5.2.0"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
@ -8904,6 +9345,11 @@ tryer@^1.0.1:
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
tslib@1.9.3:
version "1.9.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
tslib@^1.9.0: tslib@^1.9.0:
version "1.10.0" version "1.10.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
@ -9324,6 +9770,20 @@ webpack@^4.19.1, webpack@^4.33.0:
watchpack "^1.5.0" watchpack "^1.5.0"
webpack-sources "^1.3.0" webpack-sources "^1.3.0"
websocket-driver@>=0.5.1:
version "0.7.3"
resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9"
integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==
dependencies:
http-parser-js ">=0.4.0 <0.4.11"
safe-buffer ">=5.1.0"
websocket-extensions ">=0.1.1"
websocket-extensions@>=0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5: whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5:
version "1.0.5" version "1.0.5"
resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
@ -9383,6 +9843,11 @@ wide-align@^1.1.0:
dependencies: dependencies:
string-width "^1.0.2 || 2" string-width "^1.0.2 || 2"
window-size@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876"
integrity sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=
wordwrap@~0.0.2: wordwrap@~0.0.2:
version "0.0.3" version "0.0.3"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
@ -9619,11 +10084,21 @@ xmlchars@^2.1.1:
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.1.1.tgz#ef1a81c05bff629c2280007f12daca21bd6f6c93" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.1.1.tgz#ef1a81c05bff629c2280007f12daca21bd6f6c93"
integrity sha512-7hew1RPJ1iIuje/Y01bGD/mXokXxegAgVS+e+E0wSi2ILHQkYAH1+JXARwTjZSM4Z4Z+c73aKspEcqj+zPPL/w== integrity sha512-7hew1RPJ1iIuje/Y01bGD/mXokXxegAgVS+e+E0wSi2ILHQkYAH1+JXARwTjZSM4Z4Z+c73aKspEcqj+zPPL/w==
xmlhttprequest@1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"
integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=
xtend@^4.0.0, xtend@~4.0.1: xtend@^4.0.0, xtend@~4.0.1:
version "4.0.2" version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^3.2.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
integrity sha1-bRX7qITAhnnA136I53WegR4H+kE=
"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: "y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
@ -9689,6 +10164,19 @@ yargs@^13.1.0:
y18n "^4.0.0" y18n "^4.0.0"
yargs-parser "^13.1.1" yargs-parser "^13.1.1"
yargs@^3.10.0:
version "3.32.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995"
integrity sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=
dependencies:
camelcase "^2.0.1"
cliui "^3.0.3"
decamelize "^1.1.1"
os-locale "^1.4.0"
string-width "^1.0.1"
window-size "^0.1.4"
y18n "^3.2.0"
yauzl@2.10.0: yauzl@2.10.0:
version "2.10.0" version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"

Loading…
Cancel
Save