[chore] Sponsors in README (#301)
* Add images, read me links * Add API route for sponsor image * Update cache max age
This commit is contained in:
parent
eb20f1c816
commit
cd48b67a74
15 changed files with 177 additions and 40 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -14,3 +14,4 @@ coverage
|
||||||
apps/www/public/worker-*
|
apps/www/public/worker-*
|
||||||
apps/www/public/sw.js
|
apps/www/public/sw.js
|
||||||
apps/www/public/sw.js.map
|
apps/www/public/sw.js.map
|
||||||
|
.env
|
20
README.md
20
README.md
|
@ -1,5 +1,5 @@
|
||||||
<div style="text-align: center; transform: scale(.5);">
|
<div style="text-align: center; transform: scale(.5);">
|
||||||
<img src="card-repo.png"/>
|
<img src="./assets/tldraw.png"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Welcome to the [tldraw](https://tldraw.com) monorepo. Here you'll find the source code for [@tldraw/tldraw](https://www.npmjs.com/package/@tldraw/tldraw), [@tldraw/core](https://www.npmjs.com/package/@tldraw/core), and the tldraw.com website.
|
Welcome to the [tldraw](https://tldraw.com) monorepo. Here you'll find the source code for [@tldraw/tldraw](https://www.npmjs.com/package/@tldraw/tldraw), [@tldraw/core](https://www.npmjs.com/package/@tldraw/core), and the tldraw.com website.
|
||||||
|
@ -8,6 +8,14 @@ Welcome to the [tldraw](https://tldraw.com) monorepo. Here you'll find the sourc
|
||||||
|
|
||||||
💕 Love this project? Consider [becoming a sponsor](https://github.com/sponsors/steveruizok?frequency=recurring&sponsor=steveruizok).
|
💕 Love this project? Consider [becoming a sponsor](https://github.com/sponsors/steveruizok?frequency=recurring&sponsor=steveruizok).
|
||||||
|
|
||||||
|
Thanks to our corporate sponsors:
|
||||||
|
|
||||||
|
<a href="https://sentry.io"><img src="./assets/sentry.svg"></img></a>
|
||||||
|
|
||||||
|
<a href="https://vercel.com/?utm_source=team-slug&utm_campaign=oss"><img src="./assets/vercel.svg"></img></a>
|
||||||
|
|
||||||
|
...and to our [individual sponsors](https://github.com/sponsors/steveruizok#sponsors)!
|
||||||
|
|
||||||
## Contents
|
## Contents
|
||||||
|
|
||||||
This repository is a monorepo containing two packages:
|
This repository is a monorepo containing two packages:
|
||||||
|
@ -27,18 +35,18 @@ This repository is a monorepo containing two packages:
|
||||||
- [**examples/core-example-advanced**](https://github.com/tldraw/tldraw/tree/main/examples/core-example-advanced) is a second example for `@tldraw/core`.
|
- [**examples/core-example-advanced**](https://github.com/tldraw/tldraw/tree/main/examples/core-example-advanced) is a second example for `@tldraw/core`.
|
||||||
- [**examples/tldraw-example**](https://github.com/tldraw/tldraw/tree/main/examples/tldraw-example) is an example for `@tldraw/tldraw`.
|
- [**examples/tldraw-example**](https://github.com/tldraw/tldraw/tree/main/examples/tldraw-example) is an example for `@tldraw/tldraw`.
|
||||||
|
|
||||||
|
## Discussion
|
||||||
|
|
||||||
|
Want to connect? Visit the [Discord channel](https://discord.gg/SBBEVCA4PG).
|
||||||
|
|
||||||
## Contribution
|
## Contribution
|
||||||
|
|
||||||
See the [contributing guide](/CONTRIBUTING.md).
|
Interested in contributing? See the [contributing guide](/CONTRIBUTING.md).
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
Need help? Please [open an issue](https://github.com/tldraw/tldraw/issues/new) for support.
|
Need help? Please [open an issue](https://github.com/tldraw/tldraw/issues/new) for support.
|
||||||
|
|
||||||
## Discussion
|
|
||||||
|
|
||||||
Want to connect with other devs? Visit the [Discord channel](https://discord.gg/SBBEVCA4PG).
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under MIT.
|
This project is licensed under MIT.
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_API_KEY=pk_live_1LJGGaqBSNLjLT-4Jalkl-U9
|
|
|
@ -11,7 +11,7 @@ interface EditorProps {
|
||||||
isSponsor?: boolean
|
isSponsor?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Editor({ id = 'home', isSponsor = false }: EditorProps) {
|
export default function Editor({ id = 'home', isUser = false, isSponsor = false }: EditorProps) {
|
||||||
const handleMount = React.useCallback((app: TldrawApp) => {
|
const handleMount = React.useCallback((app: TldrawApp) => {
|
||||||
window.app = app
|
window.app = app
|
||||||
}, [])
|
}, [])
|
||||||
|
@ -39,7 +39,7 @@ export default function Editor({ id = 'home', isSponsor = false }: EditorProps)
|
||||||
onPersist={handlePersist}
|
onPersist={handlePersist}
|
||||||
showSponsorLink={!isSponsor}
|
showSponsorLink={!isSponsor}
|
||||||
onSignIn={isSponsor ? undefined : onSignIn}
|
onSignIn={isSponsor ? undefined : onSignIn}
|
||||||
onSignOut={onSignOut}
|
onSignOut={isUser ? onSignOut : undefined}
|
||||||
{...fileSystemEvents}
|
{...fileSystemEvents}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -38,7 +38,15 @@ export default function MultiplayerEditor({
|
||||||
|
|
||||||
// Inner Editor
|
// Inner Editor
|
||||||
|
|
||||||
function Editor({ roomId, isSponsor }: { roomId: string; isUser; isSponsor: boolean }) {
|
function Editor({
|
||||||
|
roomId,
|
||||||
|
isUser,
|
||||||
|
isSponsor,
|
||||||
|
}: {
|
||||||
|
roomId: string
|
||||||
|
isUser: boolean
|
||||||
|
isSponsor: boolean
|
||||||
|
}) {
|
||||||
const [docId] = React.useState(() => Utils.uniqueId())
|
const [docId] = React.useState(() => Utils.uniqueId())
|
||||||
|
|
||||||
const [app, setApp] = React.useState<TldrawApp>()
|
const [app, setApp] = React.useState<TldrawApp>()
|
||||||
|
@ -175,7 +183,7 @@ function Editor({ roomId, isSponsor }: { roomId: string; isUser; isSponsor: bool
|
||||||
showPages={false}
|
showPages={false}
|
||||||
showSponsorLink={isSponsor}
|
showSponsorLink={isSponsor}
|
||||||
onSignIn={isSponsor ? undefined : onSignIn}
|
onSignIn={isSponsor ? undefined : onSignIn}
|
||||||
onSignOut={onSignOut}
|
onSignOut={isUser ? onSignOut : undefined}
|
||||||
{...fileSystemEvents}
|
{...fileSystemEvents}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { isSponsoringMe } from '-utils/isSponsoringMe'
|
||||||
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
|
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next'
|
||||||
import NextAuth from 'next-auth'
|
import NextAuth from 'next-auth'
|
||||||
import Providers from 'next-auth/providers'
|
import Providers from 'next-auth/providers'
|
||||||
|
@ -30,28 +31,3 @@ export default function Auth(
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const whitelist = ['steveruizok']
|
|
||||||
|
|
||||||
async function isSponsoringMe(login: string) {
|
|
||||||
if (whitelist.includes(login)) return true
|
|
||||||
|
|
||||||
const res = await fetch('https://api.github.com/graphql', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
Authorization: 'bearer ' + process.env.GITHUB_API_SECRET,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
query: `
|
|
||||||
query {
|
|
||||||
user(login: "steveruizok") {
|
|
||||||
isSponsoredBy(accountLogin: "${login}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
}),
|
|
||||||
}).then((res) => res.json())
|
|
||||||
|
|
||||||
return res?.data?.user?.isSponsoredBy
|
|
||||||
}
|
|
||||||
|
|
96
apps/www/pages/api/sponsors.ts
Normal file
96
apps/www/pages/api/sponsors.ts
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
import { NextApiRequest, NextApiResponse } from 'next'
|
||||||
|
|
||||||
|
const AV_SIZE = 32
|
||||||
|
const PADDING = 4
|
||||||
|
const COLS = 16
|
||||||
|
|
||||||
|
type SponsorResult = { url: string; login: string }
|
||||||
|
type QueryResult = {
|
||||||
|
node: { sponsorEntity: { avatarUrl: string; login: string } }
|
||||||
|
}
|
||||||
|
|
||||||
|
function getXY(i: number) {
|
||||||
|
return [(i % COLS) * (AV_SIZE + PADDING), Math.floor(i / COLS) * (AV_SIZE + PADDING)]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function GetSponsors(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
const sponsorInfo = await fetch('https://api.github.com/graphql', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: 'bearer ' + process.env.GITHUB_API_SECRET,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
query: `{
|
||||||
|
viewer {
|
||||||
|
sponsors(first: 0) {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
sponsorshipsAsMaintainer(first: 100, orderBy: {
|
||||||
|
field:CREATED_AT,
|
||||||
|
direction:DESC
|
||||||
|
}) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
sponsorEntity {
|
||||||
|
...on User {
|
||||||
|
avatarUrl
|
||||||
|
login
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`,
|
||||||
|
}),
|
||||||
|
}).then((res) => res.json())
|
||||||
|
|
||||||
|
const totalCount: number = sponsorInfo.data.viewer.sponsors.totalCount
|
||||||
|
|
||||||
|
const results = (
|
||||||
|
sponsorInfo.data.viewer.sponsorshipsAsMaintainer.edges as QueryResult[]
|
||||||
|
).map<SponsorResult>((edge) => ({
|
||||||
|
url: edge.node.sponsorEntity.avatarUrl?.replaceAll('&', '&') ?? '',
|
||||||
|
login: edge.node.sponsorEntity.login,
|
||||||
|
}))
|
||||||
|
|
||||||
|
if (results.length % COLS <= 2) {
|
||||||
|
results.pop()
|
||||||
|
results.pop()
|
||||||
|
results.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avatars
|
||||||
|
|
||||||
|
const avatars = results
|
||||||
|
.map(({ url, login }, i) => {
|
||||||
|
const [x, y] = getXY(i)
|
||||||
|
return `<image alt="${login}" href="${url}" x="${x}" y="${y}" width="${AV_SIZE}" height="${AV_SIZE}"/>`
|
||||||
|
})
|
||||||
|
.join('')
|
||||||
|
|
||||||
|
// More text
|
||||||
|
|
||||||
|
const [x, y] = getXY(results.length)
|
||||||
|
const width = (AV_SIZE + PADDING) * 3
|
||||||
|
const more = `
|
||||||
|
<g transform="translate(${x},${y})"><text text-lenth="${width}" font-family="Arial" font-size="12px" font-weight="bold" text-anchor="middle" text-align="center" x="${
|
||||||
|
width / 2
|
||||||
|
}" y="${AV_SIZE / 2 + 3}">...and ${totalCount - 100} more!</text></g>`
|
||||||
|
|
||||||
|
const svgImage = `
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"><a href="https://github.com/sponsors/steveruizok"><g>${avatars}${more}</g></a></svg>`
|
||||||
|
|
||||||
|
// const html = `
|
||||||
|
// <div style="display: grid; width: fit-content; grid-template-columns: repeat(25, auto); gap: 4px;">
|
||||||
|
// ${images.join(`
|
||||||
|
// `)}
|
||||||
|
// </div>`
|
||||||
|
|
||||||
|
res
|
||||||
|
.status(200)
|
||||||
|
.setHeader('Cache-Control', 'max-age=604800')
|
||||||
|
.setHeader('Content-Type', 'image/svg+xml')
|
||||||
|
.send(svgImage)
|
||||||
|
}
|
|
@ -26,7 +26,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
isUser: false,
|
isUser: session?.user,
|
||||||
isSponsor: session?.user ? true : false,
|
isSponsor: session?.user ? true : false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
id,
|
id,
|
||||||
isUser: false,
|
isUser: session?.user,
|
||||||
isSponsor: session?.user ? true : false,
|
isSponsor: session?.user ? true : false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
24
apps/www/utils/isSponsoringMe.ts
Normal file
24
apps/www/utils/isSponsoringMe.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
const whitelist = ['steveruizok']
|
||||||
|
|
||||||
|
export async function isSponsoringMe(login: string) {
|
||||||
|
if (whitelist.includes(login)) return true
|
||||||
|
|
||||||
|
const res = await fetch('https://api.github.com/graphql', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: 'bearer ' + process.env.GITHUB_API_SECRET,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
query: `
|
||||||
|
query {
|
||||||
|
user(login: "steveruizok") {
|
||||||
|
isSponsoredBy(accountLogin: "${login}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
}),
|
||||||
|
}).then((res) => res.json())
|
||||||
|
|
||||||
|
return res?.data?.user?.isSponsoredBy
|
||||||
|
}
|
1
assets/sentry.svg
Normal file
1
assets/sentry.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg class="__sntry__ css-15xgryy e10nushx5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 44" width="212" height="47" style=""><defs><style type="text/css">@media (prefers-color-scheme: dark) {path.__sntry__ { fill: #362d59 !important; }}</style></defs><path d="M29,2.26a4.67,4.67,0,0,0-8,0L14.42,13.53A32.21,32.21,0,0,1,32.17,40.19H27.55A27.68,27.68,0,0,0,12.09,17.47L6,28a15.92,15.92,0,0,1,9.23,12.17H4.62A.76.76,0,0,1,4,39.06l2.94-5a10.74,10.74,0,0,0-3.36-1.9l-2.91,5a4.54,4.54,0,0,0,1.69,6.24A4.66,4.66,0,0,0,4.62,44H19.15a19.4,19.4,0,0,0-8-17.31l2.31-4A23.87,23.87,0,0,1,23.76,44H36.07a35.88,35.88,0,0,0-16.41-31.8l4.67-8a.77.77,0,0,1,1.05-.27c.53.29,20.29,34.77,20.66,35.17a.76.76,0,0,1-.68,1.13H40.6q.09,1.91,0,3.81h4.78A4.59,4.59,0,0,0,50,39.43a4.49,4.49,0,0,0-.62-2.28Z M124.32,28.28,109.56,9.22h-3.68V34.77h3.73V15.19l15.18,19.58h3.26V9.22h-3.73ZM87.15,23.54h13.23V20.22H87.14V12.53h14.93V9.21H83.34V34.77h18.92V31.45H87.14ZM71.59,20.3h0C66.44,19.06,65,18.08,65,15.7c0-2.14,1.89-3.59,4.71-3.59a12.06,12.06,0,0,1,7.07,2.55l2-2.83a14.1,14.1,0,0,0-9-3c-5.06,0-8.59,3-8.59,7.27,0,4.6,3,6.19,8.46,7.52C74.51,24.74,76,25.78,76,28.11s-2,3.77-5.09,3.77a12.34,12.34,0,0,1-8.3-3.26l-2.25,2.69a15.94,15.94,0,0,0,10.42,3.85c5.48,0,9-2.95,9-7.51C79.75,23.79,77.47,21.72,71.59,20.3ZM195.7,9.22l-7.69,12-7.64-12h-4.46L186,24.67V34.78h3.84V24.55L200,9.22Zm-64.63,3.46h8.37v22.1h3.84V12.68h8.37V9.22H131.08ZM169.41,24.8c3.86-1.07,6-3.77,6-7.63,0-4.91-3.59-8-9.38-8H154.67V34.76h3.8V25.58h6.45l6.48,9.2h4.44l-7-9.82Zm-10.95-2.5V12.6h7.17c3.74,0,5.88,1.77,5.88,4.84s-2.29,4.86-5.84,4.86Z" fill="#ffffff" class="__sntry__"></path></svg>
|
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
6
assets/vercel.svg
Normal file
6
assets/vercel.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 5.2 KiB |
|
@ -1 +0,0 @@
|
||||||
LIVEBLOCKS_PUBLIC_API_KEY=pk_live_1LJGGaqBSNLjLT-4Jalkl-U9
|
|
21
yarn.lock
21
yarn.lock
|
@ -9341,7 +9341,7 @@ jose@^1.27.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
"@panva/asn1.js" "^1.0.0"
|
"@panva/asn1.js" "^1.0.0"
|
||||||
|
|
||||||
jpeg-js@^0.4.2:
|
jpeg-js@^0.4.1, jpeg-js@^0.4.2:
|
||||||
version "0.4.3"
|
version "0.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.3.tgz#6158e09f1983ad773813704be80680550eff977b"
|
resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.3.tgz#6158e09f1983ad773813704be80680550eff977b"
|
||||||
integrity sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==
|
integrity sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==
|
||||||
|
@ -11183,6 +11183,11 @@ only@~0.0.2:
|
||||||
resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4"
|
resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4"
|
||||||
integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=
|
integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=
|
||||||
|
|
||||||
|
opentype.js@^0.4.3:
|
||||||
|
version "0.4.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/opentype.js/-/opentype.js-0.4.11.tgz#281a2390639cc15931c955d8d63c14a7c7772b41"
|
||||||
|
integrity sha1-KBojkGOcwVkxyVXY1jwUp8d3K0E=
|
||||||
|
|
||||||
optionator@^0.8.1:
|
optionator@^0.8.1:
|
||||||
version "0.8.3"
|
version "0.8.3"
|
||||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
|
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
|
||||||
|
@ -11711,6 +11716,11 @@ plist@^3.0.1:
|
||||||
base64-js "^1.5.1"
|
base64-js "^1.5.1"
|
||||||
xmlbuilder "^9.0.7"
|
xmlbuilder "^9.0.7"
|
||||||
|
|
||||||
|
pngjs@^3.3.1:
|
||||||
|
version "3.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
|
||||||
|
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
|
||||||
|
|
||||||
pngjs@^5.0.0:
|
pngjs@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb"
|
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb"
|
||||||
|
@ -11975,6 +11985,15 @@ pupa@^2.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
escape-goat "^2.0.0"
|
escape-goat "^2.0.0"
|
||||||
|
|
||||||
|
pureimage@^0.3.6:
|
||||||
|
version "0.3.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/pureimage/-/pureimage-0.3.6.tgz#3ab6070e2779193a8767fc9b657d41c6894b070f"
|
||||||
|
integrity sha512-Wtk+QdlB1X7wnfaXads+5i6tI95dNMyR7Hq9Q0qmEOXiG38JvPRcAISSzuSVGXPlgi54VFzl26ic8UpT6GLs6g==
|
||||||
|
dependencies:
|
||||||
|
jpeg-js "^0.4.1"
|
||||||
|
opentype.js "^0.4.3"
|
||||||
|
pngjs "^3.3.1"
|
||||||
|
|
||||||
q@^1.5.1:
|
q@^1.5.1:
|
||||||
version "1.5.1"
|
version "1.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
||||||
|
|
Loading…
Reference in a new issue