├── .github
└── workflows
│ └── create-release.yml
├── .gitignore
├── .nvmrc
├── README.md
├── blobbee
├── blobbee.svg
├── blobbee_3c.svg
├── blobbee_aww.svg
├── blobbee_bandaid.svg
├── blobbee_bellhop.svg
├── blobbee_blep.svg
├── blobbee_blush.svg
├── blobbee_blush_hide.svg
├── blobbee_boop.svg
├── blobbee_bot.svg
├── blobbee_bottom.svg
├── blobbee_box.svg
├── blobbee_cat_ears.svg
├── blobbee_checkmark.svg
├── blobbee_chilli_face.svg
├── blobbee_conductor.svg
├── blobbee_conductor_whistle.svg
├── blobbee_cowboy.svg
├── blobbee_cross.svg
├── blobbee_cross_stitch.svg
├── blobbee_cutlery.svg
├── blobbee_cutlery_eyes.svg
├── blobbee_drake_dislike.svg
├── blobbee_drake_like.svg
├── blobbee_eye_roll.svg
├── blobbee_eyes.svg
├── blobbee_facepalm.svg
├── blobbee_filament.svg
├── blobbee_fingerguns.svg
├── blobbee_fingerguns_cool.svg
├── blobbee_flag_ace.svg
├── blobbee_flag_agender.svg
├── blobbee_flag_aro.svg
├── blobbee_flag_bi.svg
├── blobbee_flag_france.svg
├── blobbee_flag_lesbian.svg
├── blobbee_flag_nb.svg
├── blobbee_flag_pan.svg
├── blobbee_flag_rainbow.svg
├── blobbee_flag_scotland.svg
├── blobbee_flag_trans.svg
├── blobbee_fox_ears.svg
├── blobbee_gamer.svg
├── blobbee_gamer_angry.svg
├── blobbee_grimace.svg
├── blobbee_grumpy.svg
├── blobbee_halo.svg
├── blobbee_happy.svg
├── blobbee_hat_tip.svg
├── blobbee_heart.svg
├── blobbee_heart_black.svg
├── blobbee_heart_blue.svg
├── blobbee_heart_eyes.svg
├── blobbee_heart_green.svg
├── blobbee_heart_orange.svg
├── blobbee_heart_purple.svg
├── blobbee_heart_red.svg
├── blobbee_heart_yellow.svg
├── blobbee_hmph.svg
├── blobbee_hold.svg
├── blobbee_hug.svg
├── blobbee_hug_blue_dagn.svg
├── blobbee_hug_bot.svg
├── blobbee_hug_bot_heart.svg
├── blobbee_hug_bread.svg
├── blobbee_hug_bread_heart.svg
├── blobbee_hug_bun.svg
├── blobbee_hug_bun_heart.svg
├── blobbee_hug_cat.svg
├── blobbee_hug_cat_heart.svg
├── blobbee_hug_dagn.svg
├── blobbee_hug_dlr.svg
├── blobbee_hug_dlr_heart.svg
├── blobbee_hug_dog.svg
├── blobbee_hug_dog_heart.svg
├── blobbee_hug_fox.svg
├── blobbee_hug_fox_heart.svg
├── blobbee_hug_heart.svg
├── blobbee_hug_mouse.svg
├── blobbee_hug_mouse_heart.svg
├── blobbee_hug_neomouse.svg
├── blobbee_hug_neomouse_heart.svg
├── blobbee_hug_potato.svg
├── blobbee_hug_potato_heart.svg
├── blobbee_hug_ssb.svg
├── blobbee_hug_wolf.svg
├── blobbee_hug_wolf_heart.svg
├── blobbee_kisser.svg
├── blobbee_knife.svg
├── blobbee_laptop.svg
├── blobbee_laugh.svg
├── blobbee_laugh_sweat.svg
├── blobbee_laugh_tears.svg
├── blobbee_lego.svg
├── blobbee_magnifying_glass.svg
├── blobbee_meeple.svg
├── blobbee_meeting.svg
├── blobbee_megaphone.svg
├── blobbee_mug.svg
├── blobbee_neurodiverse.svg
├── blobbee_no_spoons.svg
├── blobbee_nom_cookie.svg
├── blobbee_nom_homework.svg
├── blobbee_nom_potato.svg
├── blobbee_party.svg
├── blobbee_pat.svg
├── blobbee_peek.svg
├── blobbee_pensive.svg
├── blobbee_pleading.svg
├── blobbee_pleased.svg
├── blobbee_popcorn.svg
├── blobbee_referee.svg
├── blobbee_sad.svg
├── blobbee_scream.svg
├── blobbee_scream_angry.svg
├── blobbee_shrug.svg
├── blobbee_sleep.svg
├── blobbee_smug.svg
├── blobbee_snuggle.svg
├── blobbee_snuggle_fox.svg
├── blobbee_sob.svg
├── blobbee_sob_loud.svg
├── blobbee_spoons.svg
├── blobbee_surprise.svg
├── blobbee_think.svg
├── blobbee_thought_bubble.svg
├── blobbee_train_wagon.svg
├── blobbee_upside_down.svg
├── blobbee_uwu.svg
├── blobbee_verified.svg
├── blobbee_wave.svg
├── blobbee_wink.svg
├── blobbee_woem.svg
├── blobbee_woozy.svg
└── blobbee_zipped_mouth.svg
├── fox
└── fox_plead_collar.svg
├── misc
└── thought_bubble_close.svg
├── neobread
├── neobread.svg
├── neobread_3c.svg
├── neobread_aww.svg
├── neobread_bandaid.svg
├── neobread_bee.svg
├── neobread_blep.svg
├── neobread_blush.svg
├── neobread_blush_hide.svg
├── neobread_boop.svg
├── neobread_bot.svg
├── neobread_bottom.svg
├── neobread_box.svg
├── neobread_cat_ears.svg
├── neobread_checkmark.svg
├── neobread_chilli_face.svg
├── neobread_cowboy.svg
├── neobread_cross.svg
├── neobread_cross_stitch.svg
├── neobread_cutlery.svg
├── neobread_cutlery_eyes.svg
├── neobread_drake_dislike.svg
├── neobread_drake_like.svg
├── neobread_eye_roll.svg
├── neobread_eyes.svg
├── neobread_facepalm.svg
├── neobread_filament.svg
├── neobread_fingerguns.svg
├── neobread_fingerguns_cool.svg
├── neobread_flag_ace.svg
├── neobread_flag_agender.svg
├── neobread_flag_aro.svg
├── neobread_flag_bi.svg
├── neobread_flag_lesbian.svg
├── neobread_flag_nb.svg
├── neobread_flag_pan.svg
├── neobread_flag_rainbow.svg
├── neobread_flag_trans.svg
├── neobread_fox_ears.svg
├── neobread_gamer.svg
├── neobread_gamer_angry.svg
├── neobread_grimace.svg
├── neobread_grumpy.svg
├── neobread_halo.svg
├── neobread_happy.svg
├── neobread_hat_tip.svg
├── neobread_heart.svg
├── neobread_heart_black.svg
├── neobread_heart_blue.svg
├── neobread_heart_eyes.svg
├── neobread_heart_green.svg
├── neobread_heart_orange.svg
├── neobread_heart_purple.svg
├── neobread_heart_red.svg
├── neobread_heart_yellow.svg
├── neobread_hmph.svg
├── neobread_hold.svg
├── neobread_hug.svg
├── neobread_hug_bee.svg
├── neobread_hug_bee_heart.svg
├── neobread_hug_blue_dagn.svg
├── neobread_hug_bun.svg
├── neobread_hug_bun_heart.svg
├── neobread_hug_cat.svg
├── neobread_hug_cat_heart.svg
├── neobread_hug_dagn.svg
├── neobread_hug_dlr.svg
├── neobread_hug_dlr_heart.svg
├── neobread_hug_dog.svg
├── neobread_hug_dog_heart.svg
├── neobread_hug_fox.svg
├── neobread_hug_fox_heart.svg
├── neobread_hug_heart.svg
├── neobread_hug_mouse.svg
├── neobread_hug_mouse_heart.svg
├── neobread_hug_neomouse.svg
├── neobread_hug_neomouse_heart.svg
├── neobread_hug_potato.svg
├── neobread_hug_potato_heart.svg
├── neobread_hug_wolf.svg
├── neobread_hug_wolf_heart.svg
├── neobread_kisser.svg
├── neobread_knife.svg
├── neobread_laptop.svg
├── neobread_laugh.svg
├── neobread_laugh_sweat.svg
├── neobread_laugh_tears.svg
├── neobread_lego.svg
├── neobread_magnifying_glass.svg
├── neobread_meeple.svg
├── neobread_meeting.svg
├── neobread_megaphone.svg
├── neobread_mug.svg
├── neobread_nd.svg
├── neobread_no_spoons.svg
├── neobread_nom_cookie.svg
├── neobread_nom_homework.svg
├── neobread_nom_potato.svg
├── neobread_party.svg
├── neobread_pat.svg
├── neobread_peek.svg
├── neobread_pensive.svg
├── neobread_pleading.svg
├── neobread_pleased.svg
├── neobread_popcorn.svg
├── neobread_sad.svg
├── neobread_scream.svg
├── neobread_scream_angry.svg
├── neobread_shrug.svg
├── neobread_sleep.svg
├── neobread_smug.svg
├── neobread_snuggle.svg
├── neobread_snuggle_fox.svg
├── neobread_sob.svg
├── neobread_sob_loud.svg
├── neobread_spoons.svg
├── neobread_surprise.svg
├── neobread_think.svg
├── neobread_thought_bubble.svg
├── neobread_train_wagon.svg
├── neobread_upside_down.svg
├── neobread_uwu.svg
├── neobread_verified.svg
├── neobread_wave.svg
├── neobread_wink.svg
├── neobread_woem.svg
├── neobread_woozy.svg
└── neobread_zipped_mouth.svg
├── neodlr
├── neodlr.svg
├── neodlr_bottom.svg
├── neodlr_hug_bee.svg
├── neodlr_hug_bee_heart.svg
├── neodlr_hug_bread.svg
├── neodlr_hug_bread_heart.svg
├── neodlr_hug_cat.svg
├── neodlr_hug_cat_heart.svg
├── neodlr_hug_dog.svg
├── neodlr_hug_dog_heart.svg
├── neodlr_hug_fox.svg
├── neodlr_hug_fox_heart.svg
├── neodlr_hug_neomouse.svg
├── neodlr_hug_neomouse_heart.svg
├── neodlr_pat.svg
└── neodlr_pleading.svg
├── neofinder
├── neofinder.svg
└── neofinder_woozy.svg
├── neofriends
├── neocat_hug_bee.svg
├── neocat_hug_bee_heart.svg
├── neocat_hug_blue_dagn.svg
├── neocat_hug_bread.svg
├── neocat_hug_bread_heart.svg
├── neocat_hug_dlr.svg
├── neocat_hug_dlr_heart.svg
├── neocat_train_wagon.svg
├── neodog_hug_bee.svg
├── neodog_hug_bee_heart.svg
├── neodog_hug_dlr.svg
├── neodog_hug_dlr_heart.svg
├── neodog_train_wagon.svg
├── neofox_hug_bee.svg
├── neofox_hug_bee_heart.svg
├── neofox_hug_blue_dagn.svg
├── neofox_hug_bread.svg
├── neofox_hug_bread_heart.svg
├── neofox_hug_dlr.svg
├── neofox_hug_dlr_heart.svg
├── neofox_train_wagon.svg
├── neomouse_hug_bee.svg
├── neomouse_hug_bee_heart.svg
├── neomouse_hug_dlr.svg
├── neomouse_hug_dlr_heart.svg
└── potato_train_wagon.svg
├── neossb
└── neossb.svg
├── package-lock.json
├── package.json
├── scripts
├── create-tar-archives.sh
├── create-zip-archives.sh
├── findChanges.ts
├── generateMetaJson.ts
├── generatePNGs.ts
├── generatePreviews.ts
└── utils.ts
└── tsconfig.json
/.github/workflows/create-release.yml:
--------------------------------------------------------------------------------
1 | name: Create Release
2 | on:
3 | push:
4 | tags:
5 | - '*'
6 |
7 | jobs:
8 | create-release:
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v4
14 |
15 | - name: Install node
16 | uses: actions/setup-node@v4
17 | with:
18 | node-version: 20
19 |
20 | - name: Install dependencies
21 | run: npm install
22 |
23 | - name: Find changes
24 | id: find-changes
25 | run: npm run find-changes
26 | env:
27 | GITHUB_TOKEN: ${{ github.token }}
28 | GITHUB_REF: ${{ github.ref_name }}
29 |
30 | - name: Generate PNGs
31 | run: npm run generate-pngs
32 |
33 | - name: Generate previews
34 | run: npm run generate-previews
35 | if: ${{ steps.find-changes.outputs.hasSvgChanges == 'true' }}
36 |
37 | - name: Create tar archives
38 | run: npm run create-tars
39 |
40 | - name: Generate meta.json
41 | run: npm run generate-meta
42 |
43 | - name: Generate hi-res PNGs
44 | run: npm run generate-pngs -- --size 2048
45 |
46 | - name: Create zip archives
47 | run: npm run create-zips
48 |
49 | - name: Create release
50 | uses: softprops/action-gh-release@v2
51 | with:
52 | body: ${{ steps.find-changes.outputs.releaseNotes }}
53 | files: |
54 | tar/**
55 | zip/**
56 | previews/**
57 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | png
4 | tar
5 | zip
6 | previews
7 | manifest.json
8 | filemap.json
9 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 20
2 |
--------------------------------------------------------------------------------
/blobbee/blobbee.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
--------------------------------------------------------------------------------
/blobbee/blobbee_eyes.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
35 |
--------------------------------------------------------------------------------
/blobbee/blobbee_flag_ace.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
24 |
--------------------------------------------------------------------------------
/blobbee/blobbee_flag_aro.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
--------------------------------------------------------------------------------
/blobbee/blobbee_flag_bi.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
--------------------------------------------------------------------------------
/blobbee/blobbee_flag_france.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
--------------------------------------------------------------------------------
/blobbee/blobbee_flag_lesbian.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
--------------------------------------------------------------------------------
/blobbee/blobbee_flag_nb.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
24 |
--------------------------------------------------------------------------------
/blobbee/blobbee_flag_pan.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
--------------------------------------------------------------------------------
/blobbee/blobbee_flag_trans.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
--------------------------------------------------------------------------------
/blobbee/blobbee_upside_down.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
--------------------------------------------------------------------------------
/misc/thought_bubble_close.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
--------------------------------------------------------------------------------
/neobread/neobread.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
--------------------------------------------------------------------------------
/neobread/neobread_3c.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
--------------------------------------------------------------------------------
/neobread/neobread_blep.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
--------------------------------------------------------------------------------
/neobread/neobread_blush.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/neobread/neobread_blush_hide.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
--------------------------------------------------------------------------------
/neobread/neobread_cat_ears.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
--------------------------------------------------------------------------------
/neobread/neobread_chilli_face.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
26 |
--------------------------------------------------------------------------------
/neobread/neobread_drake_dislike.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
--------------------------------------------------------------------------------
/neobread/neobread_drake_like.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/neobread/neobread_eye_roll.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/neobread/neobread_eyes.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
--------------------------------------------------------------------------------
/neobread/neobread_facepalm.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
--------------------------------------------------------------------------------
/neobread/neobread_fingerguns.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
--------------------------------------------------------------------------------
/neobread/neobread_fingerguns_cool.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
--------------------------------------------------------------------------------
/neobread/neobread_flag_ace.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
--------------------------------------------------------------------------------
/neobread/neobread_flag_agender.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
24 |
--------------------------------------------------------------------------------
/neobread/neobread_flag_aro.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/neobread/neobread_flag_bi.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
--------------------------------------------------------------------------------
/neobread/neobread_flag_lesbian.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/neobread/neobread_flag_nb.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
--------------------------------------------------------------------------------
/neobread/neobread_flag_pan.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
--------------------------------------------------------------------------------
/neobread/neobread_flag_rainbow.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
--------------------------------------------------------------------------------
/neobread/neobread_flag_trans.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/neobread/neobread_grimace.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
27 |
--------------------------------------------------------------------------------
/neobread/neobread_grumpy.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/neobread/neobread_halo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
--------------------------------------------------------------------------------
/neobread/neobread_happy.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/neobread/neobread_heart.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
26 |
--------------------------------------------------------------------------------
/neobread/neobread_heart_black.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
26 |
--------------------------------------------------------------------------------
/neobread/neobread_heart_eyes.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
24 |
--------------------------------------------------------------------------------
/neobread/neobread_heart_red.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
26 |
--------------------------------------------------------------------------------
/neobread/neobread_kisser.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
24 |
--------------------------------------------------------------------------------
/neobread/neobread_laugh.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
--------------------------------------------------------------------------------
/neobread/neobread_laugh_sweat.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
--------------------------------------------------------------------------------
/neobread/neobread_pat.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
--------------------------------------------------------------------------------
/neobread/neobread_pensive.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
--------------------------------------------------------------------------------
/neobread/neobread_pleading.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
30 |
--------------------------------------------------------------------------------
/neobread/neobread_pleased.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
--------------------------------------------------------------------------------
/neobread/neobread_sad.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/neobread/neobread_scream.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
--------------------------------------------------------------------------------
/neobread/neobread_scream_angry.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/neobread/neobread_shrug.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
--------------------------------------------------------------------------------
/neobread/neobread_sleep.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
24 |
--------------------------------------------------------------------------------
/neobread/neobread_smug.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
--------------------------------------------------------------------------------
/neobread/neobread_sob.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
--------------------------------------------------------------------------------
/neobread/neobread_sob_loud.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
--------------------------------------------------------------------------------
/neobread/neobread_surprise.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
27 |
--------------------------------------------------------------------------------
/neobread/neobread_think.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
--------------------------------------------------------------------------------
/neobread/neobread_upside_down.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/neobread/neobread_uwu.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/neobread/neobread_wave.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
--------------------------------------------------------------------------------
/neobread/neobread_wink.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/neobread/neobread_woem.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/neobread/neobread_woozy.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
--------------------------------------------------------------------------------
/neofinder/neofinder.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "emojis",
3 | "version": "1.0.0",
4 | "description": "Various sets of emojis.",
5 | "type": "module",
6 | "scripts": {
7 | "generate-pngs": "tsx ./scripts/generatePNGs.ts",
8 | "create-tars": "./scripts/create-tar-archives.sh",
9 | "create-zips": "./scripts/create-zip-archives.sh",
10 | "generate-meta": "tsx ./scripts/generateMetaJson.ts",
11 | "find-changes": "tsx ./scripts/findChanges.ts",
12 | "generate-previews": "tsx ./scripts/generatePreviews.ts"
13 | },
14 | "license": "MIT",
15 | "dependencies": {
16 | "@actions/core": "^1.10.1",
17 | "@actions/github": "^6.0.0",
18 | "@types/archiver": "^6.0.2",
19 | "@types/cli-progress": "^3.11.5",
20 | "@types/node": "^20.11.30",
21 | "@types/yargs": "^17.0.32",
22 | "archiver": "^7.0.1",
23 | "canvas": "^2.11.2",
24 | "cli-progress": "^3.12.0",
25 | "nan": "^2.19.0",
26 | "svg2img": "^1.0.0-beta.2",
27 | "tsx": "^4.7.1",
28 | "typescript": "^5.4.2",
29 | "yargs": "^17.7.2"
30 | },
31 | "engines": {
32 | "node": ">=20"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/scripts/create-tar-archives.sh:
--------------------------------------------------------------------------------
1 | mkdir -p ./tar
2 | for dir in ./png/*/
3 | do
4 | dir=${dir%*/} # Remove trailing /
5 | dirname=${dir##*/} # Remove path before directory name
6 | echo "\n$dirname"
7 | tar -czv -f ./tar/${dirname}.tar.gz -C ${dir} .
8 | done
9 |
--------------------------------------------------------------------------------
/scripts/create-zip-archives.sh:
--------------------------------------------------------------------------------
1 | mkdir -p ./zip
2 | for dir in ./png/*/
3 | do
4 | dir=${dir%*/} # Remove trailing /
5 | dirname=${dir##*/} # Remove path before directory name
6 | echo "\n$dirname"
7 | zip -rj ./zip/${dirname}.zip ${dir}/*
8 | done
9 |
--------------------------------------------------------------------------------
/scripts/generateMetaJson.ts:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import fs from 'fs';
3 |
4 | const baseMeta = {
5 | metaVersion: 2,
6 | host: 'beehive.gay',
7 | exportedAt: new Date().toISOString(),
8 | };
9 |
10 | const pngDirectory = path.resolve('.', 'png');
11 |
12 | if (!fs.existsSync(pngDirectory)) {
13 | throw new Error('png directory does not exist');
14 | }
15 |
16 | const directories = fs
17 | .readdirSync(pngDirectory)
18 | .filter((filename) => fs.statSync(filename).isDirectory());
19 |
20 | directories.forEach((directory) => {
21 | const dirPath = path.resolve(pngDirectory, directory);
22 | const filenames = fs
23 | .readdirSync(dirPath)
24 | .filter((filename) => filename.endsWith('.png'));
25 |
26 | const emojis = filenames.map((filename) => {
27 | const name = filename.replace('.png', '');
28 | const category = name.includes('_')
29 | ? name.slice(0, name.indexOf('_'))
30 | : name;
31 |
32 | return {
33 | downloaded: true,
34 | fileName: filename,
35 | emoji: {
36 | name,
37 | category,
38 | aliases: [],
39 | },
40 | };
41 | });
42 |
43 | const meta = {
44 | ...baseMeta,
45 | emojis,
46 | };
47 |
48 | const outPath = path.resolve(dirPath, 'meta.json');
49 | fs.writeFileSync(outPath, JSON.stringify(meta, null, 2));
50 | });
51 |
--------------------------------------------------------------------------------
/scripts/generatePNGs.ts:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import fs from 'fs';
3 |
4 | import yargs from 'yargs';
5 | import cliProgress, { Presets } from 'cli-progress';
6 |
7 | import { getSvgDirectories, svg2img } from './utils.js';
8 | import { svg2imgOptions } from 'svg2img';
9 |
10 | const DEFAULT_SIZE = 256;
11 | const ALL_DIRECTORIES = getSvgDirectories();
12 |
13 | const convertSvg = (svg: string, options?: svg2imgOptions): Promise =>
14 | new Promise((resolve, reject) =>
15 | svg2img(svg, options, (err, buffer) => {
16 | if (err) {
17 | reject(err);
18 | }
19 | resolve(buffer);
20 | })
21 | );
22 |
23 | interface GenerateArgs {
24 | svgPath: string;
25 | pngPath: string;
26 | size: number;
27 | }
28 |
29 | const generate = async ({ svgPath, pngPath, size }: GenerateArgs) => {
30 | const buffer = await convertSvg(svgPath, {
31 | resvg: {
32 | fitTo: {
33 | mode: 'width',
34 | value: size,
35 | },
36 | },
37 | });
38 |
39 | fs.writeFileSync(pngPath, buffer);
40 | };
41 |
42 | const getParamsForSvgs = (
43 | svgDir: string,
44 | pngDir: string,
45 | size: number
46 | ): GenerateArgs[] => {
47 | const svgs = fs
48 | .readdirSync(svgDir)
49 | .filter((filename) => filename.endsWith('.svg'));
50 |
51 | if (!fs.existsSync(pngDir)) {
52 | fs.mkdirSync(pngDir, { recursive: true });
53 | }
54 |
55 | return svgs.map((filename) => ({
56 | svgPath: path.resolve(svgDir, filename),
57 | pngPath: path.resolve(pngDir, filename.replace('.svg', '.png')),
58 | size,
59 | }));
60 | };
61 |
62 | interface RunArgs {
63 | directories?: string[];
64 | size?: number;
65 | }
66 |
67 | const run = async ({
68 | directories = ALL_DIRECTORIES,
69 | size = DEFAULT_SIZE,
70 | }: RunArgs) => {
71 | const generationParams = directories.flatMap((dir) => {
72 | const svgDir = path.resolve('.', dir);
73 | const pngDir = path.resolve(
74 | '.',
75 | 'png',
76 | size === DEFAULT_SIZE ? dir : `${dir}-${size}`
77 | );
78 | return getParamsForSvgs(svgDir, pngDir, size);
79 | });
80 |
81 | const progress = new cliProgress.MultiBar({}, Presets.shades_classic);
82 | const progressBar = progress.create(generationParams.length, 0);
83 |
84 | for (const params of generationParams) {
85 | await generate(params);
86 | progress.log(
87 | `${params.svgPath.split('/').at(-1)} -> ${params.pngPath
88 | .split('/')
89 | .at(-1)}\n`
90 | );
91 | progressBar.increment();
92 | }
93 |
94 | progress.remove(progressBar);
95 | progress.stop();
96 | };
97 |
98 | const argv = yargs(process.argv)
99 | .option('directories', {
100 | alias: 'd',
101 | type: 'string',
102 | description: 'Input directories containing SVGs',
103 | array: true,
104 | choices: ALL_DIRECTORIES,
105 | })
106 | .option('size', {
107 | alias: 's',
108 | type: 'number',
109 | description: 'The size to generate PNGs at, in pixels',
110 | default: DEFAULT_SIZE,
111 | })
112 | .parseSync();
113 |
114 | run(argv);
115 |
--------------------------------------------------------------------------------
/scripts/generatePreviews.ts:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import fs from 'fs';
3 | import { createCanvas, Image } from 'canvas';
4 | import yargs from 'yargs';
5 |
6 | const MAX_COLUMNS = 10;
7 | const EMOJI_SIZE = 256;
8 | const SPACE_PER_EMOJI = 300;
9 | const SPACING = SPACE_PER_EMOJI - EMOJI_SIZE;
10 |
11 | const generateForDir = (dirPath: string, outPath: string) => {
12 | const filenames = fs
13 | .readdirSync(dirPath)
14 | .filter((filename) => filename.endsWith('.png'));
15 |
16 | const rows = Math.ceil(filenames.length / MAX_COLUMNS);
17 | const columns = rows === 1 ? filenames.length : MAX_COLUMNS;
18 |
19 | const height = rows * SPACE_PER_EMOJI;
20 | const width = columns * SPACE_PER_EMOJI;
21 |
22 | const canvas = createCanvas(width, height);
23 | const ctx = canvas.getContext('2d');
24 |
25 | ctx.fillStyle = '#cfb0eb';
26 | ctx.fillRect(0, 0, width, height);
27 |
28 | filenames.forEach((filename, index) => {
29 | const filePath = path.join(dirPath, filename);
30 |
31 | const x = (index % MAX_COLUMNS) * SPACE_PER_EMOJI + SPACING / 2;
32 | const y = Math.floor(index / MAX_COLUMNS) * SPACE_PER_EMOJI + SPACING / 2;
33 |
34 | const fileData = fs.readFileSync(filePath);
35 | const image = new Image();
36 | image.onload = () => {
37 | ctx.drawImage(image, x, y);
38 | };
39 | image.src = fileData;
40 | image.width = EMOJI_SIZE;
41 | });
42 |
43 | const output = canvas.toBuffer();
44 |
45 | fs.writeFileSync(outPath, output);
46 | };
47 |
48 | const { onlyUpdates } = yargs(process.argv)
49 | .option('only-updates', {
50 | type: 'boolean',
51 | description:
52 | 'Only create an image for the directory containing updated emojis',
53 | })
54 | .parseSync();
55 |
56 | const pngDirectory = path.resolve('.', 'png');
57 | if (!fs.existsSync(pngDirectory)) {
58 | throw new Error('png directory does not exist');
59 | }
60 |
61 | const pngDirs = fs
62 | .readdirSync(pngDirectory)
63 | .filter((filename) =>
64 | fs.statSync(path.join(pngDirectory, filename)).isDirectory()
65 | );
66 |
67 | const updatesDirName = pngDirs.find((filename) =>
68 | filename.startsWith('updates')
69 | );
70 |
71 | if (onlyUpdates) {
72 | if (!updatesDirName) {
73 | throw new Error('No updates directory found');
74 | }
75 |
76 | const updatesDir = path.join(pngDirectory, updatesDirName);
77 | const outPath = path.resolve('.', 'preview.png');
78 | generateForDir(updatesDir, outPath);
79 |
80 | process.exit(0);
81 | }
82 |
83 | const outputDir = path.resolve('.', 'previews');
84 | if (!fs.existsSync(outputDir)) {
85 | fs.mkdirSync(outputDir, { recursive: true });
86 | }
87 |
88 | pngDirs.forEach((dirName) => {
89 | const dirPath = path.join(pngDirectory, dirName);
90 | const outPath = path.join(outputDir, `preview-${dirName}.png`);
91 | generateForDir(dirPath, outPath);
92 | });
93 |
--------------------------------------------------------------------------------
/scripts/utils.ts:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import fs from 'fs';
3 |
4 | import svg2imgDefault from 'svg2img';
5 |
6 | export const getSvgDirectories = () => {
7 | const gitignorePath = path.resolve('.', '.gitignore');
8 | const gitignoreItems = fs.readFileSync(gitignorePath, 'utf-8').split('\n');
9 |
10 | const parentDir = path.resolve('.');
11 | return fs
12 | .readdirSync(parentDir)
13 | .filter((filename) => fs.statSync(filename).isDirectory())
14 | .filter((filename) => !gitignoreItems.includes(filename))
15 | .filter((name) => !name.startsWith('.') && name !== 'scripts');
16 | };
17 |
18 | export const svg2img =
19 | svg2imgDefault as unknown as typeof svg2imgDefault.default;
20 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "esModuleInterop": true,
5 | "module": "Node16",
6 | "moduleResolution": "node16",
7 | "strict": true,
8 | "target": "es2017",
9 | "noImplicitAny": false
10 | },
11 | "include": ["scripts/**/*"]
12 | }
13 |
--------------------------------------------------------------------------------