Add tweets and headline sponsors to website (#3572)
@@ -5,7 +5,8 @@ we'd like to work with you:
|
||||
|
||||
1. File an issue on GitHub describing the contribution you'd like to make. This
|
||||
will help us to get you started on the right foot.
|
||||
2. Create a single commit that addresses the issue:
|
||||
2. Fork the project, and make your changes in a new branch based off of the
|
||||
`main` branch:
|
||||
1. Follow the project's code style (see below)
|
||||
2. Add enough unit tests to "prove" that your patch is correct
|
||||
3. Update the project documentation as needed (see below)
|
||||
|
||||
@@ -19,6 +19,7 @@ interface Sponsor {
|
||||
url: string;
|
||||
type: 'ORGANIZATION' | 'INDIVIDUAL' | 'FUND';
|
||||
monthlyDonation: number;
|
||||
totalDonations: number;
|
||||
source: 'github' | 'opencollective' | 'manual';
|
||||
tier: Tier | null;
|
||||
}
|
||||
@@ -33,6 +34,7 @@ const tierSponsors: Record<Tier, Sponsor[]> = {
|
||||
url: 'https://tidelift.com/subscription/pkg/npm-cheerio',
|
||||
type: 'FUND',
|
||||
monthlyDonation: 0,
|
||||
totalDonations: 0,
|
||||
source: 'manual',
|
||||
tier: 'headliner',
|
||||
},
|
||||
@@ -43,6 +45,7 @@ const tierSponsors: Record<Tier, Sponsor[]> = {
|
||||
url: 'https://github.com/',
|
||||
type: 'ORGANIZATION',
|
||||
monthlyDonation: 0,
|
||||
totalDonations: 0,
|
||||
source: 'manual',
|
||||
tier: 'headliner',
|
||||
},
|
||||
@@ -53,6 +56,7 @@ const tierSponsors: Record<Tier, Sponsor[]> = {
|
||||
url: 'https://www.airbnb.com/',
|
||||
type: 'ORGANIZATION',
|
||||
monthlyDonation: 0,
|
||||
totalDonations: 0,
|
||||
source: 'manual',
|
||||
tier: 'headliner',
|
||||
},
|
||||
@@ -141,7 +145,7 @@ async function fetchOpenCollectiveSponsors(): Promise<Sponsor[]> {
|
||||
|
||||
const payload = await body.json();
|
||||
|
||||
return payload.data.account.orders.nodes.map((order: any) => {
|
||||
return payload.data.account.orders.nodes.map((order: any): Sponsor => {
|
||||
const donation = order.amount.value * 100;
|
||||
const monthlyDonation =
|
||||
order.frequency === 'YEARLY' ? Math.round(donation / 12) : donation;
|
||||
@@ -160,6 +164,13 @@ async function fetchOpenCollectiveSponsors(): Promise<Sponsor[]> {
|
||||
});
|
||||
}
|
||||
|
||||
function getMonthsActive(date: string): number {
|
||||
const now = new Date();
|
||||
const then = new Date(date);
|
||||
const months = (now.getFullYear() - then.getFullYear()) * 12;
|
||||
return months - then.getMonth() + now.getMonth() + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches GitHub Sponsors data using the GraphQL API.
|
||||
*
|
||||
@@ -207,7 +218,7 @@ async function fetchGitHubSponsors(): Promise<Sponsor[]> {
|
||||
|
||||
// Return an array in the same format as Open Collective
|
||||
return organization.sponsorshipsAsMaintainer.nodes.map(
|
||||
({ sponsor, tier, createdAt }: any) => ({
|
||||
({ sponsor, tier, createdAt }: any): Sponsor => ({
|
||||
createdAt,
|
||||
name: sponsor.name,
|
||||
image: `${sponsor.avatarUrl}&s=128`,
|
||||
@@ -216,6 +227,8 @@ async function fetchGitHubSponsors(): Promise<Sponsor[]> {
|
||||
// Workaround to get the type — fetch a field that only exists on users.
|
||||
sponsor.isViewer === undefined ? 'ORGANIZATION' : 'INDIVIDUAL',
|
||||
monthlyDonation: tier.monthlyPriceInDollars * 100,
|
||||
totalDonations:
|
||||
getMonthsActive(createdAt) * tier.monthlyPriceInDollars * 100,
|
||||
source: 'github',
|
||||
tier: getTierSlug(tier.monthlyPriceInDollars),
|
||||
}),
|
||||
@@ -285,11 +298,12 @@ for (const sponsor of sponsors) {
|
||||
|
||||
for (const tier of Object.values(tierSponsors)) {
|
||||
// Sort order based on total donations
|
||||
tier.sort((a: Sponsor, b: Sponsor) => b.monthlyDonation - a.monthlyDonation);
|
||||
tier.sort((a: Sponsor, b: Sponsor) => b.totalDonations - a.totalDonations);
|
||||
|
||||
// Set all montly donations to 0
|
||||
for (const sponsor of tier) {
|
||||
sponsor.monthlyDonation = 0;
|
||||
sponsor.totalDonations = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,9 @@ Here's an example of how to use the load method:
|
||||
```js
|
||||
import * as cheerio from 'cheerio';
|
||||
|
||||
const $ = cheerio.load('<html><body><h1>Hello, world!</h1></body></html>');
|
||||
const $ = cheerio.load(
|
||||
'<html><head><title>Hello, world!</title></head></html>',
|
||||
);
|
||||
|
||||
console.log($('h1').text());
|
||||
// Output: Hello, world!
|
||||
|
||||
@@ -78,7 +78,7 @@ const config = {
|
||||
label: 'Tutorial',
|
||||
},
|
||||
{
|
||||
to: 'docs/api/',
|
||||
to: 'docs/api',
|
||||
label: 'API',
|
||||
position: 'left',
|
||||
},
|
||||
@@ -102,7 +102,7 @@ const config = {
|
||||
},
|
||||
{
|
||||
label: 'API',
|
||||
to: 'docs/api/',
|
||||
to: 'docs/api',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -221,7 +221,7 @@ const config = {
|
||||
'xml',
|
||||
].map((name) => `/functions/${name}.html`),
|
||||
],
|
||||
to: `/docs/api/`,
|
||||
to: '/docs/api',
|
||||
},
|
||||
],
|
||||
}),
|
||||
@@ -233,16 +233,10 @@ const config = {
|
||||
// TypeDoc options
|
||||
entryPoints: ['../src/batteries.ts'],
|
||||
tsconfig: '../tsconfig.json',
|
||||
plugin: ['./typedoc/typedoc-plugin-class-fns-to-methods.cjs'],
|
||||
readme: 'none',
|
||||
excludePrivate: true,
|
||||
|
||||
externalSymbolLinkMappings: {
|
||||
typescript: {
|
||||
Promise:
|
||||
'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise',
|
||||
URL: 'https://developer.mozilla.org/en-US/docs/Web/API/URL',
|
||||
},
|
||||
domhandler: {
|
||||
Document: 'https://domhandler.js.org/classes/Document.html',
|
||||
Element: 'https://domhandler.js.org/classes/Element.html',
|
||||
|
||||
8252
website/package-lock.json
generated
@@ -17,19 +17,20 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "^3.0.1",
|
||||
"@docusaurus/module-type-aliases": "^2.4.3",
|
||||
"@docusaurus/module-type-aliases": "^3.0.1",
|
||||
"@docusaurus/plugin-client-redirects": "^3.0.1",
|
||||
"@docusaurus/preset-classic": "^3.0.1",
|
||||
"@docusaurus/remark-plugin-npm2yarn": "^2.4.3",
|
||||
"@docusaurus/remark-plugin-npm2yarn": "^3.0.1",
|
||||
"@docusaurus/theme-live-codeblock": "^3.0.1",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"docusaurus-plugin-typedoc": "^0.21.0",
|
||||
"docusaurus-plugin-typedoc": "^0.22.0",
|
||||
"prism-react-renderer": "^2.2.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"typedoc": "^0.25.3",
|
||||
"typedoc-plugin-markdown": "^3.17.1"
|
||||
"typedoc-plugin-markdown": "^3.17.1",
|
||||
"typedoc-plugin-mdn-links": "^3.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@crowdin/cli": "^3.15.0",
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
import styles from './styles.module.css';
|
||||
|
||||
type FeatureItem = {
|
||||
interface FeatureItem {
|
||||
title: string;
|
||||
Svg: React.ComponentType<React.ComponentProps<'svg'>>;
|
||||
description: JSX.Element;
|
||||
};
|
||||
}
|
||||
|
||||
const FeatureList: FeatureItem[] = [
|
||||
{
|
||||
@@ -44,9 +42,9 @@ const FeatureList: FeatureItem[] = [
|
||||
|
||||
function Feature({ title, Svg, description }: FeatureItem) {
|
||||
return (
|
||||
<div className={clsx('col col--4')}>
|
||||
<div className="col col--4">
|
||||
<div className="text--center">
|
||||
<Svg className={styles.featureSvg} role="img" />
|
||||
<Svg height="200" width="200" role="img" />
|
||||
</div>
|
||||
<div className="text--center padding-horiz--md">
|
||||
<h3>{title}</h3>
|
||||
@@ -56,15 +54,13 @@ function Feature({ title, Svg, description }: FeatureItem) {
|
||||
);
|
||||
}
|
||||
|
||||
export default function HomepageFeatures(): JSX.Element {
|
||||
export function HomepageFeatures(): JSX.Element {
|
||||
return (
|
||||
<section className={styles.features}>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
{FeatureList.map((props, idx) => (
|
||||
<Feature key={idx} {...props} />
|
||||
))}
|
||||
</div>
|
||||
<section className="container padding-top--xl ">
|
||||
<div className="row">
|
||||
{FeatureList.map((props, idx) => (
|
||||
<Feature key={idx} {...props} />
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
@@ -1,15 +0,0 @@
|
||||
.features {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 2rem 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.featureSvg {
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.featureSvg > [class~='line'] {
|
||||
stroke: var(--ifm-font-color-base);
|
||||
}
|
||||
49
website/src/components/HomepageSponsors.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import React from 'react';
|
||||
import HeartSvg from '@site/static/img/1F496.svg';
|
||||
|
||||
import Sponsors from '../../sponsors.json';
|
||||
|
||||
export function HeadlineSponsors() {
|
||||
return (
|
||||
<div className="container">
|
||||
<h2 className="text--center">Supported and Backed by</h2>
|
||||
<div className="container row" style={{ justifyContent: 'space-evenly' }}>
|
||||
{Sponsors.headliner.map((sponsor) => (
|
||||
<div className="col col--2 avatar row row--align-center margin-top--sm">
|
||||
<a
|
||||
className="avatar__photo-link avatar__photo avatar__photo--lg"
|
||||
style={{ borderRadius: '10px' }}
|
||||
href={sponsor.url}
|
||||
key={sponsor.name}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<img src={sponsor.image} alt={`${sponsor.name} logo`} />
|
||||
</a>
|
||||
|
||||
<div className="avatar__intro">
|
||||
<div className="avatar__name">{sponsor.name}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<a
|
||||
className="col col--2 avatar row padding--md margin-top--sm"
|
||||
style={{
|
||||
border: '1px solid #eaecef',
|
||||
borderRadius: '10px',
|
||||
color: 'var(--ifm-font-color-base)',
|
||||
}}
|
||||
href="https://github.com/sponsors/cheeriojs"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<HeartSvg className="avatar__photo-link avatar__photo avatar__photo--lg" />
|
||||
|
||||
<div className="avatar__intro">
|
||||
<div className="avatar__name">…and you?</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
175
website/src/components/HomepageTweets.tsx
Normal file
@@ -0,0 +1,175 @@
|
||||
import React from 'react';
|
||||
|
||||
interface TweetItem {
|
||||
id: string;
|
||||
name: string;
|
||||
user: string;
|
||||
date: string;
|
||||
tweet: React.ReactNode;
|
||||
}
|
||||
|
||||
const TweetList = [
|
||||
{
|
||||
id: '628016191928446977',
|
||||
name: 'Axel Rauschmayer',
|
||||
user: 'rauschma',
|
||||
date: '2015-08-03T02:35:00.000Z',
|
||||
tweet: (
|
||||
<>
|
||||
For transforming HTML via Node.js scripts, @mattmueller's cheerio works
|
||||
really well.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: '1616150822932385792',
|
||||
name: 'Valeri Karpov',
|
||||
user: 'code_barbarian',
|
||||
date: '2023-01-19T19:09:00.000Z',
|
||||
tweet: (
|
||||
<>
|
||||
Cheerio is a weird npm module: most devs have never heard of it, but I
|
||||
rarely build an app without it.
|
||||
<br />
|
||||
<br />
|
||||
So much utility for quick and easy HTML transformations.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: '1545481085865320449',
|
||||
name: 'Thomas Boutell',
|
||||
user: 'boutell',
|
||||
date: '2021-07-08T19:52:00.000Z',
|
||||
tweet: (
|
||||
<>
|
||||
You probably shouldn't use jQuery, but if you're great at jQuery, you're
|
||||
going to be really popular on server-side projects that need web
|
||||
scraping or HTML transformation. "npm install cheerio" ahoy!
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: '552311181760008192',
|
||||
name: 'Alistair G MacDonald',
|
||||
user: 'html5js',
|
||||
date: '2015-01-06T03:50:00.000Z',
|
||||
tweet: (
|
||||
<>
|
||||
Looking for a faster, cleaner alternative to basic JSDOM? Try Cheerio!
|
||||
#npm #javascript #nodejs
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: '1466753169900273667',
|
||||
name: 'Yogini Bende',
|
||||
user: 'hey_yogini',
|
||||
date: '2021-12-03T12:56:00.000Z',
|
||||
tweet: 'Cheerio is 🔥',
|
||||
},
|
||||
{
|
||||
id: '936243649234591744',
|
||||
name: 'Jonny Frodsham',
|
||||
user: 'jonnyfrodsham',
|
||||
date: '2017-11-30T14:40:00.000Z',
|
||||
tweet: (
|
||||
<>
|
||||
Needed to do a quick web scrape in Node for a demo. Seems like I'm back
|
||||
using jQuery in the super timesaving cheerio npm package 😯
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: '264033999272439809',
|
||||
name: 'Thomas Steiner',
|
||||
user: 'tomayac',
|
||||
date: '2012-11-01T15:59:00.000Z',
|
||||
tweet: (
|
||||
<>
|
||||
npm install cheerio. That's the #jQuery DOM API for #nodeJS essentially.
|
||||
Thanks, @MattMueller
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: '1403139379757977602',
|
||||
name: 'Mike Pennisi',
|
||||
user: 'JugglinMike',
|
||||
date: '2021-06-11T04:57:00.000Z',
|
||||
tweet: (
|
||||
<>
|
||||
Thank you @fb55 for tirelessly pushing Cheerio to version 1.0. That
|
||||
library helps so many developers expand their horizons beyond the
|
||||
browser, and you've been making it possible for a decade!
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: '1186972238190403587',
|
||||
name: 'Matthew Phillips',
|
||||
user: 'matthewcp',
|
||||
date: '2019-10-23T12:46:00.000Z',
|
||||
tweet: (
|
||||
<>
|
||||
Cheerio is (still) such a useful tool for manipulating HTML. Shout to
|
||||
@MattMueller for saving me an untold amount of time over the years.
|
||||
</>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
function Tweet({ id, name, user, date, tweet }: TweetItem) {
|
||||
const formattedDate = new Date(date).toLocaleDateString(undefined, {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
hour12: true,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="card-demo col col--4 margin-vert--sm">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<div className="avatar">
|
||||
<img
|
||||
className="avatar__photo"
|
||||
src={`https://unavatar.io/${user}`}
|
||||
alt={`${name}'s avatar`}
|
||||
loading="lazy"
|
||||
/>
|
||||
<div className="avatar__intro">
|
||||
<div className="avatar__name">{name}</div>
|
||||
<small className="avatar__subtitle">@{user}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card__body">{tweet}</div>
|
||||
<time className="card__footer">
|
||||
<a
|
||||
href={`https://twitter.com/${user}/status/${id}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{formattedDate}
|
||||
</a>
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function HomepageTweets() {
|
||||
return (
|
||||
<div className="container padding-vert--xl">
|
||||
<h2 className="text--center">What Our Users Say</h2>
|
||||
<div className="row">
|
||||
{TweetList.map((props) => (
|
||||
<Tweet {...props} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
import DancingMan from '../../static/img/1F57A.svg';
|
||||
import SparklingHeart from '../../static/img/1F496.svg';
|
||||
import Lightning from '../../static/img/26A1.svg';
|
||||
|
||||
# Attribution
|
||||
|
||||
<center>
|
||||
|
||||

|
||||

|
||||

|
||||
<DancingMan height="200px" />
|
||||
<SparklingHeart height="200px" />
|
||||
<Lightning height="200px" />
|
||||
|
||||
</center>
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/**
|
||||
* CSS files with the .module.css suffix will be treated as CSS modules
|
||||
* and scoped locally.
|
||||
*/
|
||||
|
||||
.heroBanner {
|
||||
padding: 4rem 0;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 996px) {
|
||||
.heroBanner {
|
||||
padding: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
@@ -1,27 +1,22 @@
|
||||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
import Link from '@docusaurus/Link';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import Layout from '@theme/Layout';
|
||||
import HomepageFeatures from '@site/src/components/HomepageFeatures';
|
||||
|
||||
import styles from './index.module.css';
|
||||
import { HomepageFeatures } from '../components/HomepageFeatures';
|
||||
import { HomepageTweets } from '../components/HomepageTweets';
|
||||
import { HeadlineSponsors } from '../components/HomepageSponsors';
|
||||
|
||||
function HomepageHeader() {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
return (
|
||||
<header className={clsx('hero hero--primary', styles.heroBanner)}>
|
||||
<header className="hero hero--primary padding-vert--xl text--center">
|
||||
<div className="container">
|
||||
<h1 className="hero__title">{siteConfig.title}</h1>
|
||||
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
||||
<div className={styles.buttons}>
|
||||
<Link
|
||||
className="button button--secondary button--lg"
|
||||
to="/docs/intro"
|
||||
>
|
||||
Get Started!
|
||||
</Link>
|
||||
</div>
|
||||
<Link className="button button--secondary button--lg" to="/docs/intro">
|
||||
Get Started!
|
||||
</Link>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
@@ -35,9 +30,10 @@ export default function Home(): JSX.Element {
|
||||
description={siteConfig.tagline}
|
||||
>
|
||||
<HomepageHeader />
|
||||
<main>
|
||||
<HomepageFeatures />
|
||||
</main>
|
||||
<HomepageFeatures />
|
||||
<hr className="margin-vert--xl" />
|
||||
<HeadlineSponsors />
|
||||
<HomepageTweets />
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<path fill="#FCEA2B" d="M51.8824,18.9358c0.0862,0.4637,0.5487,0.8419,1.1677,0.9554l7.0663,1.2955 c0.3309,0.0607,0.3347,0.4049,0.0038,0.4656c-1.8753,0.3438-5.352,0.9812-7.074,1.2969c-0.619,0.1135-1.0775,0.4912-1.1637,0.9548 l-1.8733,10.0742c-0.0515,0.2771-0.5978,0.2771-0.6494,0l-1.8733-10.074c-0.0862-0.4637-0.5448-0.8414-1.1639-0.9549 c-1.722-0.3156-5.1988-0.9529-7.0743-1.2967c-0.3309-0.0607-0.3309-0.4042,0-0.4649c1.8755-0.3438,5.3525-0.9813,7.0745-1.2972 c0.619-0.1135,0.6956-0.6577,0.7818-1.1213l1.4736-8.1159c0.0515-0.2771,1.3793-2.0699,1.4308-1.7927 C50.592,11.9961,51.767,18.3151,51.8824,18.9358z"/>
|
||||
<path fill="#F1B31C" d="M50.0748,33.9782l1.2105-8.8711c-1.3126-2.6598-2.2831-5.4195-2.8942-7.3846l-0.1666,1.221 c-0.0633,0.4634-0.3994,0.8408-0.8535,0.9543c-1.263,0.3156-3.8133,0.9528-5.1889,1.2965c-0.2427,0.0606-0.2427,0.404,0,0.4647 c1.3756,0.3437,3.9257,0.9807,5.1887,1.2961c0.4541,0.1134,0.7904,0.491,0.8537,0.9544l1.374,10.0688 C49.6363,34.2552,50.037,34.2552,50.0748,33.9782z"/>
|
||||
</g>
|
||||
<g class="line" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2">
|
||||
<g class="line" fill="none" stroke="var(--ifm-font-color-base)" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2">
|
||||
<path d="M29.1505,50.0504L36,58.5397l20.7339-25.6975l-0.0043-0.0034C58.4597,30.6942,59.5,27.9699,59.5,25"/>
|
||||
<path d="M45.2493,12.6217C41.245,13.183,37.8497,15.6419,36,19.0598C33.8861,15.1536,29.7533,12.5,25,12.5 c-6.9036,0-12.5,5.5964-12.5,12.5c0,2.9699,1.0403,5.6942,2.7703,7.8387l-0.0043,0.0034l2.1605,2.6777"/>
|
||||
<path d="M22.5556,32.4499l1.5469-8.0604l0.5052,3.0162c0.081,0.4824,1.6827,10.0429,1.6827,10.0429 c0.1889,1.1269,1.1869,2.0334,2.5426,2.3092L37,41.4198l-8.1728,1.663c-1.3523,0.2752-2.3482,1.1812-2.5369,2.3084l-2.1876,13.0587 l-2.1876-13.0582c-0.1889-1.1272-1.1848-2.0333-2.5372-2.3085l-8.173-1.6629l8.1735-1.6634 c1.352-0.2753,2.2663-1.8467,2.455-2.9736"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.6 KiB |
@@ -3,7 +3,7 @@
|
||||
<circle cx="33.9688" cy="8.0938" r="3" fill="#7FBCD4" stroke="none"/>
|
||||
<path fill="#7FBCD4" stroke="none" d="M42,18.0005L45,36l-1,14l-2.2998,17h-3.2998L39,51V38h-2l-5,9l2,11h-3l-4-12l6-14l-2-10l-2.7227-1.3428 c0,0-1.5986-1.6943-1.8183-1.6572c-1.1348,0.1909-6.0811,1.1738-6.7715,1.125c-2.6562-0.1875-4-2.125-7.6875-6.1245 c-1.4629-1.5864,0.375-2.6255,0.375-2.6255L19,18.0005l10-2l6-1h6l7,1l12,2c0,0-0.0156,2.248-2,2 C42,18.0005,42,18.0005,42,18.0005z"/>
|
||||
</g>
|
||||
<g class="line" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-width="2">
|
||||
<g class="line" fill="none" stroke="var(--ifm-font-color-base)" stroke-miterlimit="10" stroke-width="2">
|
||||
<circle cx="33.9688" cy="8.0938" r="3" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12.875,12l4.6963,4.6006c0.7861,0.7695,2.3115,1.2231,3.3896,1.0073l6.0782-1.2158c1.0781-0.2158,2.8584-0.4609,3.955-0.5454 l9.0118-0.6934c1.0966-0.0845,2.8808,0.003,3.9638,0.1944L59,18"/>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M29,20c0,0,0.4502,0.4502,1,1c0.5498,0.5498,1.1758,1.8823,1.3926,2.9609l1.2148,6.0782c0.2168,1.0781,0.0381,2.788-0.3945,3.7988 l-4.4258,10.3242c-0.4326,1.0108-0.5019,2.6914-0.1543,3.7354l2.7344,8.205C30.7148,57.1465,31.6748,58,32.5,58 c0.8252,0,1.3389-0.8857,1.1426-1.9678l-1.2852-7.0644c-0.1963-1.0821,0.0801-2.7549,0.6133-3.7158l3.0576-5.504 C36.5625,38.7871,37.4492,38,38,38c0.5498,0,1,0.9004,1,2v9c0,1.0996-0.0342,2.8994-0.0752,3.999l-0.4492,12.002 C38.4346,66.1006,39.1426,67,40.0508,67c0.9072,0,1.7705-0.8916,1.918-1.9824l1.7626-13.0352 c0.1475-1.0908,0.3331-2.8799,0.4112-3.9775l0.7148-10.0098c0.0781-1.0976-0.0136-2.8818-0.2051-3.9648L42,19"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@@ -2,7 +2,7 @@
|
||||
<g id="color">
|
||||
<path fill="#FCEA2B" stroke="none" d="M48.143,3.7261L16.316,37.8507c-0.6029,0.6465-0.1141,1.6589,0.801,1.6589h19.1066L19.1503,67.0482 c-0.1662,0.2681,0.215,0.5364,0.4424,0.3114l36.0628-35.704c0.6436-0.6372,0.1626-1.6882-0.7725-1.6882H36.3826L48.143,3.7261z"/>
|
||||
</g>
|
||||
<g class="line" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2">
|
||||
<g class="line" fill="none" stroke="var(--ifm-font-color-base)" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2">
|
||||
<path d="M48.1628,4.4406L16.3224,37.7817c-0.6174,0.6465-0.1168,1.6589,0.8201,1.6589h19.0829l-18.304,28.8333l37.7269-36.4785 c0.659-0.6372,0.1665-1.6882-0.791-1.6882H36.3846L48.1628,4.4406z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 705 B After Width: | Height: | Size: 724 B |
27
website/static/img/orange-c-animated.svg
Normal file
@@ -0,0 +1,27 @@
|
||||
<svg width="400" height="400" viewBox="0 0 400 400" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
#c {
|
||||
animation: grow 1s;
|
||||
transform-origin: 200px 200px;
|
||||
}
|
||||
|
||||
@keyframes grow {
|
||||
from {
|
||||
transform: scale(0.25) rotate(-60deg);
|
||||
}
|
||||
to {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<rect width="400" height="400" rx="30" fill="#E88C1F">
|
||||
<animate attributeName="opacity" from="0.3" to="1" dur="0.75s" begin="0s" fill="freeze" />
|
||||
</rect>
|
||||
<path
|
||||
id="c"
|
||||
d="m 312 122.5 c 0.2 -2.1 -1.4 -3.1 -2.5 -4.5 c -13.1 -15.8 -29.1 -27.9 -47.6 -36.3 c -10.6 -4.8 -22 -8 -33.9 -9.4 c -11.4 -1.4 -22.6 -2.1 -34 -0.8 c -14.5 1.6 -28.3 5.8 -41.5 12 c -21.1 9.9 -38 24.9 -51.3 43.6 c -8.5 11.8 -14.6 25.1 -18.2 39.4 c -3.7 14.6 -5.8 29.3 -4.2 44.5 c 1.1 10.4 2.6 20.5 5.7 30.5 c 4.5 14.6 11.8 27.9 21.1 39.9 c 10.6 13.7 23.4 25.1 38.5 33.5 c 17.5 9.7 36.3 15.5 56.4 16.7 c 7.4 0.4 14.8 0.5 22 -0.4 c 8.6 -1 17.2 -2.9 25.6 -5.5 c 10.4 -3.3 20.2 -7.6 29.4 -13.3 c 13.2 -8.2 25.1 -18 34.4 -31.1 c -21.9 -16.5 -43.8 -32.8 -65.9 -49.4 c -10.1 11.4 -22.4 17.2 -37.4 17.1 c -13.6 -0.2 -25.1 -5.7 -33.9 -15.6 c -17.8 -20 -15.2 -51.1 5.8 -68 c 18.7 -15.1 49.3 -13 65.5 7.2 c 22 -16.5 44 -33 66 -50.1 z"
|
||||
fill="#FFF"
|
||||
stroke="#000"
|
||||
stroke-width="18"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* TypeDoc plugin to convert functions that are children of classes or
|
||||
* interfaces to methods.
|
||||
*
|
||||
* They are functionally equivalent, and presenting them this way makes it
|
||||
* easier to consume the docs (as categories won't be split).
|
||||
*/
|
||||
|
||||
/* eslint-disable jsdoc/no-types */
|
||||
const td = require('typedoc');
|
||||
|
||||
/** @param {td.Application} app - The app. */
|
||||
exports.load = function (app) {
|
||||
app.converter.on(td.Converter.EVENT_CREATE_DECLARATION, updateFnsToMethods);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {td.Context} context - The context.
|
||||
* @param {td.DeclarationReflection} reflection - The reflection.
|
||||
*/
|
||||
function updateFnsToMethods(context, reflection) {
|
||||
if (
|
||||
reflection.kindOf(td.ReflectionKind.Function) &&
|
||||
reflection.parent?.kindOf(td.ReflectionKind.ClassOrInterface)
|
||||
) {
|
||||
// Unset the `Function` flag, set the `Method` flag.
|
||||
reflection.kind ^= td.ReflectionKind.Function;
|
||||
reflection.kind |= td.ReflectionKind.Method;
|
||||
}
|
||||
}
|
||||