Merge main
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Jared He 2021-11-13 19:50:04 -06:00
commit 39b6be18c0
86 changed files with 372 additions and 27 deletions

View File

@ -23,25 +23,32 @@ steps:
commands:
- npm run lint
- name: build
- name: optimize-images
image: node:16
depends_on:
- install-deps
commands:
- USE_LDAP=true npm run build:web
- npm run build:images
- name: generate-calendar
image: node:16
depends_on:
- install-deps
commands:
- npm run generate:calendar
- npm run build:calendar
- name: build
image: node:16
depends_on:
- optimize-images
commands:
- USE_LDAP=true npm run build:web
- name: export
image: node:16
depends_on:
- build
- generate-calendar
- build
commands:
- npm run export

5
.gitignore vendored
View File

@ -25,4 +25,7 @@ yarn-debug.log*
yarn-error.log*
# Calendar is automatically generated
/public/events.ics
/public/events.ics
# Images should be optimized
/public/images

View File

@ -57,6 +57,15 @@
fill: var(--primary-accent);
}
.card h1,
.card h2,
.card h3,
.card h4 {
font-size: calc(16rem / 16);
margin-top: calc(24rem / 16);
margin-bottom: calc(8rem / 16);
}
@media only screen and (max-width: calc(768rem / 16)) {
.details {
bottom: 0;

View File

@ -0,0 +1,16 @@
---
name: 'Tesla x Waterloo CSC'
short: 'Come join Tesla on Microsoft Teams for an intimate and informal talk with some of their software engineers!'
date: 'November 17 2021 18:00'
online: true
location: 'Zoom'
poster: 'images/events/2021/fall/Tesla-x-Waterloo-CSC.png'
registerLink: https://bit.ly/tesla-x-csc-sign-up-form
---
📢 Interested in an internship to help accelerate the worlds transition to sustainable energy? If youre looking to intern at Tesla in Summer 2022 or want to learn more, come join Tesla on Microsoft Teams for an intimate and informal talk with some of their software engineers! 💻 A private resume link to apply for Tesla will be provided on attendance.
📅 Event Date: Wednesday, November 17th from 6:00-7:00 pm ET.
👉 Register using the register button with your University of Waterloo email.
Excited to see you at this tech talk! 📌

View File

@ -0,0 +1,23 @@
---
name: 'Afterhours - Returning from COVID'
short: 'This Afterhours will focus on a discussion about the change from online to in-person interactions and the challenges related to building and rebuilding in-person connections.'
date: 'October 23 2021 20:00'
online: true
location: 'Zoom'
poster: 'images/events/2021/fall/afterhours-returning-from-covid.png'
registerLink: https://bit.ly/csc-afterhours-RfC
---
Everyone is welcome to attend our upcoming Afterhours event! These events give us an opportunity to have a conversation and share our experiences about uncomfortable topics, in addition to advice on how to overcome these obstacles.
Even though we've all been awaiting the end of Covid, as activities and opportunities return to being in-person, the transition can be disorienting and challenging; both speakers and participants will have a chance to share their stories and discuss their experiences. 😊 This event will focus on the change from online to in-person interactions and the challenges related to building and rebuilding in-person connections. 🤝
Registration is not required for attendance, we'll just be sending you a calendar invite, as well as an email reminder on the day of the event.
📅 Event Date: Saturday, October 23rd, 8:00- 9:00pm ET via Zoom 💻
Zoom Link:
https://us06web.zoom.us/j/83120730842?pwd=U1RnUDU1Q2tNOUZwOTZwbDdmSWFiQT09
👉 Sign up using the register button. Alternatively, you can also email us at exec@csclub.uwaterloo.ca.
Hope to see you there! 🌸

View File

@ -0,0 +1,26 @@
---
name: 'Alumni Fireside Chat'
short: 'Life After Uni'
date: 'November 06 2021 19:00'
online: true
location: 'Zoom'
poster: 'images/events/2021/fall/life-after-uni-fireside-chat.png'
registerLink: https://bit.ly/csc-sesoc-alumni-fireside-chat!
---
CSC and SESoc are proud to present the Alumni Fireside Chat!
An Sheng, Linda Wang, Evy Kassirer, Bilal Akhtar, and Nancy Iskander will be talking about their careers, experiences, and various decisions they have made after graduating university. During the event, you will have the opportunity to listen to the discussion, and then ask questions and chat with alumni! 😊
Registration is optional; well just be sending you a reminder on the day of, as well as a calendar invite.
📅 Event Date: Nov.6th 2021, 7-8:30pm ET
💻 Zoom:
Topic: CSC x SESoc Alumni Fireside Chat: Life After Uni
Time: Nov 6, 2021 07:00 PM Eastern Time (US and Canada)
Join Zoom Meeting
https://us06web.zoom.us/j/82525216481?pwd=bW85Qmd0NVdOaXZ3anpNSkhqbEJFQT09
👉 Sign up using the register button. Alternatively, you can also email us at exec@csclub.uwaterloo.ca.
Hope to see you there! 🌸

View File

@ -0,0 +1,26 @@
---
name: 'Succeeding in First Year Academics'
short: 'Come join a panelist of upper years who can give insight on how to better succeed in first year academics.'
date: 'October 30 2021 14:00'
online: true
location: 'Zoom'
poster: 'images/events/2021/fall/succeeding-in-first-year.png'
registerLink: https://bit.ly/csc-first-year-academics
---
Now that midterms have been coming and going, some of you are probably feeling stressed and overwhelmed. Well thats a normal feeling, and youre not alone! Come join a panelist of upper years who understand your suffering, and can give insight on how to better succeed in first year academics.
Registration is optional; well just be sending you a reminder on the day of, as well as a calendar invite.
📅 Event Date: Oct.30th 2021, 2-3pm ET
💻 Zoom:
Topic: CSC: Succeeding in First Year Academics Panel
Time: Oct 30, 2021 02:00 PM Eastern Time (US and Canada)
Join Zoom Meeting
https://us06web.zoom.us/j/89936812638?pwd=V1Q5Zk1idG1vc0JvMXpBMXFTVi85UT09
👉 Sign up using the register button. Alternatively, you can also email us at exec@csclub.uwaterloo.ca.
Hope to see you there! 🌸

View File

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

Before

Width:  |  Height:  |  Size: 906 B

After

Width:  |  Height:  |  Size: 906 B

View File

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

View File

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

View File

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 475 B

After

Width:  |  Height:  |  Size: 475 B

View File

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 836 B

After

Width:  |  Height:  |  Size: 836 B

View File

Before

Width:  |  Height:  |  Size: 425 B

After

Width:  |  Height:  |  Size: 425 B

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

Before

Width:  |  Height:  |  Size: 627 B

After

Width:  |  Height:  |  Size: 627 B

View File

Before

Width:  |  Height:  |  Size: 365 B

After

Width:  |  Height:  |  Size: 365 B

View File

Before

Width:  |  Height:  |  Size: 227 B

After

Width:  |  Height:  |  Size: 227 B

View File

Before

Width:  |  Height:  |  Size: 190 B

After

Width:  |  Height:  |  Size: 190 B

View File

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 220 B

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 323 KiB

After

Width:  |  Height:  |  Size: 323 KiB

View File

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View File

Before

Width:  |  Height:  |  Size: 877 KiB

After

Width:  |  Height:  |  Size: 877 KiB

View File

Before

Width:  |  Height:  |  Size: 907 KiB

After

Width:  |  Height:  |  Size: 907 KiB

View File

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

Before

Width:  |  Height:  |  Size: 246 KiB

After

Width:  |  Height:  |  Size: 246 KiB

View File

Before

Width:  |  Height:  |  Size: 183 KiB

After

Width:  |  Height:  |  Size: 183 KiB

View File

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 87 KiB

View File

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 119 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 MiB

After

Width:  |  Height:  |  Size: 4.2 MiB

View File

Before

Width:  |  Height:  |  Size: 786 KiB

After

Width:  |  Height:  |  Size: 786 KiB

View File

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 200 KiB

View File

Before

Width:  |  Height:  |  Size: 218 KiB

After

Width:  |  Height:  |  Size: 218 KiB

View File

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 847 KiB

After

Width:  |  Height:  |  Size: 847 KiB

View File

Before

Width:  |  Height:  |  Size: 968 KiB

After

Width:  |  Height:  |  Size: 968 KiB

View File

Before

Width:  |  Height:  |  Size: 733 KiB

After

Width:  |  Height:  |  Size: 733 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

Before

Width:  |  Height:  |  Size: 336 KiB

After

Width:  |  Height:  |  Size: 336 KiB

View File

Before

Width:  |  Height:  |  Size: 461 KiB

After

Width:  |  Height:  |  Size: 461 KiB

View File

Before

Width:  |  Height:  |  Size: 277 KiB

After

Width:  |  Height:  |  Size: 277 KiB

View File

Before

Width:  |  Height:  |  Size: 862 KiB

After

Width:  |  Height:  |  Size: 862 KiB

View File

Before

Width:  |  Height:  |  Size: 1012 KiB

After

Width:  |  Height:  |  Size: 1012 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

Before

Width:  |  Height:  |  Size: 526 KiB

After

Width:  |  Height:  |  Size: 526 KiB

View File

Before

Width:  |  Height:  |  Size: 454 KiB

After

Width:  |  Height:  |  Size: 454 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 177 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 897 KiB

After

Width:  |  Height:  |  Size: 897 KiB

View File

Before

Width:  |  Height:  |  Size: 785 KiB

After

Width:  |  Height:  |  Size: 785 KiB

View File

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

View File

Before

Width:  |  Height:  |  Size: 210 KiB

After

Width:  |  Height:  |  Size: 210 KiB

View File

Before

Width:  |  Height:  |  Size: 341 KiB

After

Width:  |  Height:  |  Size: 341 KiB

View File

Before

Width:  |  Height:  |  Size: 223 KiB

After

Width:  |  Height:  |  Size: 223 KiB

View File

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

Before

Width:  |  Height:  |  Size: 738 KiB

After

Width:  |  Height:  |  Size: 738 KiB

View File

Before

Width:  |  Height:  |  Size: 320 KiB

After

Width:  |  Height:  |  Size: 320 KiB

View File

Before

Width:  |  Height:  |  Size: 377 B

After

Width:  |  Height:  |  Size: 377 B

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

Before

Width:  |  Height:  |  Size: 175 B

After

Width:  |  Height:  |  Size: 175 B

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -52,6 +52,7 @@ export async function getMemberImagePath(name: string) {
(await getImage(imgPath + ".jpg")) ??
(await getImage(imgPath + ".png")) ??
(await getImage(imgPath + ".gif")) ??
(await getImage(imgPath + ".jpeg")) ??
placeholder;
return img;
}

162
package-lock.json generated
View File

@ -10,8 +10,11 @@
"@mdx-js/loader": "^1.6.22",
"@mdx-js/react": "^1.6.22",
"@next/mdx": "11.0.1",
"@squoosh/lib": "^0.4.0",
"date-fns": "^2.11.1",
"date-fns-tz": "^1.1.6",
"fs-extra": "^10.0.0",
"image-size": "^1.0.0",
"ldapts": "^3.1.0",
"next": "11.0.1",
"next-mdx-remote": "3.0.4",
@ -22,6 +25,7 @@
"remark-html": "^12.0.0"
},
"devDependencies": {
"@types/fs-extra": "^9.0.13",
"@types/mdx-js__react": "^1.5.3",
"@types/node": "^16.9.1",
"@types/react": "^17.0.14",
@ -991,6 +995,18 @@
"node": ">= 8"
}
},
"node_modules/@squoosh/lib": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@squoosh/lib/-/lib-0.4.0.tgz",
"integrity": "sha512-O1LyugWLZjMI4JZeZMA5vzfhfPjfMZXH5/HmVkRagP8B70wH3uoR7tjxfGNdSavey357MwL8YJDxbGwBBdHp7Q==",
"dependencies": {
"wasm-feature-detect": "^1.2.11",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": " ^12.5.0 || ^14.0.0 || ^16.0.0 "
}
},
"node_modules/@tsconfig/node10": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
@ -1023,6 +1039,15 @@
"@types/node": "*"
}
},
"node_modules/@types/fs-extra": {
"version": "9.0.13",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/hast": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.1.tgz",
@ -1055,9 +1080,9 @@
}
},
"node_modules/@types/node": {
"version": "16.9.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz",
"integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g=="
"version": "16.11.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz",
"integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw=="
},
"node_modules/@types/parse5": {
"version": "5.0.3",
@ -1545,9 +1570,9 @@
}
},
"node_modules/asn1": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
"dependencies": {
"safer-buffer": "~2.1.0"
}
@ -3532,6 +3557,19 @@
"resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
"integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
},
"node_modules/fs-extra": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
"integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -4571,6 +4609,17 @@
"json5": "lib/cli.js"
}
},
"node_modules/jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"dependencies": {
"universalify": "^2.0.0"
},
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/jsx-ast-utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz",
@ -4594,12 +4643,12 @@
}
},
"node_modules/ldapts": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/ldapts/-/ldapts-3.1.0.tgz",
"integrity": "sha512-fFonIR/mMNRnA78nlToOc9Fn7u3lxaGYJMnoO7/Kwfjqxv+5bgYEXVxjTGWCTbbq2JiLLGgyi5IBa7o+5MxOhg==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/ldapts/-/ldapts-3.1.1.tgz",
"integrity": "sha512-RNxTlfiPS4fTN0b7oY0OE4d+E/uVg1nNlK1ZLPFyVsp4Gr8qSclJUWjdJ5W7PUtuiWh7kEEdNq1YAA+abERZZA==",
"dependencies": {
"@types/asn1": "~0.2.0",
"@types/node": "^16.9.1",
"@types/node": "^16.11.6",
"@types/uuid": "~8.3.1",
"asn1": "~0.2.4",
"debug": "~4.3.2",
@ -9028,6 +9077,14 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
"engines": {
"node": ">= 10.0.0"
}
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@ -9177,6 +9234,11 @@
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="
},
"node_modules/wasm-feature-detect": {
"version": "1.2.11",
"resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.2.11.tgz",
"integrity": "sha512-HUqwaodrQGaZgz1lZaNioIkog9tkeEJjrM3eq4aUL04whXOVDRc/o2EGb/8kV0QX411iAYWEqq7fMBmJ6dKS6w=="
},
"node_modules/watchpack": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz",
@ -9198,6 +9260,14 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/web-streams-polyfill": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.1.1.tgz",
"integrity": "sha512-Czi3fG883e96T4DLEPRvufrF2ydhOOW1+1a6c3gNjH2aIh50DNFBdfwh2AKoOf1rXvpvavAoA11Qdq9+BKjE0Q==",
"engines": {
"node": ">= 8"
}
},
"node_modules/webidl-conversions": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
@ -10125,6 +10195,15 @@
"fastq": "^1.6.0"
}
},
"@squoosh/lib": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@squoosh/lib/-/lib-0.4.0.tgz",
"integrity": "sha512-O1LyugWLZjMI4JZeZMA5vzfhfPjfMZXH5/HmVkRagP8B70wH3uoR7tjxfGNdSavey357MwL8YJDxbGwBBdHp7Q==",
"requires": {
"wasm-feature-detect": "^1.2.11",
"web-streams-polyfill": "^3.0.3"
}
},
"@tsconfig/node10": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
@ -10157,6 +10236,15 @@
"@types/node": "*"
}
},
"@types/fs-extra": {
"version": "9.0.13",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/hast": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.1.tgz",
@ -10189,9 +10277,9 @@
}
},
"@types/node": {
"version": "16.9.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz",
"integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g=="
"version": "16.11.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz",
"integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw=="
},
"@types/parse5": {
"version": "5.0.3",
@ -10520,9 +10608,9 @@
}
},
"asn1": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
"requires": {
"safer-buffer": "~2.1.0"
}
@ -12061,6 +12149,16 @@
"resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
"integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
},
"fs-extra": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
"integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -12744,6 +12842,15 @@
"minimist": "^1.2.0"
}
},
"jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"requires": {
"graceful-fs": "^4.1.6",
"universalify": "^2.0.0"
}
},
"jsx-ast-utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz",
@ -12761,12 +12868,12 @@
"dev": true
},
"ldapts": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/ldapts/-/ldapts-3.1.0.tgz",
"integrity": "sha512-fFonIR/mMNRnA78nlToOc9Fn7u3lxaGYJMnoO7/Kwfjqxv+5bgYEXVxjTGWCTbbq2JiLLGgyi5IBa7o+5MxOhg==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/ldapts/-/ldapts-3.1.1.tgz",
"integrity": "sha512-RNxTlfiPS4fTN0b7oY0OE4d+E/uVg1nNlK1ZLPFyVsp4Gr8qSclJUWjdJ5W7PUtuiWh7kEEdNq1YAA+abERZZA==",
"requires": {
"@types/asn1": "~0.2.0",
"@types/node": "^16.9.1",
"@types/node": "^16.11.6",
"@types/uuid": "~8.3.1",
"asn1": "~0.2.4",
"debug": "~4.3.2",
@ -16103,6 +16210,11 @@
"unist-util-is": "^4.0.0"
}
},
"universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@ -16229,6 +16341,11 @@
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="
},
"wasm-feature-detect": {
"version": "1.2.11",
"resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.2.11.tgz",
"integrity": "sha512-HUqwaodrQGaZgz1lZaNioIkog9tkeEJjrM3eq4aUL04whXOVDRc/o2EGb/8kV0QX411iAYWEqq7fMBmJ6dKS6w=="
},
"watchpack": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz",
@ -16243,6 +16360,11 @@
"resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz",
"integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw=="
},
"web-streams-polyfill": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.1.1.tgz",
"integrity": "sha512-Czi3fG883e96T4DLEPRvufrF2ydhOOW1+1a6c3gNjH2aIh50DNFBdfwh2AKoOf1rXvpvavAoA11Qdq9+BKjE0Q=="
},
"webidl-conversions": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",

View File

@ -7,22 +7,26 @@
},
"scripts": {
"dev": "next dev",
"build": "npm run build:web && npm run generate:calendar",
"build": "npm run build:images && npm run build:web && npm run build:calendar",
"build:images": "ts-node ./scripts/optimize-images",
"build:web": "next build",
"build:calendar": "ts-node ./scripts/generate-calendar",
"start": "next start",
"export": "next export",
"lint": "eslint \"{pages,components,lib,hooks,scripts}/**/*.{js,ts,tsx,jsx}\" --quiet",
"lint:fix": "eslint \"{pages,components,lib,hooks,scripts}/**/*.{js,ts,tsx,jsx}\" --quiet --fix",
"generate:calendar": "ts-node ./scripts/generate-calendar",
"check-lockfile": "ts-node ./scripts/check-lockfile"
},
"dependencies": {
"@mdx-js/loader": "^1.6.22",
"@mdx-js/react": "^1.6.22",
"@next/mdx": "11.0.1",
"@squoosh/lib": "^0.4.0",
"date-fns": "^2.11.1",
"date-fns-tz": "^1.1.6",
"ldapts": "^3.1.0",
"fs-extra": "^10.0.0",
"image-size": "^1.0.0",
"next": "11.0.1",
"next-mdx-remote": "3.0.4",
"prettier": "^2.3.0",
@ -32,6 +36,7 @@
"remark-html": "^12.0.0"
},
"devDependencies": {
"@types/fs-extra": "^9.0.13",
"@types/mdx-js__react": "^1.5.3",
"@types/node": "^16.9.1",
"@types/react": "^17.0.14",

107
scripts/optimize-images.ts Normal file
View File

@ -0,0 +1,107 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
// TODO: upgrade libsquoosh once types are available: https://github.com/GoogleChromeLabs/squoosh/issues/1077
import { cpus } from "os";
import path from "path";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { ImagePool } from "@squoosh/lib";
import fse from "fs-extra";
import { default as getImageDimensions } from "image-size";
const SOURCE_DIRECTORY = "images";
const DESTINATION_DIRECTORY = path.join("public", "images");
// directory where Meet the Team headshots are stored, relative to the source directory
const TEAM_IMAGES_DIRECTORY = path.join("team", "");
const IMAGE_MINIMUM_SIZE = 512;
const GET_ENCODER_FROM_EXTENSION: { [imageExtension: string]: string } = {
jpg: "mozjpeg",
jpeg: "mozjpeg",
png: "oxipng",
};
const ENCODER_OPTIONS: { [encoder: string]: Record<string, unknown> } = {
mozjpeg: {},
oxipng: {},
};
void optimizeImages();
export async function optimizeImages() {
const imagePaths = await getFilePathsInDirectory(SOURCE_DIRECTORY);
await fse.emptyDir(DESTINATION_DIRECTORY);
// maximum number of workers is 8 in order to avoid running out of memory
const numberOfWorkers = Math.min(cpus().length, 8);
const imagePool = new ImagePool(numberOfWorkers);
await Promise.all(
imagePaths.map(async (imagePath) => {
const sourcePath = path.join(SOURCE_DIRECTORY, imagePath);
const destinationPath = path.join(DESTINATION_DIRECTORY, imagePath);
const fileExtension = imagePath.split(".").pop() ?? "";
const encoder = GET_ENCODER_FROM_EXTENSION[fileExtension];
if (!encoder) {
await fse.copy(sourcePath, destinationPath);
return;
}
const rawImageFile = await fse.readFile(sourcePath);
const ingestedImage = imagePool.ingestImage(rawImageFile);
const { width, height } = getImageDimensions(rawImageFile);
await ingestedImage.decoded;
const shouldResize =
imagePath.startsWith(TEAM_IMAGES_DIRECTORY) &&
(width ?? 0) > IMAGE_MINIMUM_SIZE &&
(height ?? 0) > IMAGE_MINIMUM_SIZE;
if (width && height && shouldResize) {
const smallerDimension = width < height ? "width" : "height";
// specifying only one dimension maintains the aspect ratio
const preprocessOptions = {
resize: {
enabled: true,
[smallerDimension]: IMAGE_MINIMUM_SIZE,
},
};
await ingestedImage.preprocess(preprocessOptions);
}
const encodeOptions = { [encoder]: ENCODER_OPTIONS[encoder] };
await ingestedImage.encode(encodeOptions);
const encodedImage = await ingestedImage.encodedWith[encoder];
await fse.outputFile(destinationPath, encodedImage.binary);
})
);
await imagePool.close();
}
async function getFilePathsInDirectory(directory: string): Promise<string[]> {
const entries = await fse.readdir(directory, { withFileTypes: true });
return (
await Promise.all(
entries.map(async (entry) => {
if (entry.isDirectory()) {
const subdirectory = path.join(directory, entry.name);
const subentries = await getFilePathsInDirectory(subdirectory);
return subentries.map((subentry) => path.join(entry.name, subentry));
}
return entry.name;
})
)
).flat();
}