├── .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 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /blobbee/blobbee_eyes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /blobbee/blobbee_flag_ace.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /blobbee/blobbee_flag_aro.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /blobbee/blobbee_flag_bi.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /blobbee/blobbee_flag_france.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /blobbee/blobbee_flag_lesbian.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /blobbee/blobbee_flag_nb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /blobbee/blobbee_flag_pan.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /blobbee/blobbee_flag_trans.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /blobbee/blobbee_upside_down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /misc/thought_bubble_close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /neobread/neobread.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /neobread/neobread_3c.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /neobread/neobread_blep.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /neobread/neobread_blush.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /neobread/neobread_blush_hide.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /neobread/neobread_cat_ears.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /neobread/neobread_chilli_face.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /neobread/neobread_drake_dislike.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /neobread/neobread_drake_like.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /neobread/neobread_eye_roll.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /neobread/neobread_eyes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /neobread/neobread_facepalm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /neobread/neobread_fingerguns.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /neobread/neobread_fingerguns_cool.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /neobread/neobread_flag_ace.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /neobread/neobread_flag_agender.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /neobread/neobread_flag_aro.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /neobread/neobread_flag_bi.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /neobread/neobread_flag_lesbian.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /neobread/neobread_flag_nb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /neobread/neobread_flag_pan.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /neobread/neobread_flag_rainbow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /neobread/neobread_flag_trans.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /neobread/neobread_grimace.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /neobread/neobread_grumpy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /neobread/neobread_halo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /neobread/neobread_happy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /neobread/neobread_heart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /neobread/neobread_heart_black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /neobread/neobread_heart_eyes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /neobread/neobread_heart_red.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /neobread/neobread_kisser.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /neobread/neobread_laugh.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /neobread/neobread_laugh_sweat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /neobread/neobread_pat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /neobread/neobread_pensive.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /neobread/neobread_pleading.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /neobread/neobread_pleased.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /neobread/neobread_sad.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /neobread/neobread_scream.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /neobread/neobread_scream_angry.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /neobread/neobread_shrug.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /neobread/neobread_sleep.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /neobread/neobread_smug.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /neobread/neobread_sob.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /neobread/neobread_sob_loud.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /neobread/neobread_surprise.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /neobread/neobread_think.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /neobread/neobread_upside_down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /neobread/neobread_uwu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /neobread/neobread_wave.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /neobread/neobread_wink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /neobread/neobread_woem.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /neobread/neobread_woozy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /neofinder/neofinder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 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 | --------------------------------------------------------------------------------