mirror of
https://github.com/acid-info/logos-press-engine.git
synced 2025-02-23 14:48:08 +00:00
Merge pull request #226 from acid-info/v1.1-lazylaoding
V1.1 lazylaoding
This commit is contained in:
commit
25727c9e18
1
.gitignore
vendored
1
.gitignore
vendored
@ -38,3 +38,4 @@ next-env.d.ts
|
||||
|
||||
public/rss.xml
|
||||
public/atom*.xml
|
||||
public/images/placeholders/*
|
||||
|
@ -60,6 +60,7 @@
|
||||
"react-player": "^2.12.0",
|
||||
"react-quick-pinch-zoom": "^4.9.0",
|
||||
"react-use": "^17.4.0",
|
||||
"sharp": "^0.33.2",
|
||||
"slugify": "^1.6.6",
|
||||
"typescript": "5.0.4",
|
||||
"use-query-params": "^2.2.1",
|
||||
|
@ -13,11 +13,13 @@ export type PostCardCoverProps = React.ComponentProps<typeof Link> & {
|
||||
imageProps: ResponsiveImageProps
|
||||
imageData: LPE.Image.Document
|
||||
playIcon?: boolean
|
||||
loadDelay?: number
|
||||
}
|
||||
export const PostCardCover: FC<PostCardCoverProps> = ({
|
||||
imageProps,
|
||||
imageData,
|
||||
playIcon,
|
||||
loadDelay = 0,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
@ -25,7 +27,7 @@ export const PostCardCover: FC<PostCardCoverProps> = ({
|
||||
{...props}
|
||||
className={`post-card__cover-image ${props.className}`}
|
||||
>
|
||||
<ResponsiveImage {...imageProps} data={imageData}>
|
||||
<ResponsiveImage {...imageProps} data={imageData} loadDelay={loadDelay}>
|
||||
{playIcon && (
|
||||
<Icon size="small">
|
||||
<UnfilledPlayIcon />
|
||||
|
@ -21,6 +21,7 @@ import { PostCardLabel } from './PostCard.Label'
|
||||
|
||||
export type PostAppearanceProps = {
|
||||
imageProps?: ResponsiveImageProps
|
||||
loadDelay?: number
|
||||
}
|
||||
|
||||
export type PostDataProps = {
|
||||
@ -47,7 +48,7 @@ export type PostCardProps = CommonProps &
|
||||
|
||||
export const PostCard = (_props: PostCardProps) => {
|
||||
const {
|
||||
appearance: { imageProps = {} } = {},
|
||||
appearance: { imageProps = {}, loadDelay = 0 } = {},
|
||||
data: {
|
||||
coverImage = null,
|
||||
date,
|
||||
@ -77,6 +78,7 @@ export const PostCard = (_props: PostCardProps) => {
|
||||
imageProps={imageProps}
|
||||
imageData={coverImage}
|
||||
playIcon={contentType === LPE.PostTypes.Podcast}
|
||||
loadDelay={loadDelay}
|
||||
/>
|
||||
) : (
|
||||
<div className="post-card__cover-image"></div>
|
||||
|
@ -4,7 +4,7 @@ import { SerializedStyles, css } from '@emotion/react'
|
||||
import styled from '@emotion/styled'
|
||||
import React, { useMemo } from 'react'
|
||||
import { LPE } from '../../types/lpe.types'
|
||||
import { chunkArray } from '../../utils/array.utils'
|
||||
import { chunkArray, shuffleArray } from '../../utils/array.utils'
|
||||
import { lsdUtils } from '../../utils/lsd.utils'
|
||||
import { lcm } from '../../utils/math.utils'
|
||||
import { PostCard, PostCardProps } from '../PostCard'
|
||||
@ -54,6 +54,10 @@ export const PostsGrid: React.FC<PostsGridProps> = ({
|
||||
[theme],
|
||||
)
|
||||
|
||||
const loadingDelayEffectIndexes = useMemo(() => {
|
||||
return shuffleArray(items.map((_, i) => i))
|
||||
}, [items])
|
||||
|
||||
return (
|
||||
<Container
|
||||
{...props}
|
||||
@ -64,7 +68,7 @@ export const PostsGrid: React.FC<PostsGridProps> = ({
|
||||
postCardStyles={postCardStyles}
|
||||
>
|
||||
<div className="row">
|
||||
{items.map(({ post, size }) => (
|
||||
{items.map(({ post, size }, index) => (
|
||||
<div key={post.id} className="post-card-wrapper">
|
||||
<PostCard
|
||||
size={size as any}
|
||||
@ -74,6 +78,9 @@ export const PostsGrid: React.FC<PostsGridProps> = ({
|
||||
displayYear={displayYear}
|
||||
displayPodcastShow={displayPodcastShow}
|
||||
data={PostCard.toData(post, shows)}
|
||||
appearance={{
|
||||
loadDelay: loadingDelayEffectIndexes[index] * 100,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import styled from '@emotion/styled'
|
||||
import Image, { ImageLoader, ImageProps } from 'next/image'
|
||||
import Image, { ImageProps } from 'next/image'
|
||||
import React, { useState } from 'react'
|
||||
import { LPE } from '../../types/lpe.types'
|
||||
|
||||
@ -8,6 +8,7 @@ export type ResponsiveImageProps = {
|
||||
nextImageProps?: Partial<ImageProps>
|
||||
fill?: boolean
|
||||
className?: string
|
||||
loadDelay?: number
|
||||
}
|
||||
|
||||
export type Props = {
|
||||
@ -15,9 +16,6 @@ export type Props = {
|
||||
alt?: string
|
||||
} & ResponsiveImageProps
|
||||
|
||||
const unbodyImageLoader: ImageLoader = ({ src, width, quality }) =>
|
||||
`${src}?w=${width}&q=${quality || 75}&auto=format`
|
||||
|
||||
export const ResponsiveImage = ({
|
||||
data,
|
||||
height,
|
||||
@ -25,22 +23,22 @@ export const ResponsiveImage = ({
|
||||
nextImageProps,
|
||||
className,
|
||||
children,
|
||||
loadDelay = 0,
|
||||
}: React.PropsWithChildren<Props>) => {
|
||||
const [loaded, setLoaded] = useState(false)
|
||||
|
||||
const lazyUrl = `${data.url}?blur=200&px=16&auto=format`
|
||||
|
||||
const imageProps: ImageProps = {
|
||||
src: `${data.url}`,
|
||||
width: data.width,
|
||||
height: data.height,
|
||||
alt: data.alt,
|
||||
className: loaded ? 'loaded' : '',
|
||||
onLoad: () => setLoaded(true),
|
||||
onLoad: () => {
|
||||
setTimeout(() => {
|
||||
setLoaded(true)
|
||||
}, loadDelay)
|
||||
},
|
||||
loading: 'lazy',
|
||||
...(data.url.startsWith('https://images.cdn.unbody.io')
|
||||
? { loader: unbodyImageLoader }
|
||||
: {}),
|
||||
...(nextImageProps || {}),
|
||||
style: {
|
||||
width: '100%',
|
||||
@ -57,7 +55,11 @@ export const ResponsiveImage = ({
|
||||
}}
|
||||
>
|
||||
<div className="comment">
|
||||
<img src={lazyUrl} alt={data.alt} title={data.alt} />
|
||||
<img
|
||||
src={data.placeholder?.replace('public/', '/')}
|
||||
alt={data.alt}
|
||||
title={data.alt}
|
||||
/>
|
||||
{children}
|
||||
</div>
|
||||
<div className={imageProps.className}>
|
||||
@ -94,7 +96,7 @@ const Container = styled.div`
|
||||
|
||||
&:last-of-type {
|
||||
opacity: 0;
|
||||
transition: opacity 250ms;
|
||||
transition: opacity 500ms;
|
||||
|
||||
&.loaded {
|
||||
opacity: 1;
|
||||
|
1
src/configs/consts.configs.ts
Normal file
1
src/configs/consts.configs.ts
Normal file
@ -0,0 +1 @@
|
||||
export const POSTS_IMAGE_PLACEHOLDER_DIR = `public/images/placeholders`
|
@ -15,4 +15,10 @@ export const uiConfigs = {
|
||||
numberOfImagesShowInTopResult: 3,
|
||||
numberOfTotalBlocksInListView: 20,
|
||||
},
|
||||
imageRender: {
|
||||
placeholder: {
|
||||
pixelation: 0.5,
|
||||
blur: 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
62
src/services/images.service.ts
Normal file
62
src/services/images.service.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { POSTS_IMAGE_PLACEHOLDER_DIR } from '@/configs/consts.configs'
|
||||
import { uiConfigs } from '@/configs/ui.configs'
|
||||
import {
|
||||
getStrapiImageUrlBySize,
|
||||
transformStrapiImageUrl,
|
||||
} from '@/services/strapi/transformers/utils'
|
||||
import axios from 'axios'
|
||||
import sharp from 'sharp'
|
||||
|
||||
export class PlaceholderService {
|
||||
cache = new Map<string, string>()
|
||||
constructor() {}
|
||||
|
||||
add(key: string, value: string) {
|
||||
this.cache.set(key, value)
|
||||
}
|
||||
|
||||
exists(key: string): boolean {
|
||||
return this.cache.has(key)
|
||||
}
|
||||
|
||||
emptyCache() {
|
||||
this.cache.clear()
|
||||
}
|
||||
|
||||
async pixelate(imagePath: string): Promise<string> {
|
||||
if (imagePath.length === 0 || imagePath.endsWith('.svg')) return ''
|
||||
|
||||
const fileName = imagePath.split('/').pop() as string
|
||||
|
||||
if (this.exists(fileName)) return this.cache.get(fileName) as string
|
||||
|
||||
const filePath = `${POSTS_IMAGE_PLACEHOLDER_DIR}/${fileName}`
|
||||
const thumbnailPath = getStrapiImageUrlBySize('thumbnail', imagePath)
|
||||
const imageUrl = transformStrapiImageUrl(thumbnailPath)
|
||||
const imageBuffer = (
|
||||
await axios({ url: imageUrl, responseType: 'arraybuffer' })
|
||||
).data as Buffer
|
||||
|
||||
try {
|
||||
await sharp(
|
||||
await sharp(imageBuffer)
|
||||
.resize(uiConfigs.imageRender.placeholder.pixelation * 100, null, {
|
||||
kernel: sharp.kernel.cubic,
|
||||
})
|
||||
.toBuffer(),
|
||||
)
|
||||
.resize(uiConfigs.imageRender.placeholder.pixelation * 400, null, {
|
||||
kernel: sharp.kernel.nearest,
|
||||
})
|
||||
.toFile(filePath)
|
||||
|
||||
this.add(fileName, filePath)
|
||||
|
||||
return filePath
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
|
||||
return ''
|
||||
}
|
||||
}
|
@ -19,9 +19,9 @@ export const episodeTransformer: Transformer<
|
||||
transform: async (helpers, data, original, root, ctx) => {
|
||||
return {
|
||||
...data,
|
||||
credits: transformStrapiHtmlContent({
|
||||
credits: await transformStrapiHtmlContent({
|
||||
html: original.attributes.credits || '',
|
||||
}).blocks as LPE.Post.TextBlock[],
|
||||
}).then((c) => c.blocks as LPE.Post.TextBlock[]),
|
||||
channels: original.attributes.channel
|
||||
? await transformChannels(original.attributes.channel)
|
||||
: [],
|
||||
|
@ -15,7 +15,7 @@ export const podcastShowTransformer: Transformer<
|
||||
classes: ['podcast'],
|
||||
objectType: 'PodcastShow',
|
||||
isMatch: (helpers, object) => object.__typename === 'PodcastShowEntity',
|
||||
transform: (helpers, data, original, root, ctx) => {
|
||||
transform: async (helpers, data, original, root, ctx) => {
|
||||
const { id, attributes } = data
|
||||
|
||||
return {
|
||||
@ -25,15 +25,15 @@ export const podcastShowTransformer: Transformer<
|
||||
numberOfEpisodes: 0,
|
||||
url: getPostLink('podcast', { showSlug: attributes.slug }),
|
||||
description: attributes.description,
|
||||
descriptionText: transformStrapiHtmlContent({
|
||||
descriptionText: await transformStrapiHtmlContent({
|
||||
html: attributes.description || '',
|
||||
}).text,
|
||||
}).then((h) => h.text),
|
||||
hosts: attributes.hosts.data.map((host) => ({
|
||||
id: '',
|
||||
name: host.attributes.name,
|
||||
emailAddress: host.attributes.email_address,
|
||||
})),
|
||||
logo: transformStrapiImageData(attributes.logo),
|
||||
logo: await transformStrapiImageData(attributes.logo),
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ export const postTransformer: Transformer<
|
||||
classes: ['post'],
|
||||
objectType: 'Post',
|
||||
isMatch: (helpers, object) => object.__typename === 'PostEntity',
|
||||
transform: (helpers, data, original, root, ctx) => {
|
||||
transform: async (helpers, data, original, root, ctx) => {
|
||||
const { id, attributes } = data
|
||||
|
||||
const type = attributes.type
|
||||
@ -26,7 +26,7 @@ export const postTransformer: Transformer<
|
||||
const isHighlighted = attributes.featured
|
||||
const isDraft = !attributes.publishedAt
|
||||
const coverImage: LPE.Post.Document['coverImage'] =
|
||||
transformStrapiImageData(attributes.cover_image)
|
||||
await transformStrapiImageData(attributes.cover_image)
|
||||
const tags: LPE.Tag.Document[] = attributes.tags.data.map((tag) => ({
|
||||
id: tag.id,
|
||||
name: tag.attributes.name,
|
||||
@ -38,15 +38,15 @@ export const postTransformer: Transformer<
|
||||
emailAddress: author.attributes.email_address,
|
||||
}))
|
||||
|
||||
const summary = transformStrapiHtmlContent({
|
||||
const summary = await transformStrapiHtmlContent({
|
||||
html: attributes.summary || '',
|
||||
}).text
|
||||
}).then((h) => h.text)
|
||||
|
||||
const {
|
||||
blocks: content,
|
||||
toc,
|
||||
text,
|
||||
} = transformStrapiHtmlContent({
|
||||
} = await transformStrapiHtmlContent({
|
||||
html: attributes.body || '',
|
||||
})
|
||||
|
||||
|
@ -14,7 +14,7 @@ export const staticPageTransformer: Transformer<
|
||||
classes: ['static_page'],
|
||||
objectType: 'StaticPage',
|
||||
isMatch: (helpers, object) => object.__typename === 'PageEntity',
|
||||
transform: (helpers, data, original, root, ctx) => {
|
||||
transform: async (helpers, data, original, root, ctx) => {
|
||||
const { id, attributes } = data
|
||||
|
||||
const title = attributes.title
|
||||
@ -22,7 +22,7 @@ export const staticPageTransformer: Transformer<
|
||||
const slug = attributes.slug
|
||||
const description = attributes.description
|
||||
|
||||
const { blocks: content } = transformStrapiHtmlContent({
|
||||
const { blocks: content } = await transformStrapiHtmlContent({
|
||||
html: attributes.body || '',
|
||||
})
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { PlaceholderService } from '@/services/images.service'
|
||||
import { isVercel } from '@/utils/env.utils'
|
||||
import * as htmlParser from 'node-html-parser'
|
||||
import slugify from 'slugify'
|
||||
import { UploadFileEntity } from '../../../lib/strapi/strapi.generated'
|
||||
@ -7,18 +9,27 @@ import { convertToIframe } from '../../../utils/string.utils'
|
||||
let assetsBaseUrl = process.env.NEXT_PUBLIC_ASSETS_BASE_URL ?? ''
|
||||
if (assetsBaseUrl.endsWith('/')) assetsBaseUrl = assetsBaseUrl.slice(1)
|
||||
|
||||
export const transformStrapiImageUrl = (url: string): string =>
|
||||
assetsBaseUrl + url
|
||||
const placeholderService = new PlaceholderService()
|
||||
placeholderService.emptyCache()
|
||||
|
||||
export const transformStrapiImageData = (
|
||||
image:
|
||||
| Pick<UploadFileEntity, 'attributes'>
|
||||
| {
|
||||
data: {
|
||||
attributes: Partial<UploadFileEntity['attributes']>
|
||||
}
|
||||
},
|
||||
): LPE.Image.Document => {
|
||||
// TODO: remove this and move it to a proper place
|
||||
type StrapiImage =
|
||||
| Pick<UploadFileEntity, 'attributes'>
|
||||
| {
|
||||
data: {
|
||||
attributes: Partial<UploadFileEntity['attributes']>
|
||||
}
|
||||
}
|
||||
|
||||
export const getStrapiImageUrlBySize = (size: string, url: string): string =>
|
||||
url.replace('/uploads/', `/uploads/${size}_`)
|
||||
|
||||
export const transformStrapiImageUrl = (filePath: string): string =>
|
||||
assetsBaseUrl + filePath
|
||||
|
||||
export const transformStrapiImageData = async (
|
||||
image: StrapiImage,
|
||||
): Promise<LPE.Image.Document> => {
|
||||
const attributes = 'data' in image ? image.data.attributes : image.attributes
|
||||
|
||||
return {
|
||||
@ -27,19 +38,27 @@ export const transformStrapiImageData = (
|
||||
caption: attributes.caption || '',
|
||||
alt: attributes.caption || attributes.alternativeText || '',
|
||||
url: attributes.url ? transformStrapiImageUrl(attributes.url) : '',
|
||||
placeholder: attributes.url
|
||||
? isVercel()
|
||||
? getStrapiImageUrlBySize(
|
||||
'thumbnail',
|
||||
transformStrapiImageUrl(attributes.url),
|
||||
)
|
||||
: await placeholderService.pixelate(attributes.url)
|
||||
: '',
|
||||
}
|
||||
}
|
||||
|
||||
export const transformStrapiHtmlContent = ({
|
||||
export const transformStrapiHtmlContent = async ({
|
||||
html,
|
||||
}: {
|
||||
html: string
|
||||
}): {
|
||||
}): Promise<{
|
||||
toc: LPE.Post.TocItem[]
|
||||
blocks: LPE.Post.ContentBlock[]
|
||||
html: string
|
||||
text: string
|
||||
} => {
|
||||
}> => {
|
||||
const toc: LPE.Post.TocItem[] = []
|
||||
const blocks: LPE.Post.ContentBlock[] = []
|
||||
|
||||
|
@ -24,6 +24,7 @@ export namespace LPE {
|
||||
height: number
|
||||
caption?: string
|
||||
captionHTML?: string
|
||||
placeholder?: string
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,3 +18,17 @@ export const chunkArray = <T>(arr: T[], ...pattern: number[]): T[][] => {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export const shuffleArray = <T>(arr: T[]): T[] => {
|
||||
const result = [...arr]
|
||||
|
||||
for (let i = result.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1))
|
||||
|
||||
const temp = result[i]
|
||||
result[i] = result[j]
|
||||
result[j] = temp
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
191
yarn.lock
191
yarn.lock
@ -658,6 +658,13 @@
|
||||
tslib "^2.6.1"
|
||||
ws "^8.13.0"
|
||||
|
||||
"@emnapi/runtime@^0.45.0":
|
||||
version "0.45.0"
|
||||
resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-0.45.0.tgz#e754de04c683263f34fd0c7f32adfe718bbe4ddd"
|
||||
integrity sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==
|
||||
dependencies:
|
||||
tslib "^2.4.0"
|
||||
|
||||
"@emotion/babel-plugin@^11.10.6":
|
||||
version "11.10.6"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz#a68ee4b019d661d6f37dec4b8903255766925ead"
|
||||
@ -1284,6 +1291,119 @@
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
||||
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
|
||||
|
||||
"@img/sharp-darwin-arm64@0.33.2":
|
||||
version "0.33.2"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.2.tgz#0a52a82c2169112794dac2c71bfba9e90f7c5bd1"
|
||||
integrity sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w==
|
||||
optionalDependencies:
|
||||
"@img/sharp-libvips-darwin-arm64" "1.0.1"
|
||||
|
||||
"@img/sharp-darwin-x64@0.33.2":
|
||||
version "0.33.2"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.2.tgz#982e26bb9d38a81f75915c4032539aed621d1c21"
|
||||
integrity sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg==
|
||||
optionalDependencies:
|
||||
"@img/sharp-libvips-darwin-x64" "1.0.1"
|
||||
|
||||
"@img/sharp-libvips-darwin-arm64@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.1.tgz#81e83ffc2c497b3100e2f253766490f8fad479cd"
|
||||
integrity sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw==
|
||||
|
||||
"@img/sharp-libvips-darwin-x64@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.1.tgz#fc1fcd9d78a178819eefe2c1a1662067a83ab1d6"
|
||||
integrity sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog==
|
||||
|
||||
"@img/sharp-libvips-linux-arm64@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.1.tgz#26eb8c556a9b0db95f343fc444abc3effb67ebcf"
|
||||
integrity sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA==
|
||||
|
||||
"@img/sharp-libvips-linux-arm@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.1.tgz#2a377b959ff7dd6528deee486c25461296a4fa8b"
|
||||
integrity sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ==
|
||||
|
||||
"@img/sharp-libvips-linux-s390x@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.1.tgz#af28ac9ba929204467ecdf843330d791e9421e10"
|
||||
integrity sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ==
|
||||
|
||||
"@img/sharp-libvips-linux-x64@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.1.tgz#4273d182aa51912e655e1214ea47983d7c1f7f8d"
|
||||
integrity sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw==
|
||||
|
||||
"@img/sharp-libvips-linuxmusl-arm64@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.1.tgz#d150c92151cea2e8d120ad168b9c358d09c77ce8"
|
||||
integrity sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg==
|
||||
|
||||
"@img/sharp-libvips-linuxmusl-x64@1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.1.tgz#e297c1a4252c670d93b0f9e51fca40a7a5b6acfd"
|
||||
integrity sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw==
|
||||
|
||||
"@img/sharp-linux-arm64@0.33.2":
|
||||
version "0.33.2"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.2.tgz#af3409f801a9bee1d11d0c7e971dcd6180f80022"
|
||||
integrity sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew==
|
||||
optionalDependencies:
|
||||
"@img/sharp-libvips-linux-arm64" "1.0.1"
|
||||
|
||||
"@img/sharp-linux-arm@0.33.2":
|
||||
version "0.33.2"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.2.tgz#181f7466e6ac074042a38bfb679eb82505e17083"
|
||||
integrity sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA==
|
||||
optionalDependencies:
|
||||
"@img/sharp-libvips-linux-arm" "1.0.1"
|
||||
|
||||
"@img/sharp-linux-s390x@0.33.2":
|
||||
version "0.33.2"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.2.tgz#9c171f49211f96fba84410b3e237b301286fa00f"
|
||||
integrity sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA==
|
||||
optionalDependencies:
|
||||
"@img/sharp-libvips-linux-s390x" "1.0.1"
|
||||
|
||||
"@img/sharp-linux-x64@0.33.2":
|
||||
version "0.33.2"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.2.tgz#b956dfc092adc58c2bf0fae2077e6f01a8b2d5d7"
|
||||
integrity sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A==
|
||||
optionalDependencies:
|
||||
"@img/sharp-libvips-linux-x64" "1.0.1"
|
||||
|
||||
"@img/sharp-linuxmusl-arm64@0.33.2":
|
||||
version "0.33.2"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.2.tgz#10e0ec5a79d1234c6a71df44c9f3b0bef0bc0f15"
|
||||
integrity sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA==
|
||||
optionalDependencies:
|
||||
"@img/sharp-libvips-linuxmusl-arm64" "1.0.1"
|
||||
|
||||
"@img/sharp-linuxmusl-x64@0.33.2":
|
||||
version "0.33.2"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.2.tgz#29e0030c24aa27c38201b1fc84e3d172899fcbe0"
|
||||
integrity sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A==
|
||||
optionalDependencies:
|
||||
"@img/sharp-libvips-linuxmusl-x64" "1.0.1"
|
||||
|
||||
"@img/sharp-wasm32@0.33.2":
|
||||
version "0.33.2"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.2.tgz#38d7c740a22de83a60ad1e6bcfce17462b0d4230"
|
||||
integrity sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ==
|
||||
dependencies:
|
||||
"@emnapi/runtime" "^0.45.0"
|
||||
|
||||
"@img/sharp-win32-ia32@0.33.2":
|
||||
version "0.33.2"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.2.tgz#09456314e223f68e5417c283b45c399635c16202"
|
||||
integrity sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g==
|
||||
|
||||
"@img/sharp-win32-x64@0.33.2":
|
||||
version "0.33.2"
|
||||
resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.2.tgz#148e96dfd6e68747da41a311b9ee4559bb1b1471"
|
||||
integrity sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg==
|
||||
|
||||
"@imgix/js-core@^3.1.3":
|
||||
version "3.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@imgix/js-core/-/js-core-3.8.0.tgz#630bc4fba8cb968d8c0e8298a2be71e39d75b8b8"
|
||||
@ -2328,11 +2448,27 @@ color-name@1.1.3:
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
|
||||
|
||||
color-name@^1.1.4, color-name@~1.1.4:
|
||||
color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
color-string@^1.9.0:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4"
|
||||
integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
|
||||
dependencies:
|
||||
color-name "^1.0.0"
|
||||
simple-swizzle "^0.2.2"
|
||||
|
||||
color@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a"
|
||||
integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==
|
||||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
color-string "^1.9.0"
|
||||
|
||||
colorette@^2.0.16, colorette@^2.0.19:
|
||||
version "2.0.20"
|
||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a"
|
||||
@ -2604,6 +2740,11 @@ detect-libc@^1.0.3:
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
|
||||
integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==
|
||||
|
||||
detect-libc@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d"
|
||||
integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==
|
||||
|
||||
dir-glob@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
||||
@ -3738,6 +3879,11 @@ is-arrayish@^0.2.1:
|
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
|
||||
integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
|
||||
|
||||
is-arrayish@^0.3.1:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
|
||||
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
|
||||
|
||||
is-bigint@^1.0.1:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
|
||||
@ -5220,6 +5366,13 @@ semver@^7.3.7:
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
semver@^7.5.4:
|
||||
version "7.5.4"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
|
||||
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
sentence-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-3.0.4.tgz#3645a7b8c117c787fde8702056225bb62a45131f"
|
||||
@ -5254,6 +5407,35 @@ shallowequal@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
|
||||
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
|
||||
|
||||
sharp@^0.33.2:
|
||||
version "0.33.2"
|
||||
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.33.2.tgz#fcd52f2c70effa8a02160b1bfd989a3de55f2dfb"
|
||||
integrity sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ==
|
||||
dependencies:
|
||||
color "^4.2.3"
|
||||
detect-libc "^2.0.2"
|
||||
semver "^7.5.4"
|
||||
optionalDependencies:
|
||||
"@img/sharp-darwin-arm64" "0.33.2"
|
||||
"@img/sharp-darwin-x64" "0.33.2"
|
||||
"@img/sharp-libvips-darwin-arm64" "1.0.1"
|
||||
"@img/sharp-libvips-darwin-x64" "1.0.1"
|
||||
"@img/sharp-libvips-linux-arm" "1.0.1"
|
||||
"@img/sharp-libvips-linux-arm64" "1.0.1"
|
||||
"@img/sharp-libvips-linux-s390x" "1.0.1"
|
||||
"@img/sharp-libvips-linux-x64" "1.0.1"
|
||||
"@img/sharp-libvips-linuxmusl-arm64" "1.0.1"
|
||||
"@img/sharp-libvips-linuxmusl-x64" "1.0.1"
|
||||
"@img/sharp-linux-arm" "0.33.2"
|
||||
"@img/sharp-linux-arm64" "0.33.2"
|
||||
"@img/sharp-linux-s390x" "0.33.2"
|
||||
"@img/sharp-linux-x64" "0.33.2"
|
||||
"@img/sharp-linuxmusl-arm64" "0.33.2"
|
||||
"@img/sharp-linuxmusl-x64" "0.33.2"
|
||||
"@img/sharp-wasm32" "0.33.2"
|
||||
"@img/sharp-win32-ia32" "0.33.2"
|
||||
"@img/sharp-win32-x64" "0.33.2"
|
||||
|
||||
shebang-command@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
||||
@ -5290,6 +5472,13 @@ signedsource@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/signedsource/-/signedsource-1.0.0.tgz#1ddace4981798f93bd833973803d80d52e93ad6a"
|
||||
integrity sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==
|
||||
|
||||
simple-swizzle@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
|
||||
integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
|
||||
dependencies:
|
||||
is-arrayish "^0.3.1"
|
||||
|
||||
slash@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||
|
Loading…
x
Reference in New Issue
Block a user